diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 53 |
2 files changed, 58 insertions, 0 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index b904aa8..17190fb 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -30,6 +30,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/ALooper.h> +#include <media/stagefright/ACodec.h> #include <media/stagefright/AudioSource.h> #include <media/stagefright/AMRWriter.h> #include <media/stagefright/AACWriter.h> @@ -1243,6 +1244,10 @@ void StagefrightRecorder::setDefaultProfileIfNecessary() { if (videoCodec == VIDEO_ENCODER_H264) { ALOGI("Force to use AVC baseline profile"); setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline); + // set 0 for invalid levels - this will be rejected by the + // codec if it cannot handle it during configure + setParamVideoEncoderLevel(ACodec::getAVCLevelFor( + videoFrameWidth, videoFrameHeight, videoFrameRate, videoBitRate)); } } } diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index d35f265..868385b 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -32,6 +32,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodecList.h> @@ -2490,6 +2491,58 @@ status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) { return setupErrorCorrectionParameters(); } +// static +int /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor( + int width, int height, int rate, int bitrate, + OMX_VIDEO_AVCPROFILETYPE profile) { + // convert bitrate to main/baseline profile kbps equivalent + switch (profile) { + case OMX_VIDEO_AVCProfileHigh10: + bitrate = divUp(bitrate, 3000); break; + case OMX_VIDEO_AVCProfileHigh: + bitrate = divUp(bitrate, 1250); break; + default: + bitrate = divUp(bitrate, 1000); break; + } + + // convert size and rate to MBs + width = divUp(width, 16); + height = divUp(height, 16); + int mbs = width * height; + rate *= mbs; + int maxDimension = max(width, height); + + static const int limits[][5] = { + /* MBps MB dim bitrate level */ + { 1485, 99, 28, 64, OMX_VIDEO_AVCLevel1 }, + { 1485, 99, 28, 128, OMX_VIDEO_AVCLevel1b }, + { 3000, 396, 56, 192, OMX_VIDEO_AVCLevel11 }, + { 6000, 396, 56, 384, OMX_VIDEO_AVCLevel12 }, + { 11880, 396, 56, 768, OMX_VIDEO_AVCLevel13 }, + { 11880, 396, 56, 2000, OMX_VIDEO_AVCLevel2 }, + { 19800, 792, 79, 4000, OMX_VIDEO_AVCLevel21 }, + { 20250, 1620, 113, 4000, OMX_VIDEO_AVCLevel22 }, + { 40500, 1620, 113, 10000, OMX_VIDEO_AVCLevel3 }, + { 108000, 3600, 169, 14000, OMX_VIDEO_AVCLevel31 }, + { 216000, 5120, 202, 20000, OMX_VIDEO_AVCLevel32 }, + { 245760, 8192, 256, 20000, OMX_VIDEO_AVCLevel4 }, + { 245760, 8192, 256, 50000, OMX_VIDEO_AVCLevel41 }, + { 522240, 8704, 263, 50000, OMX_VIDEO_AVCLevel42 }, + { 589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5 }, + { 983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 }, + { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(limits); i++) { + const int (&limit)[5] = limits[i]; + if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2] + && bitrate <= limit[3]) { + return limit[4]; + } + } + return 0; +} + status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { int32_t bitrate, iFrameInterval; if (!msg->findInt32("bitrate", &bitrate) |