1/*
2 * Copyright 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
19#include <condition_variable>
20#include <list>
21#include <map>
22#include <memory>
23#include <mutex>
24#include <ashmem.h>
25#include <buffer_handle.h>
26#include <OMX_Component.h>
27#include <OMX_Core.h>
28#include <OMX_VideoExt.h>
29#include <securec.h>
30#include "codec_hdi_callback.h"
31#include "codec_omx_ext.h"
32#include "codec_utils.h"
33#include "command_parse.h"
34#include "hdf_log.h"
35#include "sys/mman.h"
36#include "v3_0/codec_types.h"
37#include "v3_0/icodec_callback.h"
38#include "v3_0/icodec_component.h"
39#include "v3_0/icodec_component_manager.h"
40#include "v1_0/include/idisplay_buffer.h"
41
42using OHOS::HDI::Codec::V3_0::OmxCodecBuffer;
43class CodecHdiDecode : public ICodecHdiCallBackBase,
44                       public std::enable_shared_from_this<CodecHdiDecode> {
45    enum class PortIndex { PORT_INDEX_INPUT = 0, PORT_INDEX_OUTPUT = 1 };
46    struct BufferInfo {
47        std::shared_ptr<OHOS::HDI::Codec::V3_0::OmxCodecBuffer> omxBuffer;
48        std::shared_ptr<OHOS::Ashmem> avSharedPtr;
49        PortIndex portIndex;
50        BufferHandle *bufferHandle;
51        BufferInfo()
52        {
53            omxBuffer = nullptr;
54            avSharedPtr = nullptr;
55            portIndex = PortIndex::PORT_INDEX_INPUT;
56            bufferHandle = nullptr;
57        }
58        ~BufferInfo()
59        {
60            omxBuffer = nullptr;
61            if (avSharedPtr != nullptr) {
62                avSharedPtr->UnmapAshmem();
63                avSharedPtr->CloseAshmem();
64                avSharedPtr = nullptr;
65            }
66            if (bufferHandle != nullptr && gralloc_ != nullptr) {
67                gralloc_->FreeMem(*bufferHandle);
68                bufferHandle = nullptr;
69            }
70            portIndex = PortIndex::PORT_INDEX_INPUT;
71        }
72        void setBufferHandle(BufferHandle *bufferHandle)
73        {
74            if (this->bufferHandle != nullptr && gralloc_ != nullptr) {
75                gralloc_->FreeMem(*this->bufferHandle);
76            }
77            this->bufferHandle = bufferHandle;
78        }
79    };
80    using BufferInfo = struct BufferInfo;
81
82public:
83    explicit CodecHdiDecode();
84    virtual ~CodecHdiDecode();
85    bool Init(const CommandOpt &opt);
86    bool Configure();
87    bool UseBuffers();
88    void FreeBuffers();
89    void Run();
90    void Release();
91    int32_t OnEmptyBufferDone(const struct OHOS::HDI::Codec::V3_0::OmxCodecBuffer &buffer) override;
92    int32_t OnFillBufferDone(const struct OHOS::HDI::Codec::V3_0::OmxCodecBuffer &buffer) override;
93    int32_t EventHandler(OHOS::HDI::Codec::V3_0::CodecEventType event,
94        const OHOS::HDI::Codec::V3_0::EventInfo &info) override;
95    void WaitForStatusChanged();
96    void OnStatusChanged();
97    bool ReadOnePacket(FILE *fp, char *buf, uint32_t &filledCount);
98
99private:
100    int32_t UseBufferOnPort(PortIndex portIndex);
101    int32_t UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize);
102    int32_t UseBufferHandle(int bufferCount, int bufferSize);
103    int32_t CheckAndUseBufferHandle();
104    int32_t CheckAndUseDMABuffer();
105    int32_t CreateBufferHandle();
106    int32_t UseDMABuffer(PortIndex portIndex, int bufferCount, int bufferSize);
107    bool FillCodecBuffer(std::shared_ptr<BufferInfo> bufferIndo, bool &endFlag);
108    int32_t CheckSupportBufferType(PortIndex portIndex, CodecBufferType codecBufferType);
109    int GetYuvSize();
110    int32_t ConfigPortDefine();
111    bool FillAllTheBuffer();
112    int GetFreeBufferId();
113    void FreeOutBuffer();
114    void HandleEventPortSettingsChanged(uint32_t data1, uint32_t data2);
115    int32_t GetComponentName(std::string &compName);
116    uint32_t inline AlignUp(uint32_t width)
117    {
118        return (((width) + alignment_ - 1) & (~(alignment_ - 1)));
119    }
120
121private:
122    FILE *fpIn_;  // input file
123    FILE *fpOut_;
124    uint32_t width_;
125    uint32_t height_;
126    uint32_t stride_;
127    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecComponent> client_;
128    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecCallback> callback_;
129    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecComponentManager> omxMgr_;
130    uint32_t componentId_;
131    std::map<int, std::shared_ptr<BufferInfo>> omxBuffers_;  // key is buferid
132    std::map<int, void *> addrs_;
133    std::list<int> unUsedInBuffers_;
134    std::list<int> unUsedOutBuffers_;
135    std::mutex lockInputBuffers_;
136    std::condition_variable statusCondition_;
137    std::mutex statusLock_;
138    bool exit_;
139    codecMime codecMime_;
140    bool useBufferHandle_;
141    bool useDMABuffer_;
142    int count_;
143    static CodecUtil *util_;
144    static constexpr uint32_t alignment_ = 16;
145    static OHOS::HDI::Display::Buffer::V1_0::IDisplayBuffer *gralloc_;
146};
147
148#endif /* CODEC_HDI_DECODE_H */
149