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

Commit 189babb8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Mpeg4writer updates for Dolby Vision"

parents 47a9f3a4 98ae29bc
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");