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 FCODEC_H 17 #define FCODEC_H 18 19 #include <atomic> 20 #include <list> 21 #include <map> 22 #include <shared_mutex> 23 #include <functional> 24 #include <fstream> 25 #include <tuple> 26 #include <vector> 27 #include <optional> 28 #include <algorithm> 29 #include "av_common.h" 30 #include "avcodec_common.h" 31 #include "avcodec_info.h" 32 #include "block_queue.h" 33 #include "codec_utils.h" 34 #include "codecbase.h" 35 #include "media_description.h" 36 #include "fsurface_memory.h" 37 #include "task_thread.h" 38 39 namespace OHOS { 40 namespace MediaAVCodec { 41 namespace Codec { 42 using AVBuffer = Media::AVBuffer; 43 using AVAllocator = Media::AVAllocator; 44 using AVAllocatorFactory = Media::AVAllocatorFactory; 45 using MemoryFlag = Media::MemoryFlag; 46 using FormatDataType = Media::FormatDataType; 47 class FCodec : public CodecBase, public RefBase { 48 public: 49 explicit FCodec(const std::string &name); 50 ~FCodec() override; 51 int32_t Configure(const Format &format) override; 52 int32_t Start() override; 53 int32_t Stop() override; 54 int32_t Flush() override; 55 int32_t Reset() override; 56 int32_t Release() override; 57 int32_t SetParameter(const Format &format) override; 58 int32_t GetOutputFormat(Format &format) override; 59 60 int32_t QueueInputBuffer(uint32_t index) override; 61 int32_t ReleaseOutputBuffer(uint32_t index) override; 62 int32_t SetCallback(const std::shared_ptr<MediaCodecCallback> &callback) override; 63 int32_t SetOutputSurface(sptr<Surface> surface) override; 64 int32_t RenderOutputBuffer(uint32_t index) override; 65 static int32_t GetCodecCapability(std::vector<CapabilityData> &capaArray); 66 struct FBuffer { 67 public: 68 FBuffer() = default; 69 ~FBuffer() = default; 70 std::shared_ptr<AVBuffer> avBuffer_ = nullptr; 71 std::shared_ptr<FSurfaceMemory> sMemory_ = nullptr; 72 std::atomic<Owner> owner_ = Owner::OWNED_BY_US; 73 int32_t width_ = 0; 74 int32_t height_ = 0; 75 }; 76 77 private: 78 int32_t Initialize(); 79 80 enum struct State : int32_t { 81 UNINITIALIZED, 82 INITIALIZED, 83 CONFIGURED, 84 STOPPING, 85 RUNNING, 86 FLUSHED, 87 FLUSHING, 88 EOS, 89 ERROR, 90 }; 91 void DumpOutputBuffer(); 92 bool IsActive() const; 93 void ResetContext(bool isFlush = false); 94 void CalculateBufferSize(); 95 int32_t AllocateBuffers(); 96 void InitBuffers(); 97 void ResetBuffers(); 98 void ResetData(); 99 void ReleaseBuffers(); 100 void StopThread(); 101 void ReleaseResource(); 102 int32_t UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType); 103 int32_t UpdateSurfaceMemory(uint32_t index); 104 void SendFrame(); 105 void ReceiveFrame(); 106 void FindAvailIndex(uint32_t index); 107 void ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType); 108 void ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal = 0, 109 int32_t maxVal = INT_MAX); 110 int32_t ConfigureContext(const Format &format); 111 static void GetMpeg2CapProf(std::vector<CapabilityData> &capaArray); 112 static void GetMpeg4esCapProf(std::vector<CapabilityData> &capaArray); 113 static void SetMpeg4LevelsProfileGroup1(CapabilityData& capsData); 114 static void SetMpeg4LevelsProfileGroup2(CapabilityData& capsData); 115 static void SetMpeg4Profiles(CapabilityData& capsData); 116 static void GetAvcCapProf(std::vector<CapabilityData> &capaArray); 117 static void GetH263CapProf(std::vector<CapabilityData> &capaArray); 118 #ifdef SUPPORT_CODEC_RV 119 int32_t SetCodecExtradata(const Format &format); 120 #endif 121 void FramePostProcess(std::shared_ptr<FBuffer> &frameBuffer, uint32_t index, int32_t status, int ret); 122 int32_t AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize); 123 int32_t AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize); 124 int32_t ClearSurfaceAndSetQueueSize(const sptr<Surface> &surface, int32_t bufferCnt); 125 int32_t AllocateOutputBuffersFromSurface(int32_t bufferCnt); 126 int32_t FillFrameBuffer(const std::shared_ptr<FBuffer> &frameBuffer); 127 int32_t CheckFormatChange(uint32_t index, int width, int height); 128 void SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType); 129 int32_t ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface); 130 int32_t SetQueueSize(const sptr<Surface> &surface, uint32_t targetSize); 131 int32_t SwitchBetweenSurface(const sptr<Surface> &newSurface); 132 int32_t RenderNewSurfaceWithOldBuffer(const sptr<Surface> &newSurface, uint32_t index); 133 int32_t FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> &surfaceMemory, uint32_t index); 134 int32_t SetSurfaceCfg(); 135 int32_t Attach(sptr<SurfaceBuffer> surfaceBuffer); 136 int32_t Detach(sptr<SurfaceBuffer> surfaceBuffer); 137 void CombineConsumerUsage(); 138 // surface listener callback 139 void RequestBufferFromConsumer(); 140 GSError BufferReleasedByConsumer(uint64_t surfaceId); 141 GSError RegisterListenerToSurface(const sptr<Surface> &surface); 142 int32_t UnRegisterListenerToSurface(const sptr<Surface> &surface); 143 void RequestSurfaceBufferThread(); 144 void StartRequestSurfaceBufferThread(); 145 void StopRequestSurfaceBufferThread(); 146 bool RequestSurfaceBufferOnce(uint32_t index); 147 148 std::string codecName_; 149 std::atomic<State> state_ = State::UNINITIALIZED; 150 Format format_; 151 int32_t width_ = 0; 152 int32_t height_ = 0; 153 int32_t inputBufferSize_ = 0; 154 int32_t outputBufferSize_ = 0; 155 int32_t inputBufferCnt_ = 0; 156 int32_t outputBufferCnt_ = 0; 157 // INIT 158 std::shared_ptr<AVCodec> avCodec_ = nullptr; 159 // Config 160 std::shared_ptr<AVCodecContext> avCodecContext_ = nullptr; 161 // Start 162 std::shared_ptr<AVPacket> avPacket_ = nullptr; 163 std::shared_ptr<AVFrame> cachedFrame_ = nullptr; 164 // Receive frame 165 uint8_t *scaleData_[AV_NUM_DATA_POINTERS] = {nullptr}; 166 int32_t scaleLineSize_[AV_NUM_DATA_POINTERS] = {0}; 167 std::shared_ptr<Scale> scale_ = nullptr; 168 bool isConverted_ = false; 169 bool isOutBufSetted_ = false; 170 VideoPixelFormat outputPixelFmt_ = VideoPixelFormat::UNKNOWN; 171 // Running 172 std::vector<std::shared_ptr<FBuffer>> buffers_[2]; 173 std::vector<std::shared_ptr<AVBuffer>> outAVBuffer4Surface_; 174 std::shared_ptr<BlockQueue<uint32_t>> inputAvailQue_; 175 std::shared_ptr<BlockQueue<uint32_t>> codecAvailQue_; 176 std::shared_ptr<BlockQueue<uint32_t>> renderAvailQue_; 177 std::shared_ptr<BlockQueue<uint32_t>> requestSurfaceBufferQue_; 178 std::map<uint32_t, std::pair<sptr<SurfaceBuffer>, OHOS::BufferFlushConfig>> renderSurfaceBufferMap_; 179 std::optional<uint32_t> synIndex_ = std::nullopt; 180 SurfaceControl sInfo_; 181 std::shared_ptr<TaskThread> sendTask_ = nullptr; 182 std::shared_ptr<TaskThread> receiveTask_ = nullptr; 183 std::mutex inputMutex_; 184 std::mutex outputMutex_; 185 std::mutex sendMutex_; 186 std::mutex recvMutex_; 187 std::mutex syncMutex_; 188 std::mutex surfaceMutex_; 189 std::mutex formatMutex_; 190 std::mutex requestBufferMutex_; 191 std::condition_variable requestBufferCV_; 192 std::condition_variable requestBufferOnceDoneCV_; 193 std::condition_variable sendCv_; 194 std::condition_variable recvCv_; 195 std::shared_ptr<MediaCodecCallback> callback_; 196 std::atomic<bool> isSendWait_ = false; 197 std::atomic<bool> isSendEos_ = false; 198 std::atomic<bool> isBufferAllocated_ = false; 199 std::atomic<bool> requestBufferFinished_ = true; 200 std::atomic<bool> requestBufferThreadExit_ = false; 201 std::thread mRequestSurfaceBufferThread_; 202 uint32_t decNum_ = 0; 203 // dump 204 #ifdef BUILD_ENG_VERSION 205 void OpenDumpFile(); 206 std::shared_ptr<std::ofstream> dumpInFile_ = nullptr; 207 std::shared_ptr<std::ofstream> dumpOutFile_ = nullptr; 208 #endif // BUILD_ENG_VERSION 209 }; 210 } // namespace Codec 211 } // namespace MediaAVCodec 212 } // namespace OHOS 213 #endif // FCODEC_H