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

Commit d68e044b authored by Lajos Molnar's avatar Lajos Molnar Committed by Automerger Merge Worker
Browse files

Merge changes I90f3ed33,I5c1378f6 am: c560835f am: f7691271 am: 7a04a4a9

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

Change-Id: I4580902444e3236ba01e1dbc6b5ba5d13e765a34
parents d0b408cf 7a04a4a9
Loading
Loading
Loading
Loading
+41 −21
Original line number Diff line number Diff line
@@ -1127,10 +1127,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                    void *data;
                    size_t size;

                    if (AMediaFormat_getBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_2,
                    if (AMediaFormat_getBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0,
                                               &data, &size)
                        && size >= 5) {
                        const uint8_t *ptr = (const uint8_t *)data;
                        && size >= 24) {
                        const uint8_t *ptr = (const uint8_t *)data + (size - 24);
                        const uint8_t profile = ptr[2] >> 1;
                        const uint8_t bl_compatibility_id = (ptr[4]) >> 4;
                        bool create_two_tracks = false;
@@ -1147,13 +1147,15 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {

                            track_b->timescale = mLastTrack->timescale;
                            track_b->sampleTable = mLastTrack->sampleTable;
                            track_b->includes_expensive_metadata = mLastTrack->includes_expensive_metadata;
                            track_b->includes_expensive_metadata =
                                mLastTrack->includes_expensive_metadata;
                            track_b->skipTrack = mLastTrack->skipTrack;
                            track_b->elst_needs_processing = mLastTrack->elst_needs_processing;
                            track_b->elst_media_time = mLastTrack->elst_media_time;
                            track_b->elst_segment_duration = mLastTrack->elst_segment_duration;
                            track_b->elst_shift_start_ticks = mLastTrack->elst_shift_start_ticks;
                            track_b->elst_initial_empty_edit_ticks = mLastTrack->elst_initial_empty_edit_ticks;
                            track_b->elst_initial_empty_edit_ticks =
                                mLastTrack->elst_initial_empty_edit_ticks;
                            track_b->subsample_encryption = mLastTrack->subsample_encryption;

                            track_b->mTx3gBuffer = mLastTrack->mTx3gBuffer;
@@ -1166,11 +1168,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                            mLastTrack->next = track_b;
                            track_b->next = NULL;

                            // we want to remove the csd-2 key from the metadata, but
                            // we want to remove the csd-0 key from the metadata, but
                            // don't have an AMediaFormat_* function to do so. Settle
                            // for replacing this csd-2 with an empty csd-2.
                            // for replacing this csd-0 with an empty csd-0.
                            uint8_t emptybuffer[8] = {};
                            AMediaFormat_setBuffer(track_b->meta, AMEDIAFORMAT_KEY_CSD_2,
                            AMediaFormat_setBuffer(track_b->meta, AMEDIAFORMAT_KEY_CSD_0,
                                                   emptybuffer, 0);

                            if (4 == profile || 7 == profile || 8 == profile ) {
@@ -1182,6 +1184,8 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                            } else if (10 == profile) {
                                AMediaFormat_setString(track_b->meta,
                                        AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
                                AMediaFormat_setBuffer(track_b->meta, AMEDIAFORMAT_KEY_CSD_0,
                                    data, size - 24);
                            } // Should never get to else part

                            mLastTrack = track_b;
@@ -2591,9 +2595,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            *offset += chunk_size;
            break;
        }
        case FOURCC("dvcC"):
        case FOURCC("dvvC"): {

        case FOURCC("dvcC"):
        case FOURCC("dvvC"):
        case FOURCC("dvwC"):
        {
            if (chunk_data_size != 24) {
                return ERROR_MALFORMED;
            }
@@ -2612,14 +2618,29 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            if (mLastTrack == NULL)
                return ERROR_MALFORMED;

            AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_2,
            void *data = nullptr;
            size_t size = 0;
            if (AMediaFormat_getBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
                //if csd-0 is already present, then append dvcc
                auto csd0_dvcc = heapbuffer<uint8_t>(size + chunk_data_size);

                memcpy(csd0_dvcc.get(), data, size);
                memcpy(csd0_dvcc.get() + size, buffer.get(), chunk_data_size);

                AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0,
                                    csd0_dvcc.get(), size + chunk_data_size);
            } else {
                //if not set csd-0 directly
                AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0,
                                    buffer.get(), chunk_data_size);
            }
            AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME,
                                   MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);

            *offset += chunk_size;
            break;
        }

        case FOURCC("d263"):
        {
            *offset += chunk_size;
@@ -4458,7 +4479,6 @@ MediaTrackHelper *MPEG4Extractor::getTrack(size_t index) {
    if (!AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime)) {
        return NULL;
    }

    sp<ItemTable> itemTable;
    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        void *data;
@@ -4491,14 +4511,14 @@ MediaTrackHelper *MPEG4Extractor::getTrack(size_t index) {
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        void *data;
        size_t size;
        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_2, &data, &size)) {
        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)
                || size < 24) {
            return NULL;
        }

        const uint8_t *ptr = (const uint8_t *)data;

        const uint8_t *ptr = (const uint8_t *)data + (size - 24);
        // dv_major.dv_minor Should be 1.0 or 2.1
        if (size != 24 || ((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1))) {
        if ((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1)) {
            return NULL;
        }
   } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)
@@ -4576,7 +4596,7 @@ status_t MPEG4Extractor::verifyTrack(Track *track) {
            return ERROR_MALFORMED;
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_2, &data, &size)) {
        if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
            return ERROR_MALFORMED;
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
@@ -5152,11 +5172,11 @@ MPEG4Source::MPEG4Source(
        ALOGV("%s DolbyVision stream detected", __FUNCTION__);
        void *data;
        size_t size;
        CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_2, &data, &size));
        CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_0, &data, &size));

        const uint8_t *ptr = (const uint8_t *)data;
        const uint8_t *ptr = (const uint8_t *)data + (size - 24);

        CHECK(size == 24);
        CHECK(size >= 24);

        // dv_major.dv_minor Should be 1.0 or 2.1
        CHECK(!((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1)));
+120 −6
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ public:
    bool isHeic() const { return mIsHeic; }
    bool isAudio() const { return mIsAudio; }
    bool isMPEG4() const { return mIsMPEG4; }
    bool usePrefix() const { return mIsAvc || mIsHevc || mIsHeic; }
    bool usePrefix() const { return mIsAvc || mIsHevc || mIsHeic || mIsDovi; }
    bool isExifData(MediaBufferBase *buffer, uint32_t *tiffHdrOffset) const;
    void addChunkOffset(off64_t offset);
    void addItemOffsetAndSize(off64_t offset, size_t size, bool isExif);
@@ -164,6 +164,7 @@ public:
    TrackId& getTrackId() { return mTrackId; }
    status_t dump(int fd, const Vector<String16>& args) const;
    static const char *getFourCCForMime(const char *mime);
    const char *getDoviFourCC() const;
    const char *getTrackType() const;
    void resetInternal();
    int64_t trackMetaDataSize();
@@ -316,6 +317,7 @@ private:
    volatile bool mStarted;
    bool mIsAvc;
    bool mIsHevc;
    bool mIsDovi;
    bool mIsAudio;
    bool mIsVideo;
    bool mIsHeic;
@@ -370,6 +372,10 @@ private:
    uint8_t mProfileCompatible;
    uint8_t mLevelIdc;

    uint8_t mDoviProfile;
    void *mDoviConfigData;
    size_t mDoviConfigDataSize;

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

    status_t makeDoviCodecSpecificData();

    // Track authoring progress status
    void trackProgressStatus(int64_t timeUs, status_t err = OK);
    void initTrackingProgressStatus(MetaData *params);
@@ -459,6 +467,7 @@ private:
    void writePaspBox();
    void writeAvccBox();
    void writeHvccBox();
    void writeDoviConfigBox();
    void writeUrlBox();
    void writeDrefBox();
    void writeDinfBox();
@@ -617,6 +626,17 @@ status_t MPEG4Writer::Track::dump(
    return OK;
}

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

// static
const char *MPEG4Writer::Track::getFourCCForMime(const char *mime) {
    if (mime == NULL) {
@@ -671,7 +691,9 @@ status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
        mIsBackgroundMode |= isBackgroundMode;
    }

    if (Track::getFourCCForMime(mime) == NULL) {
    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        ALOGV("Add source mime '%s'", mime);
    } else if (Track::getFourCCForMime(mime) == NULL) {
        ALOGE("Unsupported mime '%s'", mime);
        return ERROR_UNSUPPORTED;
    }
@@ -2150,6 +2172,8 @@ MPEG4Writer::Track::Track(
      mMinCttsOffsetTimeUs(0),
      mMinCttsOffsetTicks(0),
      mMaxCttsOffsetTicks(0),
      mDoviConfigData(NULL),
      mDoviConfigDataSize(0),
      mCodecSpecificData(NULL),
      mCodecSpecificDataSize(0),
      mGotAllCodecSpecificData(false),
@@ -2176,6 +2200,7 @@ MPEG4Writer::Track::Track(
    mMeta->findCString(kKeyMIMEType, &mime);
    mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
    mIsHevc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
    mIsDovi = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
    mIsAudio = !strncasecmp(mime, "audio/", 6);
    mIsVideo = !strncasecmp(mime, "video/", 6);
    mIsHeic = !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
@@ -2610,7 +2635,12 @@ 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)) {
        mMeta->findData(kKeyDVCC, &type, &data, &size);
        makeDoviCodecSpecificData();
        if (!mMeta->findData(kKeyAVCC, &type, &data, &size) &&
                !mMeta->findData(kKeyHVCC, &type, &data, &size)) {
            ALOGE("Failed: No HVCC/AVCC for Dolby Vision ..\n");
            return;
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
               !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
@@ -2651,6 +2681,11 @@ MPEG4Writer::Track::~Track() {
        free(mCodecSpecificData);
        mCodecSpecificData = NULL;
    }

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

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

status_t MPEG4Writer::Track::makeDoviCodecSpecificData() {
    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)) {
        ALOGE("Failed getting Dovi config for Dolby Vision %d", (int)size);
        return ERROR_MALFORMED;
    }

    mDoviConfigData = malloc(size);
    if (mDoviConfigData == NULL) {
        ALOGE("Failed allocating Dolby Vision config data");
        return ERROR_MALFORMED;
    }

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

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

    return OK;
}

/*
 * Updates the drift time from the audio track so that
 * the video track can get the updated drift time information
@@ -3474,6 +3540,23 @@ status_t MPEG4Writer::Track::threadEntry() {
                    err = copyCodecSpecificData((const uint8_t *)buffer->data() + buffer->range_offset(),
                            buffer->range_length());
                }
                if (mIsDovi) {
                    err = makeDoviCodecSpecificData();

                    const void *data = NULL;
                    size_t size = 0;

                    uint32_t type = 0;
                    if (mDoviProfile == 9){
                        mMeta->findData(kKeyAVCC, &type, &data, &size);
                    } else if (mDoviProfile < 9)  {
                        mMeta->findData(kKeyHVCC, &type, &data, &size);
                    }

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

            buffer->release();
@@ -4173,6 +4256,7 @@ status_t MPEG4Writer::Track::checkCodecSpecificData() const {
        !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
        !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
        !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime) ||
        !strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime) ||
        !strcasecmp(MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, mime)) {
        if (!mCodecSpecificData ||
            mCodecSpecificDataSize <= 0) {
@@ -4297,7 +4381,13 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
    const char *mime;
    bool success = mMeta->findCString(kKeyMIMEType, &mime);
    CHECK(success);
    const char *fourcc = getFourCCForMime(mime);
    const char *fourcc;
    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
        fourcc = getDoviFourCC();
    } else {
        fourcc = getFourCCForMime(mime);
    }

    if (fourcc == NULL) {
        ALOGE("Unknown mime type '%s'.", mime);
        TRESPASS();
@@ -4337,6 +4427,13 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
        writeAvccBox();
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
        writeHvccBox();
    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime)) {
        if (mDoviProfile <= 8) {
            writeHvccBox();
        } else if (mDoviProfile == 9 || mDoviProfile == 32) {
            writeAvccBox();
        }
        writeDoviConfigBox();
    }

    writePaspBox();
@@ -4829,12 +4926,11 @@ void MPEG4Writer::Track::writeAvccBox() {
    mOwner->endBox();  // avcC
}


void MPEG4Writer::Track::writeHvccBox() {
    CHECK(mCodecSpecificData);
    CHECK_GE(mCodecSpecificDataSize, 5u);

    // Patch avcc's lengthSize field to match the number
    // Patch hvcc's lengthSize field to match the number
    // of bytes we use to indicate the size of a nal unit.
    uint8_t *ptr = (uint8_t *)mCodecSpecificData;
    ptr[21] = (ptr[21] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
@@ -4843,6 +4939,24 @@ void MPEG4Writer::Track::writeHvccBox() {
    mOwner->endBox();  // hvcC
}

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

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

    if (profile > 10) {
        mOwner->beginBox("dvwC");
    } else if (profile > 7) {
        mOwner->beginBox("dvvC");
    } else {
        mOwner->beginBox("dvcC");
    }
    mOwner->write(mDoviConfigData, mDoviConfigDataSize);
    mOwner->endBox();  // dvwC/dvvC/dvcC
}

void MPEG4Writer::Track::writeD263Box() {
    mOwner->beginBox("d263");
    mOwner->writeInt32(0);  // vendor
+143 −30
Original line number Diff line number Diff line
@@ -1510,7 +1510,30 @@ status_t convertMetaDataToMessage(
        msg->setBuffer("csd-0", buffer);
    }

    if (meta->findData(kKeyDVCC, &type, &data, &size)) {
    if (meta->findData(kKeyDVCC, &type, &data, &size)
            || meta->findData(kKeyDVVC, &type, &data, &size)
            || meta->findData(kKeyDVWC, &type, &data, &size)) {
        sp<ABuffer> buffer, csdOrg;
        if (msg->findBuffer("csd-0", &csdOrg)) {
            buffer = new (std::nothrow) ABuffer(size + csdOrg->size());
            if (buffer.get() == NULL || buffer->base() == NULL) {
                return NO_MEMORY;
            }

            memcpy(buffer->data(), csdOrg->data(), csdOrg->size());
            memcpy(buffer->data() + csdOrg->size(), data, size);
        } else {
            buffer = new (std::nothrow) ABuffer(size);
            if (buffer.get() == NULL || buffer->base() == NULL) {
                return NO_MEMORY;
            }
            memcpy(buffer->data(), data, size);
        }

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        const uint8_t *ptr = (const uint8_t *)data;
        ALOGV("DV: calling parseDolbyVisionProfileLevelFromDvcc with data size %zu", size);
        parseDolbyVisionProfileLevelFromDvcc(ptr, size, msg);
@@ -2015,30 +2038,131 @@ status_t convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
                   mime == MEDIA_MIMETYPE_IMAGE_AVIF) {
            meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
        } else if (mime == MEDIA_MIMETYPE_VIDEO_DOLBY_VISION) {
            if (msg->findBuffer("csd-2", &csd2)) {
                //dvcc should be 24
                if (csd2->size() == 24) {
                    meta->setData(kKeyDVCC, kTypeDVCC, csd2->data(), csd2->size());
                    uint8_t *dvcc = csd2->data();
                    const uint8_t profile = dvcc[2] >> 1;
            int32_t needCreateDoviCSD = 0;
            int32_t profile = 0;
            uint8_t bl_compatibility = 0;
            if (msg->findInt32("profile", &profile)) {
                if (profile == DolbyVisionProfileDvheSt) {
                    profile = 8;
                    bl_compatibility = 4;
                } else if (profile == DolbyVisionProfileDvavSe) {
                    profile = 9;
                    bl_compatibility = 2;
                }
                if (profile == 8 || profile == 9) {
                    needCreateDoviCSD = 1;
                }
            } else {
                ALOGW("did not find dolby vision profile");
            }
            // No dovi csd data, need to create it
            if (needCreateDoviCSD) {
                uint8_t dvcc[24];
                int32_t level = 0;
                uint8_t level_val = 0;

                if (msg->findInt32("level", &level)) {
                    const static ALookup<int32_t, uint8_t> levels {
                        {DolbyVisionLevelUnknown, 0},
                        {DolbyVisionLevelHd24, 1},
                        {DolbyVisionLevelHd30, 2},
                        {DolbyVisionLevelFhd24, 3},
                        {DolbyVisionLevelFhd30, 4},
                        {DolbyVisionLevelFhd60, 5},
                        {DolbyVisionLevelUhd24, 6},
                        {DolbyVisionLevelUhd30, 7},
                        {DolbyVisionLevelUhd48, 8},
                        {DolbyVisionLevelUhd60, 9},
                    };
                    levels.map(level, &level_val);
                    ALOGV("found dolby vision level: %d, value: %d", level, level_val);
                }

                dvcc[0] = 1; // major version
                dvcc[1] = 0; // minor version
                dvcc[2] = (uint8_t)((profile & 0x7f) << 1);// dolby vision profile
                dvcc[2] = (uint8_t)((dvcc[2] | (uint8_t)((level_val >> 5) & 0x1)) & 0xff);
                dvcc[3] = (uint8_t)((level_val & 0x1f) << 3); // dolby vision level
                dvcc[3] = (uint8_t)(dvcc[3] | (1 << 2)); // rpu_present_flag
                dvcc[3] = (uint8_t)(dvcc[3] | (1)); // bl_present_flag
                dvcc[4] = (uint8_t)(bl_compatibility << 4);// bl_compatibility id

                std::vector<uint8_t> dvcc_data(24);
                memcpy(dvcc_data.data(), dvcc, 24);
                if (profile > 10) {
                    meta->setData(kKeyDVWC, kTypeDVWC, dvcc_data.data(), 24);
                } else if (profile > 7) {
                    meta->setData(kKeyDVVC, kTypeDVVC, dvcc_data.data(), 24);
                } else {
                    meta->setData(kKeyDVCC, kTypeDVCC, dvcc_data.data(), 24);
                }
            } else if (csd0size >= 24) { // have dovi csd, just send it out...
                uint8_t *dvconfig = csd0->data() + (csd0size -24);
                profile = dvconfig[2] >> 1;
                if (profile > 10) {
                    meta->setData(kKeyDVWC, kTypeDVWC, dvconfig, 24);
                } else if (profile > 7) {
                    meta->setData(kKeyDVVC, kTypeDVVC, dvconfig, 24);
                } else {
                    meta->setData(kKeyDVCC, kTypeDVCC, dvconfig, 24);
                }
            } else {
                return BAD_VALUE;
            }

            // Send the avc/hevc/av1 csd data...
            if (csd0size >= 24) {
                sp<ABuffer> csd;
                if ( profile > 1 && profile < 9) {
                    if (msg->findBuffer("csd-hevc", &csd)) {
                        meta->setData(kKeyHVCC, kTypeHVCC, csd->data(), csd->size());
                    } else if (csd0size > 24) {
                        std::vector<uint8_t> hvcc(csd0size + 1024);
                        size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
                        meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize);
                    } else if (DolbyVisionProfileDvav110 == profile) {
                        meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
                    } else {
                    }
                } else if (profile == 9) {
                    sp<ABuffer> csd1;
                        if (msg->findBuffer("csd-1", &csd1)) {
                    if (msg->findBuffer("csd-avc", &csd)) {
                        meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
                    } else if (msg->findBuffer("csd-1", &csd1)) {
                        std::vector<char> avcc(csd0size + csd1->size() + 1024);
                        size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
                        meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
                    } else { // for dolby vision avc, csd0 also holds csd1
                        size_t i = 0;
                        int csd0realsize = 0;
                        do {
                            i = findNextNalStartCode(csd0->data() + i,
                                            csd0->size() - i) - csd0->data();
                            if (i > 0) {
                                csd0realsize = i;
                                break;
                            }
                            i += 4;
                        } while(i < csd0->size());
                        // buffer0 -> csd0
                        sp<ABuffer> buffer0 = new (std::nothrow) ABuffer(csd0realsize);
                        if (buffer0.get() == NULL || buffer0->base() == NULL) {
                            return NO_MEMORY;
                        }
                        memcpy(buffer0->data(), csd0->data(), csd0realsize);
                        // buffer1 -> csd1
                        sp<ABuffer> buffer1 = new (std::nothrow)
                                ABuffer(csd0->size() - csd0realsize);
                        if (buffer1.get() == NULL || buffer1->base() == NULL) {
                            return NO_MEMORY;
                        }
                        memcpy(buffer1->data(), csd0->data()+csd0realsize,
                                    csd0->size() - csd0realsize);

                        std::vector<char> avcc(csd0->size() + 1024);
                        size_t outsize = reassembleAVCC(buffer0, buffer1, avcc.data());
                        meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
                    }
                } else if (profile == 10) {
                    meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size() - 24);
                }
            } else {
                ALOGE("We need csd-2!!. %s", msg->debugString().c_str());
                return BAD_VALUE;
            }
        } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
            meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
@@ -2086,17 +2210,6 @@ status_t convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
        meta->setData(kKeyStreamHeader, 'mdat', csd0->data(), csd0->size());
    } else if (msg->findBuffer("d263", &csd0)) {
        meta->setData(kKeyD263, kTypeD263, csd0->data(), csd0->size());
    } else if (mime == MEDIA_MIMETYPE_VIDEO_DOLBY_VISION && msg->findBuffer("csd-2", &csd2)) {
        meta->setData(kKeyDVCC, kTypeDVCC, csd2->data(), csd2->size());

        // Remove CSD-2 from the data here to avoid duplicate data in meta
        meta->remove(kKeyOpaqueCSD2);

        if (msg->findBuffer("csd-avc", &csd0)) {
            meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size());
        } else if (msg->findBuffer("csd-hevc", &csd0)) {
            meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size());
        }
    }
    // XXX TODO add whatever other keys there are

+4 −0

File changed.

Preview size limit exceeded, changes collapsed.