Loading media/libheif/HeifDecoderImpl.cpp +50 −16 Original line number Original line Diff line number Diff line Loading @@ -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"); Loading @@ -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) { Loading Loading @@ -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*/); Loading @@ -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"); Loading Loading @@ -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); Loading @@ -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; } } Loading @@ -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. Loading @@ -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) { Loading Loading @@ -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); } } Loading Loading @@ -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; Loading media/libheif/HeifDecoderImpl.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading
media/libheif/HeifDecoderImpl.cpp +50 −16 Original line number Original line Diff line number Diff line Loading @@ -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"); Loading @@ -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) { Loading Loading @@ -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*/); Loading @@ -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"); Loading Loading @@ -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); Loading @@ -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; } } Loading @@ -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. Loading @@ -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) { Loading Loading @@ -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); } } Loading Loading @@ -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; Loading
media/libheif/HeifDecoderImpl.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading