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_TESTER_COMMON_H
17 #define HCODEC_TESTER_COMMON_H
18 
19 #include <fstream>
20 #include <mutex>
21 #include <condition_variable>
22 #include <memory>
23 #include "surface.h"
24 #include "native_avbuffer.h" // foundation/multimedia/media_foundation/interface/kits/c
25 #include "buffer/avbuffer.h" // foundation/multimedia/media_foundation/interface/inner_api
26 #include "native_avcodec_base.h" // foundation/multimedia/av_codec/interfaces/kits/c/
27 #include "command_parser.h"
28 #include "start_code_detector.h"
29 #include "test_utils.h"
30 
31 namespace OHOS::MediaAVCodec {
32 struct Span {
33     uint8_t* va;
34     size_t capacity;
35 };
36 
37 struct ImgBuf : Span {
38     GraphicPixelFormat fmt;
39     uint32_t dispW;
40     uint32_t dispH;
41     uint32_t byteStride;
42 };
43 
44 struct BufInfo : ImgBuf {
45     uint32_t idx;
46     OH_AVCodecBufferAttr attr;
47     OH_AVMemory* mem = nullptr;
48     OH_AVBuffer* cavbuf = nullptr;
49     std::shared_ptr<Media::AVBuffer> avbuf;
50     sptr<SurfaceBuffer> surfaceBuf;
51 };
52 
53 struct TesterCommon {
54     static bool Run(const CommandOpt &opt);
55     bool RunOnce();
56 
57 protected:
58     static std::shared_ptr<TesterCommon> Create(const CommandOpt &opt);
TesterCommonOHOS::MediaAVCodec::TesterCommon59     explicit TesterCommon(const CommandOpt &opt) : opt_(opt) {}
60     virtual ~TesterCommon() = default;
61     static int64_t GetNowUs();
62     virtual bool Create() = 0;
63     virtual bool SetCallback() = 0;
64     virtual bool GetInputFormat() = 0;
65     virtual bool GetOutputFormat() = 0;
66     virtual bool Start() = 0;
67     void EncoderInputLoop();
68     void DecoderInputLoop();
69     void OutputLoop();
70     void BeforeQueueInput(OH_AVCodecBufferAttr& attr);
71     void AfterGotOutput(const OH_AVCodecBufferAttr& attr);
72     virtual bool WaitForInput(BufInfo& buf) = 0;
73     virtual bool WaitForOutput(BufInfo& buf) = 0;
74     virtual bool ReturnInput(const BufInfo& buf) = 0;
75     virtual bool ReturnOutput(uint32_t idx) = 0;
76     virtual bool Flush() = 0;
77     virtual void ClearAllBuffer() = 0;
78     virtual bool Stop() = 0;
79     virtual bool Release() = 0;
80     static std::string GetCodecMime(const CodeType& type);
81 
82     CommandOpt opt_;
83     std::ifstream ifs_;
84 
85     std::mutex inputMtx_;
86     std::condition_variable inputCond_;
87     uint32_t currInputCnt_ = 0;
88 
89     std::mutex outputMtx_;
90     std::condition_variable outputCond_;
91 
92     uint64_t inTotalCnt_ = 0;
93     int64_t firstInTime_ = 0;
94     double inFps_ = 0;
95     uint64_t outTotalCnt_ = 0;
96     int64_t firstOutTime_ = 0;
97     uint64_t totalCost_ = 0;
98 
99     // encoder only
100     bool RunEncoder();
101     virtual bool ConfigureEncoder() = 0;
102     bool UpdateMemberFromResourceParam(const ResourceParams& param);
103     std::shared_ptr<Media::AVBuffer> CreateWaterMarkBuffer();
SetEncoderParameterOHOS::MediaAVCodec::TesterCommon104     virtual bool SetEncoderParameter(const SetParameterParams& param) { return true; }
SetEncoderPerFrameParamOHOS::MediaAVCodec::TesterCommon105     virtual bool SetEncoderPerFrameParam(BufInfo& buf, const PerFrameParams& param) { return true; }
106     virtual sptr<Surface> CreateInputSurface() = 0;
107     virtual bool NotifyEos() = 0;
108     virtual bool RequestIDR() = 0;
109     virtual std::optional<uint32_t> GetInputStride() = 0;
110     static bool SurfaceBufferToBufferInfo(BufInfo& buf, sptr<SurfaceBuffer> surfaceBuffer);
111     static bool NativeBufferToBufferInfo(BufInfo& buf, OH_NativeBuffer* nativeBuffer);
112     bool WaitForInputSurfaceBuffer(BufInfo& buf);
113     bool ReturnInputSurfaceBuffer(BufInfo& buf);
114     uint32_t ReadOneFrame(ImgBuf& dstImg);
115     static uint32_t ReadOneFrameYUV420P(std::ifstream& src, ImgBuf& dstImg);
116     static uint32_t ReadOneFrameYUV420SP(std::ifstream& src, ImgBuf& dstImg);
117     static uint32_t ReadOneFrameRGBA(std::ifstream& src, ImgBuf& dstImg);
118     sptr<Surface> producerSurface_;
119     uint32_t w_ = 0;
120     uint32_t h_ = 0;
121     GraphicPixelFormat displayFmt_;
122     static constexpr uint32_t BYTES_PER_PIXEL_RBGA = 4;
123     static constexpr uint32_t SAMPLE_RATIO = 2;
124 
125     // decoder only
126     class Listener : public IBufferConsumerListener {
127     public:
Listener(TesterCommon *test)128         explicit Listener(TesterCommon *test) : tester_(test) {}
129         void OnBufferAvailable() override;
130     private:
131         TesterCommon *tester_;
132     };
133 
134     bool RunDecoder();
135     bool InitDemuxer();
136     sptr<Surface> CreateSurfaceNormal();
137     virtual bool SetOutputSurface(sptr<Surface> &surface) = 0;
138     void PrepareSeek();
139     bool SeekIfNecessary(); // false means quit loop
140     virtual bool ConfigureDecoder() = 0;
141     int GetNextSample(const Span &dstSpan, size_t &sampleIdx, bool &isCsd); // return filledLen
142     sptr<Surface> surface_; // consumer
143     std::shared_ptr<StartCodeDetector> demuxer_;
144     size_t totalSampleCnt_ = 0;
145     size_t currSampleIdx_ = 0;
146     std::list<std::pair<size_t, size_t>> userSeekPos_; // seek from which index to which index
147 
148     static bool RunDecEnc(const CommandOpt &decOpt);
149     void SaveVivid(int64_t pts);
150     void CheckVivid(const BufInfo& buf);
151     static std::mutex vividMtx_;
152     static std::unordered_map<int64_t, std::vector<uint8_t>> vividMap_;
153 };
154 } // namespace OHOS::MediaAVCodec
155 #endif