/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FCODEC_H #define FCODEC_H #include #include #include #include #include #include #include #include #include #include #include "av_common.h" #include "avcodec_common.h" #include "avcodec_info.h" #include "block_queue.h" #include "codec_utils.h" #include "codecbase.h" #include "media_description.h" #include "fsurface_memory.h" #include "task_thread.h" namespace OHOS { namespace MediaAVCodec { namespace Codec { using AVBuffer = Media::AVBuffer; using AVAllocator = Media::AVAllocator; using AVAllocatorFactory = Media::AVAllocatorFactory; using MemoryFlag = Media::MemoryFlag; using FormatDataType = Media::FormatDataType; class FCodec : public CodecBase, public RefBase { public: explicit FCodec(const std::string &name); ~FCodec() override; int32_t Configure(const Format &format) override; int32_t Start() override; int32_t Stop() override; int32_t Flush() override; int32_t Reset() override; int32_t Release() override; int32_t SetParameter(const Format &format) override; int32_t GetOutputFormat(Format &format) override; int32_t QueueInputBuffer(uint32_t index) override; int32_t ReleaseOutputBuffer(uint32_t index) override; int32_t SetCallback(const std::shared_ptr &callback) override; int32_t SetOutputSurface(sptr surface) override; int32_t RenderOutputBuffer(uint32_t index) override; static int32_t GetCodecCapability(std::vector &capaArray); struct FBuffer { public: FBuffer() = default; ~FBuffer() = default; enum class Owner { OWNED_BY_US, OWNED_BY_CODEC, OWNED_BY_USER, OWNED_BY_SURFACE, }; std::shared_ptr avBuffer_ = nullptr; std::shared_ptr sMemory_ = nullptr; std::atomic owner_ = Owner::OWNED_BY_US; int32_t width_ = 0; int32_t height_ = 0; }; private: int32_t Initialize(); enum struct State : int32_t { UNINITIALIZED, INITIALIZED, CONFIGURED, STOPPING, RUNNING, FLUSHED, FLUSHING, EOS, ERROR, }; void DumpOutputBuffer(); bool IsActive() const; void ResetContext(bool isFlush = false); void CalculateBufferSize(); int32_t AllocateBuffers(); void InitBuffers(); void ResetBuffers(); void ResetData(); void ReleaseBuffers(); void StopThread(); void ReleaseResource(); int32_t UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType); int32_t UpdateSurfaceMemory(uint32_t index); void SendFrame(); void ReceiveFrame(); void FindAvailIndex(uint32_t index); void ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType); void ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal = 0, int32_t maxVal = INT_MAX); int32_t ConfigureContext(const Format &format); void FramePostProcess(std::shared_ptr &frameBuffer, uint32_t index, int32_t status, int ret); int32_t AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize); int32_t AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize); int32_t FillFrameBuffer(const std::shared_ptr &frameBuffer); int32_t CheckFormatChange(uint32_t index, int width, int height); void SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType); int32_t ReplaceOutputSurfaceWhenRunning(sptr newSurface); int32_t SetQueueSize(const sptr &surface, uint32_t targetSize); int32_t SwitchBetweenSurface(const sptr &newSurface); int32_t RenderNewSurfaceWithOldBuffer(const sptr &newSurface, uint32_t index); int32_t FlushSurfaceMemory(std::shared_ptr &surfaceMemory, uint32_t index); int32_t SetSurfaceCfg(int32_t bufferCnt); // surface listener callback void RequestBufferFromConsumer(); GSError BufferReleasedByConsumer(uint64_t surfaceId); GSError RegisterListenerToSurface(const sptr &surface); int32_t UnRegisterListenerToSurface(const sptr &surface); std::string codecName_; std::atomic state_ = State::UNINITIALIZED; Format format_; int32_t width_ = 0; int32_t height_ = 0; int32_t inputBufferSize_ = 0; int32_t outputBufferSize_ = 0; // INIT std::shared_ptr avCodec_ = nullptr; // Config std::shared_ptr avCodecContext_ = nullptr; // Start std::shared_ptr avPacket_ = nullptr; std::shared_ptr cachedFrame_ = nullptr; // Receive frame uint8_t *scaleData_[AV_NUM_DATA_POINTERS] = {nullptr}; int32_t scaleLineSize_[AV_NUM_DATA_POINTERS] = {0}; std::shared_ptr scale_ = nullptr; bool isConverted_ = false; bool isOutBufSetted_ = false; VideoPixelFormat outputPixelFmt_ = VideoPixelFormat::UNKNOWN; // Running std::vector> buffers_[2]; std::vector> outAVBuffer4Surface_; std::shared_ptr> inputAvailQue_; std::shared_ptr> codecAvailQue_; std::shared_ptr> renderAvailQue_; std::map, OHOS::BufferFlushConfig>> renderSurfaceBufferMap_; std::optional synIndex_ = std::nullopt; SurfaceControl sInfo_; std::shared_ptr sendTask_ = nullptr; std::shared_ptr receiveTask_ = nullptr; std::mutex inputMutex_; std::mutex outputMutex_; std::mutex sendMutex_; std::mutex recvMutex_; std::mutex syncMutex_; std::mutex surfaceMutex_; std::mutex formatMutex_; std::condition_variable sendCv_; std::condition_variable recvCv_; std::shared_ptr callback_; std::atomic isSendWait_ = false; std::atomic isSendEos_ = false; std::atomic isBufferAllocated_ = false; uint32_t decNum_ = 0; // dump #ifdef BUILD_ENG_VERSION void OpenDumpFile(); std::shared_ptr dumpInFile_ = nullptr; std::shared_ptr dumpOutFile_ = nullptr; #endif // BUILD_ENG_VERSION }; } // namespace Codec } // namespace MediaAVCodec } // namespace OHOS #endif // FCODEC_H