1 /*
2 * Copyright (c) 2023 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 "hardware/jpeg_hw_decoder.h"
17
18 #include <vector>
19 #include <algorithm>
20 #include <chrono>
21 #include <securec.h>
22 #include <sys/mman.h>
23
24 #include "hardware/jpeg_marker_define.h"
25 #include "hardware/jpeg_dma_pool.h"
26 #include "hdf_base.h"
27 #include "iremote_object.h"
28 #include "iproxy_broker.h"
29 #include "media_errors.h"
30 #include "image_trace.h"
31 #include "src/codec/SkJpegUtility.h"
32 #include "src/codec/SkJpegDecoderMgr.h"
33 #include "src/codec/SkJpegCodec.h"
34
35 namespace OHOS::ImagePlugin {
36 using namespace OHOS::HDI::Codec::Image::V2_1;
37 using namespace Media;
38
39 static std::mutex g_codecMtx;
40 static sptr<ICodecImage> g_codecMgr;
41 std::vector<CodecImageCapability> JpegHardwareDecoder::capList_ = {};
42 std::mutex JpegHardwareDecoder::capListMtx_;
43
44 class CodecJpegDeathRecipient : public IRemoteObject::DeathRecipient {
45 public:
OnRemoteDied(const wptr<IRemoteObject> & object)46 void OnRemoteDied(const wptr<IRemoteObject> &object) override
47 {
48 JPEG_HW_LOGW("codec_image_service died");
49 std::lock_guard<std::mutex> lk(g_codecMtx);
50 g_codecMgr = nullptr;
51 }
52 };
53
GetCodecManager()54 static sptr<ICodecImage> GetCodecManager()
55 {
56 std::lock_guard<std::mutex> lk(g_codecMtx);
57 if (g_codecMgr) {
58 return g_codecMgr;
59 }
60 JPEG_HW_LOGI("need to get ICodecImage");
61 g_codecMgr = ICodecImage::Get();
62 if (g_codecMgr == nullptr) {
63 return nullptr;
64 }
65 bool isDeathRecipientAdded = false;
66 const sptr<OHOS::IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICodecImage>(g_codecMgr);
67 if (remote) {
68 sptr<CodecJpegDeathRecipient> deathCallBack(new CodecJpegDeathRecipient());
69 isDeathRecipientAdded = remote->AddDeathRecipient(deathCallBack);
70 }
71 if (!isDeathRecipientAdded) {
72 JPEG_HW_LOGE("failed to add deathRecipient for ICodecImage!");
73 }
74 return g_codecMgr;
75 }
76
LifeSpanTimer(std::string desc)77 JpegHardwareDecoder::LifeSpanTimer::LifeSpanTimer(std::string desc) : desc_(desc)
78 {
79 startTimeInUs_ = GetCurrentTimeInUs();
80 }
81
~LifeSpanTimer()82 JpegHardwareDecoder::LifeSpanTimer::~LifeSpanTimer()
83 {
84 static constexpr float MILLISEC_TO_MICROSEC = 1000.0f;
85 int64_t timeSpanInUs = GetCurrentTimeInUs() - startTimeInUs_;
86 JPEG_HW_LOGD("%{public}s cost: %{public}.2f ms",
87 desc_.c_str(), static_cast<float>(timeSpanInUs / MILLISEC_TO_MICROSEC));
88 }
89
GetCurrentTimeInUs()90 int64_t JpegHardwareDecoder::LifeSpanTimer::GetCurrentTimeInUs()
91 {
92 auto now = std::chrono::steady_clock::now();
93 return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
94 }
95
JpegHardwareDecoder()96 JpegHardwareDecoder::JpegHardwareDecoder()
97 {
98 inputBuffer_.fenceFd = -1;
99 hwDecoder_ = GetCodecManager();
100 }
101
~JpegHardwareDecoder()102 JpegHardwareDecoder::~JpegHardwareDecoder()
103 {
104 hwDecoder_ = nullptr;
105 }
106
IsHardwareDecodeSupported(const std::string & srcImgFormat,OHOS::Media::Size srcImgSize)107 bool JpegHardwareDecoder::IsHardwareDecodeSupported(const std::string& srcImgFormat, OHOS::Media::Size srcImgSize)
108 {
109 if (hwDecoder_ == nullptr) {
110 JPEG_HW_LOGE("failed to get hardware decoder!");
111 return false;
112 }
113 if (srcImgFormat != JPEG_FORMAT_DESC) {
114 JPEG_HW_LOGE("invalid image format: %{public}s", srcImgFormat.c_str());
115 return false;
116 }
117 std::lock_guard<std::mutex> lock(capListMtx_);
118 if (capList_.size() == 0) {
119 auto ret = hwDecoder_->GetImageCapability(capList_);
120 if (ret != HDF_SUCCESS) {
121 JPEG_HW_LOGE("failed to get image capability, err=%{public}d!", ret);
122 return false;
123 }
124 }
125
126 for (const CodecImageCapability& cap : capList_) {
127 JPEG_HW_LOGD("cap info: isSoftwareCodec=%{public}d, role=%{public}d, type=%{public}d, " \
128 "maxSize=[%{public}u*%{public}u], minSize=[%{public}u*%{public}u]",
129 cap.isSoftwareCodec, cap.role, cap.type, cap.maxWidth, cap.maxHeight,
130 cap.minWidth, cap.minHeight);
131 if (!cap.isSoftwareCodec && cap.role == CODEC_IMAGE_JPEG &&
132 cap.type == CODEC_IMAGE_TYPE_DECODER &&
133 srcImgSize.width >= static_cast<int32_t>(cap.minWidth) &&
134 srcImgSize.width <= static_cast<int32_t>(cap.maxWidth) &&
135 srcImgSize.height >= static_cast<int32_t>(cap.minHeight) &&
136 srcImgSize.height <= static_cast<int32_t>(cap.maxHeight)) {
137 JPEG_HW_LOGD("decoder(%{public}s) selected", cap.name.c_str());
138 return true;
139 }
140 }
141 JPEG_HW_LOGE("no available hardware decoder, img=[%{public}ux%{public}u]", srcImgSize.width, srcImgSize.height);
142 return false;
143 }
144
GetJpegCompressInfo(SkCodec * codec)145 static jpeg_decompress_struct* GetJpegCompressInfo(SkCodec *codec)
146 {
147 if (codec == nullptr) {
148 JPEG_HW_LOGE("invalid input codec!");
149 return nullptr;
150 }
151 SkJpegCodec* jpegCodec = static_cast<SkJpegCodec*>(codec);
152 if (jpegCodec == nullptr) {
153 JPEG_HW_LOGE("invalid input jpeg codec!");
154 return nullptr;
155 }
156 if (jpegCodec->decoderMgr() == nullptr) {
157 JPEG_HW_LOGE("invalid input jpeg codec mgr!");
158 return nullptr;
159 }
160 return jpegCodec->decoderMgr()->dinfo();
161 }
162
CheckInputColorFmt(SkCodec * codec)163 bool JpegHardwareDecoder::CheckInputColorFmt(SkCodec *codec)
164 {
165 jpeg_decompress_struct* jpegCompressInfo = GetJpegCompressInfo(codec);
166 if (jpegCompressInfo == nullptr) {
167 JPEG_HW_LOGE("failed to get jpeg info");
168 return false;
169 }
170 if (jpegCompressInfo->jpeg_color_space != JCS_YCbCr) {
171 JPEG_HW_LOGI("unsupported in color: %{public}d", jpegCompressInfo->jpeg_color_space);
172 return false;
173 }
174 return true;
175 }
176
Decode(SkCodec * codec,ImagePlugin::InputDataStream * srcStream,OHOS::Media::Size srcImgSize,uint32_t sampleSize,CodecImageBuffer & outputBuffer)177 uint32_t JpegHardwareDecoder::Decode(SkCodec *codec, ImagePlugin::InputDataStream *srcStream,
178 OHOS::Media::Size srcImgSize, uint32_t sampleSize, CodecImageBuffer& outputBuffer)
179 {
180 Media::ImageTrace imageTrace("JpegHardwareDecoder::Decode");
181 LifeSpanTimer decodeTimer("jpeg hardware decode");
182 JPEG_HW_LOGD("img=[%{public}ux%{public}u], sampleSize=%{public}u",
183 srcImgSize.width, srcImgSize.height, sampleSize);
184 if (hwDecoder_ == nullptr) {
185 JPEG_HW_LOGE("failed to get hardware decoder!");
186 return Media::ERR_IMAGE_DECODE_ABNORMAL;
187 }
188 if (!IsHardwareDecodeSupported(JPEG_FORMAT_DESC, srcImgSize) || !CheckInputColorFmt(codec)) {
189 return Media::ERR_IMAGE_DATA_UNSUPPORT;
190 }
191
192 decodeInfo_.sampleSize = sampleSize;
193 bool ret = true;
194 ret = ret && PrepareInputData(codec, srcStream);
195 ret = ret && DoDecode(outputBuffer);
196 RecycleAllocatedResource();
197 if (ret) {
198 JPEG_HW_LOGD("jpeg hardware decode succeed");
199 return Media::SUCCESS;
200 }
201 return Media::ERR_IMAGE_DECODE_FAILED;
202 }
203
AssembleComponentInfo(jpeg_decompress_struct * jpegCompressInfo)204 bool JpegHardwareDecoder::AssembleComponentInfo(jpeg_decompress_struct* jpegCompressInfo)
205 {
206 static constexpr int ONE_COMPONENT = 1;
207 static constexpr int THREE_COMPONENTS = 3;
208 if (jpegCompressInfo->num_components != ONE_COMPONENT &&
209 jpegCompressInfo->num_components != THREE_COMPONENTS) {
210 JPEG_HW_LOGE("unsupported component number: %{public}d!", jpegCompressInfo->num_components);
211 return false;
212 }
213 decodeInfo_.numComponents = static_cast<uint32_t>(jpegCompressInfo->num_components);
214 for (int i = 0; i < jpegCompressInfo->num_components; ++i) {
215 decodeInfo_.compInfo.emplace_back(CodecJpegCompInfo {
216 .componentId = jpegCompressInfo->comp_info[i].component_id,
217 .componentIndex = jpegCompressInfo->comp_info[i].component_index,
218 .hSampFactor = jpegCompressInfo->comp_info[i].h_samp_factor,
219 .vSampFactor = jpegCompressInfo->comp_info[i].v_samp_factor,
220 .quantTableNo = jpegCompressInfo->comp_info[i].quant_tbl_no,
221 .dcTableNo = jpegCompressInfo->comp_info[i].dc_tbl_no,
222 .acTableNo = jpegCompressInfo->comp_info[i].ac_tbl_no,
223 .infoFlag = true
224 });
225 }
226 return true;
227 }
228
HuffmanTblTransform(JHUFF_TBL * huffTbl,CodecJpegHuffTable & tbl)229 bool JpegHardwareDecoder::HuffmanTblTransform(JHUFF_TBL* huffTbl, CodecJpegHuffTable& tbl)
230 {
231 if (huffTbl == nullptr) {
232 return false;
233 }
234 // length of bits is defined as 16 in jpeg specification
235 // bits defined in struct JHUFF_TBL has length of 17, bits[0] is unused
236 static constexpr int LIST_BITS_OFFSET = 1;
237 static constexpr int LIST_BITS_LEN = 16;
238 static constexpr int MAX_LIST_HUFFVAL_LEN = 256;
239 int actualHuffValLen = 0;
240 for (int i = LIST_BITS_OFFSET; i <= LIST_BITS_LEN; ++i) {
241 actualHuffValLen += huffTbl->bits[i];
242 }
243 JPEG_HW_LOGD("actualHuffValLen=%{public}d", actualHuffValLen);
244 if (actualHuffValLen >= MAX_LIST_HUFFVAL_LEN) {
245 JPEG_HW_LOGE("invalid huffVal len: %{public}d", actualHuffValLen);
246 return false;
247 }
248 tbl.tableFlag = true;
249 tbl.bits = std::vector<uint8_t>(&huffTbl->bits[LIST_BITS_OFFSET],
250 &huffTbl->bits[LIST_BITS_OFFSET] + LIST_BITS_LEN);
251 tbl.huffVal = std::vector<uint8_t>(huffTbl->huffval, &huffTbl->huffval[actualHuffValLen]);
252 return true;
253 }
254
AssembleHuffmanTable(jpeg_decompress_struct * jpegCompressInfo)255 void JpegHardwareDecoder::AssembleHuffmanTable(jpeg_decompress_struct* jpegCompressInfo)
256 {
257 static constexpr int HUFFMAN_TBL_CNT = 4;
258 for (int i = 0; i < HUFFMAN_TBL_CNT; ++i) {
259 CodecJpegHuffTable dcTbl;
260 if (HuffmanTblTransform(jpegCompressInfo->dc_huff_tbl_ptrs[i], dcTbl)) {
261 decodeInfo_.dcHuffTbl.emplace_back(dcTbl);
262 }
263
264 CodecJpegHuffTable acTbl;
265 if (HuffmanTblTransform(jpegCompressInfo->ac_huff_tbl_ptrs[i], acTbl)) {
266 decodeInfo_.acHuffTbl.emplace_back(acTbl);
267 }
268 }
269 }
270
AssembleQuantizationTable(jpeg_decompress_struct * jpegCompressInfo)271 void JpegHardwareDecoder::AssembleQuantizationTable(jpeg_decompress_struct* jpegCompressInfo)
272 {
273 for (int i = 0; i < NUM_QUANT_TBLS; ++i) {
274 if (jpegCompressInfo->quant_tbl_ptrs[i]) {
275 uint16_t* quantStart = reinterpret_cast<uint16_t *>(jpegCompressInfo->quant_tbl_ptrs[i]->quantval);
276 decodeInfo_.quantTbl.emplace_back(CodecJpegQuantTable {
277 .quantVal = std::vector<uint16_t>(quantStart, quantStart + DCTSIZE2),
278 .tableFlag = true
279 });
280 } else {
281 decodeInfo_.quantTbl.emplace_back(CodecJpegQuantTable {
282 .quantVal = {},
283 .tableFlag = false
284 });
285 }
286 }
287 }
288
AssembleJpegImgHeader(jpeg_decompress_struct * jpegCompressInfo)289 bool JpegHardwareDecoder::AssembleJpegImgHeader(jpeg_decompress_struct* jpegCompressInfo)
290 {
291 decodeInfo_.imageWidth = jpegCompressInfo->image_width;
292 decodeInfo_.imageHeight = jpegCompressInfo->image_height;
293 decodeInfo_.dataPrecision = static_cast<uint32_t>(jpegCompressInfo->data_precision);
294 decodeInfo_.restartInterval = jpegCompressInfo->restart_interval;
295 decodeInfo_.arithCode = jpegCompressInfo->arith_code;
296 decodeInfo_.progressiveMode = jpegCompressInfo->progressive_mode;
297 // no crop as default
298 decodeInfo_.region.flag = 0;
299 if (!AssembleComponentInfo(jpegCompressInfo)) {
300 return false;
301 }
302 AssembleHuffmanTable(jpegCompressInfo);
303 AssembleQuantizationTable(jpegCompressInfo);
304 return true;
305 }
306
CopySrcToInputBuff(ImagePlugin::InputDataStream * srcStream,BufferHandle * inputBufferHandle)307 bool JpegHardwareDecoder::CopySrcToInputBuff(ImagePlugin::InputDataStream* srcStream, BufferHandle* inputBufferHandle)
308 {
309 uint32_t positionRecord = srcStream->Tell();
310 srcStream->Seek(compressDataPos_);
311 uint32_t readSize = 0;
312 bool flag = srcStream->Read(compressDataSize_,
313 static_cast<uint8_t *>(inputBufferHandle->virAddr),
314 static_cast<uint32_t>(inputBufferHandle->size),
315 readSize);
316 srcStream->Seek(positionRecord);
317 if (!flag || readSize != compressDataSize_) {
318 JPEG_HW_LOGE("failed to read input data, readSize=%{public}u", readSize);
319 return false;
320 }
321 return true;
322 }
323
ReadTwoBytes(ImagePlugin::InputDataStream * srcStream,unsigned int pos,bool & flag)324 uint16_t JpegHardwareDecoder::ReadTwoBytes(ImagePlugin::InputDataStream* srcStream, unsigned int pos, bool& flag)
325 {
326 static constexpr int ZERO = 0;
327 static constexpr int ONE = 1;
328 static constexpr int TWO = 2;
329 static constexpr int BITS_OFFSET = 8;
330 uint8_t* readBuffer = new (std::nothrow) uint8_t[TWO];
331 uint16_t result = 0xFFFF;
332 if (readBuffer == nullptr) {
333 JPEG_HW_LOGE("new readbuffer failed");
334 flag = false;
335 } else {
336 uint32_t readSize = 0;
337 srcStream->Seek(pos);
338 bool ret = srcStream->Read(TWO, readBuffer, TWO, readSize);
339 if (!ret) {
340 JPEG_HW_LOGE("read input stream failed.");
341 flag = false;
342 }
343 result = static_cast<uint16_t>((readBuffer[ZERO] << BITS_OFFSET) + readBuffer[ONE]);
344 delete[] readBuffer;
345 }
346 return result;
347 }
348
GetCompressedDataStart(ImagePlugin::InputDataStream * srcStream)349 bool JpegHardwareDecoder::GetCompressedDataStart(ImagePlugin::InputDataStream* srcStream)
350 {
351 unsigned int fileSize = static_cast<unsigned int>(srcStream->GetStreamSize());
352 if (fileSize == 0) {
353 JPEG_HW_LOGE("input stream is null ");
354 return false;
355 }
356 uint32_t positionRecord = srcStream->Tell();
357 srcStream->Seek(0);
358 unsigned int curPos = 0;
359 bool findFlag = false;
360 while (curPos + JpegMarker::MARKER_LEN <= fileSize) {
361 bool readSuccess = true;
362 uint16_t potentialMarker = ReadTwoBytes(srcStream, curPos, readSuccess);
363 if (!readSuccess) {
364 findFlag = false;
365 break;
366 }
367 if (potentialMarker < JpegMarker::MIN_MARKER || potentialMarker > JpegMarker::MAX_MARKER) {
368 ++curPos;
369 continue;
370 }
371 if (!JumpOverCurrentJpegMarker(srcStream, curPos, fileSize, potentialMarker)) {
372 break;
373 }
374 if (potentialMarker == JpegMarker::SOS) {
375 findFlag = true;
376 compressDataPos_ = curPos;
377 compressDataSize_ = fileSize - curPos;
378 break;
379 }
380 }
381 JPEG_HW_LOGI("input stream size:%{public}u compress data size:%{public}u", fileSize, compressDataSize_);
382 srcStream->Seek(positionRecord);
383 return findFlag;
384 }
385
TryDmaPoolInBuff(ImagePlugin::InputDataStream * srcStream)386 bool JpegHardwareDecoder::TryDmaPoolInBuff(ImagePlugin::InputDataStream* srcStream)
387 {
388 ImageTrace imageTrace("JpegHardwareDecoder::TryDmaPoolInBuff");
389 PureStreamInfo curStreamInfo {compressDataPos_, compressDataSize_};
390 DmaBufferInfo allocBufferInfo {0, 0};
391 if (!DmaPool::GetInstance().AllocBufferInDmaPool(hwDecoder_, srcStream, inputBuffer_,
392 curStreamInfo, allocBufferInfo)) {
393 return false;
394 }
395 usedOffsetInPool_ = allocBufferInfo.allocatedBufferOffsetOfPool;
396 usedSizeInPool_ = allocBufferInfo.allocatedBufferSize;
397 return true;
398 }
399
TryNormalInBuff(ImagePlugin::InputDataStream * srcStream)400 bool JpegHardwareDecoder::TryNormalInBuff(ImagePlugin::InputDataStream* srcStream)
401 {
402 ImageTrace imageTrace("JpegHardwareDecoder::TryNormalInBuff");
403 // step1. alloc Buffer
404 int32_t ret = hwDecoder_->AllocateInBuffer(inputBuffer_, compressDataSize_, CODEC_IMAGE_JPEG);
405 if (ret != HDF_SUCCESS) {
406 JPEG_HW_LOGE("failed to allocate input buffer, err=%{public}d", ret);
407 return false;
408 }
409 usedOffsetInPool_ = 0;
410 // step2. copysrc to buffer
411 BufferHandle *inputBufferHandle = inputBuffer_.buffer->GetBufferHandle();
412 if (inputBufferHandle == nullptr) {
413 JPEG_HW_LOGE("inputBufferHandle is nullptr");
414 return false;
415 }
416 inputBufferHandle->virAddr = mmap(nullptr, inputBufferHandle->size,
417 PROT_READ | PROT_WRITE, MAP_SHARED, inputBufferHandle->fd, 0);
418 if (inputBufferHandle->virAddr == MAP_FAILED) {
419 JPEG_HW_LOGE("failed to map input buffer");
420 return false;
421 }
422 if (!CopySrcToInputBuff(srcStream, inputBufferHandle)) {
423 munmap(inputBufferHandle->virAddr, inputBufferHandle->size);
424 JPEG_HW_LOGE("copy bitstream to input buffer failed");
425 return false;
426 }
427 ret = munmap(inputBufferHandle->virAddr, inputBufferHandle->size);
428 if (ret != 0) {
429 JPEG_HW_LOGE("failed to unmap input buffer, err=%{public}d", ret);
430 }
431
432 return true;
433 }
434
CopySrcImgToDecodeInputBuffer(ImagePlugin::InputDataStream * srcStream)435 bool JpegHardwareDecoder::CopySrcImgToDecodeInputBuffer(ImagePlugin::InputDataStream* srcStream)
436 {
437 // max size of pure jpeg bitstream to use DMA Pool is 256KB
438 constexpr uint32_t MAX_SIZE_USE_DMA_POOL = 256 * 1024;
439 if (!GetCompressedDataStart(srcStream)) {
440 JPEG_HW_LOGE("get compressed data start failed");
441 return false;
442 }
443 if (compressDataSize_ <= MAX_SIZE_USE_DMA_POOL) {
444 if (TryDmaPoolInBuff(srcStream)) {
445 useDmaPool_ = true;
446 }
447 }
448 if ((compressDataSize_ > MAX_SIZE_USE_DMA_POOL) || (!useDmaPool_)) {
449 if (!TryNormalInBuff(srcStream)) {
450 return false;
451 }
452 }
453 decodeInfo_.compressPos = usedOffsetInPool_;
454 return true;
455 }
456
IsStandAloneJpegMarker(uint16_t marker)457 bool JpegHardwareDecoder::IsStandAloneJpegMarker(uint16_t marker)
458 {
459 auto iter = std::find(JpegMarker::STAND_ALONE_MARKER.begin(), JpegMarker::STAND_ALONE_MARKER.end(), marker);
460 return (iter != JpegMarker::STAND_ALONE_MARKER.end());
461 }
462
JumpOverCurrentJpegMarker(ImagePlugin::InputDataStream * srcStream,unsigned int & curPos,unsigned int totalLen,uint16_t marker)463 bool JpegHardwareDecoder::JumpOverCurrentJpegMarker(ImagePlugin::InputDataStream* srcStream, unsigned int& curPos,
464 unsigned int totalLen, uint16_t marker)
465 {
466 curPos += JpegMarker::MARKER_LEN;
467 if (curPos + JpegMarker::MARKER_LEN > totalLen) {
468 JPEG_HW_LOGE("invalid pos(cur=%{public}u, total=%{public}u) after jump over marker(%{public}u)",
469 curPos, totalLen, marker);
470 return false;
471 }
472 if (IsStandAloneJpegMarker(marker)) {
473 return true;
474 }
475 // jump over related parameters for those who are not stand alone markers
476 bool readSuccess = true;
477 unsigned int skipBytes = static_cast<unsigned int>(ReadTwoBytes(srcStream, curPos, readSuccess));
478 if (!readSuccess) {
479 return false;
480 }
481 curPos += skipBytes;
482 if (curPos > totalLen) {
483 JPEG_HW_LOGE("invalid pos(cur=%{public}u, total=%{public}u) after jump over related parameters " \
484 "for marker(%{public}u)", curPos, totalLen, marker);
485 return false;
486 }
487 return true;
488 }
489
PrepareInputData(SkCodec * codec,ImagePlugin::InputDataStream * srcStream)490 bool JpegHardwareDecoder::PrepareInputData(SkCodec *codec, ImagePlugin::InputDataStream *srcStream)
491 {
492 Media::ImageTrace imageTrace("PrepareInputData");
493 LifeSpanTimer decodeTimer("prepare input data");
494 jpeg_decompress_struct* jpegCompressInfo = GetJpegCompressInfo(codec);
495 if (jpegCompressInfo == nullptr || srcStream == nullptr) {
496 JPEG_HW_LOGE("failed to get jpeg compress info or invalid input stream");
497 return false;
498 }
499 bool ret = AssembleJpegImgHeader(jpegCompressInfo);
500 ret = ret && CopySrcImgToDecodeInputBuffer(srcStream);
501 return ret;
502 }
503
InitDecoder()504 bool JpegHardwareDecoder::InitDecoder()
505 {
506 LifeSpanTimer decodeTimer("init decoder");
507 if (hwDecoder_ == nullptr) {
508 JPEG_HW_LOGE("failed to get ICodecImage!");
509 return false;
510 }
511 int32_t ret = hwDecoder_->Init(CODEC_IMAGE_JPEG);
512 if (ret != HDF_SUCCESS) {
513 JPEG_HW_LOGE("failed to init decoder, err=%{public}d", ret);
514 return false;
515 }
516 hwDecoder_->NotifyPowerOn(CODEC_IMAGE_JPEG);
517 return true;
518 }
519
DoDecode(CodecImageBuffer & outputBuffer)520 bool JpegHardwareDecoder::DoDecode(CodecImageBuffer& outputBuffer)
521 {
522 Media::ImageTrace imageTrace("DoDecode");
523 LifeSpanTimer decodeTimer("do decode");
524 int32_t ret = hwDecoder_->DoJpegDecode(inputBuffer_, outputBuffer, decodeInfo_);
525 if (ret != HDF_SUCCESS) {
526 JPEG_HW_LOGE("failed to do decode, err=%{public}d", ret);
527 return false;
528 }
529 return true;
530 }
531
RecycleAllocatedResource()532 void JpegHardwareDecoder::RecycleAllocatedResource()
533 {
534 ImageTrace imageTrace("JpegHardwareDecoder::RecycleAllocatedResource");
535 if (useDmaPool_) {
536 DmaBufferInfo bufferInfo {usedSizeInPool_, usedOffsetInPool_};
537 DmaPool::GetInstance().RecycleBufferInDmaPool(bufferInfo);
538 }
539 }
540 } // namespace OHOS::ImagePlugin
541