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 
24 namespace OHOS::MediaAVCodec {
25 class HEncoder : public HCodec {
26 public:
HEncoder(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType)27     HEncoder(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType)
28         : HCodec(caps, codingType, true) {}
29     ~HEncoder() override;
30 
31 private:
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 
47 private:
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 
127 private:
128     class EncoderBuffersConsumerListener : public IBufferConsumerListener {
129     public:
EncoderBuffersConsumerListener(HEncoder *codec)130         explicit EncoderBuffersConsumerListener(HEncoder *codec) : codec_(codec) {}
131         void OnBufferAvailable() override;
132     private:
133         HEncoder* codec_;
134     };
135 
136 private:
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