• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <fstream>
17 #include <map>
18 #include <securec.h>
19 #include "ext_stream.h"
20 #include "file_source_stream.h"
21 #include "v1_0/display_buffer_type.h"
22 #include "mock_jpeg_hw_decode_flow.h"
23 
24 namespace OHOS::ImagePlugin {
25 using namespace OHOS::HDI::Codec::Image::V2_1;
26 using namespace OHOS::HDI::Display::Buffer::V1_0;
27 using namespace OHOS::HDI::Display::Composer;
28 
JpegHwDecoderFlow()29 JpegHwDecoderFlow::JpegHwDecoderFlow() : sampleSize_(1), outputColorFmt_(V1_2::PIXEL_FMT_YCRCB_420_SP)
30 {
31     bufferMgr_ = IDisplayBuffer::Get();
32     outputBuffer_.id = 0;
33     outputBuffer_.size = 0;
34     outputBuffer_.buffer = nullptr;
35     outputBuffer_.fenceFd = -1;
36     outputBuffer_.bufferRole = CODEC_IMAGE_JPEG;
37 }
38 
~JpegHwDecoderFlow()39 JpegHwDecoderFlow::~JpegHwDecoderFlow()
40 {
41     bufferMgr_ = nullptr;
42 }
43 
InitDecoder()44 bool JpegHwDecoderFlow::InitDecoder()
45 {
46     if (!hwDecoder_.InitDecoder()) {
47         JPEG_HW_LOGE("init jpeg hardware decoder failed");
48         return false;
49     }
50     return true;
51 }
52 
AllocOutputBuffer()53 bool JpegHwDecoderFlow::AllocOutputBuffer()
54 {
55     AllocInfo alloc = {
56         .width = scaledImgSize_.width,
57         .height = scaledImgSize_.height,
58         .usage =  V1_2::HBM_USE_CPU_READ | V1_2::HBM_USE_CPU_WRITE | V1_2::HBM_USE_MEM_DMA,
59         .format = outputColorFmt_
60     };
61     BufferHandle *handle = nullptr;
62     int32_t ret = bufferMgr_->AllocMem(alloc, handle);
63     if (ret != HDF_SUCCESS) {
64         JPEG_HW_LOGE("failed to alloc output buffer, err=%{public}d", ret);
65         return false;
66     }
67     if (outputColorFmt_ == V1_2::PIXEL_FMT_RGBA_8888) {
68         static constexpr uint32_t bitDepthForRgba = 4;
69         outputBufferSize_.width = static_cast<int32_t>((handle->stride) / bitDepthForRgba);
70     } else { // V1_2::PIXEL_FMT_YCRCB_420_SP
71         outputBufferSize_.width = static_cast<int32_t>(handle->stride);
72     }
73     outputBufferSize_.height = static_cast<int32_t>(handle->height);
74     outputBuffer_.buffer = new NativeBuffer(handle);
75     return true;
76 }
77 
DoDecode()78 bool JpegHwDecoderFlow::DoDecode()
79 {
80     std::unique_ptr<Media::SourceStream> stream = Media::FileSourceStream::CreateSourceStream(inputFile_);
81     ImagePlugin::InputDataStream* inputStream = stream.get();
82     std::unique_ptr<SkCodec> demoCodec = SkCodec::MakeFromStream(std::make_unique<ExtStream>(inputStream));
83     auto ret = hwDecoder_.Decode(demoCodec.get(), inputStream, orgImgSize_, sampleSize_, outputBuffer_);
84     if (ret != 0) {
85         JPEG_HW_LOGE("failed to do jpeg hardware decode, err=%{public}u", ret);
86         return false;
87     }
88     return true;
89 }
90 
DumpDecodeResult()91 bool JpegHwDecoderFlow::DumpDecodeResult()
92 {
93     JPEG_HW_LOGI("dump decode result");
94     auto getColorDesc = [this]()->std::string {
95         if (outputColorFmt_ == V1_2::PIXEL_FMT_YCRCB_420_SP) {
96             return "YUV";
97         } else if (outputColorFmt_ == V1_2::PIXEL_FMT_RGBA_8888) {
98             return "RGB";
99         }
100         return "UnknownColorFormat";
101     };
102 
103     constexpr int maxPathLen = 256;
104     char outputFilePath[maxPathLen] = {0};
105     std::string colorDesc = getColorDesc();
106     int ret = sprintf_s(outputFilePath, sizeof(outputFilePath), "%s/out_%d(%d)x%d_org_%dx%d_%s.bin",
107                         outputPath_.c_str(), scaledImgSize_.width, outputBufferSize_.width, scaledImgSize_.height,
108                         orgImgSize_.width, orgImgSize_.height, colorDesc.c_str());
109     if (ret == -1) {
110         JPEG_HW_LOGE("failed to create dump file");
111         return false;
112     }
113 
114     std::ofstream dumpOutFile;
115     dumpOutFile.open(std::string(outputFilePath), std::ios_base::binary | std::ios_base::trunc);
116     if (!dumpOutFile.is_open()) {
117         JPEG_HW_LOGE("failed to dump decode result");
118         return false;
119     }
120 
121     BufferHandle *outputHandle = outputBuffer_.buffer->GetBufferHandle();
122     bufferMgr_->Mmap(*outputHandle);
123     (void)bufferMgr_->InvalidateCache(*outputHandle);
124     dumpOutFile.write(reinterpret_cast<char*>(outputHandle->virAddr), outputHandle->size);
125     dumpOutFile.flush();
126     (void)bufferMgr_->FlushCache(*outputHandle);
127     (void)bufferMgr_->Unmap(*outputHandle);
128     dumpOutFile.close();
129     return true;
130 }
131 
UserColorFmtToPixelFmt(UserColorFormat usrColorFmt)132 std::optional<V1_2::PixelFormat> JpegHwDecoderFlow::UserColorFmtToPixelFmt(UserColorFormat usrColorFmt)
133 {
134     static const std::map<UserColorFormat, V1_2::PixelFormat> colorMap = {
135         { UserColorFormat::YUV, V1_2::PIXEL_FMT_YCRCB_420_SP },
136         { UserColorFormat::RGB, V1_2::PIXEL_FMT_RGBA_8888 }
137     };
138     auto iter = colorMap.find(usrColorFmt);
139     if (iter == colorMap.end()) {
140         JPEG_HW_LOGE("unsupported color format(%{public}d)", static_cast<int>(usrColorFmt));
141         return std::nullopt;
142     }
143     return iter->second;
144 }
145 
Run(const CommandOpt & opt,bool needDumpOutput)146 bool JpegHwDecoderFlow::Run(const CommandOpt& opt, bool needDumpOutput)
147 {
148     JPEG_HW_LOGI("jpeg hardware decode demo start");
149     std::optional<V1_2::PixelFormat> colorFmt = UserColorFmtToPixelFmt(opt.colorFmt);
150     if (!colorFmt.has_value()) {
151         JPEG_HW_LOGE("jpeg hardware decode demo failed");
152         return false;
153     }
154     inputFile_ = opt.inputFile;
155     outputPath_ = opt.outputPath;
156     outputColorFmt_ = colorFmt.value();
157     orgImgSize_.width = opt.width;
158     orgImgSize_.height = opt.height;
159     sampleSize_ = opt.sampleSize;
160     scaledImgSize_.width = static_cast<int32_t>(AlignUp(opt.width / opt.sampleSize, ALIGN_8));
161     scaledImgSize_.height = static_cast<int32_t>(AlignUp(opt.height / opt.sampleSize, ALIGN_8));
162     JPEG_HW_LOGD("orgImgSize=[%{public}ux%{public}u], scaledImgSize=[%{public}ux%{public}u], sampleSize=%{public}u",
163                  orgImgSize_.width, orgImgSize_.height, scaledImgSize_.width, scaledImgSize_.height, sampleSize_);
164     bool ret = InitDecoder();
165     ret = ret && AllocOutputBuffer();
166     ret = ret && DoDecode();
167     if (needDumpOutput) {
168         ret = ret && DumpDecodeResult();
169     }
170     if (ret) {
171         JPEG_HW_LOGI("jpeg hardware decode demo succeed");
172     } else {
173         JPEG_HW_LOGE("jpeg hardware decode demo failed");
174     }
175     return ret;
176 }
177 } // namespace OHOS::ImagePlugin