Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cb8fdbf authored by James Dong's avatar James Dong
Browse files

Added profile and level translation in SW video encoders

Change-Id: I6b9c33c7e4b497f3dc61b2a0dcf4e65727f9bcdd
parent fc9ac988
Loading
Loading
Loading
Loading
+82 −2
Original line number Diff line number Diff line
@@ -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;
        }
    }


+106 −3
Original line number Diff line number Diff line
@@ -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;