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

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

Merge "Mpeg4writer updates for Dolby Vision" am: 189babb8 am: 302d1532 am: a67bce4c

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

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


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


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


    status_t makeDoviCodecSpecificData();
    status_t getDolbyVisionProfile();


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


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


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


    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
    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);
        ALOGV("Add source mime '%s'", mime);
    } else if (Track::getFourCCForMime(mime) == NULL) {
    } else if (Track::getFourCCForMime(mime) == NULL) {
        ALOGE("Unsupported mime '%s'", mime);
        ALOGE("Unsupported mime '%s'", mime);
@@ -2173,8 +2178,7 @@ MPEG4Writer::Track::Track(
      mMinCttsOffsetTimeUs(0),
      mMinCttsOffsetTimeUs(0),
      mMinCttsOffsetTicks(0),
      mMinCttsOffsetTicks(0),
      mMaxCttsOffsetTicks(0),
      mMaxCttsOffsetTicks(0),
      mDoviConfigData(NULL),
      mDoviProfile(0),
      mDoviConfigDataSize(0),
      mCodecSpecificData(NULL),
      mCodecSpecificData(NULL),
      mCodecSpecificDataSize(0),
      mCodecSpecificDataSize(0),
      mGotAllCodecSpecificData(false),
      mGotAllCodecSpecificData(false),
@@ -2636,7 +2640,7 @@ void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
               !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
               !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
        mMeta->findData(kKeyHVCC, &type, &data, &size);
        mMeta->findData(kKeyHVCC, &type, &data, &size);
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        makeDoviCodecSpecificData();
        getDolbyVisionProfile();
        if (!mMeta->findData(kKeyAVCC, &type, &data, &size) &&
        if (!mMeta->findData(kKeyAVCC, &type, &data, &size) &&
                !mMeta->findData(kKeyHVCC, &type, &data, &size)) {
                !mMeta->findData(kKeyHVCC, &type, &data, &size)) {
            ALOGE("Failed: No HVCC/AVCC for Dolby Vision ..\n");
            ALOGE("Failed: No HVCC/AVCC for Dolby Vision ..\n");
@@ -2683,10 +2687,6 @@ MPEG4Writer::Track::~Track() {
        mCodecSpecificData = NULL;
        mCodecSpecificData = NULL;
    }
    }


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


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


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


    if (mDoviConfigData != NULL) {
    if (!mMeta->findData(kKeyDVCC, &type, &data, &size) &&
        ALOGE("Already have Dolby Vision codec specific data");
        !mMeta->findData(kKeyDVVC, &type, &data, &size) &&
        return OK;
        !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);
            ALOGE("Failed getting Dovi config for Dolby Vision %d", (int)size);
            return ERROR_MALFORMED;
            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 (!dolbyVisionProfileMap.map(dv_profile, &mDoviProfile)) {
    if (mDoviConfigData == NULL) {
      ALOGE("Failed to get Dolby Profile from DV Config data");
        ALOGE("Failed allocating Dolby Vision config data");
      return ERROR_MALFORMED;
      return ERROR_MALFORMED;
    }
    }

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

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

    return OK;
    return OK;
}
}


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

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

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

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

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


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

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


    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");
            mOwner->beginBox("dvwC");
    } else if (profile > 7) {
        } else if (mDoviProfile > DolbyVisionProfileDvheDtb) {
            mOwner->beginBox("dvvC");
            mOwner->beginBox("dvvC");
        } else {
        } else {
            mOwner->beginBox("dvcC");
            mOwner->beginBox("dvcC");
        }
        }
    mOwner->write(mDoviConfigData, mDoviConfigDataSize);
        mOwner->write(data, size);
        mOwner->endBox();  // dvwC/dvvC/dvcC
        mOwner->endBox();  // dvwC/dvvC/dvcC
    }
    }
}


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