am f7679a04
: Merge "Added encoding parameters set up for H263 video encoder" into gingerbread
Merge commit 'f7679a0493d59da8c759a6be639be5110c50fb98' into gingerbread-plus-aosp * commit 'f7679a0493d59da8c759a6be639be5110c50fb98': Added encoding parameters set up for H263 video encoder
This commit is contained in:
@ -172,6 +172,9 @@ private:
|
||||
void setVideoInputFormat(
|
||||
const char *mime, const sp<MetaData>& meta);
|
||||
|
||||
status_t setupBitRate(int32_t bitRate);
|
||||
status_t setupErrorCorrectionParameters();
|
||||
status_t setupH263EncoderParameters(const sp<MetaData>& meta);
|
||||
status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
|
||||
status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
|
||||
|
||||
|
@ -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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
|
||||
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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user