• 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 
32 namespace OHOS::MediaAVCodec {
33 using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
34 
35 class HCodec : public CodecBase, protected StateMachine {
36 public:
37     static std::shared_ptr<HCodec> Create(const std::string &name);
38     int32_t Init(Media::Meta &callerInfo) override;
39     int32_t SetCallback(const std::shared_ptr<MediaCodecCallback> &callback) override;
40     int32_t Configure(const Format &format) override;
41     int32_t SetCustomBuffer(std::shared_ptr<AVBuffer> buffer) override;
42     sptr<Surface> CreateInputSurface() override;
43     int32_t SetInputSurface(sptr<Surface> surface) override;
44     int32_t SetOutputSurface(sptr<Surface> surface) override;
45 
46     int32_t QueueInputBuffer(uint32_t index) override;
47     int32_t NotifyEos() override;
48     int32_t ReleaseOutputBuffer(uint32_t index) override;
49     int32_t RenderOutputBuffer(uint32_t index) override;
50 
51     int32_t SignalRequestIDRFrame() override;
52     int32_t SetParameter(const Format& format) override;
53     int32_t GetChannelId(int32_t &channelId) override;
54     int32_t GetInputFormat(Format& format) override;
55     int32_t GetOutputFormat(Format& format) override;
56     std::string GetHidumperInfo() override;
57     int32_t SetLowPowerPlayerMode(bool isLpp) override;
58 
59     int32_t Start() override;
60     int32_t Stop() override;
61     int32_t Flush() override;
62     int32_t Reset() override;
63     int32_t Release() override;
64     int32_t NotifyMemoryRecycle() override;
65     int32_t NotifyMemoryWriteBack() override;
66     int32_t NotifySuspend() override;
67     int32_t NotifyResume() override;
68 
69 protected:
70     enum MsgWhat : MsgType {
71         INIT,
72         SET_CALLBACK,
73         CONFIGURE,
74         CONFIGURE_BUFFER,
75         CREATE_INPUT_SURFACE,
76         SET_INPUT_SURFACE,
77         SET_OUTPUT_SURFACE,
78         START,
79         GET_INPUT_FORMAT,
80         GET_OUTPUT_FORMAT,
81         SET_PARAMETERS,
82         REQUEST_IDR_FRAME,
83         FLUSH,
84         QUEUE_INPUT_BUFFER,
85         NOTIFY_EOS,
86         RELEASE_OUTPUT_BUFFER,
87         RENDER_OUTPUT_BUFFER,
88         STOP,
89         RELEASE,
90         SUSPEND,
91         RESUME,
92         BUFFER_RECYCLE,
93         BUFFER_WRITEBACK,
94         GET_HIDUMPER_INFO,
95         PRINT_ALL_BUFFER_OWNER,
96 
97         INNER_MSG_BEGIN = 1000,
98         CODEC_EVENT,
99         OMX_EMPTY_BUFFER_DONE,
100         OMX_FILL_BUFFER_DONE,
101         GET_BUFFER_FROM_SURFACE,
102         CHECK_IF_REPEAT,
103         SUBMIT_DYNAMIC_IF_EOS,
104         CHECK_IF_STUCK,
105         FORCE_SHUTDOWN,
106     };
107 
108     enum BufferOperationMode {
109         KEEP_BUFFER,
110         RESUBMIT_BUFFER,
111         FREE_BUFFER,
112     };
113 
114     enum BufferOwner {
115         OWNED_BY_US = 0,
116         OWNED_BY_USER = 1,
117         OWNED_BY_OMX = 2,
118         OWNED_BY_SURFACE = 3,
119         OWNER_CNT = 4,
120     };
121 
122     struct PortInfo {
123         uint32_t width = 0;
124         uint32_t height = 0;
125         OMX_VIDEO_CODINGTYPE codingType;
126         std::optional<PixelFmt> pixelFmt;
127         double frameRate;
128         std::optional<uint32_t> inputBufSize;
129     };
130 
131     enum DumpMode : unsigned long {
132         DUMP_NONE = 0,
133         DUMP_ENCODER_INPUT = 0b1000,
134         DUMP_ENCODER_OUTPUT = 0b0100,
135         DUMP_DECODER_INPUT = 0b0010,
136         DUMP_DECODER_OUTPUT = 0b0001,
137     };
138 
139     struct TotalEvent {
140         uint64_t eventCnt = 0;
141         uint64_t eventSum = 0;
142     };
143 
144     struct IntervalAverage {
145         double fps;
146         double mbps;
147         double holdCnt[OWNER_CNT];
148         double holdMs[OWNER_CNT];
149     };
150 
151     struct Record {
ResetIntervalRecord152         void ResetInterval(std::optional<TimePoint> beginOfInterval)
153         {
154             beginOfInterval_ = beginOfInterval;
155             holdTimeInterval_.fill(TotalEvent{0, 0});
156             holdCntInterval_.fill(TotalEvent{0, 0});
157             frameCntInterval_ = 0;
158             frameMbitsInterval_ = 0;
159             discardCntInterval_ = 0;
160             waitFenceCostUsInterval_ = 0;
161         }
ResetAllRecord162         void ResetAll()
163         {
164             ResetInterval(std::nullopt);
165             frameCntTotal_ = 0;
166             currOwner_.fill(0);
167             lastOwnerChangeTime_.fill(std::nullopt);
168             lastPts_ = -1;
169         }
170         // 不变值
171         std::array<std::string, OWNER_CNT> ownerTraceTag_;
172         // 从构造开始到某一刻的统计值
173         uint64_t frameCntTotal_ = 0;         // 送帧/出帧总数
174         // 当前统计区间的起始时刻点
175         std::optional<TimePoint> beginOfInterval_;
176         // 从起始到某一刻的统计值
177         std::array<TotalEvent, OWNER_CNT> holdTimeInterval_;  // 每个轮转方持有单个buffer时长的总值
178         std::array<TotalEvent, OWNER_CNT> holdCntInterval_;  // 每个轮转方持有buffer数量乘以持有时长的总值
179         uint64_t frameCntInterval_ = 0;      // 送帧/出帧总个数
180         double frameMbitsInterval_ = 0;    // 送帧/出帧总M比特数
181         uint64_t discardCntInterval_ = 0;       // 丢帧总数
182         uint64_t waitFenceCostUsInterval_ = 0;  // 等fence的总耗时
183         // 某一刻的瞬时值
184         std::array<int, OWNER_CNT> currOwner_;  // 此刻每个轮转方持有几个buffer
185         std::array<std::optional<TimePoint>, OWNER_CNT> lastOwnerChangeTime_;  // 每个轮转方最新一次轮转发生在哪个时刻
186         int64_t lastPts_ = -1;          // 最新的一帧的pts
187     } record_[2]; // 2: port count
188 
189     struct BufferInfo {
BufferInfoBufferInfo190         BufferInfo(bool isIn, BufferOwner beginOwner, Record (&record)[2]) // 2: port count
191             : isInput(isIn), owner(beginOwner), lastOwnerChangeTime(std::chrono::steady_clock::now())
192         {
193             record[isInput ? OMX_DirInput : OMX_DirOutput].lastOwnerChangeTime_[owner] = lastOwnerChangeTime;
194         }
195         bool isInput;
196         BufferOwner owner;
197         BufferOwner nextStepOwner = OWNER_CNT;
198         TimePoint lastOwnerChangeTime;
199         int64_t lastFlushTime = 0;
200         uint32_t bufferId = 0;
201         std::shared_ptr<CodecHDI::OmxCodecBuffer> omxBuffer;
202         std::shared_ptr<AVBuffer> avBuffer;
203         sptr<SurfaceBuffer> surfaceBuffer;
204         bool attached = false;
205         bool needDealWithCache = false;
206         bool hasSwapedOut = false;
207 
208         void CleanUpUnusedInfo();
209         void BeginCpuAccess();
210         void EndCpuAccess();
211         bool IsValidFrame() const;
212 #ifdef BUILD_ENG_VERSION
213         void Dump(const std::string& prefix, uint64_t cnt, DumpMode dumpMode, bool isEncoder) const;
214 
215     private:
216         void Dump(const std::string& prefix, uint64_t cnt) const;
217         void DumpSurfaceBuffer(const std::string& prefix, uint64_t cnt) const;
218         void DecideDumpInfo(int& alignedH, uint32_t& totalSize, std::string& suffix, bool& dumpAsVideo) const;
219         void DumpLinearBuffer(const std::string& prefix) const;
220         static constexpr char DUMP_PATH[] = "/data/misc/hcodecdump";
221 #endif
222     };
223 
224 protected:
225     HCodec(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType, bool isEncoder);
226     ~HCodec() override;
227     static const char* ToString(MsgWhat what);
228     static const char* ToString(BufferOwner owner);
229     void ReplyErrorCode(MsgId id, int32_t err);
230     void UpdateOwner();
231     void UpdateOwner(OMX_DIRTYPE port);
232     void ReduceOwner(OMX_DIRTYPE port, BufferOwner owner);
233     void ChangeOwner(BufferInfo& info, BufferOwner newOwner);
234     void OnPrintAllBufferOwner(const MsgInfo& msg);
235     void PrintAllBufferInfo();
236     std::string OnGetHidumperInfo();
237 
238     void PrintAllBufferInfo(const TimePoint& now, OMX_DIRTYPE port);
239     void UpdateHoldCnt(const TimePoint& now, OMX_DIRTYPE port, BufferOwner owner);
240     void UpdateHoldTime(const TimePoint& now, const BufferInfo& info, BufferOwner newOwner);
241     bool CalculateInterval(const TimePoint& now, OMX_DIRTYPE port, IntervalAverage& ave);
242     void PrintStatistic(const TimePoint& now, OMX_DIRTYPE port);
243     void UpdateInputRecord(const TimePoint& now, const BufferInfo& info);
244     void UpdateOutputRecord(const TimePoint& now, const BufferInfo& info);
245     void FaultEventWrite(const std::string& faultType, const std::string& msg);
246 
247     // configure
248     virtual int32_t OnConfigure(const Format &format) = 0;
OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer)249     virtual int32_t OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer) { return AVCS_ERR_UNSUPPORT; }
250     bool GetPixelFmtFromUser(const Format &format);
251     static std::optional<double> GetFrameRateFromUser(const Format &format);
252     int32_t SetVideoPortInfo(OMX_DIRTYPE portIndex, const PortInfo& info);
253     virtual int32_t UpdateInPortFormat() = 0;
254     virtual int32_t UpdateOutPortFormat() = 0;
UpdateColorAspects()255     virtual void UpdateColorAspects() {}
256     void PrintPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& def);
257     int32_t SetFrameRateAdaptiveMode(const Format &format);
258     int32_t SetProcessName();
259     int32_t SetLowLatency(const Format &format);
260 
261     virtual void OnSetOutputSurface(const MsgInfo &msg, BufferOperationMode mode);
OnSetParameters(const Format & format)262     virtual int32_t OnSetParameters(const Format &format) { return AVCS_ERR_OK; }
OnCreateInputSurface()263     virtual sptr<Surface> OnCreateInputSurface() { return nullptr; }
OnSetInputSurface(sptr<Surface> & inputSurface)264     virtual int32_t OnSetInputSurface(sptr<Surface> &inputSurface) { return AVCS_ERR_UNSUPPORT; }
RequestIDRFrame()265     virtual int32_t RequestIDRFrame() { return AVCS_ERR_UNSUPPORT; }
266 
267     // start
268     virtual bool ReadyToStart() = 0;
269     virtual int32_t AllocateBuffersOnPort(OMX_DIRTYPE portIndex) = 0;
270     void SetCallerToBuffer(int fd, uint32_t w, uint32_t h);
271     virtual void UpdateFmtFromSurfaceBuffer() = 0;
272     int32_t GetPortDefinition(OMX_DIRTYPE portIndex, OMX_PARAM_PORTDEFINITIONTYPE& def);
273     int32_t AllocateAvSurfaceBuffers(OMX_DIRTYPE portIndex);
274     int32_t AllocateAvLinearBuffers(OMX_DIRTYPE portIndex);
275     int32_t AllocateAvHardwareBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def);
276     int32_t AllocateAvSharedBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def);
277     std::shared_ptr<CodecHDI::OmxCodecBuffer> SurfaceBufferToOmxBuffer(
278         const sptr<SurfaceBuffer>& surfaceBuffer);
279     std::shared_ptr<CodecHDI::OmxCodecBuffer> DynamicSurfaceBufferToOmxBuffer();
280 
281     virtual int32_t SubmitAllBuffersOwnedByUs() = 0;
SubmitOutBufToOmx()282     virtual int32_t SubmitOutBufToOmx() { return AVCS_ERR_UNSUPPORT; }
283     BufferInfo* FindBufferInfoByID(OMX_DIRTYPE portIndex, uint32_t bufferId);
284     std::optional<size_t> FindBufferIndexByID(OMX_DIRTYPE portIndex, uint32_t bufferId);
285     virtual void OnGetBufferFromSurface(const ParamSP& param) = 0;
286     uint32_t UserFlagToOmxFlag(AVCodecBufferFlag userFlag);
287     AVCodecBufferFlag OmxFlagToUserFlag(uint32_t omxFlag);
288     bool WaitFence(const sptr<SyncFence>& fence);
289     void WrapSurfaceBufferToSlot(BufferInfo &info,
290         const sptr<SurfaceBuffer>& surfaceBuffer, int64_t pts, uint32_t flag);
291 
292     // input buffer circulation
293     virtual void NotifyUserToFillThisInBuffer(BufferInfo &info);
294     virtual void OnQueueInputBuffer(const MsgInfo &msg, BufferOperationMode mode);
295     int32_t OnQueueInputBuffer(BufferOperationMode mode, BufferInfo* info);
296     virtual void OnSignalEndOfInputStream(const MsgInfo &msg);
297     int32_t InBufUsToOmx(BufferInfo& info);
298     virtual void OnOMXEmptyBufferDone(uint32_t bufferId, BufferOperationMode mode) = 0;
RepeatIfNecessary(const ParamSP & param)299     virtual void RepeatIfNecessary(const ParamSP& param) {}
300     bool CheckBufPixFmt(const sptr<SurfaceBuffer>& buffer);
301 
302     // output buffer circulation
DynamicModeSubmitBuffer()303     virtual void DynamicModeSubmitBuffer() {}
DynamicModeSubmitIfEos()304     virtual void DynamicModeSubmitIfEos() {}
305     int32_t NotifyOmxToFillThisOutBuffer(BufferInfo &info);
306     void OnOMXFillBufferDone(const CodecHDI::OmxCodecBuffer& omxBuffer, BufferOperationMode mode);
307     void OnOMXFillBufferDone(BufferOperationMode mode, BufferInfo& info, size_t bufferIdx);
308     void OutBufUsToUser(BufferInfo &info);
309     void OnReleaseOutputBuffer(const MsgInfo &msg, BufferOperationMode mode);
310     void OnReleaseOutputBuffer(uint32_t bufferId, BufferOperationMode mode);
OnReleaseOutputBuffer(const BufferInfo & info)311     virtual void OnReleaseOutputBuffer(const BufferInfo &info) {}
312     virtual void OnRenderOutputBuffer(const MsgInfo &msg, BufferOperationMode mode);
BeforeCbOutToUser(BufferInfo & info)313     virtual void BeforeCbOutToUser(BufferInfo &info) {}
ProcSurfaceBufferToUser(const sptr<SurfaceBuffer> & buffer)314     virtual void ProcSurfaceBufferToUser(const sptr<SurfaceBuffer>& buffer) {}
ProcAVBufferToUser(std::shared_ptr<AVBuffer> avBuffer,std::shared_ptr<CodecHDI::OmxCodecBuffer> omxBuffer)315     virtual void ProcAVBufferToUser(std::shared_ptr<AVBuffer> avBuffer,
316         std::shared_ptr<CodecHDI::OmxCodecBuffer> omxBuffer) {}
317     void RecordBufferStatus(OMX_DIRTYPE portIndex, uint32_t bufferId, BufferOwner nextOwner);
SubmitBuffersToNextOwner()318     virtual void SubmitBuffersToNextOwner() {}
319 
320     // stop/release
321     void ReclaimBuffer(OMX_DIRTYPE portIndex, BufferOwner owner, bool erase = false);
322     bool IsAllBufferOwnedByUsOrSurface(OMX_DIRTYPE portIndex);
323     bool IsAllBufferOwnedByUsOrSurface();
324     void EraseOutBuffersOwnedByUsOrSurface();
325     void ClearBufferPool(OMX_DIRTYPE portIndex);
OnClearBufferPool(OMX_DIRTYPE portIndex)326     virtual void OnClearBufferPool(OMX_DIRTYPE portIndex) {}
327     virtual void EraseBufferFromPool(OMX_DIRTYPE portIndex, size_t i) = 0;
328     void FreeOmxBuffer(OMX_DIRTYPE portIndex, const BufferInfo& info);
OnEnterUninitializedState()329     virtual void OnEnterUninitializedState() {}
330 
331     // freeze
FreezeBuffers()332     virtual int32_t FreezeBuffers() { return AVCS_ERR_UNSUPPORT; }
ActiveBuffers()333     virtual int32_t ActiveBuffers() { return AVCS_ERR_UNSUPPORT; }
DecreaseFreq()334     virtual int32_t DecreaseFreq() { return AVCS_ERR_UNSUPPORT; }
RecoverFreq()335     virtual int32_t RecoverFreq() { return AVCS_ERR_UNSUPPORT; }
336 
337     // template
338     template <typename T>
InitOMXParam(T & param)339     static inline void InitOMXParam(T& param)
340     {
341         (void)memset_s(&param, sizeof(T), 0x0, sizeof(T));
342         param.nSize = sizeof(T);
343         param.nVersion.s.nVersionMajor = 1;
344     }
345 
346     template <typename T>
InitOMXParamExt(T & param)347     static inline void InitOMXParamExt(T& param)
348     {
349         (void)memset_s(&param, sizeof(T), 0x0, sizeof(T));
350         param.size = sizeof(T);
351         param.version.s.nVersionMajor = 1;
352     }
353 
354     template <typename T>
355     bool GetParameter(uint32_t index, T& param, bool isCfg = false)
356     {
357         int8_t* p = reinterpret_cast<int8_t*>(&param);
358         std::vector<int8_t> inVec(p, p + sizeof(T));
359         std::vector<int8_t> outVec;
360         int32_t ret = isCfg ? compNode_->GetConfig(index, inVec, outVec) :
361                               compNode_->GetParameter(index, inVec, outVec);
362         if (ret != HDF_SUCCESS) {
363             return false;
364         }
365         if (outVec.size() != sizeof(T)) {
366             return false;
367         }
368         ret = memcpy_s(&param, sizeof(T), outVec.data(), outVec.size());
369         if (ret != EOK) {
370             return false;
371         }
372         return true;
373     }
374 
375     template <typename T>
376     bool SetParameter(uint32_t index, const T& param, bool isCfg = false)
377     {
378         const int8_t* p = reinterpret_cast<const int8_t*>(&param);
379         std::vector<int8_t> inVec(p, p + sizeof(T));
380         int32_t ret = isCfg ? compNode_->SetConfig(index, inVec) :
381                               compNode_->SetParameter(index, inVec);
382         if (ret != HDF_SUCCESS) {
383             return false;
384         }
385         return true;
386     }
387 
AlignTo(uint32_t side,uint32_t align)388     static inline uint32_t AlignTo(uint32_t side, uint32_t align)
389     {
390         if (align == 0) {
391             return side;
392         }
393         return (side + align - 1) / align * align;
394     }
395 
396 protected:
397     CodecHDI::CodecCompCapability caps_;
398     OMX_VIDEO_CODINGTYPE codingType_;
399     bool isEncoder_;
400     bool isSecure_ = false;
401     std::string mime_;
402     uint32_t componentId_ = 0;
403     std::string compUniqueStr_;
404     int32_t instanceId_ = -1;
405     struct CallerInfo {
406         int32_t pid = -1;
407         std::string processName;
408     };
409     struct Caller {
410         CallerInfo playerCaller;
411         CallerInfo avcodecCaller;
412         CallerInfo app;
413         bool calledByAvcodec = true;
414     } caller_;
415     static std::shared_mutex g_mtx;
416     static std::unordered_map<std::string, HCodec::Caller> g_callers;
417 
418     bool debugMode_ = false;
419     bool disableDmaSwap_ = false;
420     DumpMode dumpMode_ = DUMP_NONE;
421     sptr<CodecHDI::ICodecCallback> compCb_ = nullptr;
422     sptr<CodecHDI::ICodecComponent> compNode_ = nullptr;
423     sptr<CodecHDI::ICodecComponentManager> compMgr_ = nullptr;
424 
425     std::shared_ptr<MediaCodecCallback> callback_;
426     PixelFmt configuredFmt_{};
427     BufferRequestConfig requestCfg_{};
428     std::shared_ptr<Format> configFormat_;
429     std::shared_ptr<Format> inputFormat_;
430     std::shared_ptr<Format> outputFormat_;
431 
432     std::vector<BufferInfo> inputBufferPool_;
433     std::vector<BufferInfo> outputBufferPool_;
434     std::queue<uint32_t> inputBufIdQueueToOmx_;
435     bool isBufferCirculating_ = false;
436     bool inputPortEos_ = false;
437     bool outputPortEos_ = false;
438     bool gotFirstInput_ = false;
439     bool gotFirstOutput_ = false;
440     bool outPortHasChanged_ = false;
441     int pid_ = -1;
442     bool isLpp_ = false;
443     double codecRate_ = 0.0;
444 
445     // VRR
446     bool isVrrInitialized_ = false;
447 #ifdef USE_VIDEO_PROCESSING_ENGINE
VrrPrediction(BufferInfo & info)448     virtual int32_t VrrPrediction(BufferInfo &info) { return AVCS_ERR_UNSUPPORT; }
449 #endif
450 
451     std::unordered_map<int64_t, TimePoint> inTimeMap_;
452     uint64_t onePtsInToOutTotalCostUs_ = 0;
453     static constexpr uint64_t PRINT_PER_FRAME = 400;
454     // used when buffer circulation stoped
455     static constexpr char KEY_LAST_OWNER_CHANGE_TIME[] = "lastOwnerChangeTime";
456     TimePoint lastOwnerChangeTime_;
457     bool circulateHasStopped_ = false;
458 
459     static constexpr char BUFFER_ID[] = "buffer-id";
460     static constexpr uint32_t WAIT_FENCE_MS = 1000;
461     static constexpr uint32_t STRIDE_ALIGNMENT = 32;
462     static constexpr double FRAME_RATE_COEFFICIENT = 65536.0;
463     static constexpr double BYTE_TO_MBIT = 8.0 / 1024.0 / 1024.0;
464 
465 private:
466     struct BaseState : State {
467     protected:
468         BaseState(HCodec *codec, const std::string &stateName,
469                   BufferOperationMode inputMode = KEEP_BUFFER, BufferOperationMode outputMode = KEEP_BUFFER)
StateBaseState470             : State(stateName), codec_(codec), inputMode_(inputMode), outputMode_(outputMode) {}
471         void OnMsgReceived(const MsgInfo &info) override;
472         void ReplyErrorCode(MsgId id, int32_t err);
473         void OnCodecEvent(const MsgInfo &info);
474         virtual void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2);
475         void OnGetFormat(const MsgInfo &info);
476         virtual void OnShutDown(const MsgInfo &info) = 0;
477         virtual void OnCheckIfStuck(const MsgInfo &info);
478         void OnForceShutDown(const MsgInfo &info);
OnStateExitedBaseState479         void OnStateExited() override { codec_->stateGeneration_++; }
480         void OnSetParameters(const MsgInfo &info);
481         void OnSuspend(const MsgInfo &info);
482         void OnResume(const MsgInfo &info);
483 
484     protected:
485         HCodec *codec_;
486         BufferOperationMode inputMode_;
487         BufferOperationMode outputMode_;
488     };
489 
490     struct UninitializedState : BaseState {
UninitializedStateUninitializedState491         explicit UninitializedState(HCodec *codec) : BaseState(codec, "Uninit") {}
492     private:
493         void OnStateEntered() override;
494         void OnMsgReceived(const MsgInfo &info) override;
495         void OnShutDown(const MsgInfo &info) override;
496     };
497 
498     struct InitializedState : BaseState {
InitializedStateInitializedState499         explicit InitializedState(HCodec *codec) : BaseState(codec, "Init") {}
500     private:
501         void OnStateEntered() override;
502         void ProcessShutDownFromRunning();
503         void OnMsgReceived(const MsgInfo &info) override;
504         void OnSetCallBack(const MsgInfo &info);
505         void OnConfigure(const MsgInfo &info);
506         void OnStart(const MsgInfo &info);
507         void OnShutDown(const MsgInfo &info) override;
508     };
509 
510     struct StartingState : BaseState {
StartingStateStartingState511         explicit StartingState(HCodec *codec) : BaseState(codec, "Start") {}
512     private:
513         void OnStateEntered() override;
514         void OnStateExited() override;
515         void OnMsgReceived(const MsgInfo &info) override;
516         int32_t AllocateBuffers();
517         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
518         void OnShutDown(const MsgInfo &info) override;
519         void ReplyStartMsg(int32_t errCode);
520         bool hasError_ = false;
521     };
522 
523     struct RunningState : BaseState {
RunningStateRunningState524         explicit RunningState(HCodec *codec) : BaseState(codec, "Run", RESUBMIT_BUFFER, RESUBMIT_BUFFER) {}
525     private:
526         void OnStateEntered() override;
527         void OnMsgReceived(const MsgInfo &info) override;
528         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
529         void OnShutDown(const MsgInfo &info) override;
530         void OnFlush(const MsgInfo &info);
531         void OnBufferRecycle(const MsgInfo &info);
532     };
533 
534     struct OutputPortChangedState : BaseState {
OutputPortChangedStateOutputPortChangedState535         explicit OutputPortChangedState(HCodec *codec)
536             : BaseState(codec, "OutChange", RESUBMIT_BUFFER, FREE_BUFFER) {}
537     private:
538         void OnStateEntered() override;
539         void OnMsgReceived(const MsgInfo &info) override;
540         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
541         void OnShutDown(const MsgInfo &info) override;
542         void HandleOutputPortDisabled();
543         void HandleOutputPortEnabled();
544         void OnFlush(const MsgInfo &info);
545         void OnCheckIfStuck(const MsgInfo &info) override;
546     };
547 
548     struct FlushingState : BaseState {
FlushingStateFlushingState549         explicit FlushingState(HCodec *codec) : BaseState(codec, "Flush") {}
550     private:
551         void OnStateEntered() override;
552         void OnMsgReceived(const MsgInfo &info) override;
553         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
554         void OnShutDown(const MsgInfo &info) override;
555         void ChangeStateIfWeOwnAllBuffers();
556         bool IsFlushCompleteOnAllPorts();
557         int32_t UpdateFlushStatusOnPorts(uint32_t data1, uint32_t data2);
558         bool flushCompleteFlag_[2] {false, false};
559     };
560 
561     struct StoppingState : BaseState {
StoppingStateStoppingState562         explicit StoppingState(HCodec *codec) : BaseState(codec, "Stop"),
563             omxNodeInIdleState_(false),
564             omxNodeIsChangingToLoadedState_(false) {}
565     private:
566         void OnStateEntered() override;
567         void OnMsgReceived(const MsgInfo &info) override;
568         void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override;
569         void OnShutDown(const MsgInfo &info) override;
570         void ChangeStateIfWeOwnAllBuffers();
571         void ChangeOmxNodeToLoadedState(bool forceToFreeBuffer);
572         bool omxNodeInIdleState_;
573         bool omxNodeIsChangingToLoadedState_;
574     };
575 
576     struct FrozenState : BaseState {
FrozenStateFrozenState577         explicit FrozenState(HCodec *codec) : BaseState(codec, "Frozen") {}
578     private:
579         void OnMsgReceived(const MsgInfo &info) override;
580         void OnShutDown(const MsgInfo &info) override;
581         void OnBufferWriteback(const MsgInfo &info);
582     };
583 
584     class HdiCallback : public CodecHDI::ICodecCallback {
585     public:
HdiCallback(std::weak_ptr<MsgToken> codec)586         explicit HdiCallback(std::weak_ptr<MsgToken> codec) : codec_(codec) { }
587         virtual ~HdiCallback() = default;
588         int32_t EventHandler(CodecHDI::CodecEventType event,
589                              const CodecHDI::EventInfo& info);
590         int32_t EmptyBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
591         int32_t FillBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer);
592     private:
593         std::weak_ptr<MsgToken> codec_;
594     };
595 
596 private:
597     int32_t DoSyncCall(MsgWhat msgType, std::function<void(ParamSP)> oper, uint32_t waitMs = FIVE_SECONDS_IN_MS);
598     int32_t DoSyncCallAndGetReply(MsgWhat msgType, std::function<void(ParamSP)> oper, ParamSP &reply,
599                                   uint32_t waitMs = FIVE_SECONDS_IN_MS);
600     void PrintCaller();
601     void PrintAllCaller();
602     void RemoveCaller();
603     int32_t OnAllocateComponent();
604     void ReleaseComponent();
605     void CleanUpOmxNode();
606     void ChangeOmxToTargetState(CodecHDI::CodecStateType &state,
607                                 CodecHDI::CodecStateType targetState);
608     bool RollOmxBackToLoaded();
609 
610     int32_t ForceShutdown(int32_t generation, bool isNeedNotifyCaller);
611     void SignalError(AVCodecErrorType errorType, int32_t errorCode);
612     void DeferMessage(const MsgInfo &info);
613     void ProcessDeferredMessages();
614     void ReplyToSyncMsgLater(const MsgInfo& msg);
615     bool GetFirstSyncMsgToReply(MsgInfo& msg);
616 
617 private:
618     static constexpr size_t MAX_HCODEC_BUFFER_SIZE = 8192 * 4096 * 4; // 8K RGBA
619     static constexpr uint32_t THREE_SECONDS_IN_US = 3'000'000;
620     static constexpr uint32_t ONE_SECONDS_IN_US = 1'000'000;
621     static constexpr uint32_t FIVE_SECONDS_IN_MS = 5'000;
622     static constexpr double HIGH_FPS = 120.0;
623     static constexpr char HISYSEVENT_DOMAIN_HCODEC[] = "AV_CODEC";
624 
625     std::shared_ptr<UninitializedState> uninitializedState_;
626     std::shared_ptr<InitializedState> initializedState_;
627     std::shared_ptr<StartingState> startingState_;
628     std::shared_ptr<RunningState> runningState_;
629     std::shared_ptr<OutputPortChangedState> outputPortChangedState_;
630     std::shared_ptr<FlushingState> flushingState_;
631     std::shared_ptr<StoppingState> stoppingState_;
632     std::shared_ptr<FrozenState> frozenState_;
633 
634     int32_t stateGeneration_ = 0;
635     bool isShutDownFromRunning_ = false;
636     bool notifyCallerAfterShutdownComplete_ = false;
637     bool keepComponentAllocated_ = false;
638     bool hasFatalError_ = false;
639     std::list<MsgInfo> deferredQueue_;
640     std::map<MsgType, std::queue<std::pair<MsgId, ParamSP>>> syncMsgToReply_;
641 }; // class HCodec
642 } // namespace OHOS::MediaAVCodec
643 #endif // HCODEC_HCODEC_H
644