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