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