From 0da3410f60dff86e45ec113db680d6913279d70d Mon Sep 17 00:00:00 2001 From: jiejex Date: Fri, 8 Aug 2025 18:12:21 +0800 Subject: [PATCH] =?UTF-8?q?hvcc=E8=A7=A3=E6=9E=90range=E5=BA=94=E7=94=A8hi?= =?UTF-8?q?si=E7=A1=AC=E8=A7=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiejex --- .../test/unittest/heif_parser_box_test.cpp | 43 +++++++++- .../common/libs/image/libextplugin/BUILD.gn | 6 +- .../image/libextplugin/include/ext_decoder.h | 1 + .../include/hardware/imagecodec/grid_info.h | 2 +- .../include/heif_impl/HeifDecoderImpl.h | 4 +- .../heif_parser/box/item_property_hvcc_box.h | 20 ++++- .../heif_impl/heif_parser/heif_image.h | 2 +- .../heif_impl/heif_parser/heif_parser.h | 2 + .../image/libextplugin/src/ext_decoder.cpp | 9 ++- .../src/heif_impl/HeifDecoderImpl.cpp | 41 ++++++++-- .../box/item_property_hvcc_box.cpp | 81 ++++++++++++++++++- .../src/heif_impl/heif_parser/heif_parser.cpp | 20 ++++- 12 files changed, 209 insertions(+), 22 deletions(-) diff --git a/frameworks/innerkitsimpl/test/unittest/heif_parser_box_test.cpp b/frameworks/innerkitsimpl/test/unittest/heif_parser_box_test.cpp index 6be636d2a..78c0e05df 100644 --- a/frameworks/innerkitsimpl/test/unittest/heif_parser_box_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/heif_parser_box_test.cpp @@ -34,6 +34,7 @@ static constexpr size_t NORMAL_LENGTH = 1; static constexpr size_t SIZE_32BITS = 0xFFFFFFFF; static constexpr size_t UUID_TYPE_BYTE_NUM = 16; static constexpr uint32_t NAL_LAYER_ID = 33; +static constexpr uint8_t SKIP_DOUBLE_DATA_PROCESS_BYTE = 2; static std::vector SetUint32ToUint8Vertor(uint32_t data) { @@ -46,6 +47,21 @@ static std::vector SetUint32ToUint8Vertor(uint32_t data) return res; } +static void ProcessBoxData(std::vector &nalu) +{ + uint32_t naluSize = nalu.size(); + std::vector indicesToDelete; + for (uint32_t i = UINT16_BYTES_NUM; i < naluSize; ++i) { + if (nalu[i - UINT8_BYTES_NUM] == 0x00 && + nalu[i - SKIP_DOUBLE_DATA_PROCESS_BYTE] == 0x00 && nalu[i] == 0x03) { + indicesToDelete.push_back(i); + } + } + for (auto it = indicesToDelete.rbegin(); it != indicesToDelete.rend(); ++it) { + nalu.erase(nalu.begin() + *it); + } +} + class HeifParserBoxTest : public testing::Test { public: HeifParserBoxTest() {} @@ -366,7 +382,7 @@ HWTEST_F(HeifParserBoxTest, AppendNalDataTest001, TestSize.Level3) /** * @tc.name: AppendNalDataTest001 - * @tc.desc: HeifHvccBox + * @tc.desc: Decode HeifHvccBox to valid SPS * @tc.type: FUNC */ HWTEST_F(HeifParserBoxTest, AppendNalDataTest002, TestSize.Level3) @@ -389,6 +405,31 @@ HWTEST_F(HeifParserBoxTest, AppendNalDataTest002, TestSize.Level3) GTEST_LOG_(INFO) << "HeifParserBoxTest: AppendNalDataTest002 end"; } +/** + * @tc.name: AppendNalDataTest003 + * @tc.desc: Decode HeifHvccBox to valid SPS + * @tc.type: FUNC + */ +HWTEST_F(HeifParserBoxTest, AppendNalDataTest003, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "HeifParserBoxTest: AppendNalDataTest003 start"; + HeifHvccBox heifHvccBox; + std::vector nalData = {0x42, 0x01, 0x03, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0x00, 0xa0, 0x01, 0x80, 0x20, 0x15, 0x96, 0x37, 0xfd, + 0xc8, 0xb2, 0x6b, 0xb7, 0x35, 0x02, 0x02, 0x05, 0x00, 0x80, 0x22, 0x00, 0x01, 0x00, 0x07}; + ProcessBoxData(nalData); + heifHvccBox.ParseNalUnitAnalysisSps(nalData); + auto spsConfig = heifHvccBox.GetSpsConfig(); + ASSERT_EQ(spsConfig.nalUnitType, NAL_LAYER_ID); + ASSERT_EQ(spsConfig.bitDepthLumaMinus8, 0); + ASSERT_EQ(spsConfig.bitDepthChromaMinus8, 0); + ASSERT_EQ(spsConfig.chromaFormatIdc, 1); + ASSERT_EQ(spsConfig.picWidthInLumaSamples, 3072); + ASSERT_EQ(spsConfig.picHeightInLumaSamples, 344); + ASSERT_EQ(spsConfig.videoRangeFlag, 0); + GTEST_LOG_(INFO) << "HeifParserBoxTest: AppendNalDataTest003 end"; +} + /** * @tc.name: ParseExtentsTest001 * @tc.desc: HeifIlocBox diff --git a/plugins/common/libs/image/libextplugin/BUILD.gn b/plugins/common/libs/image/libextplugin/BUILD.gn index 3f00c6c1f..b762dd97a 100644 --- a/plugins/common/libs/image/libextplugin/BUILD.gn +++ b/plugins/common/libs/image/libextplugin/BUILD.gn @@ -385,6 +385,7 @@ if (is_arkui_x) { include_dirs = [ "include/heif_impl/heif_parser", "${image_subsystem}/frameworks/innerkitsimpl/utils/include", + "${image_subsystem}/interfaces/innerkits/include", ] sources = [ @@ -407,7 +408,10 @@ if (is_arkui_x) { "src/heif_impl/heif_parser/heif_utils.cpp", ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] subsystem_name = "multimedia" innerapi_tags = [ "platformsdk_indirect" ] diff --git a/plugins/common/libs/image/libextplugin/include/ext_decoder.h b/plugins/common/libs/image/libextplugin/include/ext_decoder.h index 285288fa5..7d468c246 100644 --- a/plugins/common/libs/image/libextplugin/include/ext_decoder.h +++ b/plugins/common/libs/image/libextplugin/include/ext_decoder.h @@ -175,6 +175,7 @@ private: OHOS::ColorManager::ColorSpace GetSrcColorSpace(); uint32_t ApplyDesiredColorSpace(DecodeContext &context); OHOS::ColorManager::ColorSpaceName heifColorSpaceName_ = ColorManager::ColorSpaceName::NONE; + bool heifIsColorSpaceFromCicp_ = false; #endif #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) diff --git a/plugins/common/libs/image/libextplugin/include/hardware/imagecodec/grid_info.h b/plugins/common/libs/image/libextplugin/include/hardware/imagecodec/grid_info.h index 21c771a92..7a626852f 100644 --- a/plugins/common/libs/image/libextplugin/include/hardware/imagecodec/grid_info.h +++ b/plugins/common/libs/image/libextplugin/include/hardware/imagecodec/grid_info.h @@ -28,7 +28,7 @@ struct GridInfo { uint32_t rows = 0; uint32_t tileWidth = 0; uint32_t tileHeight = 0; - uint8_t colorRangeflag = 1; // 0 -> limitRange:[16,235], 1 -> fullRange:[0, 255] + int8_t colorRangeflag = -1; // 0 -> limitRange:[16,235], 1 -> fullRange:[0, 255] bool IsValid() const; }; 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 26a04dbd8..bb2314073 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/HeifDecoderImpl.h @@ -78,7 +78,7 @@ public: bool SwDecode(bool isSharedMemory = false); bool IsHeifGainmapYuv400(); bool IsHeifAlphaYuv400(); - void SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName); + void SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName, bool isColorSpaceFromCicp); int32_t GetPrimaryLumaBitNum(); void setGainmapDstBuffer(uint8_t* dstBuffer, size_t rowStride, void *context); private: @@ -196,7 +196,7 @@ private: SurfaceBuffer *gainMapDstHwBuffer_; uint32_t sampleSize_ = 1; OHOS::ColorManager::ColorSpaceName colorSpaceName_ = ColorManager::ColorSpaceName::NONE; - + bool isColorSpaceFromCicp_ = false; HeifFrameInfo tmapInfo_{}; std::string errMsg_; diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/box/item_property_hvcc_box.h b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/box/item_property_hvcc_box.h index 695916963..e9b937ba5 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/box/item_property_hvcc_box.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/box/item_property_hvcc_box.h @@ -70,6 +70,22 @@ struct HvccSpsConfig { uint8_t videoRangeFlag; }; +struct RefPicSet { + uint8_t interRefPicSetPredictionFlag; + uint8_t deltaIdxMinus1; + uint8_t deltaRpsSign; + uint8_t absDeltaRpsMinus1; + std::vector usedByCurrPicFlag; + std::vector usedDeltaFlag; + std::vector deltaPoc; + uint32_t numNegativePics; + uint32_t numPositivePics; + std::vector deltaPocS0Minus1; + std::vector usedBycurrPicS0Flag; + std::vector deltaPocS1Minus1; + std::vector usedBycurrPicS1Flag; +}; + struct HvccNalArray { uint8_t arrayCompleteness; uint8_t nalUnitType; @@ -98,7 +114,7 @@ public: uint32_t GetNaluTypeId(std::vector& nalu); - void ParserHvccColorRangeFlag(const std::vector &nalArrays); + bool ParserHvccColorRangeFlag(const std::vector &nalArrays); std::vector GetNalArrays() const { return nalArrays_; }; @@ -120,6 +136,8 @@ public: void ReadGolombCodesForSizeId(std::vector &nalUnits, uint32_t sizeId); + void ParseStRefPicSet(std::vector &nalUnits, uint32_t stRpsIdx, uint32_t numShortTermResPicSets); + protected: heif_error ParseContent(HeifStreamReader& reader) override; heif_error ParseNalUnitArray(HeifStreamReader& reader, std::vector>& nalUnits); diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_image.h b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_image.h index 0483189fa..20e2045ef 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_image.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_image.h @@ -135,7 +135,7 @@ private: int lumaBitNum_ = -1; int chromaBitNum_ = -1; - int colorRangeFlag_ = 1; + int colorRangeFlag_ = -1; heif_item_id thumbnailMasterItemId_ = 0; std::vector> m_thumbnails; diff --git a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_parser.h b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_parser.h index 3b457f2e0..e152a3eab 100644 --- a/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_parser.h +++ b/plugins/common/libs/image/libextplugin/include/heif_impl/heif_parser/heif_parser.h @@ -96,6 +96,8 @@ private: std::shared_ptr inputStream_; long tiffOffset_ = 0; + bool isHasRangeFlag_ = false; + uint8_t range_ = 1; // boxes std::shared_ptr ftypBox_; diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index c0c3a24ce..627f978d0 100644 --- a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp +++ b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp @@ -1219,7 +1219,7 @@ bool ExtDecoder::DoHeifSwDecode(DecodeContext &context) } CHECK_ERROR_RETURN_RET(cond, false); auto dstBuffer = reinterpret_cast(context.pixelsBuffer.context); - decoder->SetSampleFormat(DEFAULT_SAMPLE_SIZE, heifColorSpaceName_); + decoder->SetSampleFormat(DEFAULT_SAMPLE_SIZE, heifColorSpaceName_, heifIsColorSpaceFromCicp_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->SwDecode(false); @@ -1245,7 +1245,7 @@ uint32_t ExtDecoder::DoHeifToRgbDecode(DecodeContext &context) CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_UNSUPPORT); } auto dstBuffer = reinterpret_cast(context.pixelsBuffer.context); - decoder->SetSampleFormat(sampleSize_, heifColorSpaceName_); + decoder->SetSampleFormat(sampleSize_, heifColorSpaceName_, heifIsColorSpaceFromCicp_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->decode(nullptr); @@ -2106,6 +2106,7 @@ OHOS::ColorManager::ColorSpace ExtDecoder::GetSrcColorSpace() #endif if (cName != ColorManager::NONE) { heifColorSpaceName_ = cName; + heifIsColorSpaceFromCicp_ = true; IMAGE_LOGI("%{public}s profile has CICP, cName: %{public}u", __func__, static_cast(cName)); return ColorManager::ColorSpace(cName); } @@ -2478,7 +2479,7 @@ 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->SetSampleFormat(sampleSize_, heifColorSpaceName_, heifIsColorSpaceFromCicp_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->decode(nullptr); @@ -2525,7 +2526,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->SetSampleFormat(DEFAULT_SAMPLE_SIZE, heifColorSpaceName_, heifIsColorSpaceFromCicp_); decoder->setDstBuffer(reinterpret_cast(context.pixelsBuffer.buffer), dstBuffer->GetStride(), context.pixelsBuffer.context); bool decodeRet = decoder->decode(nullptr); 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 d2e95e444..af9af1b46 100644 --- a/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp +++ b/plugins/common/libs/image/libextplugin/src/heif_impl/HeifDecoderImpl.cpp @@ -74,6 +74,8 @@ const static int IMAGE_ID = 123; const static uint16_t BT2020_PRIMARIES = 9; const static std::string HEIF_SHAREMEM_NAME = "HeifRawData"; +const static uint32_t LIMIT_RANGE_FLAG = 0; +const static int INVALID_GRID_FLAG = -1; const std::map HEIF_AUXTTYPE_ID_MAP = { {AuxiliaryPictureType::GAINMAP, HEIF_AUXTTYPE_ID_GAINMAP}, @@ -322,6 +324,29 @@ void HeifDecoderImpl::SetColorSpaceInfo(HeifFrameInfo* info, const std::shared_p } } +bool HeifDecodeImpl::SeekRefGridRangeInfo(const std::shared_ptr &image) +{ + if (parser_ != nullptr || image == nullptr) { + return false; + } + std::string imageType = parser_->GetItemType(image->GetItemId()); + if (imageType != "grid") { + IMAGE_LOGE("seek grid error, type is : %{public}s", imageType.c_str()); + return false; + } + std::vector> tileImages; + parser_->GetTileImages(image->GetItemId(), tileImages); + if (tileImages.empty() || tileImages[0] == nullptr) { + IMAGE_LOGE("grid image has no tile image"); + return false; + } + auto firstTileImage = tileImages[0]; + int range = firstTileImage->GetColorRangeFlag(); + image->setColorRangeFlag(range); + IMAGE_LOGD("set grid from ref grid is %{public}d", range); + return false; +} + void HeifDecoderImpl::InitGridInfo(const std::shared_ptr &image, GridInfo &gridInfo) { if (!image) { @@ -343,6 +368,9 @@ void HeifDecoderImpl::InitGridInfo(const std::shared_ptr &image, Grid gridInfo.displayHeight = image->GetOriginalHeight(); } + if (image->GetColorRangeFlag() == INVALID_GRID_FLAG) { + SeekRefGridInfo(image); + } gridInfo.colorRangeFlag = image->GetColorRangeFlag(); GetTileSize(image, gridInfo); GetRowColNum(gridInfo); @@ -461,10 +489,11 @@ GSError HeifDecoderImpl::HwSetColorSpaceData(sptr& buffer, GridIn 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}; + CM_ColorSpaceInfo {COLORPRIMARIES_BT601_P, TRANSFUNC_SRGB, MATRIX_BT601_P, RANGE_FULL}; + + if (!isColorSpaceFromCicp_) { + colorSpaceInfo.range = gridInfo.colorRangeFlag == LIMIT_RANGE_FLAG ? RANGE_LIMITED : RANGE_FULL; + IMAGE_LOGD("HwSetColorSpaceData gridInfo range : %{public}d", gridInfo.colorRangeFlag); } std::vector colorSpaceInfoVec; auto ret = MetadataManager::ConvertMetadataToVec(colorSpaceInfo, colorSpaceInfoVec); @@ -1206,10 +1235,12 @@ bool HeifDecoderImpl::decodeSequence(int frameIndex, HeifFrameInfo *frameInfo) return false; } -void HeifDecoderImpl::SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName) +void HeifDecoderImpl::SetSampleFormat(uint32_t sampleSize, ColorManager::ColorSpaceName colorSpaceName, + bool isColorSpaceFromCicp) { sampleSize_ = sampleSize; colorSpaceName_ = colorSpaceName; + isColorSpaceFromCicp_ = isColorSpaceFromCicp; } void HeifDecoderImpl::GetGainmapColorSpace(ColorManager::ColorSpaceName &gainmapColor) diff --git a/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/box/item_property_hvcc_box.cpp b/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/box/item_property_hvcc_box.cpp index 31aa1aa31..b47aa6be5 100644 --- a/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/box/item_property_hvcc_box.cpp +++ b/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/box/item_property_hvcc_box.cpp @@ -14,6 +14,7 @@ */ #include "box/item_property_hvcc_box.h" +#include "image_log.h" static const uint8_t GENGERAL_PROFILE_SPACE_SHIFT = 6; static const uint8_t GENERAL_TIER_FLAG_SHIFT = 5; @@ -40,6 +41,8 @@ static const uint8_t SUB_LAYER_PROFILE_IDC_SIZE = 5; static const uint8_t PCM_ENABLED_FLAG = 4; static const uint8_t NUM_TEMPORAL_ID_SIZE = 6; static const uint8_t MAX_COEF_NUM = 64; +static uint32_t HEIF_MAX_IMAGE_DPB_SIZE = 32; +static uint32_t HEIF_NUM_DELTA_POCS = 1; namespace OHOS { namespace ImagePlugin { @@ -230,11 +233,18 @@ void HeifHvccBox::ProcessBoxData(std::vector &nalu) } } -void HeifHvccBox::ParserHvccColorRangeFlag(const std::vector &nalArrays) +bool HeifHvccBox::ParserHvccColorRangeFlag(const std::vector &nalArrays) { auto spsBox = GetNaluData(nalArrays, SPS_BOX_TYPE); + if (spsBox.empty()) { + return false; + } ProcessBoxData(spsBox); - ParseNalUnitAnalysisSps(spsBox); + if (!ParseNalUnitAnalysisSps(spsBox)) { + IMAGE_LOGD("Sps does not return a range flag"); + return false; + } + return true; } void HeifHvccBox::ProfileTierLevel(std::vector &nalUnits, uint32_t profilePresentFlag, @@ -319,11 +329,14 @@ bool HeifHvccBox::ParseSpsSyntax(std::vector &nalUnits) spsConfig_.spsVideoParameterSetId = GetGolombCode(nalUnits); spsConfig_.chromaFormatIdc = GetGolombCode(nalUnits); + IMAGE_LOGD("HeifParser::SPS chromaFormatIdc is %{public}d", spsConfig_.chromaFormatIdc); if (spsConfig_.chromaFormatIdc == SUB_LAYER_MINUS) { spsConfig_.separateColourPlaneFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); } spsConfig_.picWidthInLumaSamples = GetGolombCode(nalUnits); spsConfig_.picHeightInLumaSamples = GetGolombCode(nalUnits); + IMAGE_LOGD("HeifParser::SPS picWidthInLumaSamples : %{public}d", spsConfig_.picWidthInLumaSamples); + IMAGE_LOGD("HeifParser::SPS picHeightInLumaSamples : %{public}d", spsConfig_.picHeightInLumaSamples); spsConfig_.conformanceWindowFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); if (spsConfig_.conformanceWindowFlag == READ_BIT_NUM_FLAG) { spsConfig_.confWinLefOffset = GetGolombCode(nalUnits); @@ -333,6 +346,8 @@ bool HeifHvccBox::ParseSpsSyntax(std::vector &nalUnits) } spsConfig_.bitDepthLumaMinus8 = GetGolombCode(nalUnits); spsConfig_.bitDepthChromaMinus8 = GetGolombCode(nalUnits); + IMAGE_LOGD("HeifParser::SPS bitDepthLumaMinus8 : %{public}d", spsConfig_.bitDepthLumaMinus8); + IMAGE_LOGD("HeifParser::SPS bitDepthChromaMinus8 : %{public}d", spsConfig_.bitDepthChromaMinus8); spsConfig_.log2MaxPicOrderCntLsbMinus4 = GetGolombCode(nalUnits); spsConfig_.spsSubLayerOrderingInfoPresentFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); uint32_t i = spsConfig_.spsSubLayerOrderingInfoPresentFlag ? 0 : spsConfig_.spsMaxSubLayersMinus1; @@ -395,10 +410,68 @@ bool HeifHvccBox::ParseSpsVuiParameter(std::vector &nalUnits) if (videoSignalTypePresentFlag) { GetWord(nalUnits, SUB_LAYER_MINUS); spsConfig_.videoRangeFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); + IMAGE_LOGD("HeifParser::SPS videoRangeFlag : %{public}d", spsConfig_.videoRangeFlag); } return true; } +void HeifHvccBox::ParseStRefPicSet(std::vector &nalUnits, uint32_t stRpsIdx, uint32_t numShortTermRefPicSets) +{ + RefPicSet rps; + if (stRpsIdx != 0) { + rps.interRefPicSetPredictionFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); + } else { + rps.interRefPicSetPredictionFlag = 0; + } + if (rps.interRefPicSetPredictionFlag) { + if (stRpsIdx == numShortTermRefPicSets) { + rps.deltaIdxMinus1 = GetGolombCode(nalUnits); + } else { + rps.deltaIdxMinus1 = 0; + } + rps.deltaRpsSign = GetWord(nalUnits, READ_BIT_NUM_FLAG); + rps.absDeltaRpsMinus1 = GetGolombCode(nalUnits); + + uint32_t refRpsIdx = stRpsIdx - (rps.deltaIdxMinus1 + 1); + IMAGE_LOGD("HeifParser::SPS refRpsIdx : %{public}d", refRpsIdx); + + rps.usedByCurrPicFlag.resize(HEIF_NUM_DELTA_POCS); + rps.usedDeltaFlag.resize(HEIF_NUM_DELTA_POCS); + + for (uint32_t i = 0; i <= HEIF_NUM_DELTA_POCS; i++) { + rps.usedDeltaFlag[i] = GetWord(nalUnits, READ_BIT_NUM_FLAG); + if (!rps.usedByCurrPicFlag[i]) { + rps.usedDeltaFlag[i] = GetWord(nalUnits, READ_BIT_NUM_FLAG); + } else { + rps.usedDeltaFlag[i] = 1; + } + } + } else { + rps.numNegativePics = GetGolombCode(nalUnits); + rps.numPositivePics = GetGolombCode(nalUnits); + + if (rps.numNegativePics > HEIF_MAX_IMAGE_DPB_SIZE || rps.numPositivePics > HEIF_MAX_IMAGE_DPB_SIZE) { + IMAGE_LOGE("HeifParser:: RPS pics-Buffering more than max"); + return; + } + rps.deltaPocS0Minus1.resize(rps.numNegativePics); + rps.usedBycurrPicS0Flag.resize(rps.numNegativePics); + + for (uint32_t i = 0; i < rps.numNegativePics; i++) { + rps.deltaPocS0Minus1[i] = GetGolombCode(nalUnits); + rps.usedBycurrPicS0Flag[i] = GetWord(nalUnits, READ_BIT_NUM_FLAG); + } + + rps.deltaPocS1Minus1.resize(rps.numPositivePics); + rps.usedBycurrPicS1Flag.resize(rps.numPositivePics); + + for (uint32_t i = 0; i < rps.numPositivePics; i++) { + rps.deltaPocS1Minus1[i] = GetGolombCode(nalUnits); + rps.usedBycurrPicS1Flag[i] = GetWord(nalUnits, READ_BIT_NUM_FLAG); + } + } +} + bool HeifHvccBox::ParseSpsSyntaxScalingList(std::vector &nalUnits) { spsConfig_.scalingListEnabeldFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); @@ -419,6 +492,10 @@ bool HeifHvccBox::ParseSpsSyntaxScalingList(std::vector &nalUnits) GetWord(nalUnits, READ_BIT_NUM_FLAG); } spsConfig_.numShortTermRefPicSets = GetGolombCode(nalUnits); + IMAGE_LOGD("HeifParser:: SPS numShortTermRefPicSets : %{public}d", spsConfig_.numShortTermRefPicSets); + for (uint32_t i = 0; i < spsConfig_.numShortTermRefPicSets; i++) { + ParseStRefPicSet(nalUnits, i, spsConfig_.numShortTermRefPicSets); + } spsConfig_.longTermRefPicsPresentFlag = GetWord(nalUnits, READ_BIT_NUM_FLAG); if (spsConfig_.longTermRefPicsPresentFlag == READ_BIT_NUM_FLAG) { uint32_t numLongTermRefPicSps = GetGolombCode(nalUnits); diff --git a/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/heif_parser.cpp b/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/heif_parser.cpp index 9b2f70312..c723d6354 100644 --- a/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/heif_parser.cpp +++ b/plugins/common/libs/image/libextplugin/src/heif_impl/heif_parser/heif_parser.cpp @@ -397,6 +397,10 @@ heif_error HeifParser::AssembleImages() return heif_error_primary_item_not_found; } + if (isHasRangeFlag_) { + primaryImage_->SetColorRangeFlag(range_); + } + ExtractGainmap(allItemIds); ExtractDerivedImageProperties(); ExtractNonMasterImages(); @@ -548,10 +552,18 @@ void HeifParser::ExtractImageProperties(std::shared_ptr &image) image->SetChromaBitNum(hvccConfig.bitDepthChroma); image->SetDefaultPixelFormat((HeifPixelFormat) hvccConfig.chromaFormat); - auto nalArrays = hvcc->GetNalArrays(); - hvcc->ParserHvccColorRangeFlag(nalArrays); - auto spsConfig = hvcc->GetSpsConfig(); - image->SetColorRangeFlag(static_cast(spsConfig.videoRangeFlag)); + if (!isHasRangeFlag_) { + auto nalArrays = hvcc->GetNalArrays(); + bool isGetFlag = hvcc->ParserHvccColorRangeFlag(nalArrays); + if (isGetFlag) { + auto spsConfig = hvcc->GetSpsConfig(); + image->SetColorRangeFlag(static_cast(spsConfig.videoRangeFlag)); + range_ = spsConfig.videoRangeFlag; + isHasRangeFlag_ = true; + } + } else { + image->SetColorRangeFlag(range_); + } } ExtractDisplayData(image, itemId); } -- Gitee