1/*
2 * Copyright (C) 2023 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 HCODEC_HCODEC_H
17#define HCODEC_HCODEC_H
18
19#include <queue>
20#include <array>
21#include <functional>
22#include <unordered_set>
23#include "securec.h"
24#include "OMX_Component.h"  // third_party/openmax/api/1.1.2
25#include "codecbase.h"
26#include "avcodec_errors.h"
27#include "state_machine.h"
28#include "codec_hdi.h"
29#include "type_converter.h"
30#include "buffer/avbuffer.h"
31#include "meta/meta_key.h" // foundation/multimedia/histreamer/interface/inner_api/
32
33namespace OHOS::MediaAVCodec {
34class HCodec : public CodecBase, protected StateMachine, public std::enable_shared_from_this<HCodec> {
35public:
36    static std::shared_ptr<HCodec> Create(const std::string &name);
37    int32_t Init(Media::Meta &callerInfo) override;
38    int32_t SetCallback(const std::shared_ptr<MediaCodecCallback> &callback) override;
39    int32_t Configure(const Format &format) override;
40    int32_t SetCustomBuffer(std::shared_ptr<AVBuffer> buffer) override;
41    sptr<Surface> CreateInputSurface() override;
42    int32_t SetInputSurface(sptr<Surface> surface) override;
43    int32_t SetOutputSurface(sptr<Surface> surface) override;
44
45    int32_t QueueInputBuffer(uint32_t index) override;
46    int32_t NotifyEos() override;
47    int32_t ReleaseOutputBuffer(uint32_t index) override;
48    int32_t RenderOutputBuffer(uint32_t index) override;
49
50    int32_t SignalRequestIDRFrame() override;
51    int32_t SetParameter(const Format& format) override;
52    int32_t GetInputFormat(Format& format) override;
53    int32_t GetOutputFormat(Format& format) override;
54    std::string GetHidumperInfo() override;
55
56    int32_t Start() override;
57    int32_t Stop() override;
58    int32_t Flush() override;
59    int32_t Reset() override;
60    int32_t Release() override;
61    virtual GSError OnBufferReleasedByConsumer(uint64_t surfaceId) { return GSERROR_OK; }
62
63protected:
64    enum MsgWhat : MsgType {
65        INIT,
66        SET_CALLBACK,
67        CONFIGURE,
68        CONFIGURE_BUFFER,
69        CREATE_INPUT_SURFACE,
70        SET_INPUT_SURFACE,
71        SET_OUTPUT_SURFACE,
72        START,
73        GET_INPUT_FORMAT,
74        GET_OUTPUT_FORMAT,
75        SET_PARAMETERS,
76        REQUEST_IDR_FRAME,
77        FLUSH,
78        QUEUE_INPUT_BUFFER,
79        NOTIFY_EOS,
80        RELEASE_OUTPUT_BUFFER,
81        RENDER_OUTPUT_BUFFER,
82        STOP,
83        RELEASE,
84        GET_HIDUMPER_INFO,
85        PRINT_ALL_BUFFER_OWNER,
86
87        INNER_MSG_BEGIN = 1000,
88        CODEC_EVENT,
89        OMX_EMPTY_BUFFER_DONE,
90        OMX_FILL_BUFFER_DONE,
91        GET_BUFFER_FROM_SURFACE,
92        CHECK_IF_REPEAT,
93        CHECK_IF_STUCK,
94        FORCE_SHUTDOWN,
95    };
96
97    enum BufferOperationMode {
98        KEEP_BUFFER,
99        RESUBMIT_BUFFER,
100        FREE_BUFFER,
101    };
102
103    enum BufferOwner {
104        OWNED_BY_US = 0,
105        OWNED_BY_USER = 1,
106        OWNED_BY_OMX = 2,
107        OWNED_BY_SURFACE = 3,
108        OWNER_CNT = 4,
109    };
110
111    struct PortInfo {
112        uint32_t width = 0;
113        uint32_t height = 0;
114        OMX_VIDEO_CODINGTYPE codingType;
115        std::optional<PixelFmt> pixelFmt;
116        double frameRate;
117        std::optional<uint32_t> inputBufSize;
118    };
119
120    enum DumpMode : unsigned long {
121        DUMP_NONE = 0,
122        DUMP_ENCODER_INPUT = 0b1000,
123        DUMP_ENCODER_OUTPUT = 0b0100,
124        DUMP_DECODER_INPUT = 0b0010,
125        DUMP_DECODER_OUTPUT = 0b0001,
126    };
127
128    struct BufferInfo {
129        BufferInfo() : lastOwnerChangeTime(std::chrono::steady_clock::now()) {}
130        bool isInput = true;
131        BufferOwner owner = OWNED_BY_US;
132        std::chrono::time_point<std::chrono::steady_clock> lastOwnerChangeTime;
133        int64_t lastFlushTime = 0;
134        uint32_t bufferId = 0;
135        std::shared_ptr<CodecHDI::OmxCodecBuffer> omxBuffer;
136        std::shared_ptr<AVBuffer> avBuffer;
137        sptr<SurfaceBuffer> surfaceBuffer;
138        bool needDealWithCache = false;
139
140        void CleanUpUnusedInfo();
141        void BeginCpuAccess();
142        void EndCpuAccess();
143        bool IsValidFrame() const;
144#ifdef BUILD_ENG_VERSION
145        void Dump(const std::string& prefix, uint64_t cnt, DumpMode dumpMode, bool isEncoder) const;
146
147    private:
148        void Dump(const std::string& prefix, uint64_t cnt) const;
149        void DumpSurfaceBuffer(const std::string& prefix, uint64_t cnt) const;
150        void DecideDumpInfo(int& alignedH, uint32_t& totalSize, std::string& suffix, bool& dumpAsVideo) const;
151        void DumpLinearBuffer(const std::string& prefix) const;
152        static constexpr char DUMP_PATH[] = "/data/misc/hcodecdump";
153#endif
154    };
155
156protected:
157    HCodec(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType, bool isEncoder);
158    ~HCodec() override;
159    static const char* ToString(MsgWhat what);
160    static const char* ToString(BufferOwner owner);
161    void ReplyErrorCode(MsgId id, int32_t err);
162    void OnPrintAllBufferOwner(const MsgInfo& msg);
163    void PrintAllBufferInfo();
164    void PrintAllBufferInfo(bool isInput, std::chrono::time_point<std::chrono::steady_clock> now);
165    void PrintStatistic(bool isInput, std::chrono::time_point<std::chrono::steady_clock> now);
166    std::string OnGetHidumperInfo();
167    void UpdateOwner();
168    void UpdateOwner(bool isInput);
169    void ReduceOwner(bool isInput, BufferOwner owner);
170    void ChangeOwner(BufferInfo& info, BufferOwner newOwner);
171    void ChangeOwnerNormal(BufferInfo& info, BufferOwner newOwner);
172    void ChangeOwnerDebug(BufferInfo& info, BufferOwner newOwner);
173    void UpdateInputRecord(const BufferInfo& info, std::chrono::time_point<std::chrono::steady_clock> now);
174    void UpdateOutputRecord(const BufferInfo& info, std::chrono::time_point<std::chrono::steady_clock> now);
175
176    // configure
177    virtual int32_t OnConfigure(const Format &format) = 0;
178    virtual int32_t OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer) { return AVCS_ERR_UNSUPPORT; }
179    bool GetPixelFmtFromUser(const Format &format);
180    static std::optional<double> GetFrameRateFromUser(const Format &format);
181    int32_t SetVideoPortInfo(OMX_DIRTYPE portIndex, const PortInfo& info);
182    virtual int32_t UpdateInPortFormat() = 0;
183    virtual int32_t UpdateOutPortFormat() = 0;
184    virtual void UpdateColorAspects() {}
185    void PrintPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& def);
186    int32_t SetFrameRateAdaptiveMode(const Format &format);
187    int32_t SetProcessName();
188    int32_t SetLowLatency(const Format &format);
189
190    virtual void OnSetOutputSurface(const MsgInfo &msg, BufferOperationMode mode);
191    virtual int32_t OnSetParameters(const Format &format) { return AVCS_ERR_OK; }
192    virtual sptr<Surface> OnCreateInputSurface() { return nullptr; }
193    virtual int32_t OnSetInputSurface(sptr<Surface> &inputSurface) { return AVCS_ERR_UNSUPPORT; }
194    virtual int32_t RequestIDRFrame() { return AVCS_ERR_UNSUPPORT; }
195
196    // start
197    virtual bool ReadyToStart() = 0;
198    virtual int32_t AllocateBuffersOnPort(OMX_DIRTYPE portIndex) = 0;
199    virtual void SetCallerToBuffer(int fd) {}
200    virtual void UpdateFormatFromSurfaceBuffer() = 0;
201    int32_t GetPortDefinition(OMX_DIRTYPE portIndex, OMX_PARAM_PORTDEFINITIONTYPE& def);
202    int32_t AllocateAvSurfaceBuffers(OMX_DIRTYPE portIndex);
203    int32_t AllocateAvLinearBuffers(OMX_DIRTYPE portIndex);
204    int32_t AllocateAvHardwareBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def);
205    int32_t AllocateAvSharedBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def);
206    std::shared_ptr<CodecHDI::OmxCodecBuffer> SurfaceBufferToOmxBuffer(
207        const sptr<SurfaceBuffer>& surfaceBuffer);
208    std::shared_ptr<CodecHDI::OmxCodecBuffer> DynamicSurfaceBufferToOmxBuffer();
209
210    virtual int32_t SubmitAllBuffersOwnedByUs() = 0;
211    virtual int32_t SubmitOutputBuffersToOmxNode() { return AVCS_ERR_UNSUPPORT; }
212    BufferInfo* FindBufferInfoByID(OMX_DIRTYPE portIndex, uint32_t bufferId);
213    std::optional<size_t> FindBufferIndexByID(OMX_DIRTYPE portIndex, uint32_t bufferId);
214    virtual void OnGetBufferFromSurface(const ParamSP& param) = 0;
215    uint32_t UserFlagToOmxFlag(AVCodecBufferFlag userFlag);
216    AVCodecBufferFlag OmxFlagToUserFlag(uint32_t omxFlag);
217    bool WaitFence(const sptr<SyncFence>& fence);
218    void WrapSurfaceBufferToSlot(BufferInfo &info,
219        const sptr<SurfaceBuffer>& surfaceBuffer, int64_t pts, uint32_t flag);
220
221    // input buffer circulation
222    virtual void NotifyUserToFillThisInBuffer(BufferInfo &info);
223    virtual void OnQueueInputBuffer(const MsgInfo &msg, BufferOperationMode mode);
224    int32_t OnQueueInputBuffer(BufferOperationMode mode, BufferInfo* info);
225    virtual void OnSignalEndOfInputStream(const MsgInfo &msg);
226    int32_t NotifyOmxToEmptyThisInBuffer(BufferInfo& info);
227    virtual void OnOMXEmptyBufferDone(uint32_t bufferId, BufferOperationMode mode) = 0;
228    virtual void RepeatIfNecessary(const ParamSP& param) {}
229    bool CheckBufPixFmt(const sptr<SurfaceBuffer>& buffer);
230
231    // output buffer circulation
232    virtual void DynamicModeSubmitBuffer() {}
233    int32_t NotifyOmxToFillThisOutBuffer(BufferInfo &info);
234    void OnOMXFillBufferDone(const CodecHDI::OmxCodecBuffer& omxBuffer, BufferOperationMode mode);
235    void OnOMXFillBufferDone(BufferOperationMode mode, BufferInfo& info, size_t bufferIdx);
236    void NotifyUserOutBufferAvaliable(BufferInfo &info);
237    void OnReleaseOutputBuffer(const MsgInfo &msg, BufferOperationMode mode);
238    virtual void OnReleaseOutputBuffer(const BufferInfo &info) {}
239    virtual void OnRenderOutputBuffer(const MsgInfo &msg, BufferOperationMode mode);
240    virtual void ExtractPerFrameParamFromOmxBuffer(
241        const std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
242        std::shared_ptr<Media::Meta> &meta) {}
243
244    // stop/release
245    void ReclaimBuffer(OMX_DIRTYPE portIndex, BufferOwner owner, bool erase = false);
246    bool IsAllBufferOwnedByUsOrSurface(OMX_DIRTYPE portIndex);
247    bool IsAllBufferOwnedByUsOrSurface();
248    void EraseOutBuffersOwnedByUsOrSurface();
249    void ClearBufferPool(OMX_DIRTYPE portIndex);
250    virtual void OnClearBufferPool(OMX_DIRTYPE portIndex) {}
251    virtual void EraseBufferFromPool(OMX_DIRTYPE portIndex, size_t i) = 0;
252    void FreeOmxBuffer(OMX_DIRTYPE portIndex, const BufferInfo& info);
253    virtual void OnEnterUninitializedState() {}
254
255    // template
256    template <typename T>
257    static inline void InitOMXParam(T& param)
258    {
259        (void)memset_s(&param, sizeof(T), 0x0, sizeof(T));
260        param.nSize = sizeof(T);
261        param.nVersion.s.nVersionMajor = 1;
262    }
263
264    template <typename T>
265    static inline void InitOMXParamExt(T& param)
266    {
267        (void)memset_s(&param, sizeof(T), 0x0, sizeof(T));
268        param.size = sizeof(T);
269        param.version.s.nVersionMajor = 1;
270    }
271
272    template <typename T>
273    bool GetParameter(uint32_t index, T& param, bool isCfg = false)
274    {
275        int8_t* p = reinterpret_cast<int8_t*>(&param);
276        std::vector<int8_t> inVec(p, p + sizeof(T));
277        std::vector<int8_t> outVec;
278        int32_t ret = isCfg ? compNode_->GetConfig(index, inVec, outVec) :
279                              compNode_->GetParameter(index, inVec, outVec);
280        if (ret != HDF_SUCCESS) {
281            return false;
282        }
283        if (outVec.size() != sizeof(T)) {
284            return false;
285        }
286        ret = memcpy_s(&param, sizeof(T), outVec.data(), outVec.size());
287        if (ret != EOK) {
288            return false;
289        }
290        return true;
291    }
292
293    template <typename T>
294    bool SetParameter(uint32_t index, const T& param, bool isCfg = false)
295    {
296        const int8_t* p = reinterpret_cast<const int8_t*>(&param);
297        std::vector<int8_t> inVec(p, p + sizeof(T));
298        int32_t ret = isCfg ? compNode_->SetConfig(index, inVec) :
299                              compNode_->SetParameter(index, inVec);
300        if (ret != HDF_SUCCESS) {
301            return false;
302        }
303        return true;
304    }
305
306    static inline uint32_t AlignTo(uint32_t side, uint32_t align)
307    {
308        if (align == 0) {
309            return side;
310        }
311        return (side + align - 1) / align * align;
312    }
313
314protected:
315    CodecHDI::CodecCompCapability caps_;
316    OMX_VIDEO_CODINGTYPE codingType_;
317    bool isEncoder_;
318    bool isSecure_ = false;
319    std::string shortName_;
320    uint32_t componentId_ = 0;
321    std::string compUniqueStr_;
322    struct CallerInfo {
323        int32_t pid = -1;
324        std::string processName;
325    } playerCaller_, avcodecCaller_;
326    bool calledByAvcodec_ = true;
327    bool debugMode_ = false;
328    DumpMode dumpMode_ = DUMP_NONE;
329    sptr<CodecHDI::ICodecCallback> compCb_ = nullptr;
330    sptr<CodecHDI::ICodecComponent> compNode_ = nullptr;
331    sptr<CodecHDI::ICodecComponentManager> compMgr_ = nullptr;
332
333    std::shared_ptr<MediaCodecCallback> callback_;
334    PixelFmt configuredFmt_{};
335    BufferRequestConfig requestCfg_{};
336    std::shared_ptr<Format> configFormat_;
337    std::shared_ptr<Format> inputFormat_;
338    std::shared_ptr<Format> outputFormat_;
339
340    std::vector<BufferInfo> inputBufferPool_;
341    std::vector<BufferInfo> outputBufferPool_;
342    bool isBufferCirculating_ = false;
343    bool inputPortEos_ = false;
344    bool outputPortEos_ = false;
345    bool gotFirstInput_ = false;
346    bool gotFirstOutput_ = false;
347    bool outPortHasChanged_ = false;
348
349    // VRR
350#ifdef USE_VIDEO_PROCESSING_ENGINE
351    bool isVrrEnable_ = false;
352    virtual int32_t VrrPrediction(BufferInfo &info) { return AVCS_ERR_UNSUPPORT; }
353#endif
354
355    struct TotalCntAndCost {
356        uint64_t totalCnt = 0;
357        uint64_t totalCostUs = 0;
358    };
359
360    // whole lift time
361    uint64_t inTotalCnt_ = 0;
362    TotalCntAndCost outRecord_;
363    std::unordered_map<int64_t, std::chrono::time_point<std::chrono::steady_clock>> inTimeMap_;
364
365    // normal: every 200 frames, debug: whole life time
366    static constexpr uint64_t PRINT_PER_FRAME = 200;
367    std::array<TotalCntAndCost, OWNER_CNT> inputHoldTimeRecord_;
368    std::array<TotalCntAndCost, OWNER_CNT> outputHoldTimeRecord_;
369    std::chrono::time_point<std::chrono::steady_clock> firstInTime_;
370    std::chrono::time_point<std::chrono::steady_clock> firstOutTime_;
371
372    // used when buffer circulation stoped
373    static constexpr char KEY_LAST_OWNER_CHANGE_TIME[] = "lastOwnerChangeTime";
374    std::chrono::time_point<std::chrono::steady_clock> lastOwnerChangeTime_;
375    uint32_t circulateWarnPrintedTimes_ = 0;
376    static constexpr uint32_t MAX_CIRCULATE_WARN_TIMES = 3;
377
378    std::array<int, HCodec::OWNER_CNT> inputOwner_ {};
379    std::array<std::string, HCodec::OWNER_CNT> inputOwnerStr_ {};
380    std::array<int, HCodec::OWNER_CNT> outputOwner_ {};
381    std::array<std::string, HCodec::OWNER_CNT> outputOwnerStr_ {};
382
383    static constexpr char BUFFER_ID[] = "buffer-id";
384    static constexpr uint32_t WAIT_FENCE_MS = 1000;
385    static constexpr uint32_t WARN_FENCE_MS = 30;
386    static constexpr uint32_t STRIDE_ALIGNMENT = 32;
387    static constexpr double FRAME_RATE_COEFFICIENT = 65536.0;
388
389private:
390    struct BaseState : State {
391    protected:
392        BaseState(HCodec *codec, const std::string &stateName,
393                  BufferOperationMode inputMode = KEEP_BUFFER, BufferOperationMode outputMode = KEEP_BUFFER)
394            : State(stateName), codec_(codec), inputMode_(inputMode), outputMode_(outputMode) {}
395        void OnMsgReceived(const MsgInfo &info) override;
396        void ReplyErrorCode(MsgId id, int32_t err);
397        void OnCodecEvent(const MsgInfo &info);
398        virtual void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2);
399        void OnGetFormat(const MsgInfo &info);
400        virtual void OnShutDown(const MsgInfo &info) = 0;
401        virtual void OnCheckIfStuck(const MsgInfo &info);
402        void OnForceShutDown(const MsgInfo &info);
403        void OnStateExited() override { codec_->stateGeneration_++; }
404        void OnSetParameters(const MsgInfo &info);
405
406    protected:
407        HCodec *codec_;
408        BufferOperationMode inputMode_;
409        BufferOperationMode outputMode_;
410    };
411
412    struct UninitializedState : BaseState {
413        explicit UninitializedState(HCodec *codec) : BaseState(codec, "Uninitialized") {}
414    private:
415        void OnStateEntered() override;
416        void OnMsgReceived(const MsgInfo &info) override;
417        void OnShutDown(const MsgInfo &info) override;
418    };
419
420    struct InitializedState : BaseState {
421        explicit InitializedState(HCodec *codec) : BaseState(codec, "Initialized") {}
422    private:
423        void OnStateEntered() override;
424        void ProcessShutDownFromRunning();
425        void OnMsgReceived(const MsgInfo &info) override;
426        void OnSetCallBack(const MsgInfo &info);
427        void OnConfigure(const MsgInfo &info);
428        void OnStart(const MsgInfo &info);
429        void OnShutDown(const MsgInfo &info) override;
430    };
431
432    struct StartingState : BaseState {
433        explicit StartingState(HCodec *codec) : BaseState(codec, "Starting") {}
434    private:
435        void OnStateEntered() override;
436        void OnStateExited() override;
437        void OnMsgReceived(const MsgInfo &info) override;
438        int32_t AllocateBuffers();
439        void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
440        void OnShutDown(const MsgInfo &info) override;
441        void ReplyStartMsg(int32_t errCode);
442        bool hasError_ = false;
443    };
444
445    struct RunningState : BaseState {
446        explicit RunningState(HCodec *codec) : BaseState(codec, "Running", RESUBMIT_BUFFER, RESUBMIT_BUFFER) {}
447    private:
448        void OnStateEntered() override;
449        void OnMsgReceived(const MsgInfo &info) override;
450        void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
451        void OnShutDown(const MsgInfo &info) override;
452        void OnFlush(const MsgInfo &info);
453    };
454
455    struct OutputPortChangedState : BaseState {
456        explicit OutputPortChangedState(HCodec *codec)
457            : BaseState(codec, "OutputPortChanged", RESUBMIT_BUFFER, FREE_BUFFER) {}
458    private:
459        void OnStateEntered() override;
460        void OnMsgReceived(const MsgInfo &info) override;
461        void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
462        void OnShutDown(const MsgInfo &info) override;
463        void HandleOutputPortDisabled();
464        void HandleOutputPortEnabled();
465        void OnFlush(const MsgInfo &info);
466        void OnCheckIfStuck(const MsgInfo &info) override;
467    };
468
469    struct FlushingState : BaseState {
470        explicit FlushingState(HCodec *codec) : BaseState(codec, "Flushing") {}
471    private:
472        void OnStateEntered() override;
473        void OnMsgReceived(const MsgInfo &info) override;
474        void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
475        void OnShutDown(const MsgInfo &info) override;
476        void ChangeStateIfWeOwnAllBuffers();
477        bool IsFlushCompleteOnAllPorts();
478        int32_t UpdateFlushStatusOnPorts(uint32_t data1, uint32_t data2);
479        bool flushCompleteFlag_[2] {false, false};
480    };
481
482    struct StoppingState : BaseState {
483        explicit StoppingState(HCodec *codec) : BaseState(codec, "Stopping"),
484            omxNodeInIdleState_(false),
485            omxNodeIsChangingToLoadedState_(false) {}
486    private:
487        void OnStateEntered() override;
488        void OnMsgReceived(const MsgInfo &info) override;
489        void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
490        void OnShutDown(const MsgInfo &info) override;
491        void ChangeStateIfWeOwnAllBuffers();
492        void ChangeOmxNodeToLoadedState(bool forceToFreeBuffer);
493        bool omxNodeInIdleState_;
494        bool omxNodeIsChangingToLoadedState_;
495    };
496
497    class HdiCallback : public CodecHDI::ICodecCallback {
498    public:
499        explicit HdiCallback(std::weak_ptr<HCodec> codec) : codec_(codec) { }
500        virtual ~HdiCallback() = default;
501        int32_t EventHandler(CodecHDI::CodecEventType event,
502                             const CodecHDI::EventInfo& info);
503        int32_t EmptyBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
504        int32_t FillBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
505    private:
506        std::weak_ptr<HCodec> codec_;
507    };
508
509private:
510    int32_t DoSyncCall(MsgWhat msgType, std::function<void(ParamSP)> oper);
511    int32_t DoSyncCallAndGetReply(MsgWhat msgType, std::function<void(ParamSP)> oper, ParamSP &reply);
512    void PrintCaller();
513    int32_t OnAllocateComponent();
514    void ReleaseComponent();
515    void CleanUpOmxNode();
516    void ChangeOmxToTargetState(CodecHDI::CodecStateType &state,
517                                CodecHDI::CodecStateType targetState);
518    bool RollOmxBackToLoaded();
519
520    int32_t ForceShutdown(int32_t generation, bool isNeedNotifyCaller);
521    void SignalError(AVCodecErrorType errorType, int32_t errorCode);
522    void DeferMessage(const MsgInfo &info);
523    void ProcessDeferredMessages();
524    void ReplyToSyncMsgLater(const MsgInfo& msg);
525    bool GetFirstSyncMsgToReply(MsgInfo& msg);
526
527private:
528    static constexpr size_t MAX_HCODEC_BUFFER_SIZE = 8192 * 4096 * 4; // 8K RGBA
529    static constexpr uint32_t THREE_SECONDS_IN_US = 3'000'000;
530    static constexpr uint32_t ONE_SECONDS_IN_US = 1'000'000;
531    static constexpr uint32_t FIVE_SECONDS_IN_MS = 5'000;
532
533    std::shared_ptr<UninitializedState> uninitializedState_;
534    std::shared_ptr<InitializedState> initializedState_;
535    std::shared_ptr<StartingState> startingState_;
536    std::shared_ptr<RunningState> runningState_;
537    std::shared_ptr<OutputPortChangedState> outputPortChangedState_;
538    std::shared_ptr<FlushingState> flushingState_;
539    std::shared_ptr<StoppingState> stoppingState_;
540
541    int32_t stateGeneration_ = 0;
542    bool isShutDownFromRunning_ = false;
543    bool notifyCallerAfterShutdownComplete_ = false;
544    bool keepComponentAllocated_ = false;
545    bool hasFatalError_ = false;
546    std::list<MsgInfo> deferredQueue_;
547    std::map<MsgType, std::queue<std::pair<MsgId, ParamSP>>> syncMsgToReply_;
548}; // class HCodec
549} // namespace OHOS::MediaAVCodec
550#endif // HCODEC_HCODEC_H
551