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