summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-06-08 11:58:53 -0700
committerJames Dong <jdong@google.com>2010-06-08 12:30:58 -0700
commitddcc4a66d848deef6fb4689e64e30cd9bd2684fe (patch)
treee34375b6ca52818e02b45af527e68e4b42c92be1
parent365a963142093a1cd8efdcea76b5f65096a5b115 (diff)
Remove some hard-coded encoding parameters
Change-Id: I7a8ccd5d57891a6a585c8da2ee53acb094955913
-rw-r--r--include/media/stagefright/MetaData.h11
-rw-r--r--include/media/stagefright/OMXCodec.h7
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp33
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h2
-rw-r--r--media/libstagefright/CameraSource.cpp10
-rw-r--r--media/libstagefright/OMXCodec.cpp81
6 files changed, 109 insertions, 35 deletions
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index dc2bd502..6a206027 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -30,10 +30,13 @@ namespace android {
// The following keys map to int32_t data unless indicated otherwise.
enum {
kKeyMIMEType = 'mime', // cstring
- kKeyWidth = 'widt',
- kKeyHeight = 'heig',
- kKeyChannelCount = '#chn',
- kKeySampleRate = 'srte',
+ kKeyWidth = 'widt', // int32_t
+ kKeyHeight = 'heig', // int32_t
+ kKeyIFramesInterval = 'ifiv', // int32_t
+ kKeyStride = 'strd', // int32_t
+ kKeySliceHeight = 'slht', // int32_t
+ kKeyChannelCount = '#chn', // int32_t
+ kKeySampleRate = 'srte', // int32_t
kKeyBitRate = 'brte', // int32_t (bps)
kKeyESDS = 'esds', // raw data
kKeyAVCC = 'avcc', // raw data
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index aceeab8b..3fbb4697 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -166,11 +166,10 @@ private:
OMX_COLOR_FORMATTYPE colorFormat);
void setVideoInputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height,
- OMX_U32 frameRate, OMX_U32 bitRate);
+ const char *mime, const sp<MetaData>& meta);
- status_t setupMPEG4EncoderParameters();
- status_t setupAVCEncoderParameters();
+ status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
+ status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
status_t setVideoOutputFormat(
const char *mime, OMX_U32 width, OMX_U32 height);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 572389f2..1a684a96 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -287,14 +287,32 @@ status_t StagefrightRecorder::setParamMaxDurationOrFileSize(int64_t limit,
status_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) {
LOGV("setParamInterleaveDuration: %d", durationUs);
- if (durationUs <= 20000) { // XXX: 20 ms
+ if (durationUs <= 500000) { // 500 ms
+ // If interleave duration is too small, it is very inefficient to do
+ // interleaving since the metadata overhead will count for a significant
+ // portion of the saved contents
LOGE("Audio/video interleave duration is too small: %d us", durationUs);
return BAD_VALUE;
+ } else if (durationUs >= 10000000) { // 10 seconds
+ // If interleaving duration is too large, it can cause the recording
+ // session to use too much memory since we have to save the output
+ // data before we write them out
+ LOGE("Audio/video interleave duration is too large: %d us", durationUs);
+ return BAD_VALUE;
}
mInterleaveDurationUs = durationUs;
return OK;
}
+// If interval < 0, only the first frame is I frame, and rest are all P frames
+// If interval == 0, all frames are encoded as I frames. No P frames
+// If interval > 0, it is the time spacing between 2 neighboring I frames
+status_t StagefrightRecorder::setParamIFramesInterval(int32_t interval) {
+ LOGV("setParamIFramesInterval: %d seconds", interval);
+ mIFramesInterval = interval;
+ return OK;
+}
+
status_t StagefrightRecorder::setParameter(
const String8 &key, const String8 &value) {
LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -335,6 +353,11 @@ status_t StagefrightRecorder::setParameter(
if (safe_strtoi32(value.string(), &durationUs)) {
return setParamInterleaveDuration(durationUs);
}
+ } else if (key == "param-i-frames-interval") {
+ int32_t interval;
+ if (safe_strtoi32(value.string(), &interval)) {
+ return setParamIFramesInterval(interval);
+ }
} else {
LOGE("setParameter: failed to find key %s", key.string());
}
@@ -619,12 +642,17 @@ status_t StagefrightRecorder::startMPEG4Recording() {
sp<MetaData> meta = cameraSource->getFormat();
- int32_t width, height;
+ int32_t width, height, stride, sliceHeight;
CHECK(meta->findInt32(kKeyWidth, &width));
CHECK(meta->findInt32(kKeyHeight, &height));
+ CHECK(meta->findInt32(kKeyStride, &stride));
+ CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
+ enc_meta->setInt32(kKeyIFramesInterval, mIFramesInterval);
+ enc_meta->setInt32(kKeyStride, stride);
+ enc_meta->setInt32(kKeySliceHeight, sliceHeight);
OMXClient client;
CHECK_EQ(client.connect(), OK);
@@ -702,6 +730,7 @@ status_t StagefrightRecorder::reset() {
mAudioChannels = 1;
mAudioBitRate = 12200;
mInterleaveDurationUs = 0;
+ mIFramesInterval = 1;
mOutputFd = -1;
mFlags = 0;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index b7d554b5..b491e9fb 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -75,6 +75,7 @@ private:
int32_t mAudioChannels;
int32_t mSampleRate;
int32_t mInterleaveDurationUs;
+ int32_t mIFramesInterval;
int64_t mMaxFileSizeBytes;
int64_t mMaxFileDurationUs;
@@ -92,6 +93,7 @@ private:
status_t setParamAudioNumberOfChannels(int32_t channles);
status_t setParamAudioSamplingRate(int32_t sampleRate);
status_t setParamInterleaveDuration(int32_t durationUs);
+ status_t setParamIFramesInterval(int32_t interval);
status_t setParamMaxDurationOrFileSize(int64_t limit, bool limit_is_duration);
StagefrightRecorder(const StagefrightRecorder &);
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 416b75ca..67759c05 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -128,7 +128,7 @@ CameraSource::CameraSource(const sp<Camera> &camera)
String8 s = mCamera->getParameters();
printf("params: \"%s\"\n", s.string());
- int32_t width, height;
+ int32_t width, height, stride, sliceHeight;
CameraParameters params(s);
params.getPreviewSize(&width, &height);
@@ -136,11 +136,19 @@ CameraSource::CameraSource(const sp<Camera> &camera)
CHECK(colorFormatStr != NULL);
int32_t colorFormat = getColorFormat(colorFormatStr);
+ // XXX: query camera for the stride and slice height
+ // when the capability becomes available.
+ stride = width;
+ sliceHeight = height;
+
mMeta = new MetaData;
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
mMeta->setInt32(kKeyColorFormat, colorFormat);
mMeta->setInt32(kKeyWidth, width);
mMeta->setInt32(kKeyHeight, height);
+ mMeta->setInt32(kKeyStride, stride);
+ mMeta->setInt32(kKeySliceHeight, sliceHeight);
+
}
CameraSource::~CameraSource() {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 7c3df310..ba357486 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -571,17 +571,14 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
}
if (!strncasecmp(mMIME, "video/", 6)) {
- int32_t width, height;
- bool success = meta->findInt32(kKeyWidth, &width);
- success = success && meta->findInt32(kKeyHeight, &height);
- CHECK(success);
if (mIsEncoder) {
- int32_t frameRate = 25; // XXX
- int32_t bitRate = 3000000; // bit rate
- //success = success && meta->findInt32(kKeySampleRate, &frameRate);
- setVideoInputFormat(mMIME, width, height, frameRate, bitRate);
+ setVideoInputFormat(mMIME, meta);
} else {
+ int32_t width, height;
+ bool success = meta->findInt32(kKeyWidth, &width);
+ success = success && meta->findInt32(kKeyHeight, &height);
+ CHECK(success);
status_t err = setVideoOutputFormat(
mMIME, width, height);
@@ -745,9 +742,17 @@ static size_t getFrameSize(
}
void OMXCodec::setVideoInputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height,
- OMX_U32 frameRate, OMX_U32 bitRate) {
- CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
+ const char *mime, const sp<MetaData>& meta) {
+
+ int32_t width, height, frameRate, bitRate, stride, sliceHeight;
+ bool success = meta->findInt32(kKeyWidth, &width);
+ success = success && meta->findInt32(kKeyHeight, &height);
+ success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ success = success && meta->findInt32(kKeyBitRate, &bitRate);
+ success = success && meta->findInt32(kKeyStride, &stride);
+ success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
+ CHECK(success);
+ CHECK(stride != 0);
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
@@ -766,8 +771,6 @@ void OMXCodec::setVideoInputFormat(
colorFormat = OMX_COLOR_FormatYCbYCr;
}
-
-
status_t err;
OMX_PARAM_PORTDEFINITIONTYPE def;
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
@@ -784,12 +787,15 @@ void OMXCodec::setVideoInputFormat(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
- def.nBufferSize = getFrameSize(colorFormat, width, height);
+ def.nBufferSize = getFrameSize(colorFormat,
+ stride > 0? stride: -stride, sliceHeight);
CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
+ video_def->nStride = stride;
+ video_def->nSliceHeight = sliceHeight;
video_def->xFramerate = (frameRate << 16); // Q16 format
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat;
@@ -826,7 +832,7 @@ void OMXCodec::setVideoInputFormat(
switch (compressionFormat) {
case OMX_VIDEO_CodingMPEG4:
{
- CHECK_EQ(setupMPEG4EncoderParameters(), OK);
+ CHECK_EQ(setupMPEG4EncoderParameters(meta), OK);
break;
}
@@ -835,7 +841,7 @@ void OMXCodec::setVideoInputFormat(
case OMX_VIDEO_CodingAVC:
{
- CHECK_EQ(setupAVCEncoderParameters(), OK);
+ CHECK_EQ(setupAVCEncoderParameters(meta), OK);
break;
}
@@ -845,7 +851,23 @@ void OMXCodec::setVideoInputFormat(
}
}
-status_t OMXCodec::setupMPEG4EncoderParameters() {
+static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
+ if (iFramesInterval < 0) {
+ return 0xFFFFFFFF;
+ } else if (iFramesInterval == 0) {
+ return 0;
+ }
+ OMX_U32 ret = frameRate * iFramesInterval;
+ CHECK(ret > 1);
+ return ret;
+}
+
+status_t OMXCodec::setupMPEG4EncoderParameters(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_MPEG4TYPE mpeg4type;
InitOMXParams(&mpeg4type);
mpeg4type.nPortIndex = kPortIndexOutput;
@@ -861,9 +883,11 @@ status_t OMXCodec::setupMPEG4EncoderParameters() {
mpeg4type.nAllowedPictureTypes =
OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
- mpeg4type.nPFrames = 23;
+ mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
+ if (mpeg4type.nPFrames == 0) {
+ mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
mpeg4type.nBFrames = 0;
-
mpeg4type.nIDCVLCThreshold = 0;
mpeg4type.bACPred = OMX_TRUE;
mpeg4type.nMaxPacketSize = 256;
@@ -890,7 +914,7 @@ status_t OMXCodec::setupMPEG4EncoderParameters() {
CHECK_EQ(err, OK);
bitrateType.eControlRate = OMX_Video_ControlRateVariable;
- bitrateType.nTargetBitrate = 1000000;
+ bitrateType.nTargetBitrate = bitRate;
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoBitrate,
@@ -922,7 +946,13 @@ status_t OMXCodec::setupMPEG4EncoderParameters() {
return OK;
}
-status_t OMXCodec::setupAVCEncoderParameters() {
+status_t OMXCodec::setupAVCEncoderParameters(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_AVCTYPE h264type;
InitOMXParams(&h264type);
h264type.nPortIndex = kPortIndexOutput;
@@ -935,8 +965,11 @@ status_t OMXCodec::setupAVCEncoderParameters() {
OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
h264type.nSliceHeaderSpacing = 0;
- h264type.nBFrames = 0;
- h264type.nPFrames = 24; // XXX
+ h264type.nBFrames = 0; // No B frames support yet
+ h264type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
+ if (h264type.nPFrames == 0) {
+ h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
h264type.bUseHadamard = OMX_TRUE;
h264type.nRefFrames = 1;
h264type.nRefIdx10ActiveMinus1 = 0;
@@ -969,7 +1002,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
CHECK_EQ(err, OK);
bitrateType.eControlRate = OMX_Video_ControlRateVariable;
- bitrateType.nTargetBitrate = 3000000; // XXX
+ bitrateType.nTargetBitrate = bitRate;
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoBitrate,