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

Commit a5219650 authored by Dichen Zhang's avatar Dichen Zhang Committed by Android (Google) Code Review
Browse files

Merge "Keep mRetriever thread-save"

parents 3f0c710a 92e5107a
Loading
Loading
Loading
Loading
+50 −16
Original line number Original line Diff line number Diff line
@@ -344,19 +344,22 @@ bool HeifDecoderImpl::reinit(HeifFrameInfo* frameInfo) {
    mFrameDecoded = false;
    mFrameDecoded = false;
    mFrameMemory.clear();
    mFrameMemory.clear();


    mRetriever = new MediaMetadataRetriever();
    sp<MediaMetadataRetriever> retriever = new MediaMetadataRetriever();
    status_t err = mRetriever->setDataSource(mDataSource, "image/heif");
    status_t err = retriever->setDataSource(mDataSource, "image/heif");
    if (err != OK) {
    if (err != OK) {
        ALOGE("failed to set data source!");
        ALOGE("failed to set data source!");

        mRetriever.clear();
        mRetriever.clear();
        mDataSource.clear();
        mDataSource.clear();
        return false;
        return false;
    }
    }
    {
        Mutex::Autolock _l(mRetrieverLock);
        mRetriever = retriever;
    }
    ALOGV("successfully set data source.");
    ALOGV("successfully set data source.");


    const char* hasImage = mRetriever->extractMetadata(METADATA_KEY_HAS_IMAGE);
    const char* hasImage = retriever->extractMetadata(METADATA_KEY_HAS_IMAGE);
    const char* hasVideo = mRetriever->extractMetadata(METADATA_KEY_HAS_VIDEO);
    const char* hasVideo = retriever->extractMetadata(METADATA_KEY_HAS_VIDEO);


    mHasImage = hasImage && !strcasecmp(hasImage, "yes");
    mHasImage = hasImage && !strcasecmp(hasImage, "yes");
    mHasVideo = hasVideo && !strcasecmp(hasVideo, "yes");
    mHasVideo = hasVideo && !strcasecmp(hasVideo, "yes");
@@ -364,7 +367,7 @@ bool HeifDecoderImpl::reinit(HeifFrameInfo* frameInfo) {
    HeifFrameInfo* defaultInfo = nullptr;
    HeifFrameInfo* defaultInfo = nullptr;
    if (mHasImage) {
    if (mHasImage) {
        // image index < 0 to retrieve primary image
        // image index < 0 to retrieve primary image
        sp<IMemory> sharedMem = mRetriever->getImageAtIndex(
        sp<IMemory> sharedMem = retriever->getImageAtIndex(
                -1, mOutputColor, true /*metaOnly*/);
                -1, mOutputColor, true /*metaOnly*/);


        if (sharedMem == nullptr || sharedMem->unsecurePointer() == nullptr) {
        if (sharedMem == nullptr || sharedMem->unsecurePointer() == nullptr) {
@@ -399,7 +402,7 @@ bool HeifDecoderImpl::reinit(HeifFrameInfo* frameInfo) {
    }
    }


    if (mHasVideo) {
    if (mHasVideo) {
        sp<IMemory> sharedMem = mRetriever->getFrameAtTime(0,
        sp<IMemory> sharedMem = retriever->getFrameAtTime(0,
                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
                mOutputColor, true /*metaOnly*/);
                mOutputColor, true /*metaOnly*/);


@@ -425,7 +428,7 @@ bool HeifDecoderImpl::reinit(HeifFrameInfo* frameInfo) {


        initFrameInfo(&mSequenceInfo, videoFrame);
        initFrameInfo(&mSequenceInfo, videoFrame);


        const char* frameCount = mRetriever->extractMetadata(METADATA_KEY_VIDEO_FRAME_COUNT);
        const char* frameCount = retriever->extractMetadata(METADATA_KEY_VIDEO_FRAME_COUNT);
        if (frameCount == nullptr) {
        if (frameCount == nullptr) {
            android_errorWriteWithInfoLog(0x534e4554, "215002587", -1, NULL, 0);
            android_errorWriteWithInfoLog(0x534e4554, "215002587", -1, NULL, 0);
            ALOGD("No valid sequence information in metadata");
            ALOGD("No valid sequence information in metadata");
@@ -511,14 +514,27 @@ bool HeifDecoderImpl::setOutputColor(HeifColorFormat heifColor) {
}
}


bool HeifDecoderImpl::decodeAsync() {
bool HeifDecoderImpl::decodeAsync() {
    wp<MediaMetadataRetriever> weakRetriever;
    {
        Mutex::Autolock _l(mRetrieverLock);
        weakRetriever = mRetriever;
        mRetriever.clear();
    }

    for (size_t i = 1; i < mNumSlices; i++) {
    for (size_t i = 1; i < mNumSlices; i++) {
        sp<MediaMetadataRetriever> retriever = weakRetriever.promote();
        if (retriever == nullptr) {
            return false;
        }

        ALOGV("decodeAsync(): decoding slice %zu", i);
        ALOGV("decodeAsync(): decoding slice %zu", i);
        size_t top = i * mSliceHeight;
        size_t top = i * mSliceHeight;
        size_t bottom = (i + 1) * mSliceHeight;
        size_t bottom = (i + 1) * mSliceHeight;
        if (bottom > mImageInfo.mHeight) {
        if (bottom > mImageInfo.mHeight) {
            bottom = mImageInfo.mHeight;
            bottom = mImageInfo.mHeight;
        }
        }
        sp<IMemory> frameMemory = mRetriever->getImageRectAtIndex(

        sp<IMemory> frameMemory = retriever->getImageRectAtIndex(
                -1, mOutputColor, 0, top, mImageInfo.mWidth, bottom);
                -1, mOutputColor, 0, top, mImageInfo.mWidth, bottom);
        {
        {
            Mutex::Autolock autolock(mLock);
            Mutex::Autolock autolock(mLock);
@@ -534,9 +550,6 @@ bool HeifDecoderImpl::decodeAsync() {
            mScanlineReady.signal();
            mScanlineReady.signal();
        }
        }
    }
    }
    // Aggressive clear to avoid holding on to resources
    mRetriever.clear();

    // Hold on to mDataSource in case the client wants to redecode.
    // Hold on to mDataSource in case the client wants to redecode.
    return false;
    return false;
}
}
@@ -549,6 +562,17 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {
        return true;
        return true;
    }
    }


    sp<MediaMetadataRetriever> retriever;
    {
        Mutex::Autolock _l(mRetrieverLock);
        if (mRetriever == nullptr) {
            ALOGE("Failed to get MediaMetadataRetriever!");
            return false;
        }

        retriever = mRetriever;
    }

    // See if we want to decode in slices to allow client to start
    // See if we want to decode in slices to allow client to start
    // scanline processing in parallel with decode. If this fails
    // scanline processing in parallel with decode. If this fails
    // we fallback to decoding the full frame.
    // we fallback to decoding the full frame.
@@ -563,7 +587,7 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {


        if (mNumSlices > 1) {
        if (mNumSlices > 1) {
            // get first slice and metadata
            // get first slice and metadata
            sp<IMemory> frameMemory = mRetriever->getImageRectAtIndex(
            sp<IMemory> frameMemory = retriever->getImageRectAtIndex(
                    -1, mOutputColor, 0, 0, mImageInfo.mWidth, mSliceHeight);
                    -1, mOutputColor, 0, 0, mImageInfo.mWidth, mSliceHeight);


            if (frameMemory == nullptr || frameMemory->unsecurePointer() == nullptr) {
            if (frameMemory == nullptr || frameMemory->unsecurePointer() == nullptr) {
@@ -598,9 +622,9 @@ bool HeifDecoderImpl::decode(HeifFrameInfo* frameInfo) {


    if (mHasImage) {
    if (mHasImage) {
        // image index < 0 to retrieve primary image
        // image index < 0 to retrieve primary image
        mFrameMemory = mRetriever->getImageAtIndex(-1, mOutputColor);
        mFrameMemory = retriever->getImageAtIndex(-1, mOutputColor);
    } else if (mHasVideo) {
    } else if (mHasVideo) {
        mFrameMemory = mRetriever->getFrameAtTime(0,
        mFrameMemory = retriever->getFrameAtTime(0,
                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, mOutputColor);
                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC, mOutputColor);
    }
    }


@@ -658,7 +682,17 @@ bool HeifDecoderImpl::decodeSequence(int frameIndex, HeifFrameInfo* frameInfo) {
    // set total scanline to sequence height now
    // set total scanline to sequence height now
    mTotalScanline = mSequenceInfo.mHeight;
    mTotalScanline = mSequenceInfo.mHeight;


    mFrameMemory = mRetriever->getFrameAtIndex(frameIndex, mOutputColor);
    sp<MediaMetadataRetriever> retriever;
    {
        Mutex::Autolock _l(mRetrieverLock);
        retriever = mRetriever;
        if (retriever == nullptr) {
            ALOGE("failed to get MediaMetadataRetriever!");
            return false;
        }
    }

    mFrameMemory = retriever->getFrameAtIndex(frameIndex, mOutputColor);
    if (mFrameMemory == nullptr || mFrameMemory->unsecurePointer() == nullptr) {
    if (mFrameMemory == nullptr || mFrameMemory->unsecurePointer() == nullptr) {
        ALOGE("decode: videoFrame is a nullptr");
        ALOGE("decode: videoFrame is a nullptr");
        return false;
        return false;
+2 −0
Original line number Original line Diff line number Diff line
@@ -72,6 +72,8 @@ private:
    bool mHasVideo;
    bool mHasVideo;
    size_t mSequenceLength;
    size_t mSequenceLength;


    Mutex mRetrieverLock;

    // Slice decoding only
    // Slice decoding only
    Mutex mLock;
    Mutex mLock;
    Condition mScanlineReady;
    Condition mScanlineReady;