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

Commit ec809369 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I84a8914b,I434c5252,Ic81f305a into av-aosp.lnx.2.0-dev

* changes:
  stagefright: Enhance MPEG4 writer/extractor to store/retrieve layer info
  MPEG4Writer: Handle writing multiple NAL units in a video sample
  stagefright: ACodec: Enable temporal layered encoding
parents e0b0a36e b2264390
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -481,6 +481,9 @@ protected:
    status_t setOperatingRate(float rateFloat, bool isVideo);
    status_t getIntraRefreshPeriod(uint32_t *intraRefreshPeriod);
    status_t setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure);
    status_t configureTemporalLayers(
            uint32_t numLayers, uint32_t numBLayers, bool inConfigure,
            sp<AMessage> &outputFormat);

    status_t setMinBufferSize(OMX_U32 portIndex, size_t size);

+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public:

    status_t setGeoData(int latitudex10000, int longitudex10000);
    status_t setCaptureRate(float captureFps);
    status_t setTemporalLayerCount(uint32_t layerCount);
    virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
    virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }

@@ -196,6 +197,7 @@ private:
protected:
    static void StripStartcode(MediaBuffer *buffer);
    virtual off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
    off64_t addMultipleLengthPrefixedSamples_l(MediaBuffer *buffer);

private:
    bool exceedsFileSizeLimit();
+2 −0
Original line number Diff line number Diff line
@@ -204,6 +204,8 @@ enum {
                                   // transfer Function, value defined by ColorAspects.Transfer.
    kKeyColorMatrix      = 'cMtx', // int32_t,
                                   // color Matrix, value defined by ColorAspects.MatrixCoeffs.
    kKeyTemporalLayerId  = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
    kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
};

enum {
+103 −0
Original line number Diff line number Diff line
@@ -2493,6 +2493,82 @@ status_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfi
    return OK;
}

status_t ACodec::configureTemporalLayers(
        uint32_t numLayers, uint32_t numBLayers, bool inConfigure,
        sp<AMessage> &outputFormat) {
    if (!mIsVideo || !mIsEncoder) {
        return INVALID_OPERATION;
    }

    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
    InitOMXParams(&layerParams);
    layerParams.nPortIndex = kPortIndexOutput;
    status_t err = mOMX->getParameter(
            mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
            &layerParams, sizeof(layerParams));

    if (err != OK) {
        return err;
    }

    if (numLayers > layerParams.nLayerCountMax ||
            numBLayers > layerParams.nBLayerCountMax) {
        ALOGE("Requested temporal layer count (total=%u B=%u) exceeds max (total=%d B=%d)",
            numLayers, numBLayers, layerParams.nLayerCountMax,
            layerParams.nBLayerCountMax);
        return ERROR_UNSUPPORTED;
    }

    if (!inConfigure) {
        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
        InitOMXParams(&layerConfig);
        layerConfig.nPLayerCountActual = numLayers - numBLayers;
        layerConfig.nBLayerCountActual = numBLayers;
        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
        layerConfig.nPortIndex = kPortIndexOutput;
        layerConfig.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
        err = mOMX->setConfig(
                mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
                &layerConfig, sizeof(layerConfig));
        return err;
    }

    layerParams.nPLayerCountActual = numLayers - numBLayers;
    layerParams.nBLayerCountActual = numBLayers;
    layerParams.bBitrateRatiosSpecified = OMX_FALSE;
    layerParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
    err = mOMX->setParameter(
            mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
            &layerParams, sizeof(layerParams));

    if (err != OK) {
        return err;
    }

    err = mOMX->getParameter(
            mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
            &layerParams, sizeof(layerParams));

    if (err != OK) {
        return err;
    }

    ALOGI("Temporal layers requested (total=%u B=%u) v/s configured (total=%u B=%u)",
            numLayers, numBLayers, layerParams.nPLayerCountActual,
            layerParams.nBLayerCountActual);

#if 0
    mOutputFormat = mOutputFormat->dup();
    mOutputFormat->setInt32("num-temporal-layers",
            layerParams.nPLayerCountActual + layerParams.nBLayerCountActual);
    mOutputFormat->setInt32("num-temporal-b-layers", layerParams.nBLayerCountActual);
#endif
    outputFormat->setInt32("num-temporal-layers",
            layerParams.nPLayerCountActual + layerParams.nBLayerCountActual);

    return err;
}

status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
    OMX_PARAM_PORTDEFINITIONTYPE def;
    InitOMXParams(&def);
@@ -3790,6 +3866,21 @@ status_t ACodec::setupVideoEncoder(
        err = OK;
    }

    if (compressionFormat == OMX_VIDEO_CodingAVC ||
            compressionFormat == OMX_VIDEO_CodingHEVC) {
        int32_t numLayers = 0;
        int32_t numBLayers = 0;
        if (msg->findInt32("num-temporal-layers", &numLayers)) {
            msg->findInt32("num-temporal-b-layers", &numBLayers);
            err = configureTemporalLayers(numLayers, numBLayers, true, outputFormat);
            if (err != OK) {
                ALOGE("Configuring temporal layers (P=%d B=%d) failed: %d",
                        numLayers, numBLayers, err);
                // not a fatal error
            }
        }
    }

    if (err == OK) {
        ALOGI("setupVideoEncoder succeeded");
    }
@@ -7363,6 +7454,18 @@ status_t ACodec::setParameters(const sp<AMessage> &params) {
        }
    }

    int32_t numLayers = 0,
            numBLayers = 0;
    if (params->findInt32("num-temporal-layers", &numLayers)) {
        params->findInt32("num-temporal-b-layers", &numBLayers);
        status_t err = configureTemporalLayers(numLayers, numBLayers, false, mOutputFormat);
        if (err != OK) {
            ALOGE("Dynamic configuration of temporal layers (P=%d B=%d) failed: %d",
                    numLayers, numBLayers, err);
            err = OK;
        }
    }

    return OK;
}

+22 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@

#include <byteswap.h>
#include "include/ID3.h"
#include "include/avc_utils.h"

#ifndef UINT32_MAX
#define UINT32_MAX       (4294967295U)
@@ -2471,6 +2472,15 @@ status_t MPEG4Extractor::parseQTMetaVal(
        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
            mFileMetaData->setFloat(kKeyCaptureFramerate, *(float *)&val);
        }
    } else if (dataType == 67 && dataSize >= 4) {
        // BE signed int32
        uint32_t val;
        if (!mDataSource->getUInt32(offset, &val)) {
            return ERROR_MALFORMED;
        }
        if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
            mFileMetaData->setInt32(kKeyTemporalLayerCount, val);
        }
    } else {
        // add more keys if needed
        ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
@@ -4464,6 +4474,12 @@ status_t MPEG4Source::read(
                    kKeyTargetTime, targetSampleTimeUs);
        }

        if (mIsAVC) {
            uint32_t layerId = FindAVCLayerId(
                    (const uint8_t *)mBuffer->data(), mBuffer->range_length());
            mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
        }

        if (isSyncSample) {
            mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
        }
@@ -4627,6 +4643,12 @@ status_t MPEG4Source::fragmentedRead(
                        kKeyTargetTime, targetSampleTimeUs);
            }

            if (mIsAVC) {
                uint32_t layerId = FindAVCLayerId(
                        (const uint8_t *)mBuffer->data(), mBuffer->range_length());
                mBuffer->meta_data()->setInt32(kKeyTemporalLayerId, layerId);
            }

            if (isSyncSample) {
                mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
            }
Loading