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

Commit 33ffab3e authored by Lajos Molnar's avatar Lajos Molnar Committed by android-build-merger
Browse files

stagefright: use colr box for color aspects

am: 58fb7c6e

* commit '58fb7c6e':
  stagefright: use colr box for color aspects
parents 4917e98b 58fb7c6e
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -27,14 +27,14 @@ template<typename T, typename U>
struct ALookup {
    ALookup(std::initializer_list<std::pair<T, U>> list);

    bool lookup(const T& from, U *to);
    bool rlookup(const U& from, T *to);
    bool lookup(const T& from, U *to) const;
    bool rlookup(const U& from, T *to) const;

    template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type>
    inline bool map(const T& from, V *to) { return lookup(from, to); }
    inline bool map(const T& from, V *to) const { return lookup(from, to); }

    template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type>
    inline bool map(const V& from, T *to) { return rlookup(from, to); }
    inline bool map(const V& from, T *to) const { return rlookup(from, to); }

private:
    std::vector<std::pair<T, U>> mTable;
@@ -46,7 +46,7 @@ ALookup<T, U>::ALookup(std::initializer_list<std::pair<T, U>> list)
}

template<typename T, typename U>
bool ALookup<T, U>::lookup(const T& from, U *to) {
bool ALookup<T, U>::lookup(const T& from, U *to) const {
    for (auto elem : mTable) {
        if (elem.first == from) {
            *to = elem.second;
@@ -57,7 +57,7 @@ bool ALookup<T, U>::lookup(const T& from, U *to) {
}

template<typename T, typename U>
bool ALookup<T, U>::rlookup(const U& from, T *to) {
bool ALookup<T, U>::rlookup(const U& from, T *to) const {
    for (auto elem : mTable) {
        if (elem.second == from) {
            *to = elem.first;
+9 −0
Original line number Diff line number Diff line
@@ -129,6 +129,15 @@ struct ColorUtils {
    static status_t convertCodecColorAspectsToPlatformAspects(
            const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer);

    // converts Other values to Unspecified
    static void convertCodecColorAspectsToIsoAspects(
            const ColorAspects &aspects,
            int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange);
    // converts unsupported values to Other
    static void convertIsoColorAspectsToCodecAspects(
            int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
            ColorAspects &aspects);

    // updates Unspecified color aspects to their defaults based on the video size
    static void setDefaultCodecColorAspectsIfNeeded(
            ColorAspects &aspects, int32_t width, int32_t height);
+59 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
@@ -2083,6 +2084,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            break;
        }

        case FOURCC('c', 'o', 'l', 'r'):
        {
            *offset += chunk_size;
            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
            // ignore otherwise
            if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) {
                status_t err = parseColorInfo(data_offset, chunk_data_size);
                if (err != OK) {
                    return err;
                }
            }

            break;
        }

        case FOURCC('t', 'i', 't', 'l'):
        case FOURCC('p', 'e', 'r', 'f'):
        case FOURCC('a', 'u', 't', 'h'):
@@ -2663,6 +2679,49 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
    return OK;
}

status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
    if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
        return ERROR_MALFORMED;
    }

    uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
    if (buffer == NULL) {
        return ERROR_MALFORMED;
    }
    if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
        delete[] buffer;
        buffer = NULL;

        return ERROR_IO;
    }

    int32_t type = U32_AT(&buffer[0]);
    if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11)
            || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) {
        int32_t primaries = U16_AT(&buffer[4]);
        int32_t transfer = U16_AT(&buffer[6]);
        int32_t coeffs = U16_AT(&buffer[8]);
        bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128);

        ColorAspects aspects;
        ColorUtils::convertIsoColorAspectsToCodecAspects(
                primaries, transfer, coeffs, fullRange, aspects);

        // only store the first color specification
        if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) {
            mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
            mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
            mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
            mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange);
        }
    }

    delete[] buffer;
    buffer = NULL;

    return OK;
}

status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
    if (size < 4 || size == SIZE_MAX) {
        return ERROR_MALFORMED;
+26 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
@@ -371,6 +372,7 @@ private:
    void writeVmhdBox();
    void writeHdlrBox();
    void writeTkhdBox(uint32_t now);
    void writeColrBox();
    void writeMp4aEsdsBox();
    void writeMp4vEsdsBox();
    void writeAudioFourCCBox();
@@ -2353,6 +2355,7 @@ status_t MPEG4Writer::Track::threadEntry() {
        if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
                && isCodecConfig) {
            CHECK(!mGotAllCodecSpecificData);
            mMeta = mSource->getFormat(); // get output format after format change

            if (mIsAvc) {
                status_t err = makeAVCCodecSpecificData(
@@ -2960,9 +2963,32 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
    }

    writePaspBox();
    writeColrBox();
    mOwner->endBox();  // mp4v, s263 or avc1
}

void MPEG4Writer::Track::writeColrBox() {
    ColorAspects aspects;
    memset(&aspects, 0, sizeof(aspects));
    // TRICKY: using | instead of || because we want to execute all findInt32-s
    if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
            | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
            | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
            | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
        int32_t primaries, transfer, coeffs;
        bool fullRange;
        ColorUtils::convertCodecColorAspectsToIsoAspects(
                aspects, &primaries, &transfer, &coeffs, &fullRange);
        mOwner->beginBox("colr");
        mOwner->writeFourcc("nclx");
        mOwner->writeInt16(primaries);
        mOwner->writeInt16(transfer);
        mOwner->writeInt16(coeffs);
        mOwner->writeInt8(fullRange ? 128 : 0);
        mOwner->endBox(); // colr
    }
}

void MPEG4Writer::Track::writeAudioFourCCBox() {
    const char *mime;
    bool success = mMeta->findCString(kKeyMIMEType, &mime);
+7 −0
Original line number Diff line number Diff line
@@ -781,6 +781,13 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {

            mAvailEncoderInputIndices.push_back(index);
            feedEncoderInputBuffers();
        } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) {
            status_t err = mEncoder->getOutputFormat(&mOutputFormat);
            if (err != OK) {
                signalEOS(err);
                break;
            }
            convertMessageToMetaData(mOutputFormat, mMeta);
        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
            int32_t index;
            size_t offset;
Loading