• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33 namespace OHOS::MediaAVCodec {
34 class HCodec : public CodecBase, protected StateMachine, public std::enable_shared_from_this<HCodec> {
35 public:
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;
OnBufferReleasedByConsumer(uint64_t surfaceId)61     virtual GSError OnBufferReleasedByConsumer(uint64_t surfaceId) { return GSERROR_OK; }
62 
63 protected:
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 {
BufferInfoBufferInfo129         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 
156 protected:
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;
OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer)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;
UpdateColorAspects()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 
OnSetOutputSurface(const sptr<Surface> & surface,bool cfg)190     virtual int32_t OnSetOutputSurface(const sptr<Surface> &surface, bool cfg) { return AVCS_ERR_UNSUPPORT; }
OnSetParameters(const Format & format)191     virtual int32_t OnSetParameters(const Format &format) { return AVCS_ERR_OK; }
OnCreateInputSurface()192     virtual sptr<Surface> OnCreateInputSurface() { return nullptr; }
OnSetInputSurface(sptr<Surface> & inputSurface)193     virtual int32_t OnSetInputSurface(sptr<Surface> &inputSurface) { return AVCS_ERR_UNSUPPORT; }
RequestIDRFrame()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;
SetCallerToBuffer(int fd)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;
SubmitOutputBuffersToOmxNode()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;
RepeatIfNecessary(const ParamSP & param)228     virtual void RepeatIfNecessary(const ParamSP& param) {}
229     bool CheckBufPixFmt(const sptr<SurfaceBuffer>& buffer);
230 
231     // output buffer circulation
SubmitDynamicBufferIfPossible()232     virtual void SubmitDynamicBufferIfPossible() {}
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);
OnReleaseOutputBuffer(const BufferInfo & info)238     virtual void OnReleaseOutputBuffer(const BufferInfo &info) {}
239     virtual void OnRenderOutputBuffer(const MsgInfo &msg, BufferOperationMode mode);
ExtractPerFrameParamFromOmxBuffer(const std::shared_ptr<CodecHDI::OmxCodecBuffer> & omxBuffer,std::shared_ptr<Media::Meta> & meta)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);
OnClearBufferPool(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);
OnEnterUninitializedState()253     virtual void OnEnterUninitializedState() {}
254 
255     // template
256     template <typename T>
InitOMXParam(T & param)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>
InitOMXParamExt(T & param)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 
AlignTo(uint32_t side,uint32_t align)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 
314 protected:
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     struct TotalCntAndCost {
350         uint64_t totalCnt = 0;
351         uint64_t totalCostUs = 0;
352     };
353 
354     // whole lift time
355     uint64_t inTotalCnt_ = 0;
356     TotalCntAndCost outRecord_;
357     std::unordered_map<int64_t, std::chrono::time_point<std::chrono::steady_clock>> inTimeMap_;
358 
359     // normal: every 200 frames, debug: whole life time
360     static constexpr uint64_t PRINT_PER_FRAME = 200;
361     std::array<TotalCntAndCost, OWNER_CNT> inputHoldTimeRecord_;
362     std::array<TotalCntAndCost, OWNER_CNT> outputHoldTimeRecord_;
363     std::chrono::time_point<std::chrono::steady_clock> firstInTime_;
364     std::chrono::time_point<std::chrono::steady_clock> firstOutTime_;
365 
366     // used when buffer circulation stoped
367     static constexpr char KEY_LAST_OWNER_CHANGE_TIME[] = "lastOwnerChangeTime";
368     std::chrono::time_point<std::chrono::steady_clock> lastOwnerChangeTime_;
369     uint32_t circulateWarnPrintedTimes_ = 0;
370     static constexpr uint32_t MAX_CIRCULATE_WARN_TIMES = 3;
371 
372     std::array<int, HCodec::OWNER_CNT> inputOwner_ {};
373     std::array<std::string, HCodec::OWNER_CNT> inputOwnerStr_ {};
374     std::array<int, HCodec::OWNER_CNT> outputOwner_ {};
375     std::array<std::string, HCodec::OWNER_CNT> outputOwnerStr_ {};
376 
377     static constexpr char BUFFER_ID[] = "buffer-id";
378     static constexpr uint32_t WAIT_FENCE_MS = 1000;
379     static constexpr uint32_t WARN_FENCE_MS = 30;
380     static constexpr uint32_t STRIDE_ALIGNMENT = 32;
381     static constexpr double FRAME_RATE_COEFFICIENT = 65536.0;
382 
383 private:
384     struct BaseState : State {
385     protected:
386         BaseState(HCodec *codec, const std::string &stateName,
387                   BufferOperationMode inputMode = KEEP_BUFFER, BufferOperationMode outputMode = KEEP_BUFFER)
StateBaseState388             : State(stateName), codec_(codec), inputMode_(inputMode), outputMode_(outputMode) {}
389         void OnMsgReceived(const MsgInfo &info) override;
390         void ReplyErrorCode(MsgId id, int32_t err);
391         void OnCodecEvent(const MsgInfo &info);
392         virtual void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2);
393         void OnGetFormat(const MsgInfo &info);
394         virtual void OnShutDown(const MsgInfo &info) = 0;
395         virtual void OnCheckIfStuck(const MsgInfo &info);
396         void OnForceShutDown(const MsgInfo &info);
OnStateExitedBaseState397         void OnStateExited() override { codec_->stateGeneration_++; }
398         void OnSetParameters(const MsgInfo &info);
399 
400     protected:
401         HCodec *codec_;
402         BufferOperationMode inputMode_;
403         BufferOperationMode outputMode_;
404     };
405 
406     struct UninitializedState : BaseState {
UninitializedStateUninitializedState407         explicit UninitializedState(HCodec *codec) : BaseState(codec, "Uninitialized") {}
408     private:
409         void OnStateEntered() override;
410         void OnMsgReceived(const MsgInfo &info) override;
411         void OnShutDown(const MsgInfo &info) override;
412     };
413 
414     struct InitializedState : BaseState {
InitializedStateInitializedState415         explicit InitializedState(HCodec *codec) : BaseState(codec, "Initialized") {}
416     private:
417         void OnStateEntered() override;
418         void ProcessShutDownFromRunning();
419         void OnMsgReceived(const MsgInfo &info) override;
420         void OnSetCallBack(const MsgInfo &info);
421         void OnConfigure(const MsgInfo &info);
422         void OnStart(const MsgInfo &info);
423         void OnShutDown(const MsgInfo &info) override;
424     };
425 
426     struct StartingState : BaseState {
StartingStateStartingState427         explicit StartingState(HCodec *codec) : BaseState(codec, "Starting") {}
428     private:
429         void OnStateEntered() override;
430         void OnStateExited() override;
431         void OnMsgReceived(const MsgInfo &info) override;
432         int32_t AllocateBuffers();
433         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
434         void OnShutDown(const MsgInfo &info) override;
435         void ReplyStartMsg(int32_t errCode);
436         bool hasError_ = false;
437     };
438 
439     struct RunningState : BaseState {
RunningStateRunningState440         explicit RunningState(HCodec *codec) : BaseState(codec, "Running", RESUBMIT_BUFFER, RESUBMIT_BUFFER) {}
441     private:
442         void OnStateEntered() override;
443         void OnMsgReceived(const MsgInfo &info) override;
444         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
445         void OnShutDown(const MsgInfo &info) override;
446         void OnFlush(const MsgInfo &info);
447     };
448 
449     struct OutputPortChangedState : BaseState {
OutputPortChangedStateOutputPortChangedState450         explicit OutputPortChangedState(HCodec *codec)
451             : BaseState(codec, "OutputPortChanged", RESUBMIT_BUFFER, FREE_BUFFER) {}
452     private:
453         void OnStateEntered() override;
454         void OnMsgReceived(const MsgInfo &info) override;
455         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
456         void OnShutDown(const MsgInfo &info) override;
457         void HandleOutputPortDisabled();
458         void HandleOutputPortEnabled();
459         void OnFlush(const MsgInfo &info);
460         void OnCheckIfStuck(const MsgInfo &info) override;
461     };
462 
463     struct FlushingState : BaseState {
FlushingStateFlushingState464         explicit FlushingState(HCodec *codec) : BaseState(codec, "Flushing") {}
465     private:
466         void OnStateEntered() override;
467         void OnMsgReceived(const MsgInfo &info) override;
468         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
469         void OnShutDown(const MsgInfo &info) override;
470         void ChangeStateIfWeOwnAllBuffers();
471         bool IsFlushCompleteOnAllPorts();
472         int32_t UpdateFlushStatusOnPorts(uint32_t data1, uint32_t data2);
473         bool flushCompleteFlag_[2] {false, false};
474     };
475 
476     struct StoppingState : BaseState {
StoppingStateStoppingState477         explicit StoppingState(HCodec *codec) : BaseState(codec, "Stopping"),
478             omxNodeInIdleState_(false),
479             omxNodeIsChangingToLoadedState_(false) {}
480     private:
481         void OnStateEntered() override;
482         void OnMsgReceived(const MsgInfo &info) override;
483         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
484         void OnShutDown(const MsgInfo &info) override;
485         void ChangeStateIfWeOwnAllBuffers();
486         void ChangeOmxNodeToLoadedState(bool forceToFreeBuffer);
487         bool omxNodeInIdleState_;
488         bool omxNodeIsChangingToLoadedState_;
489     };
490 
491     class HdiCallback : public CodecHDI::ICodecCallback {
492     public:
HdiCallback(std::weak_ptr<HCodec> codec)493         explicit HdiCallback(std::weak_ptr<HCodec> codec) : codec_(codec) { }
494         virtual ~HdiCallback() = default;
495         int32_t EventHandler(CodecHDI::CodecEventType event,
496                              const CodecHDI::EventInfo& info);
497         int32_t EmptyBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
498         int32_t FillBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
499     private:
500         std::weak_ptr<HCodec> codec_;
501     };
502 
503 private:
504     int32_t DoSyncCall(MsgWhat msgType, std::function<void(ParamSP)> oper);
505     int32_t DoSyncCallAndGetReply(MsgWhat msgType, std::function<void(ParamSP)> oper, ParamSP &reply);
506     void PrintCaller();
507     int32_t OnAllocateComponent();
508     void ReleaseComponent();
509     void CleanUpOmxNode();
510     void ChangeOmxToTargetState(CodecHDI::CodecStateType &state,
511                                 CodecHDI::CodecStateType targetState);
512     bool RollOmxBackToLoaded();
513 
514     int32_t ForceShutdown(int32_t generation, bool isNeedNotifyCaller);
515     void SignalError(AVCodecErrorType errorType, int32_t errorCode);
516     void DeferMessage(const MsgInfo &info);
517     void ProcessDeferredMessages();
518     void ReplyToSyncMsgLater(const MsgInfo& msg);
519     bool GetFirstSyncMsgToReply(MsgInfo& msg);
520 
521 private:
522     static constexpr size_t MAX_HCODEC_BUFFER_SIZE = 8192 * 4096 * 4; // 8K RGBA
523     static constexpr uint32_t THREE_SECONDS_IN_US = 3'000'000;
524     static constexpr uint32_t ONE_SECONDS_IN_US = 1'000'000;
525     static constexpr uint32_t FIVE_SECONDS_IN_MS = 5'000;
526 
527     std::shared_ptr<UninitializedState> uninitializedState_;
528     std::shared_ptr<InitializedState> initializedState_;
529     std::shared_ptr<StartingState> startingState_;
530     std::shared_ptr<RunningState> runningState_;
531     std::shared_ptr<OutputPortChangedState> outputPortChangedState_;
532     std::shared_ptr<FlushingState> flushingState_;
533     std::shared_ptr<StoppingState> stoppingState_;
534 
535     int32_t stateGeneration_ = 0;
536     bool isShutDownFromRunning_ = false;
537     bool notifyCallerAfterShutdownComplete_ = false;
538     bool keepComponentAllocated_ = false;
539     bool hasFatalError_ = false;
540     std::list<MsgInfo> deferredQueue_;
541     std::map<MsgType, std::queue<std::pair<MsgId, ParamSP>>> syncMsgToReply_;
542 }; // class HCodec
543 } // namespace OHOS::MediaAVCodec
544 #endif // HCODEC_HCODEC_H
545