summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/StagefrightRecorder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice/StagefrightRecorder.cpp')
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp298
1 files changed, 257 insertions, 41 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index e521fae..442dba1 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <utils/Log.h>
+#include <inttypes.h>
#include "WebmWriter.h"
#include "StagefrightRecorder.h"
@@ -43,6 +44,7 @@
#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/WAVEWriter.h>
#include <media/MediaProfiles.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
@@ -55,9 +57,12 @@
#include <system/audio.h>
#include "ARTPWriter.h"
+#include <stagefright/AVExtensions.h>
namespace android {
+static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 4GB
+
// To collect the encoder usage for the battery app
static void addBatteryData(uint32_t params) {
sp<IBinder> binder =
@@ -75,7 +80,8 @@ StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
mOutputFd(-1),
mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
- mStarted(false) {
+ mStarted(false),
+ mRecPaused(false) {
ALOGV("Constructor");
reset();
@@ -179,7 +185,8 @@ status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) {
status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
ALOGV("setVideoEncoder: %d", ve);
if (ve < VIDEO_ENCODER_DEFAULT ||
- ve >= VIDEO_ENCODER_LIST_END) {
+ (ve >= VIDEO_ENCODER_LIST_END && ve <= VIDEO_ENCODER_LIST_VENDOR_START) ||
+ ve >= VIDEO_ENCODER_LIST_VENDOR_END) {
ALOGE("Invalid video encoder: %d", ve);
return BAD_VALUE;
}
@@ -249,7 +256,7 @@ status_t StagefrightRecorder::setInputSurface(
}
status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
- ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
+ ALOGV("setOutputFile: %d, %" PRId64 ", %" PRId64 "", fd, offset, length);
// These don't make any sense, do they?
CHECK_EQ(offset, 0ll);
CHECK_EQ(length, 0ll);
@@ -364,7 +371,7 @@ status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) {
status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
ALOGV("setParamAudioNumberOfChannels: %d", channels);
- if (channels <= 0 || channels >= 3) {
+ if (channels <= 0 || channels >= 7) {
ALOGE("Invalid number of audio channels: %d", channels);
return BAD_VALUE;
}
@@ -416,42 +423,46 @@ status_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) {
}
status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
- ALOGV("setParamMaxFileDurationUs: %lld us", timeUs);
+ ALOGV("setParamMaxFileDurationUs: %" PRId64 " us", timeUs);
// This is meant for backward compatibility for MediaRecorder.java
if (timeUs <= 0) {
- ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs);
+ ALOGW("Max file duration is not positive: %" PRId64 " us. Disabling duration limit.", timeUs);
timeUs = 0; // Disable the duration limit for zero or negative values.
} else if (timeUs <= 100000LL) { // XXX: 100 milli-seconds
- ALOGE("Max file duration is too short: %lld us", timeUs);
+ ALOGE("Max file duration is too short: %" PRId64 " us", timeUs);
return BAD_VALUE;
}
if (timeUs <= 15 * 1000000LL) {
- ALOGW("Target duration (%lld us) too short to be respected", timeUs);
+ ALOGW("Target duration (%" PRId64 " us) too short to be respected", timeUs);
}
mMaxFileDurationUs = timeUs;
return OK;
}
status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
- ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes);
+ ALOGV("setParamMaxFileSizeBytes: %" PRId64 " bytes", bytes);
// This is meant for backward compatibility for MediaRecorder.java
if (bytes <= 0) {
- ALOGW("Max file size is not positive: %lld bytes. "
+ ALOGW("Max file size is not positive: %" PRId64 " bytes. "
"Disabling file size limit.", bytes);
bytes = 0; // Disable the file size limit for zero or negative values.
} else if (bytes <= 1024) { // XXX: 1 kB
- ALOGE("Max file size is too small: %lld bytes", bytes);
+ ALOGE("Max file size is too small: %" PRId64 " bytes", bytes);
return BAD_VALUE;
}
if (bytes <= 100 * 1024) {
- ALOGW("Target file size (%lld bytes) is too small to be respected", bytes);
+ ALOGW("Target file size (%" PRId64 " bytes) is too small to be respected", bytes);
}
mMaxFileSizeBytes = bytes;
+
+ // If requested size is >4GB, force 64-bit offsets
+ mUse64BitFileOffset |= (bytes >= kMax32BitFileSize);
+
return OK;
}
@@ -500,9 +511,9 @@ status_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) {
}
status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
- ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
+ ALOGV("setParamTrackTimeStatus: %" PRId64 "", timeDurationUs);
if (timeDurationUs < 20000) { // Infeasible if shorter than 20 ms?
- ALOGE("Tracking time duration too short: %lld us", timeDurationUs);
+ ALOGE("Tracking time duration too short: %" PRId64 " us", timeDurationUs);
return BAD_VALUE;
}
mTrackEveryTimeDurationUs = timeDurationUs;
@@ -581,11 +592,11 @@ status_t StagefrightRecorder::setParamCaptureFpsEnable(int32_t captureFpsEnable)
status_t StagefrightRecorder::setParamCaptureFps(float fps) {
ALOGV("setParamCaptureFps: %.2f", fps);
- int64_t timeUs = (int64_t) (1000000.0 / fps + 0.5f);
+ int64_t timeUs = (int64_t) (1000000.0f / fps + 0.5f);
// Not allowing time more than a day
if (timeUs <= 0 || timeUs > 86400*1E6) {
- ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", timeUs);
+ ALOGE("Time between frame capture (%" PRId64 ") is out of range [0, 1 Day]", timeUs);
return BAD_VALUE;
}
@@ -813,9 +824,15 @@ status_t StagefrightRecorder::prepareInternal() {
status = setupMPEG2TSRecording();
break;
+ case OUTPUT_FORMAT_WAVE:
+ status = setupWAVERecording();
+ break;
+
default:
- ALOGE("Unsupported output file format: %d", mOutputFormat);
- status = UNKNOWN_ERROR;
+ if (handleCustomRecording() != OK) {
+ ALOGE("Unsupported output file format: %d", mOutputFormat);
+ status = UNKNOWN_ERROR;
+ }
break;
}
@@ -836,6 +853,22 @@ status_t StagefrightRecorder::start() {
return INVALID_OPERATION;
}
+ if (mRecPaused == true) {
+ status_t err = mWriter->start();
+ if (err != OK) {
+ ALOGE("Writer start in StagefrightRecorder pause failed");
+ return err;
+ }
+
+ err = setSourcePause(false);
+ if (err != OK) {
+ ALOGE("Source start after pause failed");
+ return err;
+ }
+
+ mRecPaused = false;
+ return OK;
+ }
status_t status = OK;
if (mVideoSource != VIDEO_SOURCE_SURFACE) {
@@ -872,6 +905,7 @@ status_t StagefrightRecorder::start() {
case OUTPUT_FORMAT_AAC_ADTS:
case OUTPUT_FORMAT_RTP_AVP:
case OUTPUT_FORMAT_MPEG2TS:
+ case OUTPUT_FORMAT_WAVE:
{
status = mWriter->start();
break;
@@ -879,8 +913,10 @@ status_t StagefrightRecorder::start() {
default:
{
- ALOGE("Unsupported output file format: %d", mOutputFormat);
- status = UNKNOWN_ERROR;
+ if (handleCustomOutputFormats() != OK) {
+ ALOGE("Unsupported output file format: %d", mOutputFormat);
+ status = UNKNOWN_ERROR;
+ }
break;
}
}
@@ -927,13 +963,36 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {
}
}
- sp<AudioSource> audioSource =
- new AudioSource(
- mAudioSource,
- mOpPackageName,
- sourceSampleRate,
- mAudioChannels,
- mSampleRate);
+ // If using QCOM extension (Camera 1 HAL) for slow motion recording
+ // mCaptureFpsEnable and mCaptureFps will not be set via setCaptureRate
+ // We need to query from AVUtil, in order to support slow motion audio recording
+ if (mVideoSourceNode != NULL) {
+ int hfrRatio = AVUtils::get()->HFRUtils().getHFRRatio(mVideoSourceNode->getFormat());
+ if (hfrRatio != 1) {
+ // Upscale the sample rate for slow motion recording.
+ // Fail audio source creation if source sample rate is too high, as it could
+ // cause out-of-memory due to large input buffer size. And audio recording
+ // probably doesn't make sense in the scenario, since the slow-down factor
+ // is probably huge (eg. mSampleRate=48K, hfrRatio=240, mFrameRate=1).
+ const static int32_t SAMPLE_RATE_HZ_MAX = 192000;
+ sourceSampleRate =
+ (mSampleRate * hfrRatio + mFrameRate / 2) / mFrameRate;
+ if (sourceSampleRate < mSampleRate || sourceSampleRate > SAMPLE_RATE_HZ_MAX) {
+ ALOGE("source sample rate out of range! "
+ "(mSampleRate %d, hfrRatio %d, mFrameRate %d",
+ mSampleRate, hfrRatio, mFrameRate);
+ return NULL;
+ }
+ }
+ }
+
+
+ sp<AudioSource> audioSource = AVFactory::get()->createAudioSource(
+ mAudioSource,
+ mOpPackageName,
+ sourceSampleRate,
+ mAudioChannels,
+ mSampleRate);
status_t err = audioSource->initCheck();
@@ -963,10 +1022,15 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {
format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
format->setInt32("aac-profile", OMX_AUDIO_AACObjectELD);
break;
+ case AUDIO_ENCODER_LPCM:
+ format->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
+ break;
default:
- ALOGE("Unknown audio encoder: %d", mAudioEncoder);
- return NULL;
+ if (handleCustomAudioSource(format) != OK) {
+ ALOGE("Unknown audio encoder: %d", mAudioEncoder);
+ return NULL;
+ }
}
int32_t maxInputSize;
@@ -984,12 +1048,20 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {
sp<MediaSource> audioEncoder =
MediaCodecSource::Create(mLooper, format, audioSource);
+ // If encoder could not be created (as in LPCM), then
+ // use the AudioSource directly as the MediaSource.
+ if (audioEncoder == NULL &&
+ mAudioEncoder == AUDIO_ENCODER_LPCM) {
+ ALOGD("No encoder is needed for linear PCM format");
+ audioEncoder = audioSource;
+ }
mAudioSourceNode = audioSource;
if (audioEncoder == NULL) {
ALOGE("Failed to create audio encoder");
}
+ mAudioEncoderOMX = audioEncoder;
return audioEncoder;
}
@@ -1155,6 +1227,15 @@ status_t StagefrightRecorder::setupMPEG2TSRecording() {
return OK;
}
+status_t StagefrightRecorder::setupWAVERecording() {
+ CHECK(mOutputFormat == OUTPUT_FORMAT_WAVE);
+ CHECK(mAudioEncoder == AUDIO_ENCODER_LPCM);
+ CHECK(mAudioSource != AUDIO_SOURCE_CNT);
+
+ mWriter = new WAVEWriter(mOutputFd);
+ return setupRawAudioRecording();
+}
+
void StagefrightRecorder::clipVideoFrameRate() {
ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder);
if (mFrameRate == -1) {
@@ -1222,7 +1303,8 @@ status_t StagefrightRecorder::checkVideoEncoderCapabilities() {
(mVideoEncoder == VIDEO_ENCODER_H263 ? MEDIA_MIMETYPE_VIDEO_H263 :
mVideoEncoder == VIDEO_ENCODER_MPEG_4_SP ? MEDIA_MIMETYPE_VIDEO_MPEG4 :
mVideoEncoder == VIDEO_ENCODER_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 :
- mVideoEncoder == VIDEO_ENCODER_H264 ? MEDIA_MIMETYPE_VIDEO_AVC : ""),
+ mVideoEncoder == VIDEO_ENCODER_H264 ? MEDIA_MIMETYPE_VIDEO_AVC :
+ mVideoEncoder == VIDEO_ENCODER_H265 ? MEDIA_MIMETYPE_VIDEO_HEVC : ""),
false /* decoder */, true /* hwCodec */, &codecs);
if (!mCaptureFpsEnable) {
@@ -1309,8 +1391,10 @@ void StagefrightRecorder::setDefaultVideoEncoderIfNecessary() {
int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName(
"vid.codec", mCameraId, CAMCORDER_QUALITY_LOW);
- if (videoCodec > VIDEO_ENCODER_DEFAULT &&
- videoCodec < VIDEO_ENCODER_LIST_END) {
+ if ((videoCodec > VIDEO_ENCODER_DEFAULT &&
+ videoCodec < VIDEO_ENCODER_LIST_END) ||
+ (videoCodec > VIDEO_ENCODER_LIST_VENDOR_START &&
+ videoCodec < VIDEO_ENCODER_LIST_VENDOR_END)) {
mVideoEncoder = (video_encoder)videoCodec;
} else {
// default to H.264 if camcorder profile not available
@@ -1440,22 +1524,23 @@ status_t StagefrightRecorder::setupCameraSource(
videoSize.height = mVideoHeight;
if (mCaptureFpsEnable) {
if (mTimeBetweenCaptureUs < 0) {
- ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld",
+ ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %" PRId64 "",
mTimeBetweenCaptureUs);
return BAD_VALUE;
}
- mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
+ mCameraSourceTimeLapse = AVFactory::get()->CreateCameraSourceTimeLapseFromCamera(
mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
videoSize, mFrameRate, mPreviewSurface,
mTimeBetweenCaptureUs);
*cameraSource = mCameraSourceTimeLapse;
} else {
- *cameraSource = CameraSource::CreateFromCamera(
+ *cameraSource = AVFactory::get()->CreateCameraSourceFromCamera(
mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
videoSize, mFrameRate,
mPreviewSurface);
}
+ AVUtils::get()->cacheCaptureBuffers(mCamera, mVideoEncoder);
mCamera.clear();
mCameraProxy.clear();
if (*cameraSource == NULL) {
@@ -1487,6 +1572,15 @@ status_t StagefrightRecorder::setupCameraSource(
return OK;
}
+bool StagefrightRecorder::setCustomVideoEncoderMime(const video_encoder videoEncoder,
+ sp<AMessage> format) {
+ if (videoEncoder == VIDEO_ENCODER_H265) {
+ format->setString("mime", MEDIA_MIMETYPE_VIDEO_HEVC);
+ return true;
+ }
+ return false;
+}
+
status_t StagefrightRecorder::setupVideoEncoder(
sp<MediaSource> cameraSource,
sp<MediaSource> *source) {
@@ -1512,6 +1606,9 @@ status_t StagefrightRecorder::setupVideoEncoder(
break;
default:
+ if (setCustomVideoEncoderMime(mVideoEncoder, format)) {
+ break;
+ }
CHECK(!"Should not be here, unsupported video encoding.");
break;
}
@@ -1535,13 +1632,13 @@ status_t StagefrightRecorder::setupVideoEncoder(
format->setInt32("width", mVideoWidth);
format->setInt32("height", mVideoHeight);
format->setInt32("stride", mVideoWidth);
- format->setInt32("slice-height", mVideoWidth);
+ format->setInt32("slice-height", mVideoHeight);
format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
// set up time lapse/slow motion for surface source
if (mCaptureFpsEnable) {
if (mTimeBetweenCaptureUs <= 0) {
- ALOGE("Invalid mTimeBetweenCaptureUs value: %lld",
+ ALOGE("Invalid mTimeBetweenCaptureUs value: %" PRId64 "",
mTimeBetweenCaptureUs);
return BAD_VALUE;
}
@@ -1553,6 +1650,10 @@ status_t StagefrightRecorder::setupVideoEncoder(
format->setInt32("frame-rate", mFrameRate);
format->setInt32("i-frame-interval", mIFramesIntervalSec);
+ if (cameraSource != NULL) {
+ setupCustomVideoEncoderParams(cameraSource, format);
+ }
+
if (mVideoTimeScale > 0) {
format->setInt32("time-scale", mVideoTimeScale);
}
@@ -1594,6 +1695,8 @@ status_t StagefrightRecorder::setupVideoEncoder(
mGraphicBufferProducer = encoder->getGraphicBufferProducer();
}
+ mVideoSourceNode = cameraSource;
+ mVideoEncoderOMX = encoder;
*source = encoder;
return OK;
@@ -1611,11 +1714,14 @@ status_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) {
case AUDIO_ENCODER_AAC:
case AUDIO_ENCODER_HE_AAC:
case AUDIO_ENCODER_AAC_ELD:
+ case AUDIO_ENCODER_LPCM:
break;
default:
- ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
- return UNKNOWN_ERROR;
+ if (handleCustomAudioEncoder() != OK) {
+ ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
+ return UNKNOWN_ERROR;
+ }
}
sp<MediaSource> audioEncoder = createAudioSource();
@@ -1637,7 +1743,7 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
if (mOutputFormat == OUTPUT_FORMAT_WEBM) {
writer = new WebmWriter(mOutputFd);
} else {
- writer = mp4writer = new MPEG4Writer(mOutputFd);
+ writer = mp4writer = AVFactory::get()->CreateMPEG4Writer(mOutputFd);
}
if (mVideoSource < VIDEO_SOURCE_LIST_END) {
@@ -1708,6 +1814,8 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
int64_t startTimeUs = systemTime() / 1000;
(*meta)->setInt64(kKeyTime, startTimeUs);
+ int64_t startTimeBootUs = systemTime(SYSTEM_TIME_BOOTTIME) / 1000;
+ (*meta)->setInt64(kKeyTimeBoot, startTimeBootUs);
(*meta)->setInt32(kKeyFileType, mOutputFormat);
(*meta)->setInt32(kKeyBitRate, mTotalBitRate);
if (mMovieTimeScale > 0) {
@@ -1726,10 +1834,23 @@ void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
status_t StagefrightRecorder::pause() {
ALOGV("pause");
+ status_t err = OK;
if (mWriter == NULL) {
return UNKNOWN_ERROR;
}
- mWriter->pause();
+ err = setSourcePause(true);
+ if (err != OK) {
+ ALOGE("StagefrightRecorder pause failed");
+ return err;
+ }
+
+ err = mWriter->pause();
+ if (err != OK) {
+ ALOGE("Writer pause failed");
+ return err;
+ }
+
+ mRecPaused = true;
if (mStarted) {
mStarted = false;
@@ -1758,6 +1879,16 @@ status_t StagefrightRecorder::stop() {
mCameraSourceTimeLapse = NULL;
}
+ if (mRecPaused) {
+ status_t err = setSourcePause(false);
+ if (err != OK) {
+ ALOGE("Source start after pause in StagefrightRecorder stop failed");
+ return err;
+ }
+
+ mRecPaused = false;
+ }
+
if (mWriter != NULL) {
err = mWriter->stop();
mWriter.clear();
@@ -1927,4 +2058,89 @@ status_t StagefrightRecorder::dump(
::write(fd, result.string(), result.size());
return OK;
}
+
+status_t StagefrightRecorder::setSourcePause(bool pause) {
+ status_t err = OK;
+ if (pause) {
+ if (mVideoEncoderOMX != NULL) {
+ err = mVideoEncoderOMX->pause();
+ if (err != OK) {
+ ALOGE("OMX VideoEncoder pause failed");
+ return err;
+ }
+ }
+ if (mAudioEncoderOMX != NULL) {
+ if (mAudioEncoderOMX != mAudioSourceNode) {
+ err = mAudioEncoderOMX->pause();
+ if (err != OK) {
+ ALOGE("OMX AudioEncoder pause failed");
+ return err;
+ }
+ } else {
+ // If AudioSource is the same as MediaSource(as in LPCM),
+ // bypass omx encoder pause() call.
+ ALOGV("OMX AudioEncoder->pause() bypassed");
+ }
+ }
+ if (mVideoSourceNode != NULL) {
+ err = mVideoSourceNode->pause();
+ if (err != OK) {
+ ALOGE("OMX VideoSourceNode pause failed");
+ return err;
+ }
+ }
+ if (mAudioSourceNode != NULL) {
+ err = mAudioSourceNode->pause();
+ if (err != OK) {
+ ALOGE("OMX AudioSourceNode pause failed");
+ return err;
+ }
+ }
+ } else {
+ if (mVideoSourceNode != NULL) {
+ err = mVideoSourceNode->start();
+ if (err != OK) {
+ ALOGE("OMX VideoSourceNode start failed");
+ return err;
+ }
+ }
+ if (mAudioSourceNode != NULL) {
+ err = mAudioSourceNode->start();
+ if (err != OK) {
+ ALOGE("OMX AudioSourceNode start failed");
+ return err;
+ }
+ }
+ if (mVideoEncoderOMX != NULL) {
+ err = mVideoEncoderOMX->start();
+ if (err != OK) {
+ ALOGE("OMX VideoEncoder start failed");
+ return err;
+ }
+ }
+ if (mAudioEncoderOMX != NULL) {
+ if (mAudioEncoderOMX != mAudioSourceNode) {
+ err = mAudioEncoderOMX->start();
+ if (err != OK) {
+ ALOGE("OMX AudioEncoder start failed");
+ return err;
+ }
+ } else {
+ // If AudioSource is the same as MediaSource(as in LPCM),
+ // bypass omx encoder start() call.
+ ALOGV("OMX AudioEncoder->start() bypassed");
+ }
+ }
+ }
+ return err;
+}
+
+void StagefrightRecorder::setupCustomVideoEncoderParams(sp<MediaSource> cameraSource,
+ sp<AMessage> &format) {
+
+ // Setup HFR if needed
+ AVUtils::get()->HFRUtils().initializeHFR(cameraSource->getFormat(), format,
+ mMaxFileDurationUs, mVideoEncoder);
+}
+
} // namespace android