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

Commit ed91abeb authored by Riaz Rahaman's avatar Riaz Rahaman Committed by Ricardo Cerqueira
Browse files

libstagefright: Add support for High Frame Rate Encoding

Based on kkeyhfr key value from meta data, add support in OMXCodec and
MPEG4Writer for HFR mode

Change-Id: I2fe0780865bd01451bf8e77acf028b498c1c9f28

Conflicts:

	media/libmediaplayerservice/StagefrightRecorder.cpp
	media/libstagefright/OMXCodec.cpp
parent b451abeb
Loading
Loading
Loading
Loading
+81 −0
Original line number Diff line number Diff line
@@ -1438,11 +1438,21 @@ status_t StagefrightRecorder::setupVideoEncoder(
    sp<MetaData> meta = cameraSource->getFormat();

    int32_t width, height, stride, sliceHeight, colorFormat;
#ifdef QCOM_HARDWARE
    int32_t hfr;
#endif
    CHECK(meta->findInt32(kKeyWidth, &width));
    CHECK(meta->findInt32(kKeyHeight, &height));
    CHECK(meta->findInt32(kKeyStride, &stride));
    CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
    CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
#ifdef QCOM_HARDWARE
    CHECK(meta->findInt32(kKeyHFR, &hfr));

    if(hfr) {
      mMaxFileDurationUs = mMaxFileDurationUs * (hfr/mFrameRate);
    }
#endif

    enc_meta->setInt32(kKeyWidth, width);
    enc_meta->setInt32(kKeyHeight, height);
@@ -1450,9 +1460,80 @@ status_t StagefrightRecorder::setupVideoEncoder(
    enc_meta->setInt32(kKeyStride, stride);
    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
    enc_meta->setInt32(kKeyColorFormat, colorFormat);
#ifdef QCOM_HARDWARE
    enc_meta->setInt32(kKeyHFR, hfr);
#endif
    if (mVideoTimeScale > 0) {
        enc_meta->setInt32(kKeyTimeScale, mVideoTimeScale);
    }

#ifdef QCOM_HARDWARE
    char mDeviceName[100];
    property_get("ro.board.platform",mDeviceName,"0");
    if(!strncmp(mDeviceName, "msm7627a", 8)) {
      if(hfr && (width * height > 432*240)) {
        LOGE("HFR mode is supported only upto WQVGA resolution");
        return INVALID_OPERATION;
      }
    }
    else {
      if(hfr && ((mVideoEncoder != VIDEO_ENCODER_H264) || (width * height > 800*480))) {
        LOGE("HFR mode is supported only upto WVGA and H264 codec.");
        return INVALID_OPERATION;
      }
    }
#endif

    /*
     * can set profile from the app as a parameter.
     * For the mean time, set from shell
     */

    char value[PROPERTY_VALUE_MAX];
    bool customProfile = false;

    if (property_get("encoder.video.profile", value, NULL) > 0) {
        customProfile = true;
    }

    if (customProfile) {
        switch ( mVideoEncoder ) {
        case VIDEO_ENCODER_H264:
            if (strncmp("base", value, 4) == 0) {
                mVideoEncoderProfile = OMX_VIDEO_AVCProfileBaseline;
                LOGI("H264 Baseline Profile");
            }
            else if (strncmp("main", value, 4) == 0) {
                mVideoEncoderProfile = OMX_VIDEO_AVCProfileMain;
                LOGI("H264 Main Profile");
            }
            else if (strncmp("high", value, 4) == 0) {
                mVideoEncoderProfile = OMX_VIDEO_AVCProfileHigh;
                LOGI("H264 High Profile");
            }
            else {
               LOGW("Unsupported H264 Profile");
            }
            break;
        case VIDEO_ENCODER_MPEG_4_SP:
            if (strncmp("simple", value, 5) == 0 ) {
                mVideoEncoderProfile = OMX_VIDEO_MPEG4ProfileSimple;
                LOGI("MPEG4 Simple profile");
            }
            else if (strncmp("asp", value, 3) == 0 ) {
                mVideoEncoderProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
                LOGI("MPEG4 Advanced Simple Profile");
            }
            else {
                LOGW("Unsupported MPEG4 Profile");
            }
            break;
        default:
            LOGW("No custom profile support for other codecs");
            break;
        }
    }

    if (mVideoEncoderProfile != -1) {
        enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile);
    }
+15 −0
Original line number Diff line number Diff line
@@ -532,6 +532,18 @@ status_t CameraSource::initWithCameraAccess(
        }
    }

#ifdef QCOM_HARDWARE
    const char *hfr_str = params.get("video-hfr");
    int32_t hfr = -1;
    if ( hfr_str != NULL ) {
      hfr = atoi(hfr_str);
    }
    if(hfr < 0) {
      LOGW("Invalid hfr value(%d) set from app. Disabling HFR.", hfr);
      hfr = 0;
    }
