diff options
author | James Dong <jdong@google.com> | 2010-10-19 17:35:35 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-10-27 23:47:37 -0700 |
commit | 5cb8fdbfeda95fdc70e8edb69adc20c57cb277be (patch) | |
tree | 00bb06f131a2d83ff2113867d28e2f43a5b40221 /media/libstagefright/codecs | |
parent | fc9ac988e08a8b4c42e58999300265989f26f24c (diff) | |
download | frameworks_av-5cb8fdbfeda95fdc70e8edb69adc20c57cb277be.zip frameworks_av-5cb8fdbfeda95fdc70e8edb69adc20c57cb277be.tar.gz frameworks_av-5cb8fdbfeda95fdc70e8edb69adc20c57cb277be.tar.bz2 |
Added profile and level translation in SW video encoders
Change-Id: I6b9c33c7e4b497f3dc61b2a0dcf4e65727f9bcdd
Diffstat (limited to 'media/libstagefright/codecs')
-rw-r--r-- | media/libstagefright/codecs/avc/enc/AVCEncoder.cpp | 84 | ||||
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp | 109 |
2 files changed, 188 insertions, 5 deletions
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp index 52a391f..a6b179e 100644 --- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp +++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp @@ -33,6 +33,80 @@ namespace android { +static status_t ConvertOmxAvcProfileToAvcSpecProfile( + int32_t omxProfile, AVCProfile* pvProfile) { + LOGV("ConvertOmxAvcProfileToAvcSpecProfile: %d", omxProfile); + switch (omxProfile) { + case OMX_VIDEO_AVCProfileBaseline: + *pvProfile = AVC_BASELINE; + return OK; + default: + LOGE("Unsupported omx profile: %d", omxProfile); + } + return BAD_VALUE; +} + +static status_t ConvertOmxAvcLevelToAvcSpecLevel( + int32_t omxLevel, AVCLevel *pvLevel) { + LOGV("ConvertOmxAvcLevelToAvcSpecLevel: %d", omxLevel); + AVCLevel level = AVC_LEVEL5_1; + switch (omxLevel) { + case OMX_VIDEO_AVCLevel1: + level = AVC_LEVEL1_B; + break; + case OMX_VIDEO_AVCLevel1b: + level = AVC_LEVEL1; + break; + case OMX_VIDEO_AVCLevel11: + level = AVC_LEVEL1_1; + break; + case OMX_VIDEO_AVCLevel12: + level = AVC_LEVEL1_2; + break; + case OMX_VIDEO_AVCLevel13: + level = AVC_LEVEL1_3; + break; + case OMX_VIDEO_AVCLevel2: + level = AVC_LEVEL2; + break; + case OMX_VIDEO_AVCLevel21: + level = AVC_LEVEL2_1; + break; + case OMX_VIDEO_AVCLevel22: + level = AVC_LEVEL2_2; + break; + case OMX_VIDEO_AVCLevel3: + level = AVC_LEVEL3; + break; + case OMX_VIDEO_AVCLevel31: + level = AVC_LEVEL3_1; + break; + case OMX_VIDEO_AVCLevel32: + level = AVC_LEVEL3_2; + break; + case OMX_VIDEO_AVCLevel4: + level = AVC_LEVEL4; + break; + case OMX_VIDEO_AVCLevel41: + level = AVC_LEVEL4_1; + break; + case OMX_VIDEO_AVCLevel42: + level = AVC_LEVEL4_2; + break; + case OMX_VIDEO_AVCLevel5: + level = AVC_LEVEL5; + break; + case OMX_VIDEO_AVCLevel51: + level = AVC_LEVEL5_1; + break; + default: + LOGE("Unknown omx level: %d", omxLevel); + return BAD_VALUE; + } + *pvLevel = level; + return OK; +} + inline static void ConvertYUV420SemiPlanarToYUV420Planar( uint8_t *inyuv, uint8_t* outyuv, int32_t width, int32_t height) { @@ -231,10 +305,16 @@ status_t AVCEncoder::initCheck(const sp<MetaData>& meta) { mEncParams->level = AVC_LEVEL3_2; int32_t profile, level; if (meta->findInt32(kKeyVideoProfile, &profile)) { - mEncParams->profile = (AVCProfile) profile; + if (OK != ConvertOmxAvcProfileToAvcSpecProfile( + profile, &mEncParams->profile)) { + return BAD_VALUE; + } } if (meta->findInt32(kKeyVideoLevel, &level)) { - mEncParams->level = (AVCLevel) level; + if (OK != ConvertOmxAvcLevelToAvcSpecLevel( + level, &mEncParams->level)) { + return BAD_VALUE; + } } diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp index a011137..d5a5313 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp @@ -32,6 +32,104 @@ namespace android { +static status_t ConvertOmxProfileLevel( + MP4EncodingMode mode, + int32_t omxProfile, + int32_t omxLevel, + ProfileLevelType* pvProfileLevel) { + LOGV("ConvertOmxProfileLevel: %d/%d/%d", mode, omxProfile, omxLevel); + ProfileLevelType profileLevel; + if (mode == H263_MODE) { + switch (omxProfile) { + case OMX_VIDEO_H263ProfileBaseline: + if (omxLevel > OMX_VIDEO_H263Level45) { + LOGE("Unsupported level (%d) for H263", omxLevel); + return BAD_VALUE; + } else { + LOGW("PV does not support level configuration for H263"); + profileLevel = CORE_PROFILE_LEVEL2; + break; + } + default: + LOGE("Unsupported profile (%d) for H263", omxProfile); + return BAD_VALUE; + } + } else { // MPEG4 + switch (omxProfile) { + case OMX_VIDEO_MPEG4ProfileSimple: + switch (omxLevel) { + case OMX_VIDEO_MPEG4Level0b: + profileLevel = SIMPLE_PROFILE_LEVEL0; + break; + case OMX_VIDEO_MPEG4Level1: + profileLevel = SIMPLE_PROFILE_LEVEL1; + break; + case OMX_VIDEO_MPEG4Level2: + profileLevel = SIMPLE_PROFILE_LEVEL2; + break; + case OMX_VIDEO_MPEG4Level3: + profileLevel = SIMPLE_PROFILE_LEVEL3; + break; + default: + LOGE("Unsupported level (%d) for MPEG4 simple profile", + omxLevel); + return BAD_VALUE; + } + case OMX_VIDEO_MPEG4ProfileSimpleScalable: + switch (omxLevel) { + case OMX_VIDEO_MPEG4Level0b: + profileLevel = SIMPLE_SCALABLE_PROFILE_LEVEL0; + break; + case OMX_VIDEO_MPEG4Level1: + profileLevel = SIMPLE_SCALABLE_PROFILE_LEVEL1; + break; + case OMX_VIDEO_MPEG4Level2: + profileLevel = SIMPLE_SCALABLE_PROFILE_LEVEL2; + break; + default: + LOGE("Unsupported level (%d) for MPEG4 simple " + "scalable profile", omxLevel); + return BAD_VALUE; + } + case OMX_VIDEO_MPEG4ProfileCore: + switch (omxLevel) { + case OMX_VIDEO_MPEG4Level1: + profileLevel = CORE_PROFILE_LEVEL1; + break; + case OMX_VIDEO_MPEG4Level2: + profileLevel = CORE_PROFILE_LEVEL2; + break; + default: + LOGE("Unsupported level (%d) for MPEG4 core " + "profile", omxLevel); + return BAD_VALUE; + } + case OMX_VIDEO_MPEG4ProfileCoreScalable: + switch (omxLevel) { + case OMX_VIDEO_MPEG4Level1: + profileLevel = CORE_SCALABLE_PROFILE_LEVEL1; + break; + case OMX_VIDEO_MPEG4Level2: + profileLevel = CORE_SCALABLE_PROFILE_LEVEL2; + break; + case OMX_VIDEO_MPEG4Level3: + profileLevel = CORE_SCALABLE_PROFILE_LEVEL3; + break; + default: + LOGE("Unsupported level (%d) for MPEG4 core " + "scalable profile", omxLevel); + return BAD_VALUE; + } + default: + LOGE("Unsupported MPEG4 profile (%d)", omxProfile); + return BAD_VALUE; + } + } + + *pvProfileLevel = profileLevel; + return OK; +} + inline static void ConvertYUV420SemiPlanarToYUV420Planar( uint8_t *inyuv, uint8_t* outyuv, int32_t width, int32_t height) { @@ -150,9 +248,14 @@ status_t M4vH263Encoder::initCheck(const sp<MetaData>& meta) { // If profile and level setting is not correct, failure // is reported when the encoder is initialized. mEncParams->profile_level = CORE_PROFILE_LEVEL2; - int32_t profileLevel; - if (meta->findInt32(kKeyVideoLevel, &profileLevel)) { - mEncParams->profile_level = (ProfileLevelType)profileLevel; + int32_t profile, level; + if (meta->findInt32(kKeyVideoProfile, &profile) && + meta->findInt32(kKeyVideoLevel, &level)) { + if (OK != ConvertOmxProfileLevel( + mEncParams->encMode, profile, level, + &mEncParams->profile_level)) { + return BAD_VALUE; + } } mEncParams->packetSize = 32; |