diff --git a/frameworks/innerkitsimpl/utils/include/color_utils.h b/frameworks/innerkitsimpl/utils/include/color_utils.h index 39cd539ce4facb3e674532beaed4a33167928d6a..1120c2546c79fbb53f4eda5d0ffa6f2e63551ae6 100644 --- a/frameworks/innerkitsimpl/utils/include/color_utils.h +++ b/frameworks/innerkitsimpl/utils/include/color_utils.h @@ -29,6 +29,8 @@ namespace Media { class ColorUtils { public: + static std::map COLORSPACE_NAME_TO_COLORINFO_MAP; template static ColorManager::ColorSpaceName CicpToColorSpace(T primaries, T transfer, T matrix, uint8_t range); diff --git a/frameworks/innerkitsimpl/utils/src/color_utils.cpp b/frameworks/innerkitsimpl/utils/src/color_utils.cpp index 31ec021ad34a56f44e30afec70341cc549c091f9..89db069a0163ec11c23f3d4d6e4508f8bae63b56 100644 --- a/frameworks/innerkitsimpl/utils/src/color_utils.cpp +++ b/frameworks/innerkitsimpl/utils/src/color_utils.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "color_utils.h" +using namespace OHOS::HDI::Display::Graphic::Common::V1_0; namespace OHOS { namespace Media { @@ -54,6 +55,62 @@ enum CicpMatrix { CICP_MATRIX_BT2100_ICTCP = 14, }; +std::map ColorUtils::COLORSPACE_NAME_TO_COLORINFO_MAP = { + { ColorManager::BT601_EBU, + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_P, TRANSFUNC_BT709, MATRIX_BT601_P, RANGE_FULL} }, + { ColorManager::BT601_SMPTE_C, + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_N, TRANSFUNC_BT709, MATRIX_BT601_N, RANGE_FULL} }, + { ColorManager::BT709, CM_ColorSpaceInfo {COLORPRIMARIES_BT709, TRANSFUNC_BT709, MATRIX_BT709, RANGE_FULL} }, + { ColorManager::BT2020_HLG, CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_HLG, MATRIX_BT2020, RANGE_FULL} }, + { ColorManager::BT2020_PQ, CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_PQ, MATRIX_BT2020, RANGE_FULL} }, + { ColorManager::BT601_EBU_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_P, TRANSFUNC_BT709, MATRIX_BT601_P, RANGE_LIMITED} }, + { ColorManager::BT601_SMPTE_C_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_N, TRANSFUNC_BT709, MATRIX_BT601_N, RANGE_LIMITED} }, + { ColorManager::BT709_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_BT709, TRANSFUNC_BT709, MATRIX_BT709, RANGE_LIMITED} }, + { ColorManager::BT2020_HLG_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_HLG, MATRIX_BT2020, RANGE_LIMITED} }, + { ColorManager::BT2020_PQ_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_PQ, MATRIX_BT2020, RANGE_LIMITED} }, + { ColorManager::SRGB, CM_ColorSpaceInfo {COLORPRIMARIES_SRGB, TRANSFUNC_SRGB, MATRIX_BT601_N, RANGE_FULL} }, + { ColorManager::DISPLAY_P3, + CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_SRGB, MATRIX_P3, RANGE_FULL} }, + { ColorManager::P3_HLG, CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_HLG, MATRIX_P3, RANGE_FULL} }, + { ColorManager::P3_PQ, CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_PQ, MATRIX_P3, RANGE_FULL} }, + { ColorManager::ADOBE_RGB, + CM_ColorSpaceInfo {COLORPRIMARIES_ADOBERGB, TRANSFUNC_ADOBERGB, MATRIX_ADOBERGB, RANGE_FULL} }, + { ColorManager::SRGB_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_SRGB, TRANSFUNC_SRGB, MATRIX_BT601_N, RANGE_LIMITED} }, + { ColorManager::DISPLAY_P3_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_SRGB, MATRIX_P3, RANGE_LIMITED} }, + { ColorManager::P3_HLG_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_HLG, MATRIX_P3, RANGE_LIMITED} }, + { ColorManager::P3_PQ_LIMIT, CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_PQ, MATRIX_P3, RANGE_LIMITED} }, + { ColorManager::ADOBE_RGB_LIMIT, + CM_ColorSpaceInfo {COLORPRIMARIES_ADOBERGB, TRANSFUNC_ADOBERGB, MATRIX_ADOBERGB, RANGE_LIMITED} }, + { ColorManager::LINEAR_SRGB, + CM_ColorSpaceInfo {COLORPRIMARIES_SRGB, TRANSFUNC_LINEAR, MATRIX_BT709, RANGE_LIMITED} }, + { ColorManager::LINEAR_BT709, + CM_ColorSpaceInfo {COLORPRIMARIES_SRGB, TRANSFUNC_LINEAR, MATRIX_BT709, RANGE_LIMITED} }, + { ColorManager::LINEAR_P3, + CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_LINEAR, MATRIX_BT709, RANGE_LIMITED} }, + { ColorManager::LINEAR_BT2020, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_LINEAR, MATRIX_BT709, RANGE_LIMITED} }, + { ColorManager::DISPLAY_SRGB, + CM_ColorSpaceInfo {COLORPRIMARIES_SRGB, TRANSFUNC_SRGB, MATRIX_BT601_N, RANGE_FULL} }, + { ColorManager::DISPLAY_P3_SRGB, + CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_SRGB, MATRIX_P3, RANGE_FULL} }, + { ColorManager::DISPLAY_P3_HLG, CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_HLG, MATRIX_P3, RANGE_FULL} }, + { ColorManager::DISPLAY_P3_PQ, CM_ColorSpaceInfo {COLORPRIMARIES_P3_D65, TRANSFUNC_PQ, MATRIX_P3, RANGE_FULL} }, + { ColorManager::DISPLAY_BT2020_SRGB, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_SRGB, MATRIX_BT2020, RANGE_FULL} }, + { ColorManager::DISPLAY_BT2020_HLG, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_HLG, MATRIX_BT2020, RANGE_FULL} }, + { ColorManager::DISPLAY_BT2020_PQ, + CM_ColorSpaceInfo {COLORPRIMARIES_BT2020, TRANSFUNC_PQ, MATRIX_BT2020, RANGE_FULL} }, +}; + ColorManager::ColorSpaceName P3ToColorSpace(uint16_t transfer, uint8_t range) { if (transfer == CICP_TRANSFER_PQ) { diff --git a/plugins/common/libs/image/libextplugin/BUILD.gn b/plugins/common/libs/image/libextplugin/BUILD.gn index 65d737edd19303d0871a90c3937f5b139e39c17e..3f00c6c1f31f419d7085bc1f07d9c6ef20d09b8e 100644 --- a/plugins/common/libs/image/libextplugin/BUILD.gn +++ b/plugins/common/libs/image/libextplugin/BUILD.gn @@ -453,29 +453,12 @@ ohos_shared_library("heifimpl") { sources = [ "src/heif_impl/HeifDecoderImpl.cpp" ] - if (enable_heif_hw_decode) { - sources += [ - "src/hardware/heif_hw_decoder.cpp", - "src/hardware/imagecodec/codec_state.cpp", - "src/hardware/imagecodec/format.cpp", - "src/hardware/imagecodec/image_codec.cpp", - "src/hardware/imagecodec/image_codec_buffer.cpp", - "src/hardware/imagecodec/image_codec_dfx.cpp", - "src/hardware/imagecodec/image_codec_list.cpp", - "src/hardware/imagecodec/image_decoder.cpp", - "src/hardware/imagecodec/msg_handle_loop.cpp", - "src/hardware/imagecodec/state_machine.cpp", - "src/hardware/imagecodec/type_converter.cpp", - ] - } - deps = [ ":heifparser", "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", ] external_deps = [ - "ffrt:libffrt", "graphic_2d:color_manager", "graphic_surface:surface", "hilog:libhilog", @@ -485,7 +468,8 @@ ohos_shared_library("heifimpl") { external_deps += [ "c_utils:utils", "drivers_interface_codec:libcodec_proxy_4.0", - "ffmpeg:libohosffmpeg", + "drivers_interface_codec:libimage_proxy_2.1", + "drivers_interface_display:display_commontype_idl_headers", "hdf_core:libhdi", "hitrace:hitrace_meter", "init:libbegetutil", diff --git a/plugins/common/libs/image/libextplugin/include/ext_decoder.h b/plugins/common/libs/image/libextplugin/include/ext_decoder.h index 764bea194b571d45f66efb07ae7405423a5a30a0..18fd3436eab57db35c0c0256489833accd100531 100644 --- a/plugins/common/libs/image/libextplugin/include/ext_decoder.h +++ b/plugins/common/libs/image/libextplugin/include/ext_decoder.h @@ -101,6 +101,7 @@ private: bool IsSupportCropOnDecode(); bool IsSupportCropOnDecode(SkIRect &target); bool IsSupportHardwareDecode(); + bool IsDivisibleBySampleSize(); bool IsSupportSampleDecode(OHOS::Media::PixelFormat desiredFormat); bool IsYuv420Format(OHOS::Media::PixelFormat format) const; bool IsHeifToYuvDecode(const DecodeContext &context) const; @@ -125,14 +126,20 @@ private: uint32_t DmaMemAlloc(DecodeContext &context, uint64_t count, SkImageInfo &dstInfo); uint32_t JpegHwDmaMemAlloc(DecodeContext &context, uint64_t count, SkImageInfo &dstInfo); uint32_t DmaAlloc(DecodeContext &context, uint64_t count, const OHOS::BufferRequestConfig &requestConfig); - uint32_t AllocateHeifYuvAuxiliaryBuffer(DecodeContext& context, uint32_t width, uint32_t height); - uint32_t HeifYUVMemAlloc(DecodeContext &context); + uint32_t HeifYUVMemAlloc(DecodeContext &context, SkImageInfo &heifInfo); + uint32_t DoHeifDecode(DecodeContext &context); + uint32_t DoHeifToRgbDecode(DecodeContext &context); + void SetHeifSampleSize(const PixelDecodeOptions &opts, int &dstWidth, int &dstHeight, + SkColorType desireColor, SkAlphaType desireAlpha); + bool IsSupportHeifHardwareDecode(const PixelDecodeOptions &opts); + bool DoHeifSwDecode(DecodeContext &context); void SetHeifDecodeError(DecodeContext &context); void SetHeifParseError(); uint32_t ConvertFormatToYUV(DecodeContext &context, SkImageInfo &skInfo, uint64_t byteCount, OHOS::Media::PixelFormat format); bool IsHeifToSingleHdrDecode(const DecodeContext &context) const; uint32_t DoHeifToSingleHdrDecode(OHOS::ImagePlugin::DecodeContext &context); + uint32_t AllocHeifSingleHdrBuffer(DecodeContext &context); uint32_t HandleGifCache(uint8_t* src, uint8_t* dst, uint64_t rowStride, int dstHeight); uint32_t GetFramePixels(SkImageInfo& info, uint8_t* buffer, uint64_t rowStride, SkCodec::Options options); FrameCacheInfo InitFrameCacheInfo(const uint64_t rowStride, SkImageInfo info); @@ -167,6 +174,7 @@ private: std::shared_ptr srcColorSpace_ = nullptr; OHOS::ColorManager::ColorSpace GetSrcColorSpace(); uint32_t ApplyDesiredColorSpace(DecodeContext &context); + OHOS::ColorManager::ColorSpaceName heifColorSpaceName_ = ColorManager::ColorSpaceName::NONE; #endif #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoder.h b/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoder.h index 3de4d9b214a8147fc86b8a20d905c6675337658d..3e4e3b24af98a7216683717ed5c7f844822693b0 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoder.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoder.h @@ -99,7 +99,6 @@ struct HeifDecoder { virtual size_t skipScanlines(int count) = 0; virtual bool getImageInfo(HeifFrameInfo *frameInfo) = 0; virtual bool decodeGainmap() = 0; - virtual void setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride) = 0; virtual bool getGainmapInfo(HeifFrameInfo* frameInfo) = 0; virtual bool getTmapInfo(HeifFrameInfo* frameInfo) = 0; virtual HeifImageHdrType getHdrType() = 0; diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h b/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h index cc0765395b1e3ad857ceb3fd3e648c2efe0d27d9..78b9426e5f872dd49f58aa8291440d5a825db501 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h @@ -24,7 +24,9 @@ #include "image_type.h" #include "surface_buffer.h" -#include "hardware/heif_hw_decoder.h" +#ifdef IMAGE_COLORSPACE_FLAG +#include "color_space.h" +#endif namespace OHOS::Media { class ImageFwkExtManager; @@ -56,7 +58,7 @@ public: bool getImageInfo(HeifFrameInfo *frameInfo) override; bool decodeGainmap() override; - void setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride) override; + void setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride, void *context); bool getGainmapInfo(HeifFrameInfo* frameInfo) override; bool getTmapInfo(HeifFrameInfo* frameInfo) override; HeifImageHdrType getHdrType() override; @@ -73,6 +75,10 @@ public: void setAuxiliaryDstBuffer(uint8_t* dstBuffer, size_t dstSize, size_t rowStride, void *context); void getFragmentMetadata(Media::Rect& fragmentMetadata); bool SwDecode(bool isSharedMemory = false); + bool IsHeifGainmapNotYuv420(); + bool IsHeifAlphaNotYuv420(); + void SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName); + int32_t GetPrimaryLumaBitNum(); private: bool Reinit(HeifFrameInfo *frameInfo); @@ -88,32 +94,37 @@ private: bool ProcessChunkHead(uint8_t *data, size_t len); - void ReleaseHwDecoder(HeifHardwareDecoder *hwDecoder, bool isReuse); + bool copyToAshmem(std::vector> &inputs, std::vector> &hwInputs); + + void SetHwDecodeInfo(GridInfo &gridInfo, + OHOS::HDI::Codec::Image::V2_1::CodecHeifDecInfo &heifDecodeInfo); + + GSError HwSetColorSpaceData(sptr &buffer, GridInfo &gridInfo); - bool HwDecodeImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, GridInfo &gridInfo, - sptr *outBuffer, bool isPrimary); + bool HwDecodeImage(std::shared_ptr &image, GridInfo &gridInfo, + sptr *outBuffer, bool isPrimary); - void PreparePackedInput(HeifHardwareDecoder *hwDecoder, std::vector> tileImages, + void PreparePackedInput(std::vector> tileImages, std::vector> &packedInput, size_t gridCount); - bool HwDecodeGrids(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer); + bool AllocateHwOutputBuffer(sptr &hwBuffer, bool isPrimary); - bool HwDecodeIovls(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer); + bool HwDecodeGrids(std::shared_ptr &image, + GridInfo &gridInfo, sptr &hwBuffer); - bool HwDecodeIdenImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, GridInfo &gridInfo, - sptr *outBuffer, bool isPrimary); + bool HwDecodeIovls(std::shared_ptr &image, + GridInfo &gridInfo, sptr &hwBuffer); - bool HwDecodeSingleImage(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer); + bool HwDecodeIdenImage(std::shared_ptr &image, GridInfo &gridInfo, + sptr *outBuffer, bool isPrimary); + + bool HwDecodeSingleImage(std::shared_ptr &image, + GridInfo &gridInfo, sptr &hwBuffer); bool HwDecodeMimeImage(std::shared_ptr &image); - bool HwDecodeMovieFirstFrameImage(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer); + bool HwDecodeMovieFirstFrameImage(std::shared_ptr &image, + GridInfo &gridInfo, sptr &hwBuffer); bool SwDecodeImage(std::shared_ptr &image, HevcSoftDecodeParam ¶m, GridInfo &gridInfo, bool isPrimary); @@ -150,6 +161,8 @@ private: void SetColorSpaceInfo(HeifFrameInfo* info, const std::shared_ptr& image); + void GetGainmapColorSpace(ColorManager::ColorSpaceName &gainmapColor); + void SetHardwareDecodeErrMsg(const uint32_t width, const uint32_t height); std::shared_ptr parser_; @@ -178,6 +191,9 @@ private: bool isAuxiliaryDecode_ = false; bool isGainmapDecode_ = false; SurfaceBuffer *auxiliaryDstHwBuffer_; + SurfaceBuffer *gainMapDstHwBuffer_; + uint32_t sampleSize_ = 1; + OHOS::ColorManager::ColorSpaceName colorSpaceName_ = ColorManager::colorSpaceName::NONE; HeifFrameInfo tmapInfo_{}; std::string errMsg_; diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/hevc_sw_decode_param.h b/plugins/common/libs/image/libextplugin/include/heif_impl/hevc_sw_decode_param.h index 6dcb0c5dd1e765dfa8ee98d0b4ff7e3943fb5fd2..6376d42e60c23111d06cf41d6c018165de12cdce 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/hevc_sw_decode_param.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/hevc_sw_decode_param.h @@ -23,12 +23,15 @@ namespace OHOS { namespace ImagePlugin { struct HevcSoftDecodeParam { GridInfo gridInfo {}; + Media::PixelFormat srcpixFmt = Media::PixelFormat::UNKNOWN; Media::PixelFormat dstPixFmt = Media::PixelFormat::UNKNOWN; uint8_t *dstBuffer = nullptr; uint32_t bufferSize = 0; uint32_t dstStride = 0; void *hwBuffer = nullptr; bool isSharedMemory = false; + void *Yuv400Buffer = nullptr; + uint32_t gainmapRowStride = 0; }; } // namespace ImagePlugin } // namespace OHOS diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index c34d67565596946d4bb101aad659f424861a9ef3..1be95395a9c455a2ea4b7132a42f62aee7faf924 100644 --- a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp +++ b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp @@ -118,6 +118,11 @@ namespace { constexpr static int32_t SK_REPETITION_COUNT_INFINITE = -1; constexpr static int32_t SK_REPETITION_COUNT_ERROR_VALUE = -2; constexpr static int32_t BYTES_PER_YUV_SAMPLE = 2; + constexpr static uint32_t HEIF_HARDWARE_TILE_MIN_DIM = 128; + constexpr static uint32_t HEIF_HARDWARE_TILE_MAX_DIM = 4096; + constexpr static uint32_t HEIF_HARDWARE_DISPLAY_MIN_DIM = 128; + constexpr static int LUMA_8_BIT = 8; + constexpr static int LUMA_10_BIT = 10; } namespace OHOS { @@ -389,7 +394,7 @@ static uint32_t HeapMemAlloc(DecodeContext &context, uint64_t count) return SUCCESS; } -uint32_t ExtDecoder::HeifYUVMemAlloc(OHOS::ImagePlugin::DecodeContext &context) +uint32_t ExtDecoder::HeifYUVMemAlloc(OHOS::ImagePlugin::DecodeContext &context, SkImageInfo &heifInfo) { #ifdef HEIF_HW_DECODE_ENABLE auto heifContext = reinterpret_cast(codec_->getHeifContext()); @@ -398,46 +403,29 @@ uint32_t ExtDecoder::HeifYUVMemAlloc(OHOS::ImagePlugin::DecodeContext &context) } GridInfo gridInfo = heifContext->GetGridInfo(); - HeifHardwareDecoder decoder; - GraphicPixelFormat graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCRCB_420_SP; - if (context.info.pixelFormat == PixelFormat::NV12) { - graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_420_SP; - } else if (context.info.pixelFormat == PixelFormat::YCRCB_P010) { - graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCRCB_P010; - } else if (context.info.pixelFormat == PixelFormat::YCBCR_P010) { - graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_P010; - } - sptr hwBuffer = decoder.AllocateOutputBuffer(gridInfo.displayWidth, gridInfo.displayHeight, - graphicPixelFormat); - if (hwBuffer == nullptr) { - IMAGE_LOGE("HeifHardwareDecoder AllocateOutputBuffer return null"); - return ERR_DMA_NOT_EXIST; - } - - void* nativeBuffer = hwBuffer.GetRefPtr(); - int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer); - if (err != OHOS::GSERROR_OK) { - IMAGE_LOGE("HeifYUVMemAlloc Reference failed"); - return ERR_DMA_DATA_ABNORMAL; + uint64_t byteCount = static_cast(heifInfo.computeMinByteSize()); + bool cond = DmaMemAlloc(context, byteCount, heifInfo) != SUCCESS; + CHECK_INFO_RETURN_RET_LOG(cond, false, "DMA memalloc execution failed."); + uint8_t* dstBuffer = static_cast(context.pixelsBuffer.buffer); + SurfaceBuffer* sbBuffer = reinterpret_cast (context.pixelsBuffer.context); + int32_t rowStride = sbBuffer->GetStride(); + if (rowStride <= 0) { + return false; } - IMAGE_LOGI("ExtDecoder::HeifYUVMemAlloc sb stride is %{public}d, height is %{public}d, size is %{public}d", - hwBuffer->GetStride(), hwBuffer->GetHeight(), hwBuffer->GetSize()); - uint64_t yuvBufferSize = JpegDecoderYuv::GetYuvOutSize(info_.width(), info_.height()); - SetDecodeContextBuffer(context, AllocatorType::DMA_ALLOC, - static_cast(hwBuffer->GetVirAddr()), yuvBufferSize, nativeBuffer); + sbBuffer->GetStride(), sbBuffer->GetHeight(), sbBuffer->GetSize()); OH_NativeBuffer_Planes *planes = nullptr; - GSError retVal = hwBuffer->GetPlanesInfo(reinterpret_cast(&planes)); + GSError retVal = sbBuffer->GetPlanesInfo(reinterpret_cast(&planes)); if (retVal != OHOS::GSERROR_OK || planes == nullptr || planes->planeCount < NUM_2) { IMAGE_LOGE("heif yuv decode, Get planesInfo failed, retVal:%{public}d", retVal); } else { uint32_t uvPlaneOffset = (context.info.pixelFormat == PixelFormat::NV12 || context.info.pixelFormat == PixelFormat::YCBCR_P010) ? NUM_ONE : NUM_2; - context.yuvInfo.imageSize = { info_.width(), info_.height() }; - context.yuvInfo.yWidth = info_.width(); - context.yuvInfo.yHeight = info_.height(); - context.yuvInfo.uvWidth = static_cast((info_.width() + 1) / NUM_2); - context.yuvInfo.uvHeight = static_cast((info_.height() + 1) / NUM_2); + context.yuvInfo.imageSize = { heifInfo.width(), heifInfo.height() }; + context.yuvInfo.yWidth = heifInfo.width(); + context.yuvInfo.yHeight = heifInfo.height(); + context.yuvInfo.uvWidth = static_cast((heifInfo.width() + 1) / NUM_2); + context.yuvInfo.uvHeight = static_cast((heifInfo.height() + 1) / NUM_2); context.yuvInfo.yStride = planes->planes[0].columnStride; context.yuvInfo.uvStride = planes->planes[uvPlaneOffset].columnStride; context.yuvInfo.yOffset = planes->planes[0].offset; @@ -780,12 +768,16 @@ uint32_t ExtDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions & dstHeight = opts.desiredSize.height; } #endif - if (IsLowDownScale(opts.desiredSize, info_) && GetScaledSize(dstWidth, dstHeight, scale)) { - dstInfo_ = SkImageInfo::Make(dstWidth, dstHeight, desireColor, desireAlpha, - getDesiredColorSpace(info_, opts)); + if (codec_->getEncodedFormat() != SkEncodedImageFormat::kHEIF) { + if (IsLowDownScale(opts.desiredSize, info_) && GetScaledSize(dstWidth, dstHeight, scale)) { + dstInfo_ = SkImageInfo::Make(dstWidth, dstHeight, desireColor, desireAlpha, + getDesiredColorSpace(info_, opts)); + } else { + dstInfo_ = SkImageInfo::Make(info_.width(), info_.height(), + desireColor, desireAlpha, getDesiredColorSpace(info_, opts)); + } } else { - dstInfo_ = SkImageInfo::Make(info_.width(), info_.height(), - desireColor, desireAlpha, getDesiredColorSpace(info_, opts)); + SetHeifSampleSize(opts, dstWidth, dstHeight, desireColor, desireAlpha); } auto resCode = CheckDecodeOptions(index, opts); CHECK_ERROR_RETURN_RET(resCode != SUCCESS, resCode); @@ -1160,6 +1152,148 @@ void ExtDecoder::InitJpegDecoder() } #endif +bool ExtDecoder::IsSupportHeifHardwareDecode(const PixelDecodeOptions &opts) +{ +#ifdef HEIF_HW_DECODE_ENABLE + auto decoder = reinterpret_cast(codec_->getHeifContext()); + if (decoder == nullptr) { + IMAGE_LOGE("Decode HeifDecoder is nullptr"); + return false; + } + GridInfo gridInfo = decoder->GetGridInfo(); + if (!ImageSystemProperties::GetHeifHardwareDecodeEnabled()) { + return false; + } + if (decoder->IsHeifGainmapNotYuv420() || decoder->IsHeifAlphaNotYuv420()) { + IMAGE_LOGD("The gainmap or alpha channel of the HEIF is not YUV420 format"); + return false; + } + if (opts.CropRect.width > ZERO || opts.CropRect.height > ZERO) { + IMAGE_LOGD("HEIF regiondecode does not set sampleSize"); + return false; + } + if (decoder->GetPrimaryLumaBitNum() == LUMA_10_BIT) { + IMAGE_LOGD("HEIF primary image is Luma 10bit, not support set samplesize"); + return false; + } + return gridInfo.tileWidth >= HEIF_HARDWARE_TILE_MIN_DIM && + gridInfo.tileHeight >= HEIF_HARDWARE_TILE_MIN_DIM && + gridInfo.tileWidth <= HEIF_HARDWARE_TILE_MAX_DIM && + gridInfo.tileHeight <= HEIF_HARDWARE_TILE_MAX_DIM && + gridInfo.displayWidth >= HEIF_HARDWARE_DISPLAY_MIN_DIM && + gridInfo.displayHeight >= HEIF_HARDWARE_DISPLAY_MIN_DIM; +#else + return false; +#endif +} + +bool ExtDecoder::IsDivisibleBySampleSize() +{ + return info_.width() % sampleSize_ == 0 && inf_.height() % sampleSize_ == 0; +} + +void ExtDecoder::SetHeifSampleSize(const PixelDecodeOptions &opts, int &dstWidth, int &dstHeight, + SkColorType desireColor, SkAlphaType desireAlpha) +{ +#ifdef HEIF_HW_DECODE_ENABLE + float scale = ZERO; + if (IsSupportHeifHardwareDecode(opts) && IsLowDownScale(opts.desiredSize, info_) && + GetHardwareScaledSize(dstWidth, dstHeight, scale) && IsDivisibleBySampleSize()) { + dstInfo_ = SkImageInfo::Make(dstWidth, dstHeight, + desireColor, desireAlpha, getDesiredColorSpace(info_, opts)); + } else { + sampleSize_ = DEFAULT_SAMPLE_SIZE; + dstInfo_ = SkImageInfo::Make(info_.width(), info_.height(), + desireColor, desireAlpha, getDesiredColorSpace(info_, opts)); + } +#endif +} + +bool ExtDecoder::DoHeifSwDecode(DecodeContext &context) +{ +#ifdef HEIF_HW_DECODE_ENABLE + sampleSize_ = 1; + context.outInfo.size.width = static_cast(info_.width()); + context.outInfo.size.height = static_cast(info_.height()); + auto decoder = reinterpret_cast(codec_->getHeifContext()); + if (decoder == nullptr) { + IMAGE_LOGE("Decode HeifDecoder is nullptr"); + return false; + } + ReleaseOutputBuffer(context, context.allocatorType); + uint64_t byteCount = info_.computeMinByteSize(); + //If the HWdecode failed, software does not support samplesize, allocate memory based on original image. + bool cond = false; + if (IsHeifToYuvDecode(context)) { + cond = HeifYUVMemAlloc(context, info_) != SUCCESS; + } else { + cond = DmaMemAlloc(context, byteCount, info_) != SUCCESS; + } + CHECK_ERROR_RETURN_RET(cond, false); + auto dstBuffer = reinterpret_cast(context.pixelsBuffer.context); + decoder->SetSampleFormat(DEFAULT_SAMPLE_SIZE, heifColorSpaceName_); + decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), + dstBuffer->GetStride(), context.pixelsBuffer.context); + bool decodeRet = decoder->SwDecode(false); + return decodeRet; +#else + return false; +#endif +} + +uint32_t ExtDecoder::DoHeifToRgbDecode(DecodeContext &context) +{ +#ifdef HEIF_HW_DECODE_ENABLE + auto decoder = reinterpret_cast(codec_->getHeifContext()); + if (decoder == nullptr) { + IMAGE_LOGE("DoHeifToRgbDecode HeifDecoder is nullptr"); + return ERR_IMAGE_DATA_UNSUPPORT; + } + uint64_t byteCount = dstInfo_.computeMinByteSize(); + if (ImageUtils::IsSdrPixelMapReuseSuccess(context, info_.width(), info_.height(), reusePixelmap_)) { + IMAGE_LOGI("HEIF RGB Maindecode reusePixelmap success"); + } else { + bool cond = DmaMemAlloc(context, byteCount, dstInfo_) != SUCCESS; + CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_UNSUPPORT); + } + auto dstBuffer = reinterpret_cast(context.pixelsBuffer.context); + decoder->SetSampleFormat(sampleSize_, heifColorSpaceName_); + decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), + dstBuffer->GetStride(), context.pixelsBuffer.context); + bool decodeRet = decoder->decode(nullptr); + if (!decodeRet && sampleSize_ != DEFAULT_SAMPLE_SIZE) { + IMAGE_LOGD("hwdecode failed, do heif sw decode"); + decodeRet = DoHeifSwDecode(context); + } + if (!decodeRet) { + decoder->getErrMsg(context.hardDecodeError); + } + return decodeRet ? SUCCESS : ERR_IMAGE_DATA_UNSUPPORT; +#else + return ERR_IMAGE_DATA_UNSUPPORT; +#endif +} + +uint32_t ExtDecoder::DoHeifDecode(DecodeContext &context) +{ +#ifdef HEIF_HW_DECODE_ENABLE + context.isHardDecode = true; + if (IsHeifSharedMemDecode(context)) { + context.isHardDecode = false; + return DoHeifSharedMemDecode(context); + } + if (IsHeifToYuvDecode(context)) { + return DoHeifToYuvDecode(context); + } + if (IsHeifToSingleHdrDecode(context)) { + return DoHeifToSingleHdrDecode(context); + } + return DoHeifToRgbDecode(context); +#else + return ERR_IMAGE_DATA_UNSUPPORT; +#endif +} + uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) { #ifdef SK_ENABLE_OHOS_CODEC @@ -1197,19 +1331,19 @@ uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) CHECK_ERROR_RETURN_RET(res != SUCCESS, res); context.outInfo.size.width = static_cast(dstInfo_.width()); context.outInfo.size.height = static_cast(dstInfo_.height()); - if (IsHeifSharedMemDecode(context)) { - context.isHardDecode = false; - return DoHeifSharedMemDecode(context); - } - if (IsHeifToYuvDecode(context)) { - context.isHardDecode = true; - return DoHeifToYuvDecode(context); + SkEncodedImageFormat skEncodeFormat = codec_->getEncodedFormat(); +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); + if (timerFd >= 0) { + close(timerFd); + ffrt::submit([skEncodeFormat] { + ReportImageType(skEncodeFormat); + }, {}, {}); } - if (IsHeifToSingleHdrDecode(context)) { - context.isHardDecode = true; - return DoHeifToSingleHdrDecode(context); +#endif + if (skEncodeFormat == SkEncodedImageFormat::kHEIF) { + return DoHeifDecode(context); } - SkEncodedImageFormat skEncodeFormat = codec_->getEncodedFormat(); PixelFormat format = context.info.pixelFormat; bool isOutputYuv420Format = IsYuv420Format(context.info.pixelFormat); uint32_t result = 0; @@ -1225,9 +1359,6 @@ uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) context.pixelsBuffer.buffer = nullptr; #endif } - if (skEncodeFormat == SkEncodedImageFormat::kHEIF) { - context.isHardDecode = true; - } uint64_t byteCount = dstInfo_.computeMinByteSize(); uint8_t *dstBuffer = nullptr; std::unique_ptr tmpBuffer; @@ -1261,13 +1392,6 @@ uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) "%{public}s: surface buffer is nullptr", __func__); rowStride = static_cast(sbBuffer->GetStride()); } - int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (timerFd >= 0) { - close(timerFd); - ffrt::submit([skEncodeFormat] { - ReportImageType(skEncodeFormat); - }, {}, {}); - } #endif IMAGE_LOGD("decode format %{public}d", skEncodeFormat); if (skEncodeFormat == SkEncodedImageFormat::kGIF || skEncodeFormat == SkEncodedImageFormat::kWEBP) { @@ -1278,7 +1402,7 @@ uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) SkCodec::Result ret = codec_->getPixels(dstInfo_, dstBuffer, rowStride, &dstOptions_); if (ret == SkCodec::kIncompleteInput || ret == SkCodec::kErrorInInput) { IMAGE_LOGI("Decode broken data success. Triggered kIncompleteInput feature of skia!"); - } else if (ret != SkCodec::kSuccess && ResetCodec() && skEncodeFormat != SkEncodedImageFormat::kHEIF) { + } else if (ret != SkCodec::kSuccess && ResetCodec()) { ret = codec_->getPixels(dstInfo_, dstBuffer, rowStride, &dstOptions_); // Try again } if (ret != SkCodec::kSuccess && ret != SkCodec::kIncompleteInput && ret != SkCodec::kErrorInInput) { @@ -1992,6 +2116,7 @@ OHOS::ColorManager::ColorSpace ExtDecoder::GetSrcColorSpace() profile->cicp.full_range_flag); #endif if (cName != ColorManager::NONE) { + heifColorSpaceName_ = cName; IMAGE_LOGI("%{public}s profile has CICP, cName: %{public}u", __func__, static_cast(cName)); return ColorManager::ColorSpace(cName); } @@ -1999,6 +2124,7 @@ OHOS::ColorManager::ColorSpace ExtDecoder::GetSrcColorSpace() if (codec_->getEncodedFormat() == SkEncodedImageFormat::kHEIF) { ColorManager::ColorSpaceName cName = GetHeifNclxColor(codec_.get()); if (cName != ColorManager::NONE) { + heifColorSpaceName_ = cName; IMAGE_LOGI("%{public}s profile has HEIF NCLX color, cName: %{public}u", __func__, static_cast(cName)); return ColorManager::ColorSpace(cName); @@ -2014,6 +2140,7 @@ OHOS::ColorManager::ColorSpace ExtDecoder::GetSrcColorSpace() } IMAGE_LOGD("%{public}s Use name to make a custom graphic colorspace. name: %{public}u", __func__, static_cast(name)); + heifColorSpaceName_ = cName; return OHOS::ColorManager::ColorSpace(name); } @@ -2374,7 +2501,7 @@ bool ExtDecoder::IsHeifToYuvDecode(const DecodeContext &context) const uint32_t ExtDecoder::DoHeifToYuvDecode(OHOS::ImagePlugin::DecodeContext &context) { #ifdef HEIF_HW_DECODE_ENABLE - auto decoder = reinterpret_cast(codec_->getHeifContext()); + auto decoder = reinterpret_cast(codec_->getHeifContext()); CHECK_ERROR_RETURN_RET_LOG(decoder == nullptr, ERR_IMAGE_DATA_UNSUPPORT, "YUV Decode HeifDecoder is nullptr"); if (ImageUtils::IsSdrPixelMapReuseSuccess(context, info_.width(), info_.height(), reusePixelmap_)) { IMAGE_LOGI("DoHeifToYuvDecode reusePixelmap success"); @@ -2385,9 +2512,13 @@ uint32_t ExtDecoder::DoHeifToYuvDecode(OHOS::ImagePlugin::DecodeContext &context auto dstBuffer = reinterpret_cast(context.pixelsBuffer.context); decoder->setOutputColor(context.info.pixelFormat == PixelFormat::NV12 ? kHeifColorFormat_NV12 : kHeifColorFormat_NV21); + decoder->SetSampleFormat(sampleSize_, heifColorSpaceName_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), - dstBuffer->GetStride(), context.pixelsBuffer.context); + dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->decode(nullptr); + if (!decodeRet && sampleSize_ != DEFAULT_SAMPLE_SIZE) { + decodeRet = DoHeifSwDecode(context); + } if (!decodeRet) { decoder->getErrMsg(context.hardDecodeError); } @@ -2414,11 +2545,11 @@ uint32_t ExtDecoder::DoHeifToSingleHdrDecode(DecodeContext &context) uint64_t byteCount = static_cast(info_.computeMinByteSize()); if (context.info.pixelFormat == PixelFormat::YCBCR_P010 || context.info.pixelFormat == PixelFormat::YCRCB_P010) { - uint32_t allocRet = HeifYUVMemAlloc(context); + uint32_t allocRet = HeifYUVMemAlloc(context, dstInfo_); cond = allocRet != SUCCESS; CHECK_ERROR_RETURN_RET(cond, allocRet); } else { - if (DmaMemAlloc(context, byteCount, info_) != SUCCESS) { + if (DmaMemAlloc(context, byteCount, dstInfo_) != SUCCESS) { return ERR_IMAGE_DATA_UNSUPPORT; } } @@ -2428,6 +2559,7 @@ uint32_t ExtDecoder::DoHeifToSingleHdrDecode(DecodeContext &context) auto formatSearch = HEIF_FORMAT_MAP.find(context.info.pixelFormat); heifFormat = (formatSearch != HEIF_FORMAT_MAP.end()) ? formatSearch->second : kHeifColorFormat_RGBA_1010102; decoder->setOutputColor(heifFormat); + decoder->SetSampleFormat(DEFAULT_SAMPLE_SIZE, heifColorSpaceName_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->decode(nullptr); @@ -2508,7 +2640,7 @@ bool ExtDecoder::DecodeHeifGainMap(DecodeContext& context) #ifdef HEIF_HW_DECODE_ENABLE bool cond = codec_ == nullptr || codec_->getEncodedFormat() != SkEncodedImageFormat::kHEIF; CHECK_ERROR_RETURN_RET_LOG(cond, false, "decode heif gainmap, codec error"); - auto decoder = reinterpret_cast(codec_->getHeifContext()); + auto decoder = reinterpret_cast(codec_->getHeifContext()); cond = decoder == nullptr; CHECK_ERROR_RETURN_RET_LOG(cond, false, "decode heif gainmap, decoder error"); HeifFrameInfo gainmapInfo; @@ -2518,11 +2650,14 @@ bool ExtDecoder::DecodeHeifGainMap(DecodeContext& context) cond = width > INT_MAX || height > INT_MAX; CHECK_INFO_RETURN_RET_LOG(cond, false, "DecodeHeifGainmap size exceeds the maximum value"); IMAGE_LOGD("DecodeHeifGainmap size:%{public}d-%{public}d", width, height); - SkImageInfo dstInfo = SkImageInfo::Make(static_cast(width), static_cast(height), + uint32_t dstGainmapWidth = width / sampleSize_; + uint32_t dstGianmapHeight = height / sampleSize_; + IMAGE_LOGD("DecodeHeifGainmap dstsize:%{public}d-%{public}d", dstGainmapWidth, dstGianmapHeight); + SkImageInfo dstInfo = SkImageInfo::Make(static_cast(dstGainmapWidth), static_cast(dstGianmapHeight), dstInfo_.colorType(), dstInfo_.alphaType(), dstInfo_.refColorSpace()); uint64_t byteCount = static_cast(dstInfo.computeMinByteSize()); - context.info.size.width = width; - context.info.size.height = height; + context.info.size.width = dstGainmapWidth; + context.info.size.height = dstGainmapWidth; cond = DmaMemAlloc(context, byteCount, dstInfo) != SUCCESS; CHECK_ERROR_RETURN_RET(cond, false); auto* dstBuffer = static_cast(context.pixelsBuffer.buffer); @@ -2532,7 +2667,7 @@ bool ExtDecoder::DecodeHeifGainMap(DecodeContext& context) FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer); return false; } - decoder->setGainmapDstBuffer(dstBuffer, static_cast(rowStride)); + decoder->setGainmapDstBuffer(dstBuffer, static_cast(rowStride), context.pixelsBuffer.context); if (!decoder->decodeGainmap()) { FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer); return false; @@ -2655,35 +2790,6 @@ bool ExtDecoder::CheckAuxiliaryMap(AuxiliaryPictureType type) return false; } -uint32_t ExtDecoder::AllocateHeifYuvAuxiliaryBuffer(DecodeContext& context, uint32_t width, uint32_t height) -{ -#ifdef HEIF_HW_DECODE_ENABLE - HeifHardwareDecoder heifDecoder; - auto decoder = reinterpret_cast(codec_->getHeifContext()); - GraphicPixelFormat graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCRCB_420_SP; - if (context.info.pixelFormat == PixelFormat::NV12) { - graphicPixelFormat = GRAPHIC_PIXEL_FMT_YCBCR_420_SP; - } - sptr hwBuffer = heifDecoder.AllocateOutputBuffer(width, height, graphicPixelFormat); - CHECK_ERROR_RETURN_RET_LOG(hwBuffer == nullptr, ERR_DMA_NOT_EXIST, - "HeifHardwareDecoder YUV AuxiliaryMap AllocateOutputBuffer return null"); - void* nativeBuffer = hwBuffer.GetRefPtr(); - int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer); - CHECK_ERROR_RETURN_RET_LOG(err != OHOS::GSERROR_OK, ERR_DMA_DATA_ABNORMAL, - "YUV AuxiliaryMap MemAlloc Reference failed"); - IMAGE_LOGI("Allocate HeifYUV AuxiBuffer sb stride is %{public}d, height is %{public}d, size is %{public}d", - hwBuffer->GetStride(), hwBuffer->GetHeight(), hwBuffer->GetSize()); - uint64_t yuvBufferSize = JpegDecoderYuv::GetYuvOutSize(width, height); - SetDecodeContextBuffer(context, AllocatorType::DMA_ALLOC, - static_cast(hwBuffer->GetVirAddr()), yuvBufferSize, nativeBuffer); - decoder->setAuxiliaryDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), - context.pixelsBuffer.bufferSize, hwBuffer->GetStride(), context.pixelsBuffer.context); - return SUCCESS; -#else - return ERR_IMAGE_DATA_UNSUPPORT; -#endif -} - bool ExtDecoder::DecodeHeifAuxiliaryMap(DecodeContext& context, AuxiliaryPictureType type) { #ifdef HEIF_HW_DECODE_ENABLE @@ -2713,22 +2819,16 @@ bool ExtDecoder::DecodeHeifAuxiliaryMap(DecodeContext& context, AuxiliaryPicture uint64_t byteCount = tempByteCount; context.info.size.width = width; context.info.size.height = height; - if (IsYuv420Format(context.info.pixelFormat)) { - uint32_t allocRet = AllocateHeifYuvAuxiliaryBuffer(context, width, height); - if (allocRet != SUCCESS) { - return false; - } - } else { - cond = DmaMemAlloc(context, byteCount, dstInfo) != SUCCESS; - CHECK_INFO_RETURN_RET_LOG(cond, false, "DmaMemAlloc execution failed."); - auto* dstBuffer = static_cast(context.pixelsBuffer.buffer); - auto* sbBuffer = reinterpret_cast(context.pixelsBuffer.context); - int32_t rowStride = sbBuffer->GetStride(); - if (rowStride <= 0) { - return false; - } - decoder->setAuxiliaryDstBuffer(dstBuffer, context.pixelsBuffer.bufferSize, - static_cast(rowStride), context.pixelsBuffer.context); + cond = DmaMemAlloc(context, byteCount, dstInfo) != SUCCESS; + CHECK_INFO_RETURN_RET_LOG(cond, false, "DmaMemAlloc execution failed."); + auto* dstBuffer = static_cast(context.pixelsBuffer.buffer); + auto* sbBuffer = reinterpret_cast(context.pixelsBuffer.context); + int32_t rowStride = sbBuffer->GetStride(); + if (rowStride <= 0) { + return false; + } + decoder->setAuxiliaryDstBuffer(dstBuffer, context.pixelsBuffer.bufferSize, + static_cast(rowStride), context.pixelsBuffer.context); } cond = !decoder->decodeAuxiliaryMap(); CHECK_ERROR_RETURN_RET_LOG(cond, false, diff --git a/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp b/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp index 43b58c7ea2a1f63ae3aa3962b6759bf7ea4ba7c8..9e822401dcf3e766f2f35dde16f32721f2dc2eb1 100644 --- a/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp +++ b/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp @@ -18,7 +18,7 @@ #ifdef HEIF_HW_DECODE_ENABLE #include #include -#include "ffrt.h" +#include #include "image_fwk_ext_manager.h" #include "image_func_timer.h" #include "image_system_properties.h" @@ -26,19 +26,15 @@ #include "image_utils.h" #include "image_log.h" #include "media_errors.h" +#include "metadata_convertor.h" +#include "v1_0/buffer_handle_meta_key_type.h" +#include "vpe_utils.h" +#include "iremote_object.h" +#include "iproxy_broker.h" +#include "color_utils.h" -#include "hardware/heif_hw_decoder.h" #include "heif_impl/hevc_sw_decode_param.h" -#ifdef __cplusplus -extern "C" { -#endif -#include "libswscale/swscale.h" -#include "libavcodec/avcodec.h" -#ifdef __cplusplus -} -#endif - #include #include @@ -52,6 +48,7 @@ namespace OHOS { namespace ImagePlugin { using namespace Media; +using namespace OHOS::HDI::Display::Graphic::Common::V1_0; const static int LUMA_8_BIT = 8; const static int LUMA_10_BIT = 10; const static int DEGREE_360 = 360; @@ -70,48 +67,13 @@ const static int PIXEL_SIZE_4 = 4; const static int MAX_ALPHA = 255; const static int GRID_NUM_2 = 2; -const static uint32_t YCBCR_UV_PLANE = 1; -const static uint32_t PLANE_COUNT_TWO = 2; const static uint32_t HEIF_HARDWARE_TILE_MIN_DIM = 128; const static uint32_t HEIF_HARDWARE_TILE_MAX_DIM = 4096; const static uint32_t HEIF_HARDWARE_DISPLAY_MIN_DIM = 128; -const static size_t MAX_INPUT_BUFFER_SIZE = 5 * 1024 * 1024; +const static int IMAGE_ID = 123; const static uint16_t BT2020_PRIMARIES = 9; -const static int BIT_SHIFT_16BITS = 16; - -typedef uint8_t uvec8[16]; -typedef int16_t vec16[8]; -struct YuvConstants { - uvec8 kUVCoeff; - vec16 kRGBCoeffBias; -}; - -typedef int (*FUNC_NV21ToARGBMatrix)(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height); - -const std::string YUV_LIB_PATH = "libyuv.z.so"; -static void* g_dlHandler = nullptr; -static FUNC_NV21ToARGBMatrix g_libyuvNV21ToARGBMatrixFunc = nullptr; -static struct YuvConstants* g_kYvuI601Constants = nullptr; -static struct YuvConstants* g_kYvuJPEGConstants = nullptr; - -struct PixelFormatConvertParam { - uint8_t *data; - uint32_t width; - uint32_t height; - uint32_t stride; - uint8_t colorRangeFlag; - OH_NativeBuffer_Planes *planesInfo; - AVPixelFormat format; -}; +const static std::string HEIF_SHAREMEM_NAME = "HeifRawData"; const std::map HEIF_AUXTTYPE_ID_MAP = { {AuxiliaryPictureType::GAINMAP, HEIF_AUXTTYPE_ID_GAINMAP}, @@ -121,177 +83,39 @@ const std::map HEIF_AUXTTYPE_ID_MAP = { {AuxiliaryPictureType::FRAGMENT_MAP, HEIF_AUXTTYPE_ID_FRAGMENT_MAP} }; -static bool FillFrameInfoForPixelConvert(AVFrame *frame, PixelFormatConvertParam ¶m) -{ - if (param.format == AV_PIX_FMT_NV12 || param.format == AV_PIX_FMT_NV21 || param.format == AV_PIX_FMT_P010) { - bool cond = (param.planesInfo == nullptr || param.planesInfo->planeCount < PLANE_COUNT_TWO); - CHECK_ERROR_RETURN_RET_LOG(cond, false, "planesInfo is invalid for yuv buffer"); - const OH_NativeBuffer_Plane &planeY = param.planesInfo->planes[0]; - const OH_NativeBuffer_Plane &planeUV = param.planesInfo->planes[param.format == AV_PIX_FMT_NV21 ? 2 : 1]; - IMAGE_LOGI("planeY offset: %{public}llu, columnStride: %{public}u, rowStride: %{public}u," - " planeUV offset: %{public}llu, columnStride: %{public}u, rowStride: %{public}u", - planeY.offset, planeY.columnStride, planeY.rowStride, - planeUV.offset, planeUV.columnStride, planeUV.rowStride); - frame->data[0] = param.data + planeY.offset; - frame->data[1] = param.data + planeUV.offset; - frame->linesize[0] = static_cast(planeY.columnStride); - frame->linesize[1] = static_cast(planeUV.columnStride); - } else { - IMAGE_LOGI("rgb stride: %{public}d", param.stride); - frame->data[0] = param.data; - frame->linesize[0] = static_cast(param.stride); - } - return true; -} - -static void UnloadLibYuv() -{ - g_libyuvNV21ToARGBMatrixFunc = nullptr; - g_kYvuI601Constants = nullptr; - g_kYvuJPEGConstants = nullptr; - if (g_dlHandler) { - dlclose(g_dlHandler); - g_dlHandler = nullptr; - } -} - -__attribute__((destructor)) void DeinitLibyuv() -{ - UnloadLibYuv(); -} - -static bool LoadLibyuv() -{ - if (g_libyuvNV21ToARGBMatrixFunc && g_kYvuI601Constants && g_kYvuJPEGConstants) { - return true; - } - void* g_dlHandler = dlopen(YUV_LIB_PATH.c_str(), RTLD_LAZY | RTLD_NODELETE); - if (g_dlHandler == nullptr) { - IMAGE_LOGE("HeifDecoder dlopen libyuv, failed"); - return false; - } - g_libyuvNV21ToARGBMatrixFunc = (FUNC_NV21ToARGBMatrix)dlsym(g_dlHandler, "NV21ToARGBMatrix"); - g_kYvuI601Constants = (YuvConstants*)dlsym(g_dlHandler, "kYvuI601Constants"); - g_kYvuJPEGConstants = (YuvConstants*)dlsym(g_dlHandler, "kYvuJPEGConstants"); - if (!g_libyuvNV21ToARGBMatrixFunc || !g_kYvuI601Constants || !g_kYvuJPEGConstants) { - IMAGE_LOGE("HeifDecoder load func, failed"); - return false; +static std::mutex g_codecMtxDecode; +static sptr g_codecMgrDecode; +class HeifDecodeDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr& object) override + { + IMAGE_LOGW("codec_image_service died"); + std::lock_guard lk(g_codecMtxDecode); + g_codecMgrDecode = nullptr; } - return true; -} +}; -static bool ConvertNV12ToRGBA(PixelFormatConvertParam &srcParam, PixelFormatConvertParam &dstParam) +static sptr GetCodecManager() { - ImageTrace trace(__func__); - bool cond = LoadLibyuv(); - CHECK_ERROR_RETURN_RET(!cond, false); - AVFrame *srcFrame = av_frame_alloc(); - AVFrame *dstFrame = av_frame_alloc(); - if (srcFrame == nullptr || dstFrame == nullptr) { - av_frame_free(&srcFrame); - av_frame_free(&dstFrame); - return false; + std::lock_guard lk(g_codecMtxDecode); + if (g_codecMgrDecode) { + return g_codecMgrDecode; } - const YuvConstants *yuvConstants = g_kYvuI601Constants; - if (srcParam.colorRangeFlag == 1) { - yuvConstants = g_kYvuJPEGConstants; - } - bool res = FillFrameInfoForPixelConvert(srcFrame, srcParam) && - FillFrameInfoForPixelConvert(dstFrame, dstParam) && - 0 == g_libyuvNV21ToARGBMatrixFunc( - srcFrame->data[0], srcFrame->linesize[0], - srcFrame->data[1], srcFrame->linesize[1], - dstFrame->data[0], dstFrame->linesize[0], - yuvConstants, - static_cast(srcParam.width), - static_cast(srcParam.height)); - av_frame_free(&srcFrame); - av_frame_free(&dstFrame); - return res; -} - -static bool ConvertPixelFormat(PixelFormatConvertParam &srcParam, PixelFormatConvertParam &dstParam) -{ - ImageTrace trace("ConvertPixelFormat %d %d", srcParam.format, dstParam.format); - IMAGE_LOGD("ConvertPixelFormat %{public}d %{public}d", srcParam.format, dstParam.format); - if (srcParam.format == AV_PIX_FMT_NV12 && dstParam.format == AV_PIX_FMT_RGBA && - ConvertNV12ToRGBA(srcParam, dstParam)) { - return true; + IMAGE_LOGI("need to get ICodecImage"); + g_codecMgrDecode = OHOS::HDI::Codec::Image::V2_1::ICodecImage::Get(); + bool cond = g_codecMgrDecode == nullptr; + CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "ICodecImage get failed"); + bool isDeathRecipientAdded = false; + const sptr &remote = + OHOS::HDI::hdi_objcast(g_codecMgrDecode); + if (remote) { + sptr deathCallBack(new HeifDecodeDeathRecipient()); + isDeathRecipientAdded = remote->AddDeathRecipient(deathCallBack); } - bool res = false; - AVFrame *srcFrame = av_frame_alloc(); - AVFrame *dstFrame = av_frame_alloc(); - SwsContext *ctx = sws_getContext(static_cast(srcParam.width), static_cast(srcParam.height), - srcParam.format, - static_cast(dstParam.width), static_cast(dstParam.height), - dstParam.format, - SWS_BICUBIC, nullptr, nullptr, nullptr); - - //if need applu colorspace in scale, change defult table; - auto srcColorTable = sws_getCoefficients(SWS_CS_DEFAULT); - auto dstColorTable = sws_getCoefficients(SWS_CS_DEFAULT); - sws_setColorspaceDetails(ctx, srcColorTable, - srcParam.colorRangeFlag, - dstColorTable, 0, - 0, 1 << BIT_SHIFT_16BITS, 1 << BIT_SHIFT_16BITS); - if (srcFrame != nullptr && dstFrame != nullptr && ctx != nullptr) { - res = FillFrameInfoForPixelConvert(srcFrame, srcParam) - && FillFrameInfoForPixelConvert(dstFrame, dstParam) - && sws_scale(ctx, srcFrame->data, srcFrame->linesize, 0, - static_cast(srcParam.height), dstFrame->data, dstFrame->linesize); - } - - av_frame_free(&srcFrame); - av_frame_free(&dstFrame); - sws_freeContext(ctx); - return res; -} - -static AVPixelFormat GraphicPixFmt2AvPixFmtForYuv(GraphicPixelFormat pixelFormat) -{ - AVPixelFormat res = AV_PIX_FMT_NV12; - switch (pixelFormat) { - case GRAPHIC_PIXEL_FMT_YCBCR_420_SP: - res = AV_PIX_FMT_NV12; - break; - case GRAPHIC_PIXEL_FMT_YCRCB_420_SP: - res = AV_PIX_FMT_NV21; - break; - case GRAPHIC_PIXEL_FMT_YCBCR_P010: - res = AV_PIX_FMT_P010; - break; - default: - break; + if (!isDeathRecipientAdded) { + IMAGE_LOGI("failed to add deathRecipient for ICodecImage!"); } - return res; -} - -static AVPixelFormat PixFmt2AvPixFmtForOutput(PixelFormat pixelFormat) -{ - AVPixelFormat res = AV_PIX_FMT_RGBA; - switch (pixelFormat) { - case PixelFormat::RGBA_8888: - res = AV_PIX_FMT_RGBA; - break; - case PixelFormat::BGRA_8888: - res = AV_PIX_FMT_BGRA; - break; - case PixelFormat::RGB_565: - res = AV_PIX_FMT_RGB565; - break; - case PixelFormat::NV12: - res = AV_PIX_FMT_NV12; - break; - case PixelFormat::NV21: - res = AV_PIX_FMT_NV21; - break; - case PixelFormat::RGBA_1010102: - res = AV_PIX_FMT_X2BGR10; - break; - default: - break; - } - return res; + return g_codecMgrDecode; } static PixelFormat SkHeifColorFormat2PixelFormat(SkHeifColorFormat format) @@ -335,7 +159,7 @@ HeifDecoderImpl::HeifDecoderImpl() gainmapDstMemory_(nullptr), gainmapDstRowStride_(0), auxiliaryDstMemory_(nullptr), auxiliaryDstRowStride_(0), auxiliaryDstMemorySize_(0), isAuxiliaryDecode_(false), - auxiliaryDstHwBuffer_(nullptr) {} + auxiliaryDstHwBuffer_(nullptr), gainMapDstHwBuffer_(nullptr) {} HeifDecoderImpl::~HeifDecoderImpl() { @@ -598,6 +422,61 @@ bool HeifDecoderImpl::setOutputColor(SkHeifColorFormat heifColor) return outPixelFormat_ != PixelFormat::UNKNOWN; } +bool HeifDecoderImpl::copyToAshmem(std::vector> &inputs, std::vector> &hwInputs) +{ + ImageTrace trace("HeifDecoderImpl::copyToAshmem, total size: %d", inputs.size()); + hwInputs.clear(); + hwInputs.reserve(inputs.size()); + for (auto& input : inputs) { + size_t size = input.size(); + sptr mem = Ashmem::CreateAshmem(HEIF_SHAREMEM_NAME.c_str(), size); + if (!mem->MapAshmem(PROT_READ | PROT_WRITE)) { + IMAGE_LOGE("Ashmem map failed"); + return false; + } + if (mem == nullptr) { + IMAGE_LOGE("AshmemCreate failed"); + hwInputs.clear(); + return false; + } + if (!mem->WriteToAshmem(input.data(), size, 0)) { + IMAGE_LOGE("memcpy_s failed with error"); + hwInputs.clear(); + return false; + } + hwInputs.push_back(mem); + } + return true; +} + +GSError HeifDecoderImpl::HwSetColorSpaceData(sptr& buffer, GridInfo &gridInfo) +{ + if (buffer == nullptr) { + IMAGE_LOGE("HwSetColorSpaceData buffer is nullptr"); + return GSERROR_NO_BUFFER; + } + if (isGainmapDecode_ || isAuxiliaryDecode_) { + GetGainmapColorSpace(colorSpaceName_); + } + auto colorSpaceSearch = ColorUtils::COLORSPACE_NAME_TO_COLORINFO_MAP.find(colorSpaceName_); + CM_ColorSpaceInfo colorSpaceInfo = + (colorSpaceSearch != ColorUtils::COLORSPACE_NAME_TO_COLORINFO_MAP.end()) ? colorSpaceSearch->second : + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_P, TRANSFUNC_BT709, MATRIX_BT601_P, RANGE_LIMITED}; + if (colorSpaceName_ == ColorManager::ColorSpaceName::NONE && + gridInfo.colorRangeFlag == 1) { + colorSpaceInfo = CM_ColorSpaceInfo {COLORPRIMARIES_BT601_P, TRANSFUNC_BT709, MATRIX_BT601_P, RANGE_FULL}; + } + std::vector colorSpaceInfoVec; + auto ret = MetadataManager::ConvertMetadataToVec(colorSpaceInfo, colorSpaceInfoVec); + if (ret != GSERROR_OK) { + return ret; + } + IMAGE_LOGI("ColorSpace, ColorPrimaries:%{public}d, TransFunc:%{public}d, Matrix:%{public}d, Range:%{public}d", + colorSpaceInfo.primaries, colorSpaceInfo.transfunc, + colorSpaceInfo.matrix, colorSpaceInfo.range); + return buffer->SetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec); +} + static bool IsSupportHardwareDecode(const GridInfo &gridInfo) { if (!ImageSystemProperties::GetHeifHardwareDecodeEnabled()) { @@ -618,18 +497,21 @@ bool HeifDecoderImpl::decode(HeifFrameInfo *frameInfo) return SwDecode(); } sptr hwBuffer; - bool decodeRes = HwDecodeImage(nullptr, primaryImage_, gridInfo_, &hwBuffer, true); + IMAGE_LOGD("decode sapmpleSize:%{public}d", sampleSize_); + bool decodeRes = HwDecodeImage(primaryImage_, gridInfo_, &hwBuffer, true); + if (decodeRes) { + ImageUtils::DumpDataIfDumpEnabled(reinterpret_cast(hwBuffer->GetVirAddr()), + hwBuffer->GetSize(), "heif_hardware_decode", IMAGE_ID); + } + if (!decodeRes && sampleSize_ != DEFAULT_SCALE_SIZE) { + return false; + } if (!decodeRes) { return SwDecode(); } - bool convertRes = IsDirectYUVDecode() || - ConvertHwBufferPixelFormat(hwBuffer, gridInfo_, dstMemory_, dstRowStride_, true); - if (!convertRes) { - return false; - } bool hwApplyAlphaImageRes = HwApplyAlphaImage(primaryImage_, dstMemory_, dstRowStride_); - if (!hwApplyAlphaImageRes) { + if (!hwApplyAlphaImageRes && sampleSize_ == DEFAULT_SAMPLE_SIZE) { SwApplyAlphaImage(primaryImage_, dstMemory_, dstRowStride_); } if (hwBuffer && (hwBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) { @@ -644,10 +526,10 @@ bool HeifDecoderImpl::decode(HeifFrameInfo *frameInfo) bool HeifDecoderImpl::SwDecode(bool isSharedMemory) { HevcSoftDecodeParam param { - gridInfo_, outPixelFormat_, + gridInfo_, Media::PixelFormat::UNKNOWN, outPixelFormat_, dstMemory_, 0, static_cast(dstRowStride_), dstHwBuffer_, - isSharedMemory + isSharedMemory, nullptr, 0 }; bool decodeRes = SwDecodeImage(primaryImage_, param, gridInfo_, true); if (!decodeRes) { @@ -672,7 +554,10 @@ bool HeifDecoderImpl::DoDecodeAuxiliaryImage(std::shared_ptr &auxilia uint8_t *auxiliaryDstMemory, size_t auxiliaryDstRowStride) { sptr hwBuffer; - bool decodeRes = HwDecodeImage(nullptr, auxiliaryImage, auxiliaryGridInfo, &hwBuffer, false); + bool decodeRes = HwDecodeImage(auxiliaryImage, auxiliaryGridInfo, &hwBuffer, false); + if (!decodeRes && sampleSize_ != DEFAULT_SCALE_SIZE) { + return false; + } if (!decodeRes) { sptr swHwBuffer; bool swdecodeRes = SwDecodeAuxiliaryImage(auxiliaryImage, auxiliaryGridInfo, &swHwBuffer); @@ -680,21 +565,8 @@ bool HeifDecoderImpl::DoDecodeAuxiliaryImage(std::shared_ptr &auxilia IMAGE_LOGE("HeifDecoderImpl::SwDecodeAuxiliaryImage failed too"); return false; } - bool swConvertRes = IsAuxiliaryDirectYUVDecode(auxiliaryImage) || - ConvertHwBufferPixelFormat(swHwBuffer, auxiliaryGridInfo, auxiliaryDstMemory, - auxiliaryDstRowStride, false); - if (!swConvertRes) { - return false; - } return true; } - - bool convertRes = IsAuxiliaryDirectYUVDecode(auxiliaryImage) || - ConvertHwBufferPixelFormat(hwBuffer, auxiliaryGridInfo, auxiliaryDstMemory, - auxiliaryDstRowStride, false); - if (!convertRes) { - return false; - } return true; } @@ -714,26 +586,20 @@ bool HeifDecoderImpl::decodeAuxiliaryMap() return DoDecodeAuxiliaryImage(auxiliaryImage_, auxiliaryGridInfo_, auxiliaryDstMemory_, auxiliaryDstRowStride_); } -void HeifDecoderImpl::ReleaseHwDecoder(HeifHardwareDecoder *hwDecoder, bool isReuse) +void HeifDecoderImpl::AllocateHwOutputBuffer(sptr &hwBuffer, bool isPrimary) { - if (isReuse || hwDecoder == nullptr) { - return; - } - int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (timerFd >= 0) { - close(timerFd); - ffrt::submit([hwDecoder] { - ImageTrace trace("delete hwDecoder"); - delete hwDecoder; - }, {}, {}); - } else { - delete hwDecoder; + //hardware decode buffer. + if (isPrimary) { + hwBuffer = sptr(dstHwBuffer_); + } else if (isGainmapDecode_) { + hwBuffer = sptr(gainMapDstHwbuffer_); + } else if (isAuxiliaryDecode_) { + hwBuffer = sptr(auxiliaryDstHwbuffer_); } } -bool HeifDecoderImpl::HwDecodeImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, GridInfo &gridInfo, - sptr *outBuffer, bool isPrimary) +bool HeifDecoderImpl::HwDecodeImage(std::shared_ptr &image, GridInfo &gridInfo, + sptr *outBuffer, bool isPrimary) { bool cond = (outPixelFormat_ == PixelFormat::UNKNOWN); CHECK_ERROR_RETURN_RET_LOG(cond, false, "unknown pixel type: %{public}d", outPixelFormat_); @@ -741,118 +607,78 @@ bool HeifDecoderImpl::HwDecodeImage(HeifHardwareDecoder *hwDecoder, cond = (image == nullptr || outBuffer == nullptr); CHECK_ERROR_RETURN_RET(cond, false); - bool isReuseHwDecoder = hwDecoder != nullptr; - if (!isReuseHwDecoder) { - hwDecoder = new (std::nothrow) HeifHardwareDecoder(); - if (hwDecoder == nullptr) { - IMAGE_LOGE("make HeifHardwareDecoder failed"); - return false; - } - } - - if (image->IsMovieImage()) { - sptr hwMovieBuffer = IsDirectYUVDecode() ? sptr(dstHwBuffer_) : - hwDecoder->AllocateOutputBuffer(gridInfo.tileWidth, gridInfo.tileHeight, - GRAPHIC_PIXEL_FMT_YCBCR_420_SP); - bool res = HwDecodeMovieFirstFrameImage(hwDecoder, image, gridInfo, hwMovieBuffer); - *outBuffer = hwMovieBuffer; - return res; - } - std::string imageType = parser_->GetItemType(image->GetItemId()); if (imageType == "iden") { - bool res = HwDecodeIdenImage(hwDecoder, image, gridInfo, outBuffer, isPrimary); - ReleaseHwDecoder(hwDecoder, isReuseHwDecoder); + bool res = HwDecodeIdenImage(image, gridInfo, outBuffer, isPrimary); return res; } GraphicPixelFormat inPixelFormat = GetInPixelFormat(image); sptr hwBuffer; - if (isAuxiliaryDecode_ && IsAuxiliaryDirectYUVDecode()) { - hwBuffer = sptr(auxiliaryDstHwBuffer_); - } else { - hwBuffer = isPrimary && IsDirectYUVDecode() ? sptr(dstHwBuffer_) : - hwDecoder->AllocateOutputBuffer(gridInfo.displayWidth, gridInfo.displayHeight, inPixelFormat); - } + AllocateHwOutputBuffer(hwBuffer, isPrimary); if (hwBuffer == nullptr) { IMAGE_LOGE("decode AllocateOutputBuffer return null"); - ReleaseHwDecoder(hwDecoder, isReuseHwDecoder); return false; } if (IsDirectYUVDecode()) { inPixelFormat = static_cast(hwBuffer->GetFormat()); } - + GraphicPixelFormat inPixelFormat = static_cast(hwBuffer->GetFormat()); bool res = false; IMAGE_LOGI("HeifDecoderImpl::DecodeImage width: %{public}d, height: %{public}d, imageType: %{public}s," "inPixelFormat: %{public}d", gridInfo.displayWidth, gridInfo.displayHeight, imageType.c_str(), inPixelFormat); if (imageType == "grid") { gridInfo.enableGrid = true; - res = HwDecodeGrids(hwDecoder, image, gridInfo, hwBuffer); + res = HwDecodeGrids(image, gridInfo, hwBuffer); } else if (imageType == "hvc1") { gridInfo.enableGrid = false; - res = HwDecodeSingleImage(hwDecoder, image, gridInfo, hwBuffer); - } else if (imageType == "iovl") { - gridInfo.enableGrid = false; - res = HwDecodeIovls(hwDecoder, image, gridInfo, hwBuffer); + res = HwDecodeSingleImage(image, gridInfo, hwBuffer); } if (res) { *outBuffer = hwBuffer; } - ReleaseHwDecoder(hwDecoder, isReuseHwDecoder); return res; } -void HeifDecoderImpl::PreparePackedInput(HeifHardwareDecoder *hwDecoder, - std::vector> tileImages, - std::vector> &packedInput, size_t gridCount) -{ - if (hwDecoder->IsPackedInputSupported()) { - size_t gridLength = 0; - size_t inputIndex = 0; - packedInput.resize(GRID_NUM_2); - for (size_t index = 0; index < gridCount; ++index) { - std::shared_ptr &tileImage = tileImages[index]; - std::shared_ptr nextTileImage; - if (index == 0) { - // get hvcc header - parser_->GetItemData(tileImage->GetItemId(), &packedInput[inputIndex], heif_only_header); - ProcessChunkHead(packedInput[inputIndex].data(), packedInput[inputIndex].size()); - ++inputIndex; - } - if (packedInput[inputIndex].size() + gridLength >= MAX_INPUT_BUFFER_SIZE) { - ProcessChunkHead(packedInput[inputIndex].data(), packedInput[inputIndex].size()); - ++inputIndex; - packedInput.emplace_back(std::vector()); - } - parser_->GetItemData(tileImage->GetItemId(), &packedInput[inputIndex], heif_no_header); - gridLength = 0; - if (index + 1 != gridCount) { - nextTileImage = tileImages[index + 1]; - parser_->GetGridLength(nextTileImage->GetItemId(), gridLength); - } - } - ProcessChunkHead(packedInput[inputIndex].data(), packedInput[inputIndex].size()); - } else { - packedInput.resize(gridCount + 1); - for (size_t index = 0; index < gridCount; ++index) { - std::shared_ptr &tileImage = tileImages[index]; - if (index == 0) { - // get hvcc header - parser_->GetItemData(tileImage->GetItemId(), &packedInput[index], heif_only_header); - ProcessChunkHead(packedInput[index].data(), packedInput[index].size()); - } - parser_->GetItemData(tileImage->GetItemId(), &packedInput[index + 1], heif_no_header); - ProcessChunkHead(packedInput[index + 1].data(), packedInput[index + 1].size()); +void HeifDecoderImpl::HwPrepareUnPackedInput(std::vector> tileImages, + std::vector> &unPackedInput, size_t gridCount) +{ + unPackedInput.resize(gridCount + 1); + for (size_t index = 0; index < gridCount; ++index) { + std::shared_ptr &tileImage = tileImages[index]; + if (index == 0) { + // get hvcc header + parser_->GetItemData(tileImage->GetItemId(), &unPackedInput[index], heif_only_header); + ProcessChunkHead(unPackedInput[index].data(), unPackedInput[index].size()); } + parser_->GetItemData(tileImage->GetItemId(), &unPackedInput[index + 1], heif_no_header); + ProcessChunkHead(unPackedInput[index + 1].data(), unPackedInput[index + 1].size()); } } -bool HeifDecoderImpl::HwDecodeGrids(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, +void HeifDecoderImpl::SetHwDecodeInfo(GridInfo &gridInfo, + OHOS::HDI::Codec::Image::V2_1::CodecHeifDecInfo &heifDecodeInfo) +{ + OHOS::HDI::Codec::Image::V2_1::GridInfo hwGridInfo = { + gridInfo.displayWidth, + gridInfo.displayHeight, + gridInfo.enableGrid, + gridInfo.cols, + gridInfo.rows, + gridInfo.tileWidth, + gridInfo.tileHeight, + }; + heifDecodeInfo = { + .gridInfo = hwGridInfo, + .sampleSize = sampleSize_, + }; +} + +bool HeifDecoderImpl::HwDecodeGrids(std::shared_ptr &image, GridInfo &gridInfo, sptr &hwBuffer) { - if (hwDecoder == nullptr || image == nullptr) { - IMAGE_LOGE("HeifDecoderImpl::DecodeGrids hwDecoder or image is nullptr"); + if (image == nullptr) { + IMAGE_LOGE("HeifDecoderImpl::DecodeGrids image is nullptr"); return false; } std::vector> tileImages; @@ -866,43 +692,38 @@ bool HeifDecoderImpl::HwDecodeGrids(HeifHardwareDecoder *hwDecoder, std::shared_ IMAGE_LOGE("grid count not equal actual decode quantity"); return false; } - std::vector> packedInput; - PreparePackedInput(hwDecoder, tileImages, packedInput, gridCount); - - uint32_t err = hwDecoder->DoDecode(gridInfo, packedInput, hwBuffer); - if (err != SUCCESS) { - IMAGE_LOGE("heif hw decoder return error: %{public}d, width: %{public}d, height: %{public}d," - " imageType: grid, inPixelFormat: %{public}d, colNum: %{public}d, rowNum: %{public}d," - " tileWidth: %{public}d, tileHeight: %{public}d, hvccLen: %{public}zu", - err, gridInfo.displayWidth, gridInfo.displayHeight, - hwBuffer->GetFormat(), gridInfo.cols, gridInfo.rows, - gridInfo.tileWidth, gridInfo.tileHeight, packedInput[0].size()); - SetHardwareDecodeErrMsg(gridInfo.tileWidth, gridInfo.tileHeight); + std::vector> inputs; + HwPrepareUnPackedInput(tileImages, inputs, gridCount); + GridInfo tempGridInfo = gridInfo; + std::vector> hwInputs; + if (!copyToAshmem(inputs, hwInputs)) { return false; } - return true; -} - -bool HeifDecoderImpl::HwDecodeIovls(HeifHardwareDecoder *hwDecoder, std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer) -{ - if (hwDecoder == nullptr || image == nullptr) { - IMAGE_LOGE("HeifDecoderImpl::HwDecodeIovls hwDecoder or image is nullptr"); + auto ret = HwSetColorSpaceData(hwBuffer, gridInfo); + if (ret != GSERROR_OK) { + IMAGE_LOGE("SetColorSpaceInfo GetMetadata failed, return value is %{public}d", ret); return false; } - std::vector> iovlImages; - parser_->GetIovlImages(image->GetItemId(), iovlImages); - if (iovlImages.empty()) { - IMAGE_LOGE("iovl image has no tile image"); + OHOS::HDI::Codec::Image::V2_1::CodecHeifDecInfo heifDecodeInfo; + SetHwDecodeInfo(gridInfo, heifDecodeInfo); + auto output = sptr::MakeSptr(hwBuffer->GetBufferHandle()); + sptr codec = GetCodecManager(); + CHECK_ERROR_RETURN_RET(codec == nullptr, false); + int32_t result = codec->DoHeifDecode(hwInputs, output, heifDecodeInfo); + if (result != SUCCESS) { + IMAGE_LOGE("heif hw decoder return error: %{public}d, width: %{public}d, height: %{public}d," + " imageType: grid, inPixelFormat: %{public}d, colNum: %{public}d, rowNum: %{public}d," + " tileWidth: %{public}d, tileHeight: %{public}d, hvccLen: %{public}zu", + result, gridInfo.displayWidth, gridInfo.displayHeight, hwBuffer->GetFormat(), gridInfo.cols, + gridInfo.rows, gridInfo.tileWidth, gridInfo.tileHeight, inputs[0].size()); + SetHardwareDecodeErrMsg(gridInfo.tileWidth, gridInfo.tileHeight); return false; } - - return HwDecodeSingleImage(hwDecoder, iovlImages[0], gridInfo, hwBuffer); + return true; } -bool HeifDecoderImpl::HwDecodeIdenImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, GridInfo &gridInfo, - sptr *outBuffer, bool isPrimary) +bool HeifDecoderImpl::HwDecodeIdenImage(std::shared_ptr &image, GridInfo &gridInfo, + sptr *outBuffer, bool isPrimary) { bool cond = !image; CHECK_ERROR_RETURN_RET(cond, false); @@ -910,33 +731,42 @@ bool HeifDecoderImpl::HwDecodeIdenImage(HeifHardwareDecoder *hwDecoder, parser_->GetIdenImage(image->GetItemId(), idenImage); cond = idenImage == nullptr || idenImage == image; CHECK_ERROR_RETURN_RET_LOG(cond, false, "invalid iden image"); - return HwDecodeImage(hwDecoder, idenImage, gridInfo, outBuffer, isPrimary); + return HwDecodeImage(idenImage, gridInfo, outBuffer, isPrimary); } -bool HeifDecoderImpl::HwDecodeSingleImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer) +bool HeifDecoderImpl::HwDecodeSingleImage(std::shared_ptr &image, + GridInfo &gridInfo, sptr &hwBuffer) { - if (hwDecoder == nullptr || image == nullptr) { - IMAGE_LOGE("HeifDecoderImpl::DecodeSingleImage hwDecoder or image is nullptr"); + if (image == nullptr) { + IMAGE_LOGE("HeifDecoderImpl::DecodeSingleImage image is nullptr"); return false; } std::vector> inputs(GRID_NUM_2); - parser_->GetItemData(image->GetItemId(), &inputs[0], heif_only_header); ProcessChunkHead(inputs[0].data(), inputs[0].size()); - parser_->GetItemData(image->GetItemId(), &inputs[1], heif_no_header); ProcessChunkHead(inputs[1].data(), inputs[1].size()); - - uint32_t err = hwDecoder->DoDecode(gridInfo, inputs, hwBuffer); - if (err != SUCCESS) { + std::vector> hwInputs; + if (!copyToAshmem(inputs, hwInputs)) { + return false; + } + auto ret = HwSetColorSpaceData(hwBuffer, gridInfo); + if (ret != GSERROR_OK) { + IMAGE_LOGE("SetColorSpaceInfo GetMetadata failed, return value is %{public}d", ret); + return false; + } + OHOS::HDI::Codec::Image::V2_1::CodecHeifDecInfo heifDecodeInfo; + SetHwDecodeInfo(gridInfo, heifDecodeInfo); + auto output = sptr::MakeSptr(hwBuffer->GetBufferHandle()); + sptr codec = GetCodecManager(); + CHECK_ERROR_RETURN_RET(codec == nullptr, false); + int32_t result = codec->DoHeifDecode(hwInputs, output, heifDecodeInfo); + if (result != SUCCESS) { IMAGE_LOGE("heif hw decoder return error: %{public}d, width: %{public}d, height: %{public}d," - " imageType: hvc1, inPixelFormat: %{public}d, colNum: %{public}d, rowNum: %{public}d," - " tileWidth: %{public}d, tileHeight: %{public}d, hvccLen: %{public}zu, dataLen: %{public}zu", - err, gridInfo.displayWidth, gridInfo.displayHeight, - hwBuffer->GetFormat(), gridInfo.cols, gridInfo.rows, - gridInfo.tileWidth, gridInfo.tileHeight, inputs[0].size(), inputs[1].size()); + " imageType: hvc1, inPixelFormat: %{public}d, colNum: %{public}d, rowNum: %{public}d," + " tileWidth: %{public}d, tileHeight: %{public}d, hvccLen: %{public}zu, dataLen: %{public}zu", + result, gridInfo.displayWidth, gridInfo.displayHeight, hwBuffer->GetFormat(), gridInfo.cols, + gridInfo.rows, gridInfo.tileWidth, gridInfo.tileHeight, inputs[0].size(), inputs[1].size()); SetHardwareDecodeErrMsg(gridInfo.tileWidth, gridInfo.tileHeight); return false; } @@ -966,36 +796,6 @@ bool HeifDecoderImpl::HwDecodeMimeImage(std::shared_ptr &image) return true; } -bool HeifDecoderImpl::HwDecodeMovieFirstFrameImage(HeifHardwareDecoder *hwDecoder, - std::shared_ptr &image, - GridInfo &gridInfo, sptr &hwBuffer) -{ - if (hwDecoder == nullptr || image == nullptr) { - IMAGE_LOGE("HeifDecoderImpl::HwDecodeMovieFirstFrameImage hwDecoder or image is nullptr"); - return false; - } - std::vector> inputs(GRID_NUM_2); - - parser_->GetMovieFrameData(0, &inputs[0], heif_only_header); - ProcessChunkHead(inputs[0].data(), inputs[0].size()); - - parser_->GetMovieFrameData(0, &inputs[0], heif_no_header); - ProcessChunkHead(inputs[1].data(), inputs[1].size()); - - uint32_t err = hwDecoder->DoDecode(gridInfo, inputs, hwBuffer); - if (err != SUCCESS) { - IMAGE_LOGE("heif hw decoder return error: %{public}d, width: %{public}d, height: %{public}d," - " imageType: hvc1, inPixelFormat: %{public}d, colNum: %{public}d, rowNum: %{public}d," - " tileWidth: %{public}d, tileHeight: %{public}d, hvccLen: %{public}zu, dataLen: %{public}zu", - err, gridInfo.displayWidth, gridInfo.displayHeight, - hwBuffer->GetFormat(), gridInfo.cols, gridInfo.rows, - gridInfo.tileWidth, gridInfo.tileHeight, inputs[0].size(), inputs[1].size()); - SetHardwareDecodeErrMsg(gridInfo.tileWidth, gridInfo.tileHeight); - return false; - } - return true; -} - bool HeifDecoderImpl::SwDecodeImage(std::shared_ptr &image, HevcSoftDecodeParam ¶m, GridInfo &gridInfo, bool isPrimary) { @@ -1168,21 +968,31 @@ Media::PixelFormat GetDecodeHeifFormat(std::shared_ptr &heifImage) return PixelFormat::UNKNOWN; } -bool HeifDecoderImpl::DoSwDecodeAuxiliaryImage(std::shared_ptr &gainmapImage, GridInfo &gainmapGridInfo, - sptr &output, sptr *outputBuf) +bool HeifDecoderImpl::DoSwDecodeAuxiliaryImage(std::shared_ptr &gainmapImage, GridInfo &gainmapgridInfo, + sptr &output, sptr *outputBuf) { - PixelFormat gainmapDstFmt = GetDecodeHeifFormat(gainmapImage); - if (gainmapDstFmt == PixelFormat::UNKNOWN) { + PixelFormat gainmapSrcFmt = GetDecodeHeifFormat(gainmapImage); + PixelFormat gainmapDstFmt = PixelFormat::UNKNOWN; + if (gainmapSrcFmt == PixelFormat::UNKNOWN) { IMAGE_LOGE("HDR-IMAGE Unsupported gainmap default DstFmt"); return false; } - OH_NativeBuffer_planes *dataplanesInfo = nullptr; - output->GetplanesInfo((void **)&dataplanesInfo); - bool cond = (dataplanesInfo == nullptr); + uint32_t gainmapRowStride; + uint8_t *gainmapDstBuffer; + if (isGainmapDecode_) { + gainmapDstFmt = PixelFormat::RGBA_8888; + gainmapDstBuffer = gainmapDstMemory_; + gainmapRowStride = static_cast(gainmapDstRowStride_); + } else { + gainmapDstFmt = outPixelFormat_; + gainmapDstBuffer = auxiliaryDstMemory_; + gainmapRowStride = static_cast(auxiliaryDstRowStride_); + } + OH_NativeBuffer_Planes *dataPlanesInfo = nullptr; + output->GetPlanesInfo((void **)&dataPlanesInfo); + bool cond = (dataPlanesInfo == nullptr); CHECK_ERROR_RETURN_RET_LOG(cond, false, "failed to get src buffer planes info."); - OH_NativeBuffer_planes &planeY = dataPlanesInfo->planes[0]; void *nativeBuffer = output.GetRefPtr(); - uint8_t *data = static_cast(output->GetVirAddr()); int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer); if (err != OHOS::GSERROR_OK) { return false; @@ -1190,25 +1000,16 @@ bool HeifDecoderImpl::DoSwDecodeAuxiliaryImage(std::shared_ptr &gainm uint32_t gainmapStride = static_cast(output->GetStride()); uint32_t gainmapMemorySize = gainmapStride * static_cast(output->GetHeight()); HevcSoftDecodeParam gainmapParam { - gainmapGridInfo, gainmapDstFmt, - data + planeY.offset, gainmapMemorySize, - gainmapStride, nullptr + gainmapgridInfo, gainmapSrcFmt, gainmapDstFmt, + gainmapDstBuffer, gainmapMemorySize, + gainmapStride, nullptr, false, static_cast(nativeBuffer), gainmapRowStride }; - if (!SwDecodeImage(gainmapImage, gainmapParam, gainmapGridInfo, false)) { + if (!SwDecodeImage(gainmapImage, gainmapParam, gainmapgridInfo, false)) { ImageUtils::SurfaceBuffer_Unreference(nativeBuffer); IMAGE_LOGE("HDR-IMAGE SwDecodeImage failed"); - retur false; - } - if (gainmapImage->GetDefaultPixelFormat() == HeifPixelFormat::MONOCHROME) { - OH_NativeBuffer_Plane &planeUV = dataPlanesInfo->planes[YCBCR_UV_PLANE]; - // set UV plane to 0x80. - if (memset_s(data + planeUV.offset, gainmapMemorySize / PLANE_COUNT_TWO, - 0x80, gainmapMemorySize / PLANE_COUNT_TWO) != EOK) { - ImageUtils::SurfaceBuffer_Unreference(nativeBuffer); - return false; - } + return false; } - *outputBuf = outPut; + *outputBuf = output; if (output != nullptr) { ImageUtils::SurfaceBuffer_Unreference(nativeBuffer); } @@ -1288,7 +1089,7 @@ bool HeifDecoderImpl::HwApplyAlphaImage(std::shared_ptr &masterImage, GridInfo alphaGridInfo; sptr hwBuffer; InitGridInfo(alphaImage, alphaGridInfo); - bool decodeRes = HwDecodeImage(nullptr, alphaImage, alphaGridInfo, &hwBuffer, false); + bool decodeRes = HwDecodeImage(alphaImage, alphaGridInfo, &hwBuffer, false); if (!decodeRes) { IMAGE_LOGE("hw decode alpha image failed"); return false; @@ -1318,7 +1119,8 @@ bool HeifDecoderImpl::SwApplyAlphaImage(std::shared_ptr &masterImage, PixelFormat alphaDstFmt = PixelFormat::ALPHA_8; std::unique_ptr alphaMemory = std::make_unique(alphaMemorySize); HevcSoftDecodeParam param { - alphaGridInfo, alphaDstFmt, alphaMemory.get(), alphaMemorySize, alphaStride, nullptr + alphaGridInfo, Media::PixelFormat::UNKNOWN, alphaDstFmt, + alphaMemory.get(), alphaMemorySize, alphaStride, nullptr, false, nullptr, 0 }; bool decodeRes = SwDecodeImage(alphaImage, param, alphaGridInfo, false); bool cond = !decodeRes; @@ -1328,40 +1130,6 @@ bool HeifDecoderImpl::SwApplyAlphaImage(std::shared_ptr &masterImage, return FillAlphaChannel(masterImage, alphaMemory.get(), alphaStride, dstMemory, dstRowStride); } -bool HeifDecoderImpl::ConvertHwBufferPixelFormat(sptr &hwBuffer, GridInfo &gridInfo, - uint8_t *dstMemory, size_t dstRowStride, bool isPrimary) -{ - OH_NativeBuffer_Planes *srcBufferPlanesInfo = nullptr; - hwBuffer->GetPlanesInfo((void **)&srcBufferPlanesInfo); - if (srcBufferPlanesInfo == nullptr) { - IMAGE_LOGE("find to get src buffer planes info"); - return false; - } - - OH_NativeBuffer_Planes *dstBufferPlanesInfo = nullptr; - if (dstHwBuffer_ != nullptr && dstHwBuffer_->GetFormat() != GRAPHIC_PIXEL_FMT_RGBA_1010102) { - dstHwBuffer_->GetPlanesInfo((void **)&dstBufferPlanesInfo); - if (dstBufferPlanesInfo == nullptr) { - IMAGE_LOGE("fail to get dst buffer planes info"); - return false; - } - } - PixelFormat outFormat = isPrimary ? outPixelFormat_ : gainmapOutPixelFormat_; - PixelFormatConvertParam srcParam = {static_cast(hwBuffer->GetVirAddr()), - gridInfo.displayWidth, gridInfo.displayHeight, - static_cast(hwBuffer->GetStride()), - gridInfo.colorRangeFlag, - srcBufferPlanesInfo, - GraphicPixFmt2AvPixFmtForYuv( - static_cast(hwBuffer->GetFormat()))}; - PixelFormatConvertParam dstParam = {dstMemory, gridInfo.displayWidth, gridInfo.displayHeight, - static_cast(dstRowStride), - gridInfo.colorRangeFlag, - dstBufferPlanesInfo, - PixFmt2AvPixFmtForOutput(outFormat)}; - return ConvertPixelFormat(srcParam, dstParam); -} - bool HeifDecoderImpl::ProcessChunkHead(uint8_t *data, size_t len) { if (len < CHUNK_HEAD_SIZE) { @@ -1382,6 +1150,36 @@ bool HeifDecoderImpl::ProcessChunkHead(uint8_t *data, size_t len) return true; } +bool HeifDecoderImpl::IsHeifAlphaNotYuv420() +{ + std::shared_ptr alphaImage = primaryImage_->GetAlphaImage(); + if (alphaImage == nullptr) { + return false; + } + if (alphaImage->GetDefaultPixelFormat() != HeifPixelFormat::YUV420) { + IMAGE_LOGE("heif alphaImage is not YUV420"); + return true; + } + return false; +} + +bool HeifDecoderImpl::IsHeifGainmapNotYuv420() +{ + if (gainmapImage_ == nullptr) { + return false; + } + if (gainmapImage_->GetDefaultPixelFormat() != HeifPixelFormat::YUV420) { + IMAGE_LOGE("heif gainmapImage is not YUV420"); + return true; + } + return false; +} + +int32_t HeifDecoderImpl::GetPrimaryLumaBitNum() +{ + return primaryImage_->GetLumaBitNum(); +} + bool HeifDecoderImpl::IsDirectYUVDecode() { if (dstHwBuffer_ == nullptr || isGainmapDecode_) { @@ -1410,6 +1208,21 @@ bool HeifDecoderImpl::decodeSequence(int frameIndex, HeifFrameInfo *frameInfo) return false; } +void HeifDecoderImpl::SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName) +{ + sampleSize_ = sampleSize; + colorSpaceName_ = colorSpaceName; +} + +void HeifDecoderImpl::GetGainmapColorSpace(ColorManager::ColorSpaceName &gainmapColor) +{ + if (gainmapImageInfo_.hasNclxColor) { + gainmapColor = ColorUtils::CicpToColorSpace(gainmapImageInfo_.nclxColor.colorPrimaries, + gainmapImageInfo_.nclxColor.transferCharacteristics, gainmapImageInfo_.nclxColor.matrixCoefficients, + gainmapImageInfo_.nclxColor.fullRangeFlag); + } +} + void HeifDecoderImpl::setDstBuffer(uint8_t *dstBuffer, size_t rowStride, void *context) { dstMemory_ = dstBuffer; @@ -1417,13 +1230,13 @@ void HeifDecoderImpl::setDstBuffer(uint8_t *dstBuffer, size_t rowStride, void *c dstHwBuffer_ = reinterpret_cast(context); } -void HeifDecoderImpl::setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride) +void HeifDecoderImpl::setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride, void *context) { - if (gainmapDstMemory_ == nullptr) { - gainmapDstMemory_ = dstBuffer; - gainmapDstRowStride_ = rowStride; - isGainmapDecode_ = true; - } + gainmapDstMemory_ = dstBuffer; + gainmapDstRowStride_ = rowStride; + regionInfo_.isGainmapImage = true; + isGainmapDecode_ = true; + gainMapDstHwbuffer_ = reinterpret_cast(context); } void HeifDecoderImpl::setAuxiliaryDstBuffer(uint8_t* dstBuffer, size_t dstSize, size_t rowStride, void *context) @@ -1433,6 +1246,7 @@ void HeifDecoderImpl::setAuxiliaryDstBuffer(uint8_t* dstBuffer, size_t dstSize, auxiliaryDstRowStride_ = rowStride; isAuxiliaryDecode_ = true; auxiliaryDstHwBuffer_ = reinterpret_cast(context); + sampleSize_ = DEFAULT_SCALE_SIZE; } bool HeifDecoderImpl::getScanline(uint8_t *dst)