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 // VRR 350 #ifdef USE_VIDEO_PROCESSING_ENGINE 351 bool isVrrInitialized_ = false; VrrPrediction(BufferInfo & info)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 389 private: 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); OnStateExitedBaseState403 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 { UninitializedStateUninitializedState413 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 { InitializedStateInitializedState421 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 { StartingStateStartingState433 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 { RunningStateRunningState446 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 { OutputPortChangedStateOutputPortChangedState456 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 { FlushingStateFlushingState470 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 { StoppingStateStoppingState483 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: HdiCallback(std::weak_ptr<HCodec> codec)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 509 private: 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 527 private: 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