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(¶m, 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(¶m, 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*>(¶m); 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(¶m, 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*>(¶m); 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