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

Commit c8ca26ed authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Added profile and level translation in SW video encoders"

parents ff1df995 5cb8fdbf
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;