• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <deque>
20 #include "hcodec.h"
21 #include "codec_omx_ext.h"
22 #include "sync_fence.h"
23 #include "hcodec_utils.h"
24 
25 constexpr int32_t PREVIOUS_PTS_RECORDED_COUNT = 4;
26 constexpr int64_t TIME_RATIO_NS_TO_US = 1000;
27 constexpr int64_t TIME_RATIO_US_TO_S = 1000000;
28 constexpr double DURATION_SCALE_FACTOR = 7.0;
29 constexpr int32_t DEFAULT_FRAME_RATE = 15;
30 constexpr double SMOOTH_FACTOR_CLIP_MIN = 0.3;
31 constexpr int32_t SMOOTH_FACTOR_CLIP_RANGE_MIN = 10;
32 constexpr double SMOOTH_FACTOR_CLIP_MAX = 0.9;
33 constexpr int32_t SMOOTH_FACTOR_CLIP_RANGE_MAX = 70;
34 constexpr double AVERAGE_DURATION_ERROR_COUNT = 3.0;
35 constexpr double AVERAGE_DURATION_ERROR_FRAMERATE_RANGE = 0.5;
36 
37 namespace OHOS::MediaAVCodec {
38 class HEncoder : public HCodec {
39 public:
HEncoder(CodecHDI::CodecCompCapability caps,OMX_VIDEO_CODINGTYPE codingType)40     HEncoder(CodecHDI::CodecCompCapability caps, OMX_VIDEO_CODINGTYPE codingType)
41         : HCodec(caps, codingType, true) {}
42     ~HEncoder() override;
43 
44 private:
45     struct BufferItem {
46         BufferItem() = default;
47         ~BufferItem();
48         uint64_t generation = 0;
49         sptr<SurfaceBuffer> buffer;
50         sptr<SyncFence> fence;
51         OHOS::Rect damage;
52         sptr<Surface> surface;
53     };
54     struct InSurfaceBufferEntry {
55         std::shared_ptr<BufferItem> item; // don't change after created
56         int64_t pts = -1;           // may change
57         int32_t repeatTimes = 0;    // may change
58     };
59 
60     struct WaterMarkInfo {
61         bool enableWaterMark = false;
62         int32_t x = 0;
63         int32_t y = 0;
64         int32_t w = 0;
65         int32_t h = 0;
66     };
67 
68 private:
69     // configure
70     int32_t OnConfigure(const Format &format) override;
71     int32_t OnConfigureBuffer(std::shared_ptr<AVBuffer> buffer) override;
72     int32_t ConfigureBufferType();
73     int32_t SetupPort(const Format &format, std::optional<double> &frameRate);
74     void ConfigureProtocol(const Format &format, std::optional<double> frameRate);
75     void CalcInputBufSize(PortInfo& info, VideoPixelFormat pixelFmt);
76     int32_t UpdateInPortFormat() override;
77     int32_t UpdateOutPortFormat() override;
78     int32_t ConfigureOutputBitrate(const Format &format);
79     static std::optional<uint32_t> GetBitRateFromUser(const Format &format);
80     static std::optional<VideoEncodeBitrateMode> GetBitRateModeFromUser(const Format &format);
81     static std::optional<uint32_t> GetSQRFactorFromUser(const Format &format);
82     static std::optional<uint32_t> GetSQRMaxBitrateFromUser(const Format &format);
83     static std::optional<uint32_t> GetCRFtagetQpFromUser(const Format &format);
84     static std::optional<double> GetOperatingRateFromUser(const Format &format);
85     static int32_t GetWaterMarkInfo(std::shared_ptr<AVBuffer> buffer, WaterMarkInfo &info);
86     int32_t SetupAVCEncoderParameters(const Format &format, std::optional<double> frameRate);
87     void SetAvcFields(OMX_VIDEO_PARAM_AVCTYPE& avcType, int32_t iFrameInterval, double frameRate);
88     int32_t SetupHEVCEncoderParameters(const Format &format, std::optional<double> frameRate);
89     int32_t SetColorAspects(const Format &format);
90     int32_t OnSetParameters(const Format &format) override;
91     sptr<Surface> OnCreateInputSurface() override;
92     int32_t OnSetInputSurface(sptr<Surface> &inputSurface) override;
93     int32_t RequestIDRFrame() override;
94     void SetSqrParam(const Format &format);
95     void CheckIfEnableCb(const Format &format);
96     int32_t SetLTRParam(const Format &format);
97     int32_t EnableEncoderParamsFeedback(const Format &format);
98     int32_t SetQpRange(const Format &format, bool isCfg);
99     int32_t SetRepeat(const Format &format);
100     int32_t SetTemperalLayer(const Format &format);
101     int32_t SetConstantQualityMode(int32_t quality);
102     int32_t SetSQRMode(const Format &format);
103     int32_t EnableFrameQPMap(const Format &format);
104     int32_t ConfigBEncodeMode(const Format &format);
105     int32_t SetCRFMode(int32_t targetQp);
106     void EnableVariableFrameRate(const Format &format);
107 
108     // start
109     int32_t AllocateBuffersOnPort(OMX_DIRTYPE portIndex) override;
110     void UpdateFmtFromSurfaceBuffer() override;
111     int32_t AllocInBufsForDynamicSurfaceBuf();
112     int32_t SubmitAllBuffersOwnedByUs() override;
113     int32_t SubmitOutBufToOmx() override;
114     void ClearDirtyList();
115     bool ReadyToStart() override;
116 
117     // input buffer circulation
118     void OnGetBufferFromSurface(const ParamSP& param) override;
119     void RepeatIfNecessary(const ParamSP& param) override;
120     void SendRepeatMsg(uint64_t generation);
121     bool GetOneBufferFromSurface();
122     void TraverseAvaliableBuffers();
123     void SubmitOneBuffer(InSurfaceBufferEntry& entry, BufferInfo &info);
124     void SetBufferPts(BufferInfo* info);
125     void ResetSlot(BufferInfo& info);
126     void OnOMXEmptyBufferDone(uint32_t bufferId, BufferOperationMode mode) override;
127     void OnSignalEndOfInputStream(const MsgInfo &msg) override;
128     void OnQueueInputBuffer(const MsgInfo &msg, BufferOperationMode mode) override;
129     void CheckPts(int64_t currentPts);
130 
131     // per frame param
132     void WrapPerFrameParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
133                                         const std::shared_ptr<Media::Meta> &meta);
134     void WrapLTRParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
135                                    const std::shared_ptr<Media::Meta> &meta);
136     void WrapRequestIFrameParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
137                                              const std::shared_ptr<Media::Meta> &meta);
138     void WrapQPRangeParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
139                                        const std::shared_ptr<Media::Meta> &meta);
140     void WrapStartQPIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
141                                   const std::shared_ptr<Media::Meta> &meta);
142     void WrapQPMapParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
143                                   const std::shared_ptr<Media::Meta> &meta);
144     void WrapIsSkipFrameIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
145                                       const std::shared_ptr<Media::Meta> &meta);
146     void ParseRoiStringValid(const std::string &roiValue, std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer);
147     void WrapRoiParamIntoOmxBuffer(std::shared_ptr<CodecHDI::OmxCodecBuffer> &omxBuffer,
148                                   const std::shared_ptr<Media::Meta> &meta);
149     void BeforeCbOutToUser(BufferInfo &info) override;
150     void ExtractPerFrameLTRParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
151     void ExtractPerFrameMadParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
152     void ExtractPerFrameRealBitrateParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
153     void ExtractPerFrameFrameQpParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
154     void ExtractPerFrameIRitioParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
155     void ExtractPerFrameAveQpParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
156     void ExtractPerFrameMSEParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
157     void ExtractPerFrameLayerParam(BinaryReader &reader, std::shared_ptr<Media::Meta> &meta);
158     void DealWithResolutionChange(uint32_t newWidth, uint32_t newHeight);
159 
160     double CalculateSmoothFactorBasedPts(int64_t curPts, int64_t curDuration);
161     int32_t CalculateSmoothFpsBasedPts(int64_t curPts, int64_t curDuration);
162     int32_t UpdateTimeStampWindow(int64_t curPts, int32_t &frameRate);
163     int32_t CalculateFrameRateParamIntoOmxBuffer(int64_t curPts);
164 
165     // stop/release
166     void EraseBufferFromPool(OMX_DIRTYPE portIndex, size_t i) override;
167     void OnEnterUninitializedState() override;
168 
169 private:
170     class EncoderBuffersConsumerListener : public IBufferConsumerListener {
171     public:
EncoderBuffersConsumerListener(std::weak_ptr<MsgToken> codec)172         explicit EncoderBuffersConsumerListener(std::weak_ptr<MsgToken> codec) : codec_(codec) {}
173         void OnBufferAvailable() override;
174     private:
175         std::weak_ptr<MsgToken> codec_;
176     };
177 
178 private:
179     uint32_t width_ = 0;
180     uint32_t height_ = 0;
181     bool enableSurfaceModeInputCb_ = false;
182     bool enableLTR_ = false;
183     bool enableTSVC_ = false;
184     bool enableQPMap_ = false;
185     bool enableVariableFrameRate_ = false;
186     std::deque<int64_t> previousPtsWindow_;
187     int32_t previousSmoothFrameRate_ = 0;
188     std::optional<double> defaultFrameRate_;
189     sptr<Surface> inputSurface_;
190     uint32_t inBufferCnt_ = 0;
191     static constexpr size_t MAX_LIST_SIZE = 256;
192     static constexpr uint32_t THIRTY_MILLISECONDS_IN_US = 30'000;
193     static constexpr uint32_t SURFACE_MODE_CONSUMER_USAGE = BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_VIDEO_ENCODER;
194     static constexpr uint64_t BUFFER_MODE_REQUEST_USAGE =
195         SURFACE_MODE_CONSUMER_USAGE | BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_MMZ_CACHE;
196 
197     uint64_t currGeneration_ = 0;
198     std::list<InSurfaceBufferEntry> avaliableBuffers_;
199     InSurfaceBufferEntry newestBuffer_{};
200     std::map<uint32_t, InSurfaceBufferEntry> encodingBuffers_;
201     uint64_t repeatUs_ = 0;      // 0 means user don't set this value
202     int32_t repeatMaxCnt_ = 10;  // default repeat 10 times. <0 means repeat forever. =0 means nothing.
203     std::optional<int64_t> pts_;
204     static constexpr size_t roiNum = 6;
205 };
206 } // namespace OHOS::MediaAVCodec
207 #endif // HCODEC_HENCODER_H
208