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_ENCODE_H
17#define CODEC_HDI_ENCODE_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_utils.h"
32#include "codec_omx_ext.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 CodecHdiEncode : public ICodecHdiCallBackBase,
44                       public std::enable_shared_from_this<CodecHdiEncode> {
45    enum class PortIndex { PORT_INDEX_INPUT = 0, PORT_INDEX_OUTPUT = 1 };
46    struct BufferInfo {
47        std::shared_ptr<OmxCodecBuffer> omxBuffer;
48        std::shared_ptr<OHOS::Ashmem> avSharedPtr;
49        int bufferHandleId;
50        PortIndex portIndex;
51        BufferInfo()
52        {
53            omxBuffer = nullptr;
54            avSharedPtr = nullptr;
55            portIndex = PortIndex::PORT_INDEX_INPUT;
56            bufferHandleId = -1;
57        }
58        ~BufferInfo()
59        {
60            omxBuffer = nullptr;
61            if (avSharedPtr) {
62                avSharedPtr->UnmapAshmem();
63                avSharedPtr->CloseAshmem();
64                avSharedPtr = nullptr;
65            }
66            portIndex = PortIndex::PORT_INDEX_INPUT;
67            bufferHandleId = -1;
68        }
69    };
70    using BufferInfo = struct BufferInfo;
71
72public:
73    CodecHdiEncode();
74    virtual ~CodecHdiEncode();
75
76    bool Init(const CommandOpt &opt);
77    bool Configure();
78    bool UseBuffers();
79    int32_t UseBufferOnPort(PortIndex portIndex);
80    void FreeBuffers();
81    void Run();
82    void Release();
83    void WaitForStatusChanged();
84    void OnStatusChanged();
85    bool ReadOneFrame(FILE *fp, char *buf, uint32_t &filledCount);
86    int32_t OnEmptyBufferDone(const struct OmxCodecBuffer &buffer) override;
87    int32_t OnFillBufferDone(const struct OmxCodecBuffer &buffer) override;
88    int32_t EventHandler(OHOS::HDI::Codec::V3_0::CodecEventType event,
89        const OHOS::HDI::Codec::V3_0::EventInfo &info) override;
90
91private:
92    int32_t ConfigBitMode();
93    int32_t UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize);
94    bool FillAllTheBuffer();
95    int GetFreeBufferId();
96    int32_t ConfigPortDefine();
97    int32_t CheckAndUseBufferHandle();
98    int32_t CheckSupportBufferType(PortIndex portIndex, CodecBufferType codecBufferType);
99    int32_t CheckAndUseDMABuffer();
100    int32_t UseDMABuffer(PortIndex portIndex, int bufferCount, int bufferSize);
101    int32_t UseDynaBuffer(int bufferCount, int bufferSize);
102    bool FillCodecBuffer(std::shared_ptr<BufferInfo> bufferInfo, bool &endFlag);
103    int32_t CreateBufferHandle();
104    int32_t GetComponentName(std::string &compName);
105    uint32_t inline AlignUp(uint32_t width)
106    {
107        return (((width) + alignment_ - 1) & (~(alignment_ - 1)));
108    }
109
110private:
111    FILE *fpIn_;  // input file
112    FILE *fpOut_;
113    uint32_t width_;
114    uint32_t height_;
115    uint32_t stride_;
116    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecComponent> client_;
117    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecCallback> callback_;
118    OHOS::sptr<OHOS::HDI::Codec::V3_0::ICodecComponentManager> omxMgr_;
119    uint32_t componentId_;
120    std::map<int, std::shared_ptr<BufferInfo>> omxBuffers_;  // key is bufferID
121    std::map<int, const void *> addrs_;
122    std::list<int> unUsedInBuffers_;
123    std::list<int> unUsedOutBuffers_;
124    std::mutex lockInputBuffers_;
125    std::condition_variable statusCondition_;
126    std::mutex statusLock_;
127    bool exit_;
128    std::map<int, BufferHandle *> bufferHandles_;
129    std::list<int> freeBufferHandles_;
130    bool useBufferHandle_;
131    bool useDMABuffer_;
132    static CodecUtil *util_;
133    static constexpr uint32_t alignment_ = 16;
134    static OHOS::HDI::Display::Buffer::V1_0::IDisplayBuffer *gralloc_;
135};
136
137#endif  // CODEC_HDI_ENCODE_H