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

Commit 302d1532 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Mpeg4writer updates for Dolby Vision" am: 189babb8

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2012438

Change-Id: I0bc341ee72fb6024e2791032ba06bd8f0aa20c41
parents 75f5fd33 189babb8
Loading
Loading
Loading
Loading
+80 −65
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/ALookup.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/foundation/ColorUtils.h>
@@ -44,6 +45,7 @@
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/Utils.h>
#include <media/mediarecorder.h>
@@ -372,9 +374,7 @@ private:
    uint8_t mProfileCompatible;
    uint8_t mLevelIdc;

    uint8_t mDoviProfile;
    void *mDoviConfigData;
    size_t mDoviConfigDataSize;
    int32_t mDoviProfile;

    void *mCodecSpecificData;
    size_t mCodecSpecificDataSize;
@@ -428,7 +428,7 @@ private:
    status_t parseHEVCCodecSpecificData(
            const uint8_t *data, size_t size, HevcParameterSets &paramSets);

    status_t makeDoviCodecSpecificData();
    status_t getDolbyVisionProfile();

    // Track authoring progress status
    void trackProgressStatus(int64_t timeUs, status_t err = OK);
@@ -627,14 +627,14 @@ status_t MPEG4Writer::Track::dump(
}

const char *MPEG4Writer::Track::getDoviFourCC() const {
    if (mDoviProfile == 5) {
    if (mDoviProfile == DolbyVisionProfileDvheStn) {
        return "dvh1";
    } else if (mDoviProfile == 8) {
    } else if (mDoviProfile == DolbyVisionProfileDvheSt) {
        return "hvc1";
    } else if (mDoviProfile == 9 || mDoviProfile == 32) {
    } else if (mDoviProfile == DolbyVisionProfileDvavSe) {
        return "avc1";
    }
    return (const char*)NULL;
    return nullptr;
}

// static
@@ -692,6 +692,11 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
    }

    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        // For MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
        // getFourCCForMime() requires profile information
        // to decide the final FourCC codes.
        // So we let the creation of the new track now and
        // assign FourCC codes later using getDoviFourCC()
        ALOGV("Add source mime '%s'", mime);
    } else if (Track::getFourCCForMime(mime) == NULL) {
        ALOGE("Unsupported mime '%s'", mime);
@@ -2172,8 +2177,7 @@ MPEG4Writer::Track::Track(
      mMinCttsOffsetTimeUs(0),
      mMinCttsOffsetTicks(0),
      mMaxCttsOffsetTicks(0),
      mDoviConfigData(NULL),
      mDoviConfigDataSize(0),
      mDoviProfile(0),
      mCodecSpecificData(NULL),
      mCodecSpecificDataSize(0),
      mGotAllCodecSpecificData(false),
@@ -2635,7 +2639,7 @@ void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
               !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
        mMeta->findData(kKeyHVCC, &type, &data, &size);
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        makeDoviCodecSpecificData();
        getDolbyVisionProfile();
        if (!mMeta->findData(kKeyAVCC, &type, &data, &size) &&
                !mMeta->findData(kKeyHVCC, &type, &data, &size)) {
            ALOGE("Failed: No HVCC/AVCC for Dolby Vision ..\n");
@@ -2682,10 +2686,6 @@ MPEG4Writer::Track::~Track() {
        mCodecSpecificData = NULL;
    }

    if (mDoviConfigData != NULL) {
        free(mDoviConfigData);
        mDoviConfigData = NULL;
    }
}

void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
@@ -3364,34 +3364,37 @@ status_t MPEG4Writer::Track::makeHEVCCodecSpecificData(
    return OK;
}

status_t MPEG4Writer::Track::makeDoviCodecSpecificData() {
status_t MPEG4Writer::Track::getDolbyVisionProfile() {
    uint32_t type;
    const void *data = NULL;
    size_t size = 0;

    if (mDoviConfigData != NULL) {
        ALOGE("Already have Dolby Vision codec specific data");
        return OK;
    }

    if (!mMeta->findData(kKeyDVCC, &type, &data, &size)
             && !mMeta->findData(kKeyDVVC, &type, &data, &size)
             && !mMeta->findData(kKeyDVWC, &type, &data, &size)) {
    if (!mMeta->findData(kKeyDVCC, &type, &data, &size) &&
        !mMeta->findData(kKeyDVVC, &type, &data, &size) &&
        !mMeta->findData(kKeyDVWC, &type, &data, &size)) {
            ALOGE("Failed getting Dovi config for Dolby Vision %d", (int)size);
            return ERROR_MALFORMED;
    }
    static const ALookup<uint8_t, int32_t> dolbyVisionProfileMap = {
        {1, DolbyVisionProfileDvavPen},
        {3, DolbyVisionProfileDvheDen},
        {4, DolbyVisionProfileDvheDtr},
        {5, DolbyVisionProfileDvheStn},
        {6, DolbyVisionProfileDvheDth},
        {7, DolbyVisionProfileDvheDtb},
        {8, DolbyVisionProfileDvheSt},
        {9, DolbyVisionProfileDvavSe},
        {10, DolbyVisionProfileDvav110}
    };

    // Dolby Vision profile information is extracted as per
    // https://dolby.my.salesforce.com/sfc/p/#700000009YuG/a/4u000000l6FB/076wHYEmyEfz09m0V1bo85_25hlUJjaiWTbzorNmYY4
    uint8_t dv_profile = ((((uint8_t *)data)[2] >> 1) & 0x7f);

    mDoviConfigData = malloc(size);
    if (mDoviConfigData == NULL) {
        ALOGE("Failed allocating Dolby Vision config data");
    if (!dolbyVisionProfileMap.map(dv_profile, &mDoviProfile)) {
      ALOGE("Failed to get Dolby Profile from DV Config data");
      return ERROR_MALFORMED;
    }

    mDoviConfigDataSize = size;
    memcpy(mDoviConfigData, data, size);

    mDoviProfile = (((char *)data)[2] >> 1) & 0x7f; //getting profile info

    return OK;
}

@@ -3541,24 +3544,26 @@ status_t MPEG4Writer::Track::threadEntry() {
                            buffer->range_length());
                }
                if (mIsDovi) {
                    err = makeDoviCodecSpecificData();

                    err = getDolbyVisionProfile();
                    if(err == OK) {
                        const void *data = NULL;
                        size_t size = 0;

                        uint32_t type = 0;
                    if (mDoviProfile == 9){
                        if (mDoviProfile == DolbyVisionProfileDvavSe) {
                            mMeta->findData(kKeyAVCC, &type, &data, &size);
                    } else if (mDoviProfile < 9)  {
                        } else if (mDoviProfile < DolbyVisionProfileDvavSe) {
                            mMeta->findData(kKeyHVCC, &type, &data, &size);
                        } else {
                            ALOGW("DV Profiles > DolbyVisionProfileDvavSe are not supported");
                            err = ERROR_MALFORMED;
                        }

                    if (data != NULL && copyCodecSpecificData((uint8_t *)data, size) == OK) {
                        if (err == OK && data != NULL &&
                            copyCodecSpecificData((uint8_t *)data, size) == OK) {
                                mGotAllCodecSpecificData = true;
                        }
                    }
                }

            }
            buffer->release();
            buffer = NULL;
            if (OK != err) {
@@ -4428,10 +4433,12 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
        writeHvccBox();
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime)) {
        if (mDoviProfile <= 8) {
        if (mDoviProfile <= DolbyVisionProfileDvheSt) {
            writeHvccBox();
        } else if (mDoviProfile == 9 || mDoviProfile == 32) {
        } else if (mDoviProfile == DolbyVisionProfileDvavSe) {
            writeAvccBox();
        } else {
          TRESPASS("Unsupported Dolby Vision profile");
        }
        writeDoviConfigBox();
    }
@@ -4941,22 +4948,30 @@ void MPEG4Writer::Track::writeHvccBox() {
}

void MPEG4Writer::Track::writeDoviConfigBox() {
    CHECK(mDoviConfigData);
    CHECK_EQ(mDoviConfigDataSize, 24u);

    uint8_t *ptr = (uint8_t *)mDoviConfigData;
    uint8_t profile = (ptr[2] >> 1) & 0x7f;
    CHECK_NE(mDoviProfile, 0u);

    if (profile > 10) {
    uint32_t type = 0;
    const void *data = nullptr;
    size_t size = 0;
    // check to see which key has the configuration box.
    if (mMeta->findData(kKeyDVCC, &type, &data, &size) ||
        mMeta->findData(kKeyDVVC, &type, &data, &size) ||
        mMeta->findData(kKeyDVWC, &type, &data, &size)) {

       // if this box is present we write the box, or
       // this mp4 will be interpreted as a backward
       // compatible stream.
        if (mDoviProfile > DolbyVisionProfileDvav110) {
            mOwner->beginBox("dvwC");
    } else if (profile > 7) {
        } else if (mDoviProfile > DolbyVisionProfileDvheDtb) {
            mOwner->beginBox("dvvC");
        } else {
            mOwner->beginBox("dvcC");
        }
    mOwner->write(mDoviConfigData, mDoviConfigDataSize);
        mOwner->write(data, size);
        mOwner->endBox();  // dvwC/dvvC/dvcC
    }
}

void MPEG4Writer::Track::writeD263Box() {
    mOwner->beginBox("d263");