#endif

    int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
    if (glitchDurationUs > mGlitchDurationThresholdUs) {
        mGlitchDurationThresholdUs = glitchDurationUs;
@@ -547,6 +559,9 @@ status_t CameraSource::initWithCameraAccess(
    mMeta->setInt32(kKeyStride,      mVideoSize.width);
    mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
    mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
#ifdef QCOM_HARDWARE
    mMeta->setInt32(kKeyHFR, hfr);
#endif
    return OK;
}

+12 −0
Original line number Diff line number Diff line
@@ -1953,6 +1953,18 @@ status_t MPEG4Writer::Track::threadEntry() {
        meta_data->findInt32(kKeyIsSyncFrame, &isSync);
        CHECK(meta_data->findInt64(kKeyTime, &timestampUs));

#ifdef QCOM_HARDWARE
        if(!mIsAudio) {
          int32_t frameRate, hfr, multiple;
          bool success = mMeta->findInt32(kKeySampleRate, &frameRate);
          CHECK(success);
          success = mMeta->findInt32(kKeyHFR, &hfr);
          CHECK(success);
          multiple = hfr?(hfr/frameRate):1;
          timestampUs = multiple * timestampUs;
        }
#endif

////////////////////////////////////////////////////////////////////////////////
        if (mNumSamples == 0) {
            mFirstSampleTimeRealUs = systemTime() / 1000;
+51 −0
Original line number Diff line number Diff line
@@ -1295,15 +1295,32 @@ void OMXCodec::setVideoInputFormat(
        const char *mime, const sp<MetaData>& meta) {

    int32_t width, height, frameRate, bitRate, stride, sliceHeight;
#ifdef QCOM_HARDWARE
    int32_t hfr;

    char value[PROPERTY_VALUE_MAX];
    if ( property_get("encoder.video.bitrate", value, 0) > 0 && atoi(value) > 0){
        LOGV("Setting bit rate to %d", atoi(value));
        meta->setInt32(kKeyBitRate, atoi(value));
    }

#endif
    bool success = meta->findInt32(kKeyWidth, &width);
    success = success && meta->findInt32(kKeyHeight, &height);
    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
    success = success && meta->findInt32(kKeyBitRate, &bitRate);
    success = success && meta->findInt32(kKeyStride, &stride);
    success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
#ifdef QCOM_HARDWARE
    success = success && meta->findInt32(kKeyHFR, &hfr);
#endif
    CHECK(success);
    CHECK(stride != 0);

#ifdef QCOM_HARDWARE
    frameRate = hfr?hfr:frameRate;
#endif

    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
        compressionFormat = OMX_VIDEO_CodingAVC;
@@ -1538,9 +1555,15 @@ status_t OMXCodec::getVideoProfileLevel(

status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
    int32_t iFramesInterval, frameRate, bitRate;
#ifdef QCOM_HARDWARE
    int32_t hfr;
#endif
    bool success = meta->findInt32(kKeyBitRate, &bitRate);
    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
#ifdef QCOM_HARDWARE
    success = success && meta->findInt32(kKeyHFR, &hfr);
#endif
    CHECK(success);
    OMX_VIDEO_PARAM_H263TYPE h263type;
    InitOMXParams(&h263type);
@@ -1550,6 +1573,9 @@ status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
    CHECK_EQ(err, (status_t)OK);

#ifdef QCOM_HARDWARE
    frameRate = hfr ? hfr : frameRate;
#endif
    h263type.nAllowedPictureTypes =
        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;

@@ -1585,9 +1611,15 @@ status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {

status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
    int32_t iFramesInterval, frameRate, bitRate;
#ifdef QCOM_HARDWARE
    int32_t hfr;
#endif
    bool success = meta->findInt32(kKeyBitRate, &bitRate);
    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
#ifdef QCOM_HARDWARE
    success = success && meta->findInt32(kKeyHFR, &hfr);
#endif
    CHECK(success);
    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
    InitOMXParams(&mpeg4type);
@@ -1604,6 +1636,9 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
    mpeg4type.nAllowedPictureTypes =
        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;

#ifdef QCOM_HARDWARE
    frameRate = hfr ? hfr : frameRate;
#endif
    mpeg4type.nPFrames = setPFramesSpacing(iFramesInterval, frameRate);
    if (mpeg4type.nPFrames == 0) {
        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
@@ -1637,9 +1672,15 @@ status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {

status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
    int32_t iFramesInterval, frameRate, bitRate;
#ifdef QCOM_HARDWARE
    int32_t hfr;
#endif
    bool success = meta->findInt32(kKeyBitRate, &bitRate);
    success = success && meta->findInt32(kKeyFrameRate, &frameRate);
    success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
#ifdef QCOM_HARDWARE
    success = success && meta->findInt32(kKeyHFR, &hfr);
#endif
    CHECK(success);

    OMX_VIDEO_PARAM_AVCTYPE h264type;
@@ -1662,6 +1703,10 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
    h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profileLevel.mProfile);
    h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(profileLevel.mLevel);

#ifdef QCOM_HARDWARE
    frameRate = hfr ? hfr : frameRate;
#endif

    // FIXME:
    // Remove the workaround after the work in done.
    if (!strncmp(mComponentName, "OMX.TI.DUCATI1", 14)) {
@@ -5577,9 +5622,15 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
                bool success = inputFormat->findInt32(kKeyWidth, &width) &&
                               inputFormat->findInt32(kKeyHeight, &height);
                CHECK(success);
                int32_t frameRate = 0, hfr = 0;

                success = inputFormat->findInt32(kKeyHFR, &hfr);
                success = inputFormat->findInt32(kKeySampleRate, &frameRate);

                mOutputFormat->setInt32(kKeyWidth, width);
                mOutputFormat->setInt32(kKeyHeight, height);
                mOutputFormat->setInt32(kKeyHFR, hfr);
                mOutputFormat->setInt32(kKeySampleRate, frameRate);
#endif
            }
            break;