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

Commit b2264390 authored by Praveen Chavan's avatar Praveen Chavan Committed by Gerrit - the friendly Code Review server
Browse files

stagefright: Enhance MPEG4 writer/extractor to store/retrieve layer info

Store temporal layer-count in MP4 meta-keys.
Enhance MPEG4Extractor to parse layer-count and make it available in
file-meta.
For AVC, parse SVC-extension NALs (if available), to extract
the layer-id and make it avialble in buffer-meta.

Bug: 27596987
Change-Id: I84a8914b470a0aadec0e02692296b1915a6c776e
(cherry picked from commit 09c8bb3d3b01d213fb845cd9c24c5e18443d7626)
parent ab72e657
Loading
Loading
Loading
Loading
+1 −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; }

+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 {
+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);
            }
+21 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ static const char kMetaKey_Model[] = "com.android.model";
static const char kMetaKey_Build[]      = "com.android.build";
#endif
static const char kMetaKey_CaptureFps[] = "com.android.capture.fps";
static const char kMetaKey_TemporalLayerCount[] = "com.android.video.temporal_layers_count";

static const uint8_t kMandatoryHevcNalUnitTypes[3] = {
    kHevcNalUnitTypeVps,
@@ -1425,6 +1426,19 @@ status_t MPEG4Writer::setCaptureRate(float captureFps) {
    return OK;
}

status_t MPEG4Writer::setTemporalLayerCount(uint32_t layerCount) {
    if (layerCount > 9) {
        return BAD_VALUE;
    }

    if (layerCount > 0) {
        mMetaKeys->setInt32(kMetaKey_TemporalLayerCount, layerCount);
        mMoovExtraSize += sizeof(kMetaKey_TemporalLayerCount) + 4 + 32;
    }

    return OK;
}

void MPEG4Writer::write(const void *data, size_t size) {
    write(data, 1, size);
}
@@ -1541,6 +1555,13 @@ MPEG4Writer::Track::Track(
    mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
               !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);

    if (!mIsAudio) {
        int32_t numLayers = 0;
        if (mMeta->findInt32(kKeyTemporalLayerCount, &numLayers) && numLayers > 1) {
            mOwner->setTemporalLayerCount(numLayers);
        }
    }

    setTimeScale();
}

+5 −0
Original line number Diff line number Diff line
@@ -1319,6 +1319,11 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
        }

        convertMessageToMetaDataColorAspects(msg, meta);

        int32_t numLayers = 0;
        if (msg->findInt32("num-temporal-layers", &numLayers) && numLayers > 0) {
            meta->setInt32(kKeyTemporalLayerCount, numLayers);
        }
    } else if (mime.startsWith("audio/")) {
        int32_t numChannels;
        if (msg->findInt32("channel-count", &numChannels)) {
Loading