1 /*
2  * Copyright (c) 2024 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 #ifndef HEIF_HW_DECODER_H
17 #define HEIF_HW_DECODER_H
18 
19 #include <cinttypes>
20 #include <mutex>
21 #include <condition_variable>
22 #include <vector>
23 #include <list>
24 #include "imagecodec/grid_info.h"
25 #include "imagecodec/image_codec.h"
26 
27 namespace OHOS {
28 namespace ImagePlugin {
29 class HeifHardwareDecoder {
30 public:
31     HeifHardwareDecoder();
32     ~HeifHardwareDecoder();
33     sptr<SurfaceBuffer> AllocateOutputBuffer(uint32_t width, uint32_t height, int32_t pixelFmt);
34     bool IsPackedInputSupported();
35     uint32_t DoDecode(const GridInfo& gridInfo, std::vector<std::vector<uint8_t>>& inputs, sptr<SurfaceBuffer>& output);
36 private:
37     class HeifDecoderCallback : public ImageCodecCallback {
38     public:
39         HeifDecoderCallback(HeifHardwareDecoder* heifDecoder);
40         void OnError(ImageCodecError err) override;
41         void OnOutputFormatChanged(const Format &format) override;
42         void OnInputBufferAvailable(uint32_t index, std::shared_ptr<ImageCodecBuffer> buffer) override;
43         void OnOutputBufferAvailable(uint32_t index, std::shared_ptr<ImageCodecBuffer> buffer) override;
44         HeifHardwareDecoder* heifDecoder_;
45     };
46 private:
47     struct RawYuvCopyInfo {
48         uint8_t* yStart = 0;
49         uint8_t* uvStart = 0;
50         uint32_t stride = 0;
51         uint32_t yStride = 0;
52         uint32_t yOffset = 0;
53         uint32_t uvOffset = 0;
54     };
55 private:
56     static bool GetUvPlaneOffsetFromSurfaceBuffer(sptr<SurfaceBuffer>& surfaceBuffer, uint64_t& offset);
57     bool IsHardwareDecodeSupported(const GridInfo& gridInfo);
58     bool SetCallbackForDecoder();
59     void GetPackedInputFlag();
60     bool ConfigureDecoder(const GridInfo& gridInfo, sptr<SurfaceBuffer>& output);
61     bool SetOutputBuffer(const GridInfo& gridInfo, sptr<SurfaceBuffer> output);
62     bool WaitForOmxToReturnInputBuffer(uint32_t& bufferId, std::shared_ptr<ImageCodecBuffer>& buffer);
63     int32_t PrepareInputCodecBuffer(const std::vector<std::vector<uint8_t>>& inputs, size_t inputIndex,
64                                     std::shared_ptr<ImageCodecBuffer>& buffer);
65     void SendInputBufferLoop(const std::vector<std::vector<uint8_t>>& inputs);
66     bool WaitForOmxToReturnOutputBuffer(uint32_t& bufferId, std::shared_ptr<ImageCodecBuffer>& buffer);
67     void AssembleOutput(uint32_t outputIndex, std::shared_ptr<ImageCodecBuffer>& buffer);
68     static uint32_t CalculateDirtyLen(uint32_t displayLen, uint32_t gridLen, uint32_t totalGrid, uint32_t curGrid);
69     static bool CopyRawYuvData(const RawYuvCopyInfo& src, const RawYuvCopyInfo& dst,
70                                uint32_t dirtyWidth, uint32_t dirtyHeight);
71     void ReceiveOutputBufferLoop();
72     static int64_t GetTimestampInUs();
73     void ReleaseDecoder();
74 
75     void SignalError();
76     bool HasError();
77     void Reset();
78 
79     void FlushOutput();
80     std::string GetOutputPixelFmtDesc();
81     void DumpOutput();
82     void DumpSingleInput(const std::string& type, const GridInfo& gridInfo,
83                          const std::vector<std::vector<uint8_t>>& inputs);
84     void DumpInput(const GridInfo& gridInfo, const std::vector<std::vector<uint8_t>>& inputs);
85 private:
86     static constexpr int32_t BUFFER_CIRCULATE_TIMEOUT_IN_MS = 500;
87     static constexpr uint32_t MAX_TIMEOUT_CNT = 3;
88     static constexpr uint32_t SAMPLE_RATIO_FOR_YUV420_SP = 2;
89     static constexpr size_t MIN_SIZE_OF_INPUT = 2;
90     static constexpr int MAX_PATH_LEN = 256;
91 
92     bool packedInputFlag_ = false;
93 
94     std::shared_ptr<ImageCodec> heifDecoderImpl_;
95 
96     sptr<SurfaceBuffer> output_;
97     uint64_t uvOffsetForOutput_;
98     GridInfo gridInfo_;
99 
100     std::mutex errMtx_;
101     bool hasErr_ = false;
102 
103     std::mutex inputMtx_;
104     std::condition_variable inputCond_;
105     std::list<std::pair<uint32_t, std::shared_ptr<ImageCodecBuffer>>> inputList_;
106 
107     std::mutex outputMtx_;
108     std::condition_variable outputCond_;
109     std::list<std::pair<uint32_t, std::shared_ptr<ImageCodecBuffer>>> outputList_;
110 
111     std::thread releaseThread_;
112 };
113 } // namespace ImagePlugin
114 } // namespace OHOS
115 
116 #endif // HEIF_HW_DECODER_H