summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-07-01 15:02:14 -0700
committerJames Dong <jdong@google.com>2010-07-07 12:11:53 -0700
commit145bfe5eb3e08c9689c28f6bf3287a979438b04b (patch)
treeba140d50bbed7d0f8cb76fb3bd7920ecc5c4a6ce /media
parent91952e5221d2151e10738d7228575c4afe444f5e (diff)
downloadframeworks_av-145bfe5eb3e08c9689c28f6bf3287a979438b04b.zip
frameworks_av-145bfe5eb3e08c9689c28f6bf3287a979438b04b.tar.gz
frameworks_av-145bfe5eb3e08c9689c28f6bf3287a979438b04b.tar.bz2
Allow application to set two more encoding paramters: video profile and level
Change-Id: I673e681cefe184d5c556c612c54600a24a2143e5
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp38
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h4
-rw-r--r--media/libstagefright/OMXCodec.cpp105
3 files changed, 132 insertions, 15 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 91c5b92..50f74f2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -426,6 +426,24 @@ status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
return OK;
}
+status_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) {
+ LOGV("setParamVideoEncoderProfile: %d", profile);
+
+ // Additional check will be done later when we load the encoder.
+ // For now, we are accepting values defined in OpenMAX IL.
+ mVideoEncoderProfile = profile;
+ return OK;
+}
+
+status_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) {
+ LOGV("setParamVideoEncoderLevel: %d", level);
+
+ // Additional check will be done later when we load the encoder.
+ // For now, we are accepting values defined in OpenMAX IL.
+ mVideoEncoderLevel = level;
+ return OK;
+}
+
status_t StagefrightRecorder::setParameter(
const String8 &key, const String8 &value) {
LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -484,6 +502,16 @@ status_t StagefrightRecorder::setParameter(
if (safe_strtoi32(value.string(), &interval)) {
return setParamVideoIFramesInterval(interval);
}
+ } else if (key == "video-param-encoder-profile") {
+ int32_t profile;
+ if (safe_strtoi32(value.string(), &profile)) {
+ return setParamVideoEncoderProfile(profile);
+ }
+ } else if (key == "video-param-encoder-level") {
+ int32_t level;
+ if (safe_strtoi32(value.string(), &level)) {
+ return setParamVideoEncoderLevel(level);
+ }
} else if (key == "video-param-camera-id") {
int32_t cameraId;
if (safe_strtoi32(value.string(), &cameraId)) {
@@ -851,6 +879,12 @@ status_t StagefrightRecorder::setupVideoEncoder(const sp<MediaWriter>& writer) {
enc_meta->setInt32(kKeyIFramesInterval, mIFramesInterval);
enc_meta->setInt32(kKeyStride, stride);
enc_meta->setInt32(kKeySliceHeight, sliceHeight);
+ if (mVideoEncoderProfile != -1) {
+ enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile);
+ }
+ if (mVideoEncoderLevel != -1) {
+ enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
+ }
OMXClient client;
CHECK_EQ(client.connect(), OK);
@@ -992,6 +1026,10 @@ status_t StagefrightRecorder::reset() {
mAudioSourceNode = 0;
mUse64BitFileOffset = false;
mCameraId = 0;
+ mVideoEncoderProfile = -1;
+ mVideoEncoderLevel = -1;
+ mMaxFileDurationUs = 0;
+ mMaxFileSizeBytes = 0;
mTrackEveryNumberOfFrames = 0;
mTrackEveryTimeDurationUs = 0;
mEncoderProfiles = MediaProfiles::getInstance();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index cb05571..85d2557 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -82,6 +82,8 @@ private:
int32_t mInterleaveDurationUs;
int32_t mIFramesInterval;
int32_t mCameraId;
+ int32_t mVideoEncoderProfile;
+ int32_t mVideoEncoderLevel;
int64_t mMaxFileSizeBytes;
int64_t mMaxFileDurationUs;
int32_t mTrackEveryNumberOfFrames;
@@ -108,6 +110,8 @@ private:
status_t setParamAudioSamplingRate(int32_t sampleRate);
status_t setParamVideoEncodingBitRate(int32_t bitRate);
status_t setParamVideoIFramesInterval(int32_t interval);
+ status_t setParamVideoEncoderProfile(int32_t profile);
+ status_t setParamVideoEncoderLevel(int32_t level);
status_t setParamVideoCameraId(int32_t cameraId);
status_t setParamTrackTimeStatus(int64_t timeDurationUs);
status_t setParamTrackFrameStatus(int32_t nFrames);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index dacb8d3..83f7040 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -831,7 +831,7 @@ void OMXCodec::setVideoInputFormat(
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
- video_def->xFramerate = (frameRate << 16); // Q16 format
+ video_def->xFramerate = 0; // No need for output port
video_def->nBitrate = bitRate; // Q16 format
video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused;
@@ -918,6 +918,52 @@ status_t OMXCodec::setupBitRate(int32_t bitRate) {
return OK;
}
+status_t OMXCodec::getVideoProfileLevel(
+ const sp<MetaData>& meta,
+ const CodecProfileLevel& defaultProfileLevel,
+ CodecProfileLevel &profileLevel) {
+ CODEC_LOGV("Default profile: %ld, level %ld",
+ defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
+
+ // Are the default profile and level overwriten?
+ int32_t profile, level;
+ if (!meta->findInt32(kKeyVideoProfile, &profile)) {
+ profile = defaultProfileLevel.mProfile;
+ }
+ if (!meta->findInt32(kKeyVideoLevel, &level)) {
+ level = defaultProfileLevel.mLevel;
+ }
+ CODEC_LOGV("Target profile: %d, level: %d", profile, level);
+
+ // Are the target profile and level supported by the encoder?
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
+ InitOMXParams(&param);
+ param.nPortIndex = kPortIndexOutput;
+ for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoProfileLevelQuerySupported,
+ &param, sizeof(param));
+
+ if (err != OK) return err;
+
+ int32_t supportedProfile = static_cast<int32_t>(param.eProfile);
+ int32_t supportedLevel = static_cast<int32_t>(param.eLevel);
+ CODEC_LOGV("Supported profile: %ld, level %ld",
+ supportedProfile, supportedLevel);
+
+ if (profile == supportedProfile &&
+ level == supportedLevel) {
+ profileLevel.mProfile = profile;
+ profileLevel.mLevel = level;
+ return OK;
+ }
+ }
+
+ CODEC_LOGE("Target profile (%d) and level (%d) is not supported",
+ profile, level);
+ return BAD_VALUE;
+}
+
status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
int32_t iFramesInterval, frameRate, bitRate;
bool success = meta->findInt32(kKeyBitRate, &bitRate);
@@ -941,8 +987,14 @@ status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
}
h263type.nBFrames = 0;
- h263type.eProfile = OMX_VIDEO_H263ProfileBaseline;
- h263type.eLevel = OMX_VIDEO_H263Level45;
+ // Check profile and level parameters
+ CodecProfileLevel defaultProfileLevel, profileLevel;
+ defaultProfileLevel.mProfile = OMX_VIDEO_H263ProfileBaseline;
+ defaultProfileLevel.mLevel = OMX_VIDEO_H263Level45;
+ err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
+ if (err != OK) return err;
+ h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profileLevel.mProfile);
+ h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(profileLevel.mLevel);
h263type.bPLUSPTYPEAllowed = OMX_FALSE;
h263type.bForceRoundingTypeToZero = OMX_FALSE;
@@ -992,8 +1044,14 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
mpeg4type.nHeaderExtension = 0;
mpeg4type.bReversibleVLC = OMX_FALSE;
- mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
- mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
+ // Check profile and level parameters
+ CodecProfileLevel defaultProfileLevel, profileLevel;
+ defaultProfileLevel.mProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ defaultProfileLevel.mLevel = OMX_VIDEO_MPEG4Level2;
+ err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
+ if (err != OK) return err;
+ mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profileLevel.mProfile);
+ mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(profileLevel.mLevel);
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
@@ -1029,22 +1087,39 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
if (h264type.nPFrames == 0) {
h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
}
- h264type.bUseHadamard = OMX_TRUE;
- h264type.nRefFrames = 1;
- h264type.nRefIdx10ActiveMinus1 = 0;
- h264type.nRefIdx11ActiveMinus1 = 0;
+
+ // Check profile and level parameters
+ CodecProfileLevel defaultProfileLevel, profileLevel;
+ defaultProfileLevel.mProfile = h264type.eProfile;
+ defaultProfileLevel.mLevel = h264type.eLevel;
+ err = getVideoProfileLevel(meta, defaultProfileLevel, profileLevel);
+ if (err != OK) return err;
+ h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
+ h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);
+
+ if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
+ h264type.bUseHadamard = OMX_TRUE;
+ h264type.nRefFrames = 1;
+ h264type.nRefIdx10ActiveMinus1 = 0;
+ h264type.nRefIdx11ActiveMinus1 = 0;
+ h264type.bEntropyCodingCABAC = OMX_FALSE;
+ h264type.bWeightedPPrediction = OMX_FALSE;
+ h264type.bconstIpred = OMX_FALSE;
+ h264type.bDirect8x8Inference = OMX_FALSE;
+ h264type.bDirectSpatialTemporal = OMX_FALSE;
+ h264type.nCabacInitIdc = 0;
+ }
+
+ if (h264type.nBFrames != 0) {
+ h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
+ }
+
h264type.bEnableUEP = OMX_FALSE;
h264type.bEnableFMO = OMX_FALSE;
h264type.bEnableASO = OMX_FALSE;
h264type.bEnableRS = OMX_FALSE;
h264type.bFrameMBsOnly = OMX_TRUE;
h264type.bMBAFF = OMX_FALSE;
- h264type.bEntropyCodingCABAC = OMX_FALSE;
- h264type.bWeightedPPrediction = OMX_FALSE;
- h264type.bconstIpred = OMX_FALSE;
- h264type.bDirect8x8Inference = OMX_FALSE;
- h264type.bDirectSpatialTemporal = OMX_FALSE;
- h264type.nCabacInitIdc = 0;
h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
err = mOMX->setParameter(