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