1da853ecaSopenharmony_ci/* 2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License. 5da853ecaSopenharmony_ci * You may obtain a copy of the License at 6da853ecaSopenharmony_ci * 7da853ecaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8da853ecaSopenharmony_ci * 9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and 13da853ecaSopenharmony_ci * limitations under the License. 14da853ecaSopenharmony_ci */ 15da853ecaSopenharmony_ci 16da853ecaSopenharmony_ci#ifndef HCODEC_HCODEC_H 17da853ecaSopenharmony_ci#define HCODEC_HCODEC_H 18da853ecaSopenharmony_ci 19da853ecaSopenharmony_ci#include <queue> 20da853ecaSopenharmony_ci#include <array> 21da853ecaSopenharmony_ci#include <functional> 22da853ecaSopenharmony_ci#include <unordered_set> 23da853ecaSopenharmony_ci#include "securec.h" 24da853ecaSopenharmony_ci#include "OMX_Component.h" // third_party/openmax/api/1.1.2 25da853ecaSopenharmony_ci#include "codecbase.h" 26da853ecaSopenharmony_ci#include "avcodec_errors.h" 27da853ecaSopenharmony_ci#include "state_machine.h" 28da853ecaSopenharmony_ci#include "codec_hdi.h" 29da853ecaSopenharmony_ci#include "type_converter.h" 30da853ecaSopenharmony_ci#include "buffer/avbuffer.h" 31da853ecaSopenharmony_ci#include "meta/meta_key.h" // foundation/multimedia/histreamer/interface/inner_api/ 32da853ecaSopenharmony_ci 33da853ecaSopenharmony_cinamespace OHOS::MediaAVCodec { 34da853ecaSopenharmony_ciclass HCodec : public CodecBase, protected StateMachine, public std::enable_shared_from_this<HCodec> { 35da853ecaSopenharmony_cipublic: 36da853ecaSopenharmony_ci static std::shared_ptr<HCodec> Create(const std::string &name); 37da853ecaSopenharmony_ci int32_t Init(Media::Meta &callerInfo) override; 38da853ecaSopenharmony_ci int32_t SetCallback(const std::shared_ptr<MediaCodecCallback> &callback) override; 39da853ecaSopenharmony_ci int32_t Configure(const Format &format) override; 40da853ecaSopenharmony_ci int32_t SetCustomBuffer(std::shared_ptr<AVBuffer> buffer) override; 41da853ecaSopenharmony_ci sptr<Surface> CreateInputSurface() override; 42da853ecaSopenharmony_ci int32_t SetInputSurface(sptr<Surface> surface) override; 43da853ecaSopenharmony_ci int32_t SetOutputSurface(sptr<Surface> surface) override; 44da853ecaSopenharmony_ci 45da853ecaSopenharmony_ci int32_t QueueInputBuffer(uint32_t index) override; 46da853ecaSopenharmony_ci int32_t NotifyEos() override; 47da853ecaSopenharmony_ci int32_t ReleaseOutputBuffer(uint32_t index) override; 48da853ecaSopenharmony_ci int32_t RenderOutputBuffer(uint32_t index) override; 49da853ecaSopenharmony_ci 50da853ecaSopenharmony_ci int32_t SignalRequestIDRFrame() override; 51da853ecaSopenharmony_ci int32_t SetParameter(const Format& format) override; 52da853ecaSopenharmony_ci int32_t GetInputFormat(Format& format) override; 53da853ecaSopenharmony_ci int32_t GetOutputFormat(Format& format) override; 54da853ecaSopenharmony_ci std::string GetHidumperInfo() override; 55da853ecaSopenharmony_ci 56da853ecaSopenharmony_ci int32_t Start() override; 57da853ecaSopenharmony_ci int32_t Stop() override; 58da853ecaSopenharmony_ci int32_t Flush() override; 59da853ecaSopenharmony_ci int32_t Reset() override; 60da853ecaSopenharmony_ci int32_t Release() override; 61da853ecaSopenharmony_ci virtual GSError OnBufferReleasedByConsumer(uint64_t surfaceId) { return GSERROR_OK; } 62da853ecaSopenharmony_ci 63da853ecaSopenharmony_ciprotected: 64da853ecaSopenharmony_ci enum MsgWhat : MsgType { 65da853ecaSopenharmony_ci INIT, 66da853ecaSopenharmony_ci SET_CALLBACK, 67da853ecaSopenharmony_ci CONFIGURE, 68da853ecaSopenharmony_ci CONFIGURE_BUFFER, 69da853ecaSopenharmony_ci CREATE_INPUT_SURFACE, 70da853ecaSopenharmony_ci SET_INPUT_SURFACE, 71da853ecaSopenharmony_ci SET_OUTPUT_SURFACE, 72da853ecaSopenharmony_ci START, 73da853ecaSopenharmony_ci GET_INPUT_FORMAT, 74da853ecaSopenharmony_ci GET_OUTPUT_FORMAT, 75da853ecaSopenharmony_ci SET_PARAMETERS, 76da853ecaSopenharmony_ci REQUEST_IDR_FRAME, 77da853ecaSopenharmony_ci FLUSH, 78da853ecaSopenharmony_ci QUEUE_INPUT_BUFFER, 79da853ecaSopenharmony_ci NOTIFY_EOS, 80da853ecaSopenharmony_ci RELEASE_OUTPUT_BUFFER, 81da853ecaSopenharmony_ci RENDER_OUTPUT_BUFFER, 82da853ecaSopenharmony_ci STOP, 83da853ecaSopenharmony_ci RELEASE, 84da853ecaSopenharmony_ci GET_HIDUMPER_INFO, 85da853ecaSopenharmony_ci PRINT_ALL_BUFFER_OWNER, 86da853ecaSopenharmony_ci 87da853ecaSopenharmony_ci INNER_MSG_BEGIN = 1000, 88da853ecaSopenharmony_ci CODEC_EVENT, 89da853ecaSopenharmony_ci OMX_EMPTY_BUFFER_DONE, 90da853ecaSopenharmony_ci OMX_FILL_BUFFER_DONE, 91da853ecaSopenharmony_ci GET_BUFFER_FROM_SURFACE, 92da853ecaSopenharmony_ci CHECK_IF_REPEAT, 93da853ecaSopenharmony_ci CHECK_IF_STUCK, 94da853ecaSopenharmony_ci FORCE_SHUTDOWN, 95da853ecaSopenharmony_ci }; 96da853ecaSopenharmony_ci 97da853ecaSopenharmony_ci enum BufferOperationMode { 98da853ecaSopenharmony_ci KEEP_BUFFER, 99da853ecaSopenharmony_ci RESUBMIT_BUFFER, 100da853ecaSopenharmony_ci FREE_BUFFER, 101da853ecaSopenharmony_ci }; 102da853ecaSopenharmony_ci 103da853ecaSopenharmony_ci enum BufferOwner { 104da853ecaSopenharmony_ci OWNED_BY_US = 0, 105da853ecaSopenharmony_ci OWNED_BY_USER = 1, 106da853ecaSopenharmony_ci OWNED_BY_OMX = 2, 107da853ecaSopenharmony_ci OWNED_BY_SURFACE = 3, 108da853ecaSopenharmony_ci OWNER_CNT = 4, 109da853ecaSopenharmony_ci }; 110da853ecaSopenharmony_ci 111da853ecaSopenharmony_ci struct PortInfo { 112da853ecaSopenharmony_ci uint32_t width = 0; 113da853ecaSopenharmony_ci uint32_t height = 0; 114da853ecaSopenharmony_ci OMX_VIDEO_CODINGTYPE codingType; 115da853ecaSopenharmony_ci std::optional<PixelFmt> pixelFmt; 116da853ecaSopenharmony_ci double frameRate; 117da853ecaSopenharmony_ci std::optional<uint32_t> inputBufSize; 118da853ecaSopenharmony_ci }; 119da853ecaSopenharmony_ci 120da853ecaSopenharmony_ci enum DumpMode : unsigned long { 121da853ecaSopenharmony_ci DUMP_NONE = 0, 122da853ecaSopenharmony_ci DUMP_ENCODER_INPUT = 0b1000, 123da853ecaSopenharmony_ci DUMP_ENCODER_OUTPUT = 0b0100, 124da853ecaSopenharmony_ci DUMP_DECODER_INPUT = 0b0010, 125da853ecaSopenharmony_ci DUMP_DECODER_OUTPUT = 0b0001, 126da853ecaSopenharmony_ci }; 127da853ecaSopenharmony_ci 128da853ecaSopenharmony_ci struct BufferInfo { 129da853ecaSopenharmony_ci BufferInfo() : lastOwnerChangeTime(std::chrono::steady_clock::now()) {} 130da853ecaSopenharmony_ci bool isInput = true; 131da853ecaSopenharmony_ci BufferOwner owner = OWNED_BY_US; 132da853ecaSopenharmony_ci std::chrono::time_point<std::chrono::steady_clock> lastOwnerChangeTime; 133da853ecaSopenharmony_ci int64_t lastFlushTime = 0; 134da853ecaSopenharmony_ci uint32_t bufferId = 0; 135da853ecaSopenharmony_ci std::shared_ptr<CodecHDI::OmxCodecBuffer> omxBuffer; 136da853ecaSopenharmony_ci std::shared_ptr<AVBuffer> avBuffer; 137da853ecaSopenharmony_ci sptr<SurfaceBuffer> surfaceBuffer; 138da853ecaSopenharmony_ci bool needDealWithCache = false; 139da853ecaSopenharmony_ci 140da853ecaSopenharmony_ci void CleanUpUnusedInfo(); 141da853ecaSopenharmony_ci void BeginCpuAccess(); 142da853ecaSopenharmony_ci void EndCpuAccess(); 143da853ecaSopenharmony_ci bool IsValidFrame() const; 144da853ecaSopenharmony_ci#ifdef BUILD_ENG_VERSION 145da853ecaSopenharmony_ci void Dump(const std::string& prefix, uint64_t cnt, DumpMode dumpMode, bool isEncoder) const; 146da853ecaSopenharmony_ci 147da853ecaSopenharmony_ci private: 148da853ecaSopenharmony_ci void Dump(const std::string& prefix, uint64_t cnt) const; 149da853ecaSopenharmony_ci void DumpSurfaceBuffer(const std::string& prefix, uint64_t cnt) const; 150da853ecaSopenharmony_ci void DecideDumpInfo(int& alignedH, uint32_t& totalSize, std::string& suffix, bool& dumpAsVideo) const; 151da853ecaSopenharmony_ci void DumpLinearBuffer(const std::string& prefix) const; 152da853ecaSopenharmony_ci static constexpr char DUMP_PATH[] = "/data/misc/hcodecdump"; 153da853ecaSopenharmony_ci#endif 154da853ecaSopenharmony_ci }; 155da853ecaSopenharmony_ci 156da853ecaSopenharmony_ciprotected: 157da853ecaSopenharmony_ci HCodec(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType, bool isEncoder); 158da853ecaSopenharmony_ci ~HCodec() override; 159da853ecaSopenharmony_ci static const char* ToString(MsgWhat what); 160da853ecaSopenharmony_ci static const char* ToString(BufferOwner owner); 161da853ecaSopenharmony_ci void ReplyErrorCode(MsgId id, int32_t err); 162da853ecaSopenharmony_ci void OnPrintAllBufferOwner(const MsgInfo& msg); 163da853ecaSopenharmony_ci void PrintAllBufferInfo(); 164da853ecaSopenharmony_ci void PrintAllBufferInfo(bool isInput, std::chrono::time_point<std::chrono::steady_clock> now); 165da853ecaSopenharmony_ci void PrintStatistic(bool isInput, std::chrono::time_point<std::chrono::steady_clock> now); 166da853ecaSopenharmony_ci std::string OnGetHidumperInfo(); 167da853ecaSopenharmony_ci void UpdateOwner(); 168da853ecaSopenharmony_ci void UpdateOwner(bool isInput); 169da853ecaSopenharmony_ci void ReduceOwner(bool isInput, BufferOwner owner); 170da853ecaSopenharmony_ci void ChangeOwner(BufferInfo& info, BufferOwner newOwner); 171da853ecaSopenharmony_ci void ChangeOwnerNormal(BufferInfo& info, BufferOwner newOwner); 172da853ecaSopenharmony_ci void ChangeOwnerDebug(BufferInfo& info, BufferOwner newOwner); 173da853ecaSopenharmony_ci void UpdateInputRecord(const BufferInfo& info, std::chrono::time_point<std::chrono::steady_clock> now); 174da853ecaSopenharmony_ci void UpdateOutputRecord(const BufferInfo& info, std::chrono::time_point<std::chrono::steady_clock> now); 175da853ecaSopenharmony_ci 176da853ecaSopenharmony_ci // configure 177da853ecaSopenharmony_ci virtual int32_t OnConfigure(const Format &format) = 0; 178da853ecaSopenharmony_ci virtual int32_t OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer) { return AVCS_ERR_UNSUPPORT; } 179da853ecaSopenharmony_ci bool GetPixelFmtFromUser(const Format &format); 180da853ecaSopenharmony_ci static std::optional<double> GetFrameRateFromUser(const Format &format); 181da853ecaSopenharmony_ci int32_t SetVideoPortInfo(OMX_DIRTYPE portIndex, const PortInfo& info); 182da853ecaSopenharmony_ci virtual int32_t UpdateInPortFormat() = 0; 183da853ecaSopenharmony_ci virtual int32_t UpdateOutPortFormat() = 0; 184da853ecaSopenharmony_ci virtual void UpdateColorAspects() {} 185da853ecaSopenharmony_ci void PrintPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& def); 186da853ecaSopenharmony_ci int32_t SetFrameRateAdaptiveMode(const Format &format); 187da853ecaSopenharmony_ci int32_t SetProcessName(); 188da853ecaSopenharmony_ci int32_t SetLowLatency(const Format &format); 189da853ecaSopenharmony_ci 190da853ecaSopenharmony_ci virtual void OnSetOutputSurface(const MsgInfo &msg, BufferOperationMode mode); 191da853ecaSopenharmony_ci virtual int32_t OnSetParameters(const Format &format) { return AVCS_ERR_OK; } 192da853ecaSopenharmony_ci virtual sptr<Surface> OnCreateInputSurface() { return nullptr; } 193da853ecaSopenharmony_ci virtual int32_t OnSetInputSurface(sptr<Surface> &inputSurface) { return AVCS_ERR_UNSUPPORT; } 194da853ecaSopenharmony_ci virtual int32_t RequestIDRFrame() { return AVCS_ERR_UNSUPPORT; } 195da853ecaSopenharmony_ci 196da853ecaSopenharmony_ci // start 197da853ecaSopenharmony_ci virtual bool ReadyToStart() = 0; 198da853ecaSopenharmony_ci virtual int32_t AllocateBuffersOnPort(OMX_DIRTYPE portIndex) = 0; 199da853ecaSopenharmony_ci virtual void SetCallerToBuffer(int fd) {} 200da853ecaSopenharmony_ci virtual void UpdateFormatFromSurfaceBuffer() = 0; 201da853ecaSopenharmony_ci int32_t GetPortDefinition(OMX_DIRTYPE portIndex, OMX_PARAM_PORTDEFINITIONTYPE& def); 202da853ecaSopenharmony_ci int32_t AllocateAvSurfaceBuffers(OMX_DIRTYPE portIndex); 203da853ecaSopenharmony_ci int32_t AllocateAvLinearBuffers(OMX_DIRTYPE portIndex); 204da853ecaSopenharmony_ci int32_t AllocateAvHardwareBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def); 205da853ecaSopenharmony_ci int32_t AllocateAvSharedBuffers(OMX_DIRTYPE portIndex, const OMX_PARAM_PORTDEFINITIONTYPE& def); 206da853ecaSopenharmony_ci std::shared_ptr<CodecHDI::OmxCodecBuffer> SurfaceBufferToOmxBuffer( 207da853ecaSopenharmony_ci const sptr<SurfaceBuffer>& surfaceBuffer); 208da853ecaSopenharmony_ci std::shared_ptr<CodecHDI::OmxCodecBuffer> DynamicSurfaceBufferToOmxBuffer(); 209da853ecaSopenharmony_ci 210da853ecaSopenharmony_ci virtual int32_t SubmitAllBuffersOwnedByUs() = 0; 211da853ecaSopenharmony_ci virtual int32_t SubmitOutputBuffersToOmxNode() { return AVCS_ERR_UNSUPPORT; } 212da853ecaSopenharmony_ci BufferInfo* FindBufferInfoByID(OMX_DIRTYPE portIndex, uint32_t bufferId); 213da853ecaSopenharmony_ci std::optional<size_t> FindBufferIndexByID(OMX_DIRTYPE portIndex, uint32_t bufferId); 214da853ecaSopenharmony_ci virtual void OnGetBufferFromSurface(const ParamSP& param) = 0; 215da853ecaSopenharmony_ci uint32_t UserFlagToOmxFlag(AVCodecBufferFlag userFlag); 216da853ecaSopenharmony_ci AVCodecBufferFlag OmxFlagToUserFlag(uint32_t omxFlag); 217da853ecaSopenharmony_ci bool WaitFence(const sptr<SyncFence>& fence); 218da853ecaSopenharmony_ci void WrapSurfaceBufferToSlot(BufferInfo &info, 219da853ecaSopenharmony_ci const sptr<SurfaceBuffer>& surfaceBuffer, int64_t pts, uint32_t flag); 220da853ecaSopenharmony_ci 221da853ecaSopenharmony_ci // input buffer circulation 222da853ecaSopenharmony_ci virtual void NotifyUserToFillThisInBuffer(BufferInfo &info); 223da853ecaSopenharmony_ci virtual void OnQueueInputBuffer(const MsgInfo &msg, BufferOperationMode mode); 224da853ecaSopenharmony_ci int32_t OnQueueInputBuffer(BufferOperationMode mode, BufferInfo* info); 225da853ecaSopenharmony_ci virtual void OnSignalEndOfInputStream(const MsgInfo &msg); 226da853ecaSopenharmony_ci int32_t NotifyOmxToEmptyThisInBuffer(BufferInfo& info); 227da853ecaSopenharmony_ci virtual void OnOMXEmptyBufferDone(uint32_t bufferId, BufferOperationMode mode) = 0; 228da853ecaSopenharmony_ci virtual void RepeatIfNecessary(const ParamSP& param) {} 229da853ecaSopenharmony_ci bool CheckBufPixFmt(const sptr<SurfaceBuffer>& buffer); 230da853ecaSopenharmony_ci 231da853ecaSopenharmony_ci // output buffer circulation 232da853ecaSopenharmony_ci virtual void DynamicModeSubmitBuffer() {} 233da853ecaSopenharmony_ci int32_t NotifyOmxToFillThisOutBuffer(BufferInfo &info); 234da853ecaSopenharmony_ci void OnOMXFillBufferDone(const CodecHDI::OmxCodecBuffer& omxBuffer, BufferOperationMode mode); 235da853ecaSopenharmony_ci void OnOMXFillBufferDone(BufferOperationMode mode, BufferInfo& info, size_t bufferIdx); 236da853ecaSopenharmony_ci void NotifyUserOutBufferAvaliable(BufferInfo &info); 237da853ecaSopenharmony_ci void OnReleaseOutputBuffer(const MsgInfo &msg, BufferOperationMode mode); 238da853ecaSopenharmony_ci virtual void OnReleaseOutputBuffer(const BufferInfo &info) {} 239da853ecaSopenharmony_ci virtual void OnRenderOutputBuffer(const MsgInfo &msg, BufferOperationMode mode); 240da853ecaSopenharmony_ci virtual void ExtractPerFrameParamFromOmxBuffer( 241da853ecaSopenharmony_ci const std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer, 242da853ecaSopenharmony_ci std::shared_ptr<Media::Meta> &meta) {} 243da853ecaSopenharmony_ci 244da853ecaSopenharmony_ci // stop/release 245da853ecaSopenharmony_ci void ReclaimBuffer(OMX_DIRTYPE portIndex, BufferOwner owner, bool erase = false); 246da853ecaSopenharmony_ci bool IsAllBufferOwnedByUsOrSurface(OMX_DIRTYPE portIndex); 247da853ecaSopenharmony_ci bool IsAllBufferOwnedByUsOrSurface(); 248da853ecaSopenharmony_ci void EraseOutBuffersOwnedByUsOrSurface(); 249da853ecaSopenharmony_ci void ClearBufferPool(OMX_DIRTYPE portIndex); 250da853ecaSopenharmony_ci virtual void OnClearBufferPool(OMX_DIRTYPE portIndex) {} 251da853ecaSopenharmony_ci virtual void EraseBufferFromPool(OMX_DIRTYPE portIndex, size_t i) = 0; 252da853ecaSopenharmony_ci void FreeOmxBuffer(OMX_DIRTYPE portIndex, const BufferInfo& info); 253da853ecaSopenharmony_ci virtual void OnEnterUninitializedState() {} 254da853ecaSopenharmony_ci 255da853ecaSopenharmony_ci // template 256da853ecaSopenharmony_ci template <typename T> 257da853ecaSopenharmony_ci static inline void InitOMXParam(T& param) 258da853ecaSopenharmony_ci { 259da853ecaSopenharmony_ci (void)memset_s(¶m, sizeof(T), 0x0, sizeof(T)); 260da853ecaSopenharmony_ci param.nSize = sizeof(T); 261da853ecaSopenharmony_ci param.nVersion.s.nVersionMajor = 1; 262da853ecaSopenharmony_ci } 263da853ecaSopenharmony_ci 264da853ecaSopenharmony_ci template <typename T> 265da853ecaSopenharmony_ci static inline void InitOMXParamExt(T& param) 266da853ecaSopenharmony_ci { 267da853ecaSopenharmony_ci (void)memset_s(¶m, sizeof(T), 0x0, sizeof(T)); 268da853ecaSopenharmony_ci param.size = sizeof(T); 269da853ecaSopenharmony_ci param.version.s.nVersionMajor = 1; 270da853ecaSopenharmony_ci } 271da853ecaSopenharmony_ci 272da853ecaSopenharmony_ci template <typename T> 273da853ecaSopenharmony_ci bool GetParameter(uint32_t index, T& param, bool isCfg = false) 274da853ecaSopenharmony_ci { 275da853ecaSopenharmony_ci int8_t* p = reinterpret_cast<int8_t*>(¶m); 276da853ecaSopenharmony_ci std::vector<int8_t> inVec(p, p + sizeof(T)); 277da853ecaSopenharmony_ci std::vector<int8_t> outVec; 278da853ecaSopenharmony_ci int32_t ret = isCfg ? compNode_->GetConfig(index, inVec, outVec) : 279da853ecaSopenharmony_ci compNode_->GetParameter(index, inVec, outVec); 280da853ecaSopenharmony_ci if (ret != HDF_SUCCESS) { 281da853ecaSopenharmony_ci return false; 282da853ecaSopenharmony_ci } 283da853ecaSopenharmony_ci if (outVec.size() != sizeof(T)) { 284da853ecaSopenharmony_ci return false; 285da853ecaSopenharmony_ci } 286da853ecaSopenharmony_ci ret = memcpy_s(¶m, sizeof(T), outVec.data(), outVec.size()); 287da853ecaSopenharmony_ci if (ret != EOK) { 288da853ecaSopenharmony_ci return false; 289da853ecaSopenharmony_ci } 290da853ecaSopenharmony_ci return true; 291da853ecaSopenharmony_ci } 292da853ecaSopenharmony_ci 293da853ecaSopenharmony_ci template <typename T> 294da853ecaSopenharmony_ci bool SetParameter(uint32_t index, const T& param, bool isCfg = false) 295da853ecaSopenharmony_ci { 296da853ecaSopenharmony_ci const int8_t* p = reinterpret_cast<const int8_t*>(¶m); 297da853ecaSopenharmony_ci std::vector<int8_t> inVec(p, p + sizeof(T)); 298da853ecaSopenharmony_ci int32_t ret = isCfg ? compNode_->SetConfig(index, inVec) : 299da853ecaSopenharmony_ci compNode_->SetParameter(index, inVec); 300da853ecaSopenharmony_ci if (ret != HDF_SUCCESS) { 301da853ecaSopenharmony_ci return false; 302da853ecaSopenharmony_ci } 303da853ecaSopenharmony_ci return true; 304da853ecaSopenharmony_ci } 305da853ecaSopenharmony_ci 306da853ecaSopenharmony_ci static inline uint32_t AlignTo(uint32_t side, uint32_t align) 307da853ecaSopenharmony_ci { 308da853ecaSopenharmony_ci if (align == 0) { 309da853ecaSopenharmony_ci return side; 310da853ecaSopenharmony_ci } 311da853ecaSopenharmony_ci return (side + align - 1) / align * align; 312da853ecaSopenharmony_ci } 313da853ecaSopenharmony_ci 314da853ecaSopenharmony_ciprotected: 315da853ecaSopenharmony_ci CodecHDI::CodecCompCapability caps_; 316da853ecaSopenharmony_ci OMX_VIDEO_CODINGTYPE codingType_; 317da853ecaSopenharmony_ci bool isEncoder_; 318da853ecaSopenharmony_ci bool isSecure_ = false; 319da853ecaSopenharmony_ci std::string shortName_; 320da853ecaSopenharmony_ci uint32_t componentId_ = 0; 321da853ecaSopenharmony_ci std::string compUniqueStr_; 322da853ecaSopenharmony_ci struct CallerInfo { 323da853ecaSopenharmony_ci int32_t pid = -1; 324da853ecaSopenharmony_ci std::string processName; 325da853ecaSopenharmony_ci } playerCaller_, avcodecCaller_; 326da853ecaSopenharmony_ci bool calledByAvcodec_ = true; 327da853ecaSopenharmony_ci bool debugMode_ = false; 328da853ecaSopenharmony_ci DumpMode dumpMode_ = DUMP_NONE; 329da853ecaSopenharmony_ci sptr<CodecHDI::ICodecCallback> compCb_ = nullptr; 330da853ecaSopenharmony_ci sptr<CodecHDI::ICodecComponent> compNode_ = nullptr; 331da853ecaSopenharmony_ci sptr<CodecHDI::ICodecComponentManager> compMgr_ = nullptr; 332da853ecaSopenharmony_ci 333da853ecaSopenharmony_ci std::shared_ptr<MediaCodecCallback> callback_; 334da853ecaSopenharmony_ci PixelFmt configuredFmt_{}; 335da853ecaSopenharmony_ci BufferRequestConfig requestCfg_{}; 336da853ecaSopenharmony_ci std::shared_ptr<Format> configFormat_; 337da853ecaSopenharmony_ci std::shared_ptr<Format> inputFormat_; 338da853ecaSopenharmony_ci std::shared_ptr<Format> outputFormat_; 339da853ecaSopenharmony_ci 340da853ecaSopenharmony_ci std::vector<BufferInfo> inputBufferPool_; 341da853ecaSopenharmony_ci std::vector<BufferInfo> outputBufferPool_; 342da853ecaSopenharmony_ci bool isBufferCirculating_ = false; 343da853ecaSopenharmony_ci bool inputPortEos_ = false; 344da853ecaSopenharmony_ci bool outputPortEos_ = false; 345da853ecaSopenharmony_ci bool gotFirstInput_ = false; 346da853ecaSopenharmony_ci bool gotFirstOutput_ = false; 347da853ecaSopenharmony_ci bool outPortHasChanged_ = false; 348da853ecaSopenharmony_ci 349da853ecaSopenharmony_ci // VRR 350da853ecaSopenharmony_ci#ifdef USE_VIDEO_PROCESSING_ENGINE 351da853ecaSopenharmony_ci bool isVrrEnable_ = false; 352da853ecaSopenharmony_ci virtual int32_t VrrPrediction(BufferInfo &info) { return AVCS_ERR_UNSUPPORT; } 353da853ecaSopenharmony_ci#endif 354da853ecaSopenharmony_ci 355da853ecaSopenharmony_ci struct TotalCntAndCost { 356da853ecaSopenharmony_ci uint64_t totalCnt = 0; 357da853ecaSopenharmony_ci uint64_t totalCostUs = 0; 358da853ecaSopenharmony_ci }; 359da853ecaSopenharmony_ci 360da853ecaSopenharmony_ci // whole lift time 361da853ecaSopenharmony_ci uint64_t inTotalCnt_ = 0; 362da853ecaSopenharmony_ci TotalCntAndCost outRecord_; 363da853ecaSopenharmony_ci std::unordered_map<int64_t, std::chrono::time_point<std::chrono::steady_clock>> inTimeMap_; 364da853ecaSopenharmony_ci 365da853ecaSopenharmony_ci // normal: every 200 frames, debug: whole life time 366da853ecaSopenharmony_ci static constexpr uint64_t PRINT_PER_FRAME = 200; 367da853ecaSopenharmony_ci std::array<TotalCntAndCost, OWNER_CNT> inputHoldTimeRecord_; 368da853ecaSopenharmony_ci std::array<TotalCntAndCost, OWNER_CNT> outputHoldTimeRecord_; 369da853ecaSopenharmony_ci std::chrono::time_point<std::chrono::steady_clock> firstInTime_; 370da853ecaSopenharmony_ci std::chrono::time_point<std::chrono::steady_clock> firstOutTime_; 371da853ecaSopenharmony_ci 372da853ecaSopenharmony_ci // used when buffer circulation stoped 373da853ecaSopenharmony_ci static constexpr char KEY_LAST_OWNER_CHANGE_TIME[] = "lastOwnerChangeTime"; 374da853ecaSopenharmony_ci std::chrono::time_point<std::chrono::steady_clock> lastOwnerChangeTime_; 375da853ecaSopenharmony_ci uint32_t circulateWarnPrintedTimes_ = 0; 376da853ecaSopenharmony_ci static constexpr uint32_t MAX_CIRCULATE_WARN_TIMES = 3; 377da853ecaSopenharmony_ci 378da853ecaSopenharmony_ci std::array<int, HCodec::OWNER_CNT> inputOwner_ {}; 379da853ecaSopenharmony_ci std::array<std::string, HCodec::OWNER_CNT> inputOwnerStr_ {}; 380da853ecaSopenharmony_ci std::array<int, HCodec::OWNER_CNT> outputOwner_ {}; 381da853ecaSopenharmony_ci std::array<std::string, HCodec::OWNER_CNT> outputOwnerStr_ {}; 382da853ecaSopenharmony_ci 383da853ecaSopenharmony_ci static constexpr char BUFFER_ID[] = "buffer-id"; 384da853ecaSopenharmony_ci static constexpr uint32_t WAIT_FENCE_MS = 1000; 385da853ecaSopenharmony_ci static constexpr uint32_t WARN_FENCE_MS = 30; 386da853ecaSopenharmony_ci static constexpr uint32_t STRIDE_ALIGNMENT = 32; 387da853ecaSopenharmony_ci static constexpr double FRAME_RATE_COEFFICIENT = 65536.0; 388da853ecaSopenharmony_ci 389da853ecaSopenharmony_ciprivate: 390da853ecaSopenharmony_ci struct BaseState : State { 391da853ecaSopenharmony_ci protected: 392da853ecaSopenharmony_ci BaseState(HCodec *codec, const std::string &stateName, 393da853ecaSopenharmony_ci BufferOperationMode inputMode = KEEP_BUFFER, BufferOperationMode outputMode = KEEP_BUFFER) 394da853ecaSopenharmony_ci : State(stateName), codec_(codec), inputMode_(inputMode), outputMode_(outputMode) {} 395da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 396da853ecaSopenharmony_ci void ReplyErrorCode(MsgId id, int32_t err); 397da853ecaSopenharmony_ci void OnCodecEvent(const MsgInfo &info); 398da853ecaSopenharmony_ci virtual void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2); 399da853ecaSopenharmony_ci void OnGetFormat(const MsgInfo &info); 400da853ecaSopenharmony_ci virtual void OnShutDown(const MsgInfo &info) = 0; 401da853ecaSopenharmony_ci virtual void OnCheckIfStuck(const MsgInfo &info); 402da853ecaSopenharmony_ci void OnForceShutDown(const MsgInfo &info); 403da853ecaSopenharmony_ci void OnStateExited() override { codec_->stateGeneration_++; } 404da853ecaSopenharmony_ci void OnSetParameters(const MsgInfo &info); 405da853ecaSopenharmony_ci 406da853ecaSopenharmony_ci protected: 407da853ecaSopenharmony_ci HCodec *codec_; 408da853ecaSopenharmony_ci BufferOperationMode inputMode_; 409da853ecaSopenharmony_ci BufferOperationMode outputMode_; 410da853ecaSopenharmony_ci }; 411da853ecaSopenharmony_ci 412da853ecaSopenharmony_ci struct UninitializedState : BaseState { 413da853ecaSopenharmony_ci explicit UninitializedState(HCodec *codec) : BaseState(codec, "Uninitialized") {} 414da853ecaSopenharmony_ci private: 415da853ecaSopenharmony_ci void OnStateEntered() override; 416da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 417da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 418da853ecaSopenharmony_ci }; 419da853ecaSopenharmony_ci 420da853ecaSopenharmony_ci struct InitializedState : BaseState { 421da853ecaSopenharmony_ci explicit InitializedState(HCodec *codec) : BaseState(codec, "Initialized") {} 422da853ecaSopenharmony_ci private: 423da853ecaSopenharmony_ci void OnStateEntered() override; 424da853ecaSopenharmony_ci void ProcessShutDownFromRunning(); 425da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 426da853ecaSopenharmony_ci void OnSetCallBack(const MsgInfo &info); 427da853ecaSopenharmony_ci void OnConfigure(const MsgInfo &info); 428da853ecaSopenharmony_ci void OnStart(const MsgInfo &info); 429da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 430da853ecaSopenharmony_ci }; 431da853ecaSopenharmony_ci 432da853ecaSopenharmony_ci struct StartingState : BaseState { 433da853ecaSopenharmony_ci explicit StartingState(HCodec *codec) : BaseState(codec, "Starting") {} 434da853ecaSopenharmony_ci private: 435da853ecaSopenharmony_ci void OnStateEntered() override; 436da853ecaSopenharmony_ci void OnStateExited() override; 437da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 438da853ecaSopenharmony_ci int32_t AllocateBuffers(); 439da853ecaSopenharmony_ci void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override; 440da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 441da853ecaSopenharmony_ci void ReplyStartMsg(int32_t errCode); 442da853ecaSopenharmony_ci bool hasError_ = false; 443da853ecaSopenharmony_ci }; 444da853ecaSopenharmony_ci 445da853ecaSopenharmony_ci struct RunningState : BaseState { 446da853ecaSopenharmony_ci explicit RunningState(HCodec *codec) : BaseState(codec, "Running", RESUBMIT_BUFFER, RESUBMIT_BUFFER) {} 447da853ecaSopenharmony_ci private: 448da853ecaSopenharmony_ci void OnStateEntered() override; 449da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 450da853ecaSopenharmony_ci void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override; 451da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 452da853ecaSopenharmony_ci void OnFlush(const MsgInfo &info); 453da853ecaSopenharmony_ci }; 454da853ecaSopenharmony_ci 455da853ecaSopenharmony_ci struct OutputPortChangedState : BaseState { 456da853ecaSopenharmony_ci explicit OutputPortChangedState(HCodec *codec) 457da853ecaSopenharmony_ci : BaseState(codec, "OutputPortChanged", RESUBMIT_BUFFER, FREE_BUFFER) {} 458da853ecaSopenharmony_ci private: 459da853ecaSopenharmony_ci void OnStateEntered() override; 460da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 461da853ecaSopenharmony_ci void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override; 462da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 463da853ecaSopenharmony_ci void HandleOutputPortDisabled(); 464da853ecaSopenharmony_ci void HandleOutputPortEnabled(); 465da853ecaSopenharmony_ci void OnFlush(const MsgInfo &info); 466da853ecaSopenharmony_ci void OnCheckIfStuck(const MsgInfo &info) override; 467da853ecaSopenharmony_ci }; 468da853ecaSopenharmony_ci 469da853ecaSopenharmony_ci struct FlushingState : BaseState { 470da853ecaSopenharmony_ci explicit FlushingState(HCodec *codec) : BaseState(codec, "Flushing") {} 471da853ecaSopenharmony_ci private: 472da853ecaSopenharmony_ci void OnStateEntered() override; 473da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 474da853ecaSopenharmony_ci void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override; 475da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 476da853ecaSopenharmony_ci void ChangeStateIfWeOwnAllBuffers(); 477da853ecaSopenharmony_ci bool IsFlushCompleteOnAllPorts(); 478da853ecaSopenharmony_ci int32_t UpdateFlushStatusOnPorts(uint32_t data1, uint32_t data2); 479da853ecaSopenharmony_ci bool flushCompleteFlag_[2] {false, false}; 480da853ecaSopenharmony_ci }; 481da853ecaSopenharmony_ci 482da853ecaSopenharmony_ci struct StoppingState : BaseState { 483da853ecaSopenharmony_ci explicit StoppingState(HCodec *codec) : BaseState(codec, "Stopping"), 484da853ecaSopenharmony_ci omxNodeInIdleState_(false), 485da853ecaSopenharmony_ci omxNodeIsChangingToLoadedState_(false) {} 486da853ecaSopenharmony_ci private: 487da853ecaSopenharmony_ci void OnStateEntered() override; 488da853ecaSopenharmony_ci void OnMsgReceived(const MsgInfo &info) override; 489da853ecaSopenharmony_ci void OnCodecEvent(CodecHDI::CodecEventType event, uint32_t data1, uint32_t data2) override; 490da853ecaSopenharmony_ci void OnShutDown(const MsgInfo &info) override; 491da853ecaSopenharmony_ci void ChangeStateIfWeOwnAllBuffers(); 492da853ecaSopenharmony_ci void ChangeOmxNodeToLoadedState(bool forceToFreeBuffer); 493da853ecaSopenharmony_ci bool omxNodeInIdleState_; 494da853ecaSopenharmony_ci bool omxNodeIsChangingToLoadedState_; 495da853ecaSopenharmony_ci }; 496da853ecaSopenharmony_ci 497da853ecaSopenharmony_ci class HdiCallback : public CodecHDI::ICodecCallback { 498da853ecaSopenharmony_ci public: 499da853ecaSopenharmony_ci explicit HdiCallback(std::weak_ptr<HCodec> codec) : codec_(codec) { } 500da853ecaSopenharmony_ci virtual ~HdiCallback() = default; 501da853ecaSopenharmony_ci int32_t EventHandler(CodecHDI::CodecEventType event, 502da853ecaSopenharmony_ci const CodecHDI::EventInfo& info); 503da853ecaSopenharmony_ci int32_t EmptyBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer); 504da853ecaSopenharmony_ci int32_t FillBufferDone(int64_t appData, const CodecHDI::OmxCodecBuffer& buffer); 505da853ecaSopenharmony_ci private: 506da853ecaSopenharmony_ci std::weak_ptr<HCodec> codec_; 507da853ecaSopenharmony_ci }; 508da853ecaSopenharmony_ci 509da853ecaSopenharmony_ciprivate: 510da853ecaSopenharmony_ci int32_t DoSyncCall(MsgWhat msgType, std::function<void(ParamSP)> oper); 511da853ecaSopenharmony_ci int32_t DoSyncCallAndGetReply(MsgWhat msgType, std::function<void(ParamSP)> oper, ParamSP &reply); 512da853ecaSopenharmony_ci void PrintCaller(); 513da853ecaSopenharmony_ci int32_t OnAllocateComponent(); 514da853ecaSopenharmony_ci void ReleaseComponent(); 515da853ecaSopenharmony_ci void CleanUpOmxNode(); 516da853ecaSopenharmony_ci void ChangeOmxToTargetState(CodecHDI::CodecStateType &state, 517da853ecaSopenharmony_ci CodecHDI::CodecStateType targetState); 518da853ecaSopenharmony_ci bool RollOmxBackToLoaded(); 519da853ecaSopenharmony_ci 520da853ecaSopenharmony_ci int32_t ForceShutdown(int32_t generation, bool isNeedNotifyCaller); 521da853ecaSopenharmony_ci void SignalError(AVCodecErrorType errorType, int32_t errorCode); 522da853ecaSopenharmony_ci void DeferMessage(const MsgInfo &info); 523da853ecaSopenharmony_ci void ProcessDeferredMessages(); 524da853ecaSopenharmony_ci void ReplyToSyncMsgLater(const MsgInfo& msg); 525da853ecaSopenharmony_ci bool GetFirstSyncMsgToReply(MsgInfo& msg); 526da853ecaSopenharmony_ci 527da853ecaSopenharmony_ciprivate: 528da853ecaSopenharmony_ci static constexpr size_t MAX_HCODEC_BUFFER_SIZE = 8192 * 4096 * 4; // 8K RGBA 529da853ecaSopenharmony_ci static constexpr uint32_t THREE_SECONDS_IN_US = 3'000'000; 530da853ecaSopenharmony_ci static constexpr uint32_t ONE_SECONDS_IN_US = 1'000'000; 531da853ecaSopenharmony_ci static constexpr uint32_t FIVE_SECONDS_IN_MS = 5'000; 532da853ecaSopenharmony_ci 533da853ecaSopenharmony_ci std::shared_ptr<UninitializedState> uninitializedState_; 534da853ecaSopenharmony_ci std::shared_ptr<InitializedState> initializedState_; 535da853ecaSopenharmony_ci std::shared_ptr<StartingState> startingState_; 536da853ecaSopenharmony_ci std::shared_ptr<RunningState> runningState_; 537da853ecaSopenharmony_ci std::shared_ptr<OutputPortChangedState> outputPortChangedState_; 538da853ecaSopenharmony_ci std::shared_ptr<FlushingState> flushingState_; 539da853ecaSopenharmony_ci std::shared_ptr<StoppingState> stoppingState_; 540da853ecaSopenharmony_ci 541da853ecaSopenharmony_ci int32_t stateGeneration_ = 0; 542da853ecaSopenharmony_ci bool isShutDownFromRunning_ = false; 543da853ecaSopenharmony_ci bool notifyCallerAfterShutdownComplete_ = false; 544da853ecaSopenharmony_ci bool keepComponentAllocated_ = false; 545da853ecaSopenharmony_ci bool hasFatalError_ = false; 546da853ecaSopenharmony_ci std::list<MsgInfo> deferredQueue_; 547da853ecaSopenharmony_ci std::map<MsgType, std::queue<std::pair<MsgId, ParamSP>>> syncMsgToReply_; 548da853ecaSopenharmony_ci}; // class HCodec 549da853ecaSopenharmony_ci} // namespace OHOS::MediaAVCodec 550da853ecaSopenharmony_ci#endif // HCODEC_HCODEC_H 551