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