1 /*
2  * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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 CODEC_HDI_DECODE_H
17 #define CODEC_HDI_DECODE_H
18 #include <OMX_Component.h>
19 #include <OMX_Core.h>
20 #include <OMX_VideoExt.h>
21 #include <ashmem.h>
22 #include <buffer_handle.h>
23 #include <condition_variable>
24 #include <hdf_log.h>
25 #include <securec.h>
26 #include <fstream>
27 #include <list>
28 #include <map>
29 #include <memory>
30 #include <mutex>
31 #include "codec_component_type.h"
32 #include "codec_packet_reader.h"
33 #include "command_parse.h"
34 #include "v1_0/display_composer_type.h"
35 #include "v1_0/display_buffer_type.h"
36 #include "v1_0/include/idisplay_buffer.h"
37 enum class PortIndex { PORT_INDEX_INPUT = 0, PORT_INDEX_OUTPUT = 1 };
38 
39 class CodecHdiDecode {
40     struct BufferInfo {
41         std::shared_ptr<OmxCodecBuffer> omxBuffer;
42         std::shared_ptr<OHOS::Ashmem> avSharedPtr;
43         PortIndex portIndex;
44         BufferHandle *bufferHandle;
BufferInfoBufferInfo45         BufferInfo()
46         {
47             omxBuffer = nullptr;
48             avSharedPtr = nullptr;
49             portIndex = PortIndex::PORT_INDEX_INPUT;
50             bufferHandle = nullptr;
51         }
~BufferInfoBufferInfo52         ~BufferInfo()
53         {
54             omxBuffer = nullptr;
55             if (avSharedPtr != nullptr) {
56                 avSharedPtr->UnmapAshmem();
57                 avSharedPtr->CloseAshmem();
58                 avSharedPtr = nullptr;
59             }
60             if (bufferHandle != nullptr && buffer_ != nullptr) {
61                 buffer_->FreeMem(*bufferHandle);
62                 bufferHandle = nullptr;
63             }
64             portIndex = PortIndex::PORT_INDEX_INPUT;
65         }
setBufferHandleBufferInfo66         void setBufferHandle(BufferHandle *bufferHandle)
67         {
68             if (this->bufferHandle != nullptr) {
69                 if (buffer_ != nullptr) {
70                     buffer_->FreeMem(*this->bufferHandle);
71                 }
72             }
73             this->bufferHandle = bufferHandle;
74         }
75     };
76 
77 public:
78     explicit CodecHdiDecode();
79     ~CodecHdiDecode();
80     bool Init(CommandOpt &opt);
81     bool Configure();
82     bool UseBuffers();
83     void FreeBuffers();
84     void Run();
85     void Release();
86     static int32_t OnEvent(struct CodecCallbackType *self, OMX_EVENTTYPE event, struct EventInfo *info);
87     static int32_t OnEmptyBufferDone(struct CodecCallbackType *self, int64_t appData,
88                                      const struct OmxCodecBuffer *buffer);
89     static int32_t OnFillBufferDone(struct CodecCallbackType *self, int64_t appData,
90                                     const struct OmxCodecBuffer *buffer);
91     template <typename T>
InitParam(T & param)92     inline void InitParam(T &param)
93     {
94         int32_t ret = memset_s(&param, sizeof(param), 0x0, sizeof(param));
95         if (ret != EOK) {
96             HDF_LOGE("%{public}s: memset_s param err [%{public}d].", __func__, ret);
97             return;
98         }
99         param.nSize = sizeof(param);
100         param.nVersion.s.nVersionMajor = 1;  // mVersion.s.nVersionMajor;
101     }
102     template <typename T>
InitParamInOhos(T & param)103     inline void InitParamInOhos(T &param)
104     {
105         int32_t ret = memset_s(&param, sizeof(param), 0x0, sizeof(param));
106         if (ret != EOK) {
107             HDF_LOGE("%{public}s: memset_s param err [%{public}d].", __func__, ret);
108             return;
109         }
110         param.size = sizeof(param);
111         param.version.s.nVersionMajor = 1;  // mVersion.s.nVersionMajor;
112     }
113     void WaitForStatusChanged();
114     void OnStatusChanged();
115 
116 private:
117     int32_t UseBufferOnPort(PortIndex portIndex);
118     int32_t UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize);
119     int32_t UseBufferHandle(int bufferCount, int bufferSize);
120     int32_t OnEmptyBufferDone(const struct OmxCodecBuffer &buffer);
121     int32_t OnFillBufferDone(const struct OmxCodecBuffer &buffer);
122     int32_t CheckAndUseBufferHandle();
123     int GetYuvSize();
124     int32_t ConfigPortDefine();
125     bool FillAllTheBuffer();
126     int GetFreeBufferId();
AlignUp(uint32_t width)127     uint32_t inline AlignUp(uint32_t width)
128     {
129         return (((width) + alignment_ - 1) & (~(alignment_ - 1)));
130     }
131     int32_t GetComponent();
132 
133 private:
134     std::ifstream ioIn_;
135     std::ofstream ioOut_;
136     uint32_t width_;
137     uint32_t height_;
138     uint32_t stride_;
139     struct CodecComponentType *client_;
140     struct CodecCallbackType *callback_;
141     struct CodecComponentManager *omxMgr_;
142     uint32_t componentId_;
143     std::map<int, std::shared_ptr<BufferInfo>> omxBuffers_;  // key is buferid
144     std::list<int> unUsedInBuffers_;
145     std::list<int> unUsedOutBuffers_;
146     std::mutex lockInputBuffers_;
147     std::condition_variable statusCondition_;
148     std::mutex statusLock_;
149     bool exit_;
150     ColorFormat color_;
151     OMX_COLOR_FORMATTYPE omxColorFormat_;
152     CodecMime codecMime_;
153     bool useBufferHandle_;
154     int count_;
155     static constexpr uint32_t alignment_ = 16;
156     static OHOS::HDI::Display::Buffer::V1_0::IDisplayBuffer *buffer_;
157     CodecPacketReader::Ptr reader_;
158 };
159 #endif /* CODEC_HDI_DECODE_H */