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

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

Merge "Allow application to set two more encoding paramters: video profile and...

Merge "Allow application to set two more encoding paramters: video profile and level" into gingerbread
parents 58c35573 81c929a6
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -69,6 +69,10 @@ enum {
    kKeyDate              = 'date',  // cstring
    kKeyDate              = 'date',  // cstring
    kKeyWriter            = 'writ',  // cstring
    kKeyWriter            = 'writ',  // cstring


    // video profile and level
    kKeyVideoProfile      = 'vprf',  // int32_t
    kKeyVideoLevel        = 'vlev',  // int32_t

    // Set this key to enable authoring files in 64-bit offset
    // Set this key to enable authoring files in 64-bit offset
    kKey64BitFileOffset   = 'fobt',  // int32_t (bool)
    kKey64BitFileOffset   = 'fobt',  // int32_t (bool)


+7 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ namespace android {


class MemoryDealer;
class MemoryDealer;
struct OMXCodecObserver;
struct OMXCodecObserver;
struct CodecProfileLevel;


struct OMXCodec : public MediaSource,
struct OMXCodec : public MediaSource,
                  public MediaBufferObserver {
                  public MediaBufferObserver {
@@ -178,6 +179,12 @@ private:
    status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
    status_t setupMPEG4EncoderParameters(const sp<MetaData>& meta);
    status_t setupAVCEncoderParameters(const sp<MetaData>& meta);
    status_t setupAVCEncoderParameters(const sp<MetaData>& meta);


    // If profile/level is set in the meta data, its value in the meta
    // data will be used; otherwise, the default value will be used.
    status_t getVideoProfileLevel(const sp<MetaData>& meta,
            const CodecProfileLevel& defaultProfileLevel,
            CodecProfileLevel& profileLevel);

    status_t setVideoOutputFormat(
    status_t setVideoOutputFormat(
            const char *mime, OMX_U32 width, OMX_U32 height);
            const char *mime, OMX_U32 width, OMX_U32 height);


+38 −0
Original line number Original line Diff line number Diff line
@@ -426,6 +426,24 @@ status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
    return OK;
    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(
status_t StagefrightRecorder::setParameter(
        const String8 &key, const String8 &value) {
        const String8 &key, const String8 &value) {
    LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
    LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -484,6 +502,16 @@ status_t StagefrightRecorder::setParameter(
        if (safe_strtoi32(value.string(), &interval)) {
        if (safe_strtoi32(value.string(), &interval)) {
            return setParamVideoIFramesInterval(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") {
    } else if (key == "video-param-camera-id") {
        int32_t cameraId;
        int32_t cameraId;
        if (safe_strtoi32(value.string(), &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(kKeyIFramesInterval, mIFramesInterval);
    enc_meta->setInt32(kKeyStride, stride);
    enc_meta->setInt32(kKeyStride, stride);
    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
    if (mVideoEncoderProfile != -1) {
        enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile);
    }
    if (mVideoEncoderLevel != -1) {
        enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
    }


    OMXClient client;
    OMXClient client;
    CHECK_EQ(client.connect(), OK);
    CHECK_EQ(client.connect(), OK);
@@ -992,6 +1026,10 @@ status_t StagefrightRecorder::reset() {
    mAudioSourceNode = 0;
    mAudioSourceNode = 0;
    mUse64BitFileOffset = false;
    mUse64BitFileOffset = false;
    mCameraId        = 0;
    mCameraId        = 0;
    mVideoEncoderProfile = -1;
    mVideoEncoderLevel   = -1;
    mMaxFileDurationUs = 0;
    mMaxFileSizeBytes = 0;
    mTrackEveryNumberOfFrames = 0;
    mTrackEveryNumberOfFrames = 0;
    mTrackEveryTimeDurationUs = 0;
    mTrackEveryTimeDurationUs = 0;
    mEncoderProfiles = MediaProfiles::getInstance();
    mEncoderProfiles = MediaProfiles::getInstance();
+4 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,8 @@ private:
    int32_t mInterleaveDurationUs;
    int32_t mInterleaveDurationUs;
    int32_t mIFramesInterval;
    int32_t mIFramesInterval;
    int32_t mCameraId;
    int32_t mCameraId;
    int32_t mVideoEncoderProfile;
    int32_t mVideoEncoderLevel;
    int64_t mMaxFileSizeBytes;
    int64_t mMaxFileSizeBytes;
    int64_t mMaxFileDurationUs;
    int64_t mMaxFileDurationUs;
    int32_t mTrackEveryNumberOfFrames;
    int32_t mTrackEveryNumberOfFrames;
@@ -108,6 +110,8 @@ private:
    status_t setParamAudioSamplingRate(int32_t sampleRate);
    status_t setParamAudioSamplingRate(int32_t sampleRate);
    status_t setParamVideoEncodingBitRate(int32_t bitRate);
    status_t setParamVideoEncodingBitRate(int32_t bitRate);
    status_t setParamVideoIFramesInterval(int32_t interval);
    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 setParamVideoCameraId(int32_t cameraId);
    status_t setParamTrackTimeStatus(int64_t timeDurationUs);
    status_t setParamTrackTimeStatus(int64_t timeDurationUs);
    status_t setParamTrackFrameStatus(int32_t nFrames);
    status_t setParamTrackFrameStatus(int32_t nFrames);
+90 −15
Original line number Original line Diff line number Diff line
@@ -831,7 +831,7 @@ void OMXCodec::setVideoInputFormat(


    video_def->nFrameWidth = width;
    video_def->nFrameWidth = width;
    video_def->nFrameHeight = height;
    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->nBitrate = bitRate;  // Q16 format
    video_def->eCompressionFormat = compressionFormat;
    video_def->eCompressionFormat = compressionFormat;
    video_def->eColorFormat = OMX_COLOR_FormatUnused;
    video_def->eColorFormat = OMX_COLOR_FormatUnused;
@@ -918,6 +918,52 @@ status_t OMXCodec::setupBitRate(int32_t bitRate) {
    return OK;
    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) {
status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
    int32_t iFramesInterval, frameRate, bitRate;
    int32_t iFramesInterval, frameRate, bitRate;
    bool success = meta->findInt32(kKeyBitRate, &bitRate);
    bool success = meta->findInt32(kKeyBitRate, &bitRate);
@@ -941,8 +987,14 @@ status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
    }
    }
    h263type.nBFrames = 0;
    h263type.nBFrames = 0;


    h263type.eProfile = OMX_VIDEO_H263ProfileBaseline;
    // Check profile and level parameters
    h263type.eLevel = OMX_VIDEO_H263Level45;
    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.bPLUSPTYPEAllowed = OMX_FALSE;
    h263type.bForceRoundingTypeToZero = OMX_FALSE;
    h263type.bForceRoundingTypeToZero = OMX_FALSE;
@@ -992,8 +1044,14 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
    mpeg4type.nHeaderExtension = 0;
    mpeg4type.nHeaderExtension = 0;
    mpeg4type.bReversibleVLC = OMX_FALSE;
    mpeg4type.bReversibleVLC = OMX_FALSE;


    mpeg4type.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
    // Check profile and level parameters
    mpeg4type.eLevel = OMX_VIDEO_MPEG4Level2;
    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(
    err = mOMX->setParameter(
            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
@@ -1029,22 +1087,39 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
    if (h264type.nPFrames == 0) {
    if (h264type.nPFrames == 0) {
        h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
        h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
    }
    }

    // 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.bUseHadamard = OMX_TRUE;
        h264type.nRefFrames = 1;
        h264type.nRefFrames = 1;
        h264type.nRefIdx10ActiveMinus1 = 0;
        h264type.nRefIdx10ActiveMinus1 = 0;
        h264type.nRefIdx11ActiveMinus1 = 0;
        h264type.nRefIdx11ActiveMinus1 = 0;
    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.bEntropyCodingCABAC = OMX_FALSE;
        h264type.bWeightedPPrediction = OMX_FALSE;
        h264type.bWeightedPPrediction = OMX_FALSE;
        h264type.bconstIpred = OMX_FALSE;
        h264type.bconstIpred = OMX_FALSE;
        h264type.bDirect8x8Inference = OMX_FALSE;
        h264type.bDirect8x8Inference = OMX_FALSE;
        h264type.bDirectSpatialTemporal = OMX_FALSE;
        h264type.bDirectSpatialTemporal = OMX_FALSE;
        h264type.nCabacInitIdc = 0;
        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.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;


    err = mOMX->setParameter(
    err = mOMX->setParameter(