diff options
author | James Dong <jdong@google.com> | 2010-06-29 16:29:19 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-06-29 16:44:19 -0700 |
commit | c0ab2a64589b4cd49734a122b6ef976c7ef530e5 (patch) | |
tree | f6ab79bf257897548e137f4680e35af2d613e775 /media | |
parent | e42b18677e11d27fa1d3eaa1ffcb1f98c5fc8cbf (diff) | |
download | frameworks_base-c0ab2a64589b4cd49734a122b6ef976c7ef530e5.zip frameworks_base-c0ab2a64589b4cd49734a122b6ef976c7ef530e5.tar.gz frameworks_base-c0ab2a64589b4cd49734a122b6ef976c7ef530e5.tar.bz2 |
Added encoding parameters set up for H263 video encoder
Also:
- Allowed start() call when encoder already starts and stop() call when encoder has not started yet
- Handled default value for audio/video sources/encoders and file output format
Change-Id: I03b2f7d3cf570baa0fd011a8c0ad200f2f2a5da1
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 112 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 146 | ||||
-rw-r--r-- | media/libstagefright/codecs/aacenc/AACEncoder.cpp | 10 | ||||
-rw-r--r-- | media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp | 10 | ||||
-rw-r--r-- | media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp | 11 |
5 files changed, 208 insertions, 81 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index c4aeec3..8bc6e9a 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -42,11 +42,16 @@ namespace android { -StagefrightRecorder::StagefrightRecorder() { +StagefrightRecorder::StagefrightRecorder() + : mWriter(NULL), + mOutputFd(-1) { + + LOGV("Constructor"); reset(); } StagefrightRecorder::~StagefrightRecorder() { + LOGV("Destructor"); stop(); if (mOutputFd >= 0) { @@ -56,40 +61,92 @@ StagefrightRecorder::~StagefrightRecorder() { } status_t StagefrightRecorder::init() { + LOGV("init"); return OK; } status_t StagefrightRecorder::setAudioSource(audio_source as) { - mAudioSource = as; + LOGV("setAudioSource: %d", as); + if (as < AUDIO_SOURCE_DEFAULT || + as >= AUDIO_SOURCE_LIST_END) { + return BAD_VALUE; + } + + if (as == AUDIO_SOURCE_DEFAULT) { + mAudioSource = AUDIO_SOURCE_MIC; + } else { + mAudioSource = as; + } return OK; } status_t StagefrightRecorder::setVideoSource(video_source vs) { - mVideoSource = vs; + LOGV("setVideoSource: %d", vs); + if (vs < VIDEO_SOURCE_DEFAULT || + vs >= VIDEO_SOURCE_LIST_END) { + return BAD_VALUE; + } + + if (vs == VIDEO_SOURCE_DEFAULT) { + mVideoSource = VIDEO_SOURCE_CAMERA; + } else { + mVideoSource = vs; + } return OK; } status_t StagefrightRecorder::setOutputFormat(output_format of) { - mOutputFormat = of; + LOGV("setOutputFormat: %d", of); + if (of < OUTPUT_FORMAT_DEFAULT || + of >= OUTPUT_FORMAT_LIST_END) { + return BAD_VALUE; + } + + if (of == OUTPUT_FORMAT_DEFAULT) { + mOutputFormat = OUTPUT_FORMAT_THREE_GPP; + } else { + mOutputFormat = of; + } return OK; } status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { - mAudioEncoder = ae; + LOGV("setAudioEncoder: %d", ae); + if (ae < AUDIO_ENCODER_DEFAULT || + ae >= AUDIO_ENCODER_LIST_END) { + return BAD_VALUE; + } + + if (ae == AUDIO_ENCODER_DEFAULT) { + mAudioEncoder = AUDIO_ENCODER_AMR_NB; + } else { + mAudioEncoder = ae; + } return OK; } status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { - mVideoEncoder = ve; + LOGV("setVideoEncoder: %d", ve); + if (ve < VIDEO_ENCODER_DEFAULT || + ve >= VIDEO_ENCODER_LIST_END) { + return BAD_VALUE; + } + + if (ve == VIDEO_ENCODER_DEFAULT) { + mVideoEncoder = VIDEO_ENCODER_H263; + } else { + mVideoEncoder = ve; + } return OK; } status_t StagefrightRecorder::setVideoSize(int width, int height) { + LOGV("setVideoSize: %dx%d", width, height); if (width <= 0 || height <= 0) { LOGE("Invalid video size: %dx%d", width, height); return BAD_VALUE; @@ -103,6 +160,7 @@ status_t StagefrightRecorder::setVideoSize(int width, int height) { } status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { + LOGV("setVideoFrameRate: %d", frames_per_second); if (frames_per_second <= 0 || frames_per_second > 30) { LOGE("Invalid video frame rate: %d", frames_per_second); return BAD_VALUE; @@ -141,12 +199,14 @@ status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { } status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { + LOGV("setPreviewSurface: %p", surface.get()); mPreviewSurface = surface; return OK; } status_t StagefrightRecorder::setOutputFile(const char *path) { + LOGE("setOutputFile(const char*) should not be called"); // We don't actually support this at all, as the media_server process // no longer has permissions to create files. @@ -154,6 +214,7 @@ status_t StagefrightRecorder::setOutputFile(const char *path) { } status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { + LOGV("setOutputFile: %d, %lld, %lld", fd, offset, length); // These don't make any sense, do they? CHECK_EQ(offset, 0); CHECK_EQ(length, 0); @@ -720,9 +781,15 @@ status_t StagefrightRecorder::startMPEG4Recording() { int64_t token = IPCThreadState::self()->clearCallingIdentity(); if (mCamera == 0) { mCamera = Camera::connect(mCameraId); + if (mCamera == 0) { + LOGE("Camera connection could not be established."); + return -EBUSY; + } + mFlags &= ~FLAGS_HOT_CAMERA; mCamera->lock(); } + // Set the actual video recording frame size CameraParameters params(mCamera->getParameters()); params.setPreviewSize(mVideoWidth, mVideoHeight); @@ -835,6 +902,7 @@ status_t StagefrightRecorder::startMPEG4Recording() { } status_t StagefrightRecorder::pause() { + LOGV("pause"); if (mWriter == NULL) { return UNKNOWN_ERROR; } @@ -843,20 +911,14 @@ status_t StagefrightRecorder::pause() { } status_t StagefrightRecorder::stop() { - if (mWriter == NULL) { - return UNKNOWN_ERROR; + LOGV("stop"); + if (mWriter != NULL) { + mWriter->stop(); + mWriter = NULL; } - mWriter->stop(); - mWriter = NULL; - - return OK; -} - -status_t StagefrightRecorder::close() { - stop(); - if (mCamera != 0) { + LOGV("Disconnect camera"); int64_t token = IPCThreadState::self()->clearCallingIdentity(); if ((mFlags & FLAGS_HOT_CAMERA) == 0) { LOGV("Camera was cold when we started, stopping preview"); @@ -867,10 +929,19 @@ status_t StagefrightRecorder::close() { IPCThreadState::self()->restoreCallingIdentity(token); mFlags = 0; } + + return OK; +} + +status_t StagefrightRecorder::close() { + LOGV("close"); + stop(); + return OK; } status_t StagefrightRecorder::reset() { + LOGV("reset"); stop(); // No audio or video source by default @@ -904,6 +975,13 @@ status_t StagefrightRecorder::reset() { } status_t StagefrightRecorder::getMaxAmplitude(int *max) { + LOGV("getMaxAmplitude"); + + if (max == NULL) { + LOGE("Null pointer argument"); + return BAD_VALUE; + } + if (mAudioSourceNode != 0) { *max = mAudioSourceNode->getMaxAmplitude(); } else { diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index c01ea10..dacb8d3 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -849,6 +849,7 @@ void OMXCodec::setVideoInputFormat( } case OMX_VIDEO_CodingH263: + CHECK_EQ(setupH263EncoderParameters(meta), OK); break; case OMX_VIDEO_CodingAVC: @@ -874,6 +875,90 @@ static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { return ret; } +status_t OMXCodec::setupErrorCorrectionParameters() { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; + InitOMXParams(&errorCorrectionType); + errorCorrectionType.nPortIndex = kPortIndexOutput; + + status_t err = mOMX->getParameter( + mNode, OMX_IndexParamVideoErrorCorrection, + &errorCorrectionType, sizeof(errorCorrectionType)); + CHECK_EQ(err, OK); + + errorCorrectionType.bEnableHEC = OMX_FALSE; + errorCorrectionType.bEnableResync = OMX_TRUE; + errorCorrectionType.nResynchMarkerSpacing = 256; + errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; + errorCorrectionType.bEnableRVLC = OMX_FALSE; + + err = mOMX->setParameter( + mNode, OMX_IndexParamVideoErrorCorrection, + &errorCorrectionType, sizeof(errorCorrectionType)); + CHECK_EQ(err, OK); + return OK; +} + +status_t OMXCodec::setupBitRate(int32_t bitRate) { + OMX_VIDEO_PARAM_BITRATETYPE bitrateType; + InitOMXParams(&bitrateType); + bitrateType.nPortIndex = kPortIndexOutput; + + status_t err = mOMX->getParameter( + mNode, OMX_IndexParamVideoBitrate, + &bitrateType, sizeof(bitrateType)); + CHECK_EQ(err, OK); + + bitrateType.eControlRate = OMX_Video_ControlRateVariable; + bitrateType.nTargetBitrate = bitRate; + + err = mOMX->setParameter( + mNode, OMX_IndexParamVideoBitrate, + &bitrateType, sizeof(bitrateType)); + CHECK_EQ(err, OK); + return OK; +} + +status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) { + int32_t iFramesInterval, frameRate, bitRate; + bool success = meta->findInt32(kKeyBitRate, &bitRate); + success = success && meta->findInt32(kKeySampleRate, &frameRate); + success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval); + CHECK(success); + OMX_VIDEO_PARAM_H263TYPE h263type; + InitOMXParams(&h263type); + h263type.nPortIndex = kPortIndexOutput; + + status_t err = mOMX->getParameter( + mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); + CHECK_EQ(err, OK); + + h263type.nAllowedPictureTypes = + OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + + h263type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate); + if (h263type.nPFrames == 0) { + h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI; + } + h263type.nBFrames = 0; + + h263type.eProfile = OMX_VIDEO_H263ProfileBaseline; + h263type.eLevel = OMX_VIDEO_H263Level45; + + h263type.bPLUSPTYPEAllowed = OMX_FALSE; + h263type.bForceRoundingTypeToZero = OMX_FALSE; + h263type.nPictureHeaderRepetition = 0; + h263type.nGOBHeaderInterval = 0; + + err = mOMX->setParameter( + mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type)); + CHECK_EQ(err, OK); + + CHECK_EQ(setupBitRate(bitRate), OK); + CHECK_EQ(setupErrorCorrectionParameters(), OK); + + return OK; +} + status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { int32_t iFramesInterval, frameRate, bitRate; bool success = meta->findInt32(kKeyBitRate, &bitRate); @@ -907,53 +992,15 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { mpeg4type.nHeaderExtension = 0; mpeg4type.bReversibleVLC = OMX_FALSE; - mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileCore; + mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileSimple; mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2; err = mOMX->setParameter( mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type)); CHECK_EQ(err, OK); - // ---------------- - - OMX_VIDEO_PARAM_BITRATETYPE bitrateType; - InitOMXParams(&bitrateType); - bitrateType.nPortIndex = kPortIndexOutput; - - err = mOMX->getParameter( - mNode, OMX_IndexParamVideoBitrate, - &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); - - bitrateType.eControlRate = OMX_Video_ControlRateVariable; - bitrateType.nTargetBitrate = bitRate; - - err = mOMX->setParameter( - mNode, OMX_IndexParamVideoBitrate, - &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); - - // ---------------- - - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType; - InitOMXParams(&errorCorrectionType); - errorCorrectionType.nPortIndex = kPortIndexOutput; - - err = mOMX->getParameter( - mNode, OMX_IndexParamVideoErrorCorrection, - &errorCorrectionType, sizeof(errorCorrectionType)); - CHECK_EQ(err, OK); - - errorCorrectionType.bEnableHEC = OMX_FALSE; - errorCorrectionType.bEnableResync = OMX_TRUE; - errorCorrectionType.nResynchMarkerSpacing = 256; - errorCorrectionType.bEnableDataPartitioning = OMX_FALSE; - errorCorrectionType.bEnableRVLC = OMX_FALSE; - - err = mOMX->setParameter( - mNode, OMX_IndexParamVideoErrorCorrection, - &errorCorrectionType, sizeof(errorCorrectionType)); - CHECK_EQ(err, OK); + CHECK_EQ(setupBitRate(bitRate), OK); + CHECK_EQ(setupErrorCorrectionParameters(), OK); return OK; } @@ -1004,22 +1051,7 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) { mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type)); CHECK_EQ(err, OK); - OMX_VIDEO_PARAM_BITRATETYPE bitrateType; - InitOMXParams(&bitrateType); - bitrateType.nPortIndex = kPortIndexOutput; - - err = mOMX->getParameter( - mNode, OMX_IndexParamVideoBitrate, - &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); - - bitrateType.eControlRate = OMX_Video_ControlRateVariable; - bitrateType.nTargetBitrate = bitRate; - - err = mOMX->setParameter( - mNode, OMX_IndexParamVideoBitrate, - &bitrateType, sizeof(bitrateType)); - CHECK_EQ(err, OK); + CHECK_EQ(setupBitRate(bitRate), OK); return OK; } diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp index b914023..2317de6 100644 --- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp +++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp @@ -132,7 +132,10 @@ AACEncoder::~AACEncoder() { } status_t AACEncoder::start(MetaData *params) { - CHECK(!mStarted); + if (mStarted) { + LOGW("Call start() when encoder already started"); + return OK; + } mBufferGroup = new MediaBufferGroup; mBufferGroup->add_buffer(new MediaBuffer(2048)); @@ -150,7 +153,10 @@ status_t AACEncoder::start(MetaData *params) { } status_t AACEncoder::stop() { - CHECK(mStarted); + if (!mStarted) { + LOGW("Call stop() when encoder has not started"); + return OK; + } if (mInputBuffer) { mInputBuffer->release(); diff --git a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp index 445438f..4c02fe9 100644 --- a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp +++ b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp @@ -70,7 +70,10 @@ static Mode PickModeFromBitrate(int32_t bps) { } status_t AMRNBEncoder::start(MetaData *params) { - CHECK(!mStarted); + if (mStarted) { + LOGW("Call start() when encoder already started"); + return OK; + } mBufferGroup = new MediaBufferGroup; mBufferGroup->add_buffer(new MediaBuffer(32)); @@ -97,7 +100,10 @@ status_t AMRNBEncoder::start(MetaData *params) { } status_t AMRNBEncoder::stop() { - CHECK(mStarted); + if (!mStarted) { + LOGW("Call stop() when encoder has not started."); + return OK; + } if (mInputBuffer) { mInputBuffer->release(); diff --git a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp index b70cff1..4257c6a 100644 --- a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp +++ b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp @@ -124,7 +124,10 @@ AMRWBEncoder::~AMRWBEncoder() { } status_t AMRWBEncoder::start(MetaData *params) { - CHECK(!mStarted); + if (mStarted) { + LOGW("Call start() when encoder already started"); + return OK; + } mBufferGroup = new MediaBufferGroup; @@ -142,8 +145,10 @@ status_t AMRWBEncoder::start(MetaData *params) { } status_t AMRWBEncoder::stop() { - CHECK(mStarted); - + if (!mStarted) { + LOGW("Call stop() when encoder has not started"); + return OK; + } if (mInputBuffer) { mInputBuffer->release(); |