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_HENCODER_H
17da853ecaSopenharmony_ci#define HCODEC_HENCODER_H
18da853ecaSopenharmony_ci
19da853ecaSopenharmony_ci#include "hcodec.h"
20da853ecaSopenharmony_ci#include "codec_omx_ext.h"
21da853ecaSopenharmony_ci#include "sync_fence.h"
22da853ecaSopenharmony_ci#include "hcodec_utils.h"
23da853ecaSopenharmony_ci
24da853ecaSopenharmony_cinamespace OHOS::MediaAVCodec {
25da853ecaSopenharmony_ciclass HEncoder : public HCodec {
26da853ecaSopenharmony_cipublic:
27da853ecaSopenharmony_ci    HEncoder(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType)
28da853ecaSopenharmony_ci        : HCodec(caps, codingType, true) {}
29da853ecaSopenharmony_ci    ~HEncoder() override;
30da853ecaSopenharmony_ci
31da853ecaSopenharmony_ciprivate:
32da853ecaSopenharmony_ci    struct BufferItem {
33da853ecaSopenharmony_ci        BufferItem() = default;
34da853ecaSopenharmony_ci        ~BufferItem();
35da853ecaSopenharmony_ci        uint64_t generation = 0;
36da853ecaSopenharmony_ci        sptr<SurfaceBuffer> buffer;
37da853ecaSopenharmony_ci        sptr<SyncFence> fence;
38da853ecaSopenharmony_ci        OHOS::Rect damage;
39da853ecaSopenharmony_ci        sptr<Surface> surface;
40da853ecaSopenharmony_ci    };
41da853ecaSopenharmony_ci    struct InSurfaceBufferEntry {
42da853ecaSopenharmony_ci        std::shared_ptr<BufferItem> item; // don't change after created
43da853ecaSopenharmony_ci        int64_t pts = -1;           // may change
44da853ecaSopenharmony_ci        int32_t repeatTimes = 0;    // may change
45da853ecaSopenharmony_ci    };
46da853ecaSopenharmony_ci
47da853ecaSopenharmony_ciprivate:
48da853ecaSopenharmony_ci    // configure
49da853ecaSopenharmony_ci    int32_t OnConfigure(const Format &format) override;
50da853ecaSopenharmony_ci    int32_t OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer) override;
51da853ecaSopenharmony_ci    int32_t ConfigureBufferType();
52da853ecaSopenharmony_ci    int32_t SetupPort(const Format &format, std::optional<double> frameRate);
53da853ecaSopenharmony_ci    void ConfigureProtocol(const Format &format, std::optional<double> frameRate);
54da853ecaSopenharmony_ci    void CalcInputBufSize(PortInfo& info, VideoPixelFormat pixelFmt);
55da853ecaSopenharmony_ci    int32_t UpdateInPortFormat() override;
56da853ecaSopenharmony_ci    int32_t UpdateOutPortFormat() override;
57da853ecaSopenharmony_ci    int32_t ConfigureOutputBitrate(const Format &format);
58da853ecaSopenharmony_ci    static std::optional<uint32_t> GetBitRateFromUser(const Format &format);
59da853ecaSopenharmony_ci    static std::optional<VideoEncodeBitrateMode> GetBitRateModeFromUser(const Format &format);
60da853ecaSopenharmony_ci    int32_t SetupAVCEncoderParameters(const Format &format, std::optional<double> frameRate);
61da853ecaSopenharmony_ci    void SetAvcFields(OMX_VIDEO_PARAM_AVCTYPE& avcType, int32_t iFrameInterval, double frameRate);
62da853ecaSopenharmony_ci    int32_t SetupHEVCEncoderParameters(const Format &format, std::optional<double> frameRate);
63da853ecaSopenharmony_ci    int32_t SetColorAspects(const Format &format);
64da853ecaSopenharmony_ci    int32_t OnSetParameters(const Format &format) override;
65da853ecaSopenharmony_ci    sptr<Surface> OnCreateInputSurface() override;
66da853ecaSopenharmony_ci    int32_t OnSetInputSurface(sptr<Surface> &inputSurface) override;
67da853ecaSopenharmony_ci    int32_t RequestIDRFrame() override;
68da853ecaSopenharmony_ci    void CheckIfEnableCb(const Format &format);
69da853ecaSopenharmony_ci    int32_t SetLTRParam(const Format &format);
70da853ecaSopenharmony_ci    int32_t EnableEncoderParamsFeedback(const Format &format);
71da853ecaSopenharmony_ci    int32_t SetQpRange(const Format &format, bool isCfg);
72da853ecaSopenharmony_ci    int32_t SetRepeat(const Format &format);
73da853ecaSopenharmony_ci    int32_t SetTemperalLayer(const Format &format);
74da853ecaSopenharmony_ci    int32_t SetConstantQualityMode(int32_t quality);
75da853ecaSopenharmony_ci
76da853ecaSopenharmony_ci    // start
77da853ecaSopenharmony_ci    int32_t AllocateBuffersOnPort(OMX_DIRTYPE portIndex) override;
78da853ecaSopenharmony_ci    void UpdateFormatFromSurfaceBuffer() override;
79da853ecaSopenharmony_ci    int32_t AllocInBufsForDynamicSurfaceBuf();
80da853ecaSopenharmony_ci    int32_t SubmitAllBuffersOwnedByUs() override;
81da853ecaSopenharmony_ci    int32_t SubmitOutputBuffersToOmxNode() override;
82da853ecaSopenharmony_ci    void ClearDirtyList();
83da853ecaSopenharmony_ci    bool ReadyToStart() override;
84da853ecaSopenharmony_ci
85da853ecaSopenharmony_ci    // input buffer circulation
86da853ecaSopenharmony_ci    void OnGetBufferFromSurface(const ParamSP& param) override;
87da853ecaSopenharmony_ci    void RepeatIfNecessary(const ParamSP& param) override;
88da853ecaSopenharmony_ci    void SendRepeatMsg(uint64_t generation);
89da853ecaSopenharmony_ci    bool GetOneBufferFromSurface();
90da853ecaSopenharmony_ci    void TraverseAvaliableBuffers();
91da853ecaSopenharmony_ci    void TraverseAvaliableSlots();
92da853ecaSopenharmony_ci    void SubmitOneBuffer(InSurfaceBufferEntry& entry, BufferInfo &info);
93da853ecaSopenharmony_ci    void ResetSlot(BufferInfo& info);
94da853ecaSopenharmony_ci    void OnOMXEmptyBufferDone(uint32_t bufferId, BufferOperationMode mode) override;
95da853ecaSopenharmony_ci    void OnSignalEndOfInputStream(const MsgInfo &msg) override;
96da853ecaSopenharmony_ci    void OnQueueInputBuffer(const MsgInfo &msg, BufferOperationMode mode) override;
97da853ecaSopenharmony_ci
98da853ecaSopenharmony_ci    // per frame param
99da853ecaSopenharmony_ci    void WrapPerFrameParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
100da853ecaSopenharmony_ci                                        const std::shared_ptr<Media::Meta> &meta);
101da853ecaSopenharmony_ci    void WrapLTRParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
102da853ecaSopenharmony_ci                                   const std::shared_ptr<Media::Meta> &meta);
103da853ecaSopenharmony_ci    void WrapRequestIFrameParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
104da853ecaSopenharmony_ci                                             const std::shared_ptr<Media::Meta> &meta);
105da853ecaSopenharmony_ci    void WrapQPRangeParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
106da853ecaSopenharmony_ci                                       const std::shared_ptr<Media::Meta> &meta);
107da853ecaSopenharmony_ci    void WrapStartQPIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
108da853ecaSopenharmony_ci                                  const std::shared_ptr<Media::Meta> &meta);
109da853ecaSopenharmony_ci    void WrapIsSkipFrameIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
110da853ecaSopenharmony_ci                                      const std::shared_ptr<Media::Meta> &meta);
111da853ecaSopenharmony_ci    void ExtractPerFrameParamFromOmxBuffer(const std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
112da853ecaSopenharmony_ci                                           std::shared_ptr<Media::Meta> &meta) override;
113da853ecaSopenharmony_ci    void ExtractPerFrameLTRParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
114da853ecaSopenharmony_ci    void ExtractPerFrameMadParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
115da853ecaSopenharmony_ci    void ExtractPerFrameRealBitrateParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
116da853ecaSopenharmony_ci    void ExtractPerFrameFrameQpParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
117da853ecaSopenharmony_ci    void ExtractPerFrameIRitioParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
118da853ecaSopenharmony_ci    void ExtractPerFrameAveQpParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
119da853ecaSopenharmony_ci    void ExtractPerFrameMSEParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
120da853ecaSopenharmony_ci    void ExtractPerFrameLayerParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
121da853ecaSopenharmony_ci    void DealWithResolutionChange(uint32_t newWidth, uint32_t newHeight);
122da853ecaSopenharmony_ci
123da853ecaSopenharmony_ci    // stop/release
124da853ecaSopenharmony_ci    void EraseBufferFromPool(OMX_DIRTYPE portIndex, size_t i) override;
125da853ecaSopenharmony_ci    void OnEnterUninitializedState() override;
126da853ecaSopenharmony_ci
127da853ecaSopenharmony_ciprivate:
128da853ecaSopenharmony_ci    class EncoderBuffersConsumerListener : public IBufferConsumerListener {
129da853ecaSopenharmony_ci    public:
130da853ecaSopenharmony_ci        explicit EncoderBuffersConsumerListener(HEncoder *codec) : codec_(codec) {}
131da853ecaSopenharmony_ci        void OnBufferAvailable() override;
132da853ecaSopenharmony_ci    private:
133da853ecaSopenharmony_ci        HEncoder* codec_;
134da853ecaSopenharmony_ci    };
135da853ecaSopenharmony_ci
136da853ecaSopenharmony_ciprivate:
137da853ecaSopenharmony_ci    uint32_t width_ = 0;
138da853ecaSopenharmony_ci    uint32_t height_ = 0;
139da853ecaSopenharmony_ci    bool enableSurfaceModeInputCb_ = false;
140da853ecaSopenharmony_ci    bool enableLTR_ = false;
141da853ecaSopenharmony_ci    bool enableTSVC_ = false;
142da853ecaSopenharmony_ci    sptr<Surface> inputSurface_;
143da853ecaSopenharmony_ci    uint32_t inBufferCnt_ = 0;
144da853ecaSopenharmony_ci    static constexpr size_t MAX_LIST_SIZE = 256;
145da853ecaSopenharmony_ci    static constexpr uint32_t THIRTY_MILLISECONDS_IN_US = 30'000;
146da853ecaSopenharmony_ci    static constexpr uint32_t SURFACE_MODE_CONSUMER_USAGE = BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_VIDEO_ENCODER;
147da853ecaSopenharmony_ci    static constexpr uint64_t BUFFER_MODE_REQUEST_USAGE =
148da853ecaSopenharmony_ci        SURFACE_MODE_CONSUMER_USAGE | BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_MMZ_CACHE;
149da853ecaSopenharmony_ci
150da853ecaSopenharmony_ci    uint64_t currGeneration_ = 0;
151da853ecaSopenharmony_ci    std::list<InSurfaceBufferEntry> avaliableBuffers_;
152da853ecaSopenharmony_ci    InSurfaceBufferEntry newestBuffer_{};
153da853ecaSopenharmony_ci    std::map<uint32_t, InSurfaceBufferEntry> encodingBuffers_;
154da853ecaSopenharmony_ci    uint64_t repeatUs_ = 0;      // 0 means user don't set this value
155da853ecaSopenharmony_ci    int32_t repeatMaxCnt_ = 10;  // default repeat 10 times. <0 means repeat forever. =0 means nothing.
156da853ecaSopenharmony_ci};
157da853ecaSopenharmony_ci} // namespace OHOS::MediaAVCodec
158da853ecaSopenharmony_ci#endif // HCODEC_HENCODER_H
159