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 
67     struct FBuffer {
68     public:
69         FBuffer() = default;
70         ~FBuffer() = default;
71 
72         enum class Owner {
73             OWNED_BY_US,
74             OWNED_BY_CODEC,
75             OWNED_BY_USER,
76             OWNED_BY_SURFACE,
77         };
78 
79         std::shared_ptr<AVBuffer> avBuffer_ = nullptr;
80         std::shared_ptr<FSurfaceMemory> sMemory_ = nullptr;
81         std::atomic<Owner> owner_ = Owner::OWNED_BY_US;
82         int32_t width_ = 0;
83         int32_t height_ = 0;
84     };
85 
86 private:
87     int32_t Initialize();
88 
89     enum struct State : int32_t {
90         UNINITIALIZED,
91         INITIALIZED,
92         CONFIGURED,
93         STOPPING,
94         RUNNING,
95         FLUSHED,
96         FLUSHING,
97         EOS,
98         ERROR,
99     };
100     void DumpOutputBuffer();
101     bool IsActive() const;
102     void ResetContext(bool isFlush = false);
103     void CalculateBufferSize();
104     int32_t AllocateBuffers();
105     void InitBuffers();
106     void ResetBuffers();
107     void ResetData();
108     void ReleaseBuffers();
109     void StopThread();
110     void ReleaseResource();
111     int32_t UpdateBuffers(uint32_t index, int32_t bufferSize, uint32_t bufferType);
112     int32_t UpdateSurfaceMemory(uint32_t index);
113     void SendFrame();
114     void ReceiveFrame();
115     void FindAvailIndex(uint32_t index);
116     void ConfigureSurface(const Format &format, const std::string_view &formatKey, FormatDataType formatType);
117     void ConfigureDefaultVal(const Format &format, const std::string_view &formatKey, int32_t minVal = 0,
118                              int32_t maxVal = INT_MAX);
119     int32_t ConfigureContext(const Format &format);
120     void FramePostProcess(std::shared_ptr<FBuffer> &frameBuffer, uint32_t index, int32_t status, int ret);
121     int32_t AllocateInputBuffer(int32_t bufferCnt, int32_t inBufferSize);
122     int32_t AllocateOutputBuffer(int32_t bufferCnt, int32_t outBufferSize);
123     int32_t FillFrameBuffer(const std::shared_ptr<FBuffer> &frameBuffer);
124     int32_t CheckFormatChange(uint32_t index, int width, int height);
125     void SetSurfaceParameter(const Format &format, const std::string_view &formatKey, FormatDataType formatType);
126     int32_t ReplaceOutputSurfaceWhenRunning(sptr<Surface> newSurface);
127     int32_t SetQueueSize(const sptr<Surface> &surface, uint32_t targetSize);
128     int32_t SwitchBetweenSurface(const sptr<Surface> &newSurface);
129     int32_t RenderNewSurfaceWithOldBuffer(const sptr<Surface> &newSurface, uint32_t index);
130     int32_t FlushSurfaceMemory(std::shared_ptr<FSurfaceMemory> &surfaceMemory, uint32_t index);
131     int32_t SetSurfaceCfg(int32_t bufferCnt);
132     // surface listener callback
133     void RequestBufferFromConsumer();
134     GSError BufferReleasedByConsumer(uint64_t surfaceId);
135     GSError RegisterListenerToSurface(const sptr<Surface> &surface);
136     int32_t UnRegisterListenerToSurface(const sptr<Surface> &surface);
137 
138     std::string codecName_;
139     std::atomic<State> state_ = State::UNINITIALIZED;
140     Format format_;
141     int32_t width_ = 0;
142     int32_t height_ = 0;
143     int32_t inputBufferSize_ = 0;
144     int32_t outputBufferSize_ = 0;
145     // INIT
146     std::shared_ptr<AVCodec> avCodec_ = nullptr;
147     // Config
148     std::shared_ptr<AVCodecContext> avCodecContext_ = nullptr;
149     // Start
150     std::shared_ptr<AVPacket> avPacket_ = nullptr;
151     std::shared_ptr<AVFrame> cachedFrame_ = nullptr;
152     // Receive frame
153     uint8_t *scaleData_[AV_NUM_DATA_POINTERS] = {nullptr};
154     int32_t scaleLineSize_[AV_NUM_DATA_POINTERS] = {0};
155     std::shared_ptr<Scale> scale_ = nullptr;
156     bool isConverted_ = false;
157     bool isOutBufSetted_ = false;
158     VideoPixelFormat outputPixelFmt_ = VideoPixelFormat::UNKNOWN;
159     // Running
160     std::vector<std::shared_ptr<FBuffer>> buffers_[2];
161     std::vector<std::shared_ptr<AVBuffer>> outAVBuffer4Surface_;
162     std::shared_ptr<BlockQueue<uint32_t>> inputAvailQue_;
163     std::shared_ptr<BlockQueue<uint32_t>> codecAvailQue_;
164     std::shared_ptr<BlockQueue<uint32_t>> renderAvailQue_;
165     std::map<uint32_t, std::pair<sptr<SurfaceBuffer>, OHOS::BufferFlushConfig>> renderSurfaceBufferMap_;
166     std::optional<uint32_t> synIndex_ = std::nullopt;
167     SurfaceControl sInfo_;
168     std::shared_ptr<TaskThread> sendTask_ = nullptr;
169     std::shared_ptr<TaskThread> receiveTask_ = nullptr;
170     std::mutex inputMutex_;
171     std::mutex outputMutex_;
172     std::mutex sendMutex_;
173     std::mutex recvMutex_;
174     std::mutex syncMutex_;
175     std::mutex surfaceMutex_;
176     std::mutex formatMutex_;
177     std::condition_variable sendCv_;
178     std::condition_variable recvCv_;
179     std::shared_ptr<MediaCodecCallback> callback_;
180     std::atomic<bool> isSendWait_ = false;
181     std::atomic<bool> isSendEos_ = false;
182     std::atomic<bool> isBufferAllocated_ = false;
183     uint32_t decNum_ = 0;
184     // dump
185 #ifdef BUILD_ENG_VERSION
186     void OpenDumpFile();
187     std::shared_ptr<std::ofstream> dumpInFile_ = nullptr;
188     std::shared_ptr<std::ofstream> dumpOutFile_ = nullptr;
189 #endif // BUILD_ENG_VERSION
190 };
191 } // namespace Codec
192 } // namespace MediaAVCodec
193 } // namespace OHOS
194 #endif // FCODEC_H