• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 AVDECODER_DEMO_COMMON_H
17 #define AVDECODER_DEMO_COMMON_H
18 
19 #include <iostream>
20 #include <atomic>
21 #include <fstream>
22 #include <queue>
23 #include <string>
24 #include <vector>
25 #include <thread>
26 #include <sys/time.h>
27 
28 #include "securec.h"
29 #include "media_description.h"
30 #include "avcodec_audio_decoder.h"
31 #include "nocopyable.h"
32 #include "native_avcodec_audiodecoder.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 #include "libavformat/avformat.h"
38 #include "libavutil/opt.h"
39 #ifdef __cplusplus
40 }
41 #endif
42 
43 namespace OHOS {
44     namespace MediaAVCodec {
45         extern void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData);
46         extern void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData);
47         extern void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData);
48         extern void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data,
49             OH_AVCodecBufferAttr* attr, void* userData);
50 
51         constexpr double DEFAULT_TIME_NUM = 1000000.0;
52         constexpr int32_t CODE_ERROR = -1;
53         constexpr uint32_t ERROR_INDEX = 100;
54 
55         typedef enum MyTimer {
56             TIMER_NONE = 0,
57             TIMER_INPUT = 1,
58             TIMER_FREEOUTPUT = 2,
59             TIMER_GETOUTPUTDESCRIPTION = 3
60         } MyTimer;
61 
62         class ADecSignal {
63         public:
64             std::mutex inMutex_;
65             std::mutex outMutex_;
66             std::condition_variable inCond_;
67             std::condition_variable outCond_;
68             std::queue<uint32_t> inQueue_;
69             std::queue<uint32_t> outQueue_;
70             std::queue<OH_AVMemory*> inBufferQueue_;
71             std::queue<OH_AVMemory*> outBufferQueue_;
72             std::queue<OH_AVCodecBufferAttr> attrQueue_;
73             std::queue<AVCodecBufferInfo> infoQueue_;
74             std::queue<AVCodecBufferFlag> flagQueue_;
75             std::queue<std::shared_ptr<AVSharedMemory>> inInnerBufQueue_;
76             std::queue<std::shared_ptr<AVSharedMemory>> outInnerBufQueue_;
77         };
78         class InnerADecDemoCallback : public AVCodecCallback, public NoCopyable {
79         public:
80             explicit InnerADecDemoCallback(std::shared_ptr<ADecSignal> signal);
81             ~InnerADecDemoCallback() = default;
82 
83             void OnError(AVCodecErrorType errorType, int32_t errorCode) override;
84             void OnOutputFormatChanged(const Format& format) override;
85             void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override;
86             void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
87                 std::shared_ptr<AVSharedMemory> buffer) override;
88         private:
89             std::shared_ptr<ADecSignal> innersignal_;
90         };
91 
92         class AudioDecoderDemo : public NoCopyable {
93         public:
94             AudioDecoderDemo();
95             ~AudioDecoderDemo();
96 
97             // native api
98             OH_AVCodec* NativeCreateByMime(const char* mime);
99             OH_AVCodec* NativeCreateByName(const char* name);
100             OH_AVErrCode NativeDestroy(OH_AVCodec *codec);
101             OH_AVErrCode NativeSetCallback(OH_AVCodec* codec, OH_AVCodecAsyncCallback callback);
102             OH_AVErrCode NativeConfigure(OH_AVCodec* codec, OH_AVFormat* format);
103             OH_AVErrCode NativePrepare(OH_AVCodec* codec);
104             OH_AVErrCode NativeStart(OH_AVCodec* codec);
105             OH_AVErrCode NativeStop(OH_AVCodec* codec);
106             OH_AVErrCode NativeFlush(OH_AVCodec* codec);
107             OH_AVErrCode NativeReset(OH_AVCodec* codec);
108             OH_AVFormat* NativeGetOutputDescription(OH_AVCodec* codec);
109             OH_AVErrCode NativeSetParameter(OH_AVCodec* codec, OH_AVFormat* format);
110             OH_AVErrCode NativePushInputData(OH_AVCodec* codec, uint32_t index, OH_AVCodecBufferAttr attr);
111             OH_AVErrCode NativeFreeOutputData(OH_AVCodec* codec, uint32_t index);
112             OH_AVErrCode NativeIsValid(OH_AVCodec* codec, bool* isVaild);
113 
114             void stopThread();
115             void updateInputData();
116             void updateOutputData();
117 
118             void setTimerFlag(int32_t flag);
119 
120             uint32_t NativeGetInputIndex();
121             uint8_t* NativeGetInputBuf();
122             uint32_t NativeGetOutputIndex();
123 
124             void HandleEOS(const uint32_t& index);
125             int32_t NativePushInput(uint32_t index, OH_AVMemory* buffer);
126             void NativeGetDescription();
127             void NativeWriteOutput(std::ofstream& pcmFile, uint32_t index,
128                 OH_AVCodecBufferAttr attr, OH_AVMemory* data);
129 
130             void NativeInputFunc();
131             void NativeOutputFunc();
132             void NativeGetVorbisConf(OH_AVFormat* format);
133             void NativeCreateToStart(const char* name, OH_AVFormat* format);
134             void NativeStopDec();
135             void NativeFFmpegConf(const char* name, OH_AVFormat* format);
136             void NativeCloseFFmpeg();
137             void NativeStopAndClear();
138 
139             void NativeRunCase(std::string inputFile, std::string outputFile,
140                 const char* name, OH_AVFormat* format);
141             void NativeRunCaseWithoutCreate(OH_AVCodec* handle, std::string inputFile, std::string outputFile,
142                 OH_AVFormat* format, const char* name, bool needConfig);
143             void NativeRunCasePerformance(std::string inputFile, std::string outputFile,
144                 const char* name, OH_AVFormat* format);
145             void NativeRunCaseFlush(std::string inputFile, std::string outputFileFirst,
146                 std::string outputFileSecond, const char* name, OH_AVFormat* format);
147             void NativeRunCaseReset(std::string inputFile, std::string outputFileFirst,
148                 std::string outputFileSecond, const char* name, OH_AVFormat* format);
149             OH_AVFormat* NativeRunCaseGetOutputDescription(std::string inputFile,
150                 std::string outputFile, const char* name, OH_AVFormat* format);
151 
152             // for test
153             int32_t TestReadDatFile(uint32_t index, OH_AVMemory* buffer);
154             void TestInputFunc();
155             void TestRunCase(std::string inputFile, std::string outputFile, const char* name, OH_AVFormat* format);
156             void TestFFmpeg(std::string inputFile);
157 
158             // Inner api
159             int32_t InnerCreateByMime(const std::string& mime);
160             int32_t InnerCreateByName(const std::string& name);
161             int32_t InnerConfigure(const Format& format);
162             int32_t InnerPrepare();
163             int32_t InnerStart();
164             int32_t InnerStop();
165             int32_t InnerFlush();
166             int32_t InnerReset();
167             int32_t InnerRelease();
168             int32_t InnerQueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag);
169 
170             int32_t InnerGetOutputFormat(Format& format);
171             int32_t InnerReleaseOutputBuffer(uint32_t index);
172             int32_t InnerSetParameter(const Format& format);
173             int32_t InnerSetCallback(const std::shared_ptr<AVCodecCallback>& callback);
174             int32_t InnerDestroy();
175             void InnerInputFunc();
176             uint32_t InnerInputFuncRead(uint32_t index);
177             void InnerOutputFunc();
178             void InnerRunCase(std::string inputFile, std::string outputFile,
179                 const std::string& name, Format& format);
180 
181             void InnerRunCaseOHVorbis(const std::string& name, Format& format);
182             int InnerRunCasePre();
183 
184             void InnerRunCaseFlush(std::string inputFile, std::string outputFileFirst,
185                 std::string outputFileSecond, const std::string& name, Format& format);
186 
187             void InnerRunCaseFlushPost();
188             int InnerRunCaseFlushPre();
189             void InnerRunCaseFlushOHVorbis(const std::string& name, Format& format);
190             void InnerRunCaseFlushAlloc(Format& format);
191 
192             void InnerRunCaseReset(std::string inputFile, std::string outputFileFirst,
193                 std::string outputFileSecond, const std::string& name, Format& format);
194 
195             void InnerRunCaseResetPost();
196             int InnerRunCaseResetPre();
197             void InnerRunCaseResetOHVorbis(const std::string& name, Format& format);
198             void InnerRunCaseResetAlloc(Format& format);
199             void InnerRunCaseResetInPut();
200 
201             void InnerStopThread();
202             void InnerUpdateInputData();
203             void InnerUpdateOutputData();
204             std::shared_ptr<ADecSignal> getSignal();
205 
206         private:
207             std::atomic<bool> isRunning_ = false;
208             std::unique_ptr<std::thread> inputLoop_;
209             std::unique_ptr<std::thread> outputLoop_;
210             OH_AVCodec* audioDec_;
211             ADecSignal* signal_;
212             struct OH_AVCodecAsyncCallback cb_;
213             bool isFirstFrame_ = true;
214 
215             std::ifstream inputFile_;
216             std::shared_ptr<AVCodecAudioDecoder> inneraudioDec_;
217             std::shared_ptr<ADecSignal> innersignal_;
218             std::shared_ptr<InnerADecDemoCallback> innercb_;
219             uint32_t frameCount_ = 0;
220 
221             std::queue<uint32_t> inIndexQueue_;
222             std::queue<uint8_t*> inBufQueue_;
223             std::queue<uint32_t> outIndexQueue_;
224 
225             std::string outputFilePath;
226             std::string inputFilePath;
227             OH_AVFormat* curFormat = nullptr;
228             bool isGetOutputDescription = false;
229 
230             int32_t timerFlag = 0;
231             int32_t runTimes = 0;
232             double totalTime = 0.0;
233             double otherTime = 0.0;
234             struct timeval startTime, endTime;
235             struct timeval start, end;
236             struct timeval inputStart, inputEnd;
237             struct timeval outputStart, outputEnd;
238 
239             AVFormatContext* fmpt_ctx = nullptr;
240             AVFrame* frame;
241             AVPacket pkt;
242             AVCodecContext* codec_ctx = nullptr;
243         };
244     }
245 }
246 #endif // AVDECODER_DEMO_COMMON_H