• 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 AVCODEC_AUDIO_AVBUFFER_DECODER_DEMO_H
17 #define AVCODEC_AUDIO_AVBUFFER_DECODER_DEMO_H
18 
19 #include <atomic>
20 #include <fstream>
21 #include <queue>
22 #include <string>
23 #include <thread>
24 
25 #include "audio_renderer.h"
26 #include "native_avcodec_audiocodec.h"
27 #include "nocopyable.h"
28 #include "common/native_mfmagic.h"
29 #include "native_avdemuxer.h"
30 #include "avcodec_audio_common.h"
31 
32 namespace OHOS {
33 namespace MediaAVCodec {
34 namespace AudioBufferDemo {
35 enum class AudioBufferFormatType : int32_t {
36     TYPE_AAC = 0,
37     TYPE_FLAC = 1,
38     TYPE_MP3 = 2,
39     TYPE_VORBIS = 3,
40     TYPE_AMRNB = 4,
41     TYPE_AMRWB = 5,
42     TYPE_vivid = 6,
43     TYPE_OPUS = 7,
44     TYPE_G711MU = 8,
45     TYPE_MAX = 9,
46 };
47 
48 class ADecBufferSignal {
49 public:
50     std::mutex inMutex_;
51     std::mutex outMutex_;
52     std::mutex startMutex_;
53     std::condition_variable inCond_;
54     std::condition_variable outCond_;
55     std::condition_variable startCond_;
56     std::queue<uint32_t> inQueue_;
57     std::queue<uint32_t> outQueue_;
58     std::queue<OH_AVBuffer *> inBufferQueue_;
59     std::queue<OH_AVBuffer *> outBufferQueue_;
60 };
61 
62 /**
63   * @test
64   * @Status {Create, Configure, Start, Running, EOS, Flush, Stop, Reset, Release}
65   * @StatusErrCode AV_ERR_INVALID_STATE
66   * @Allow Create -> Configure
67   * @Allow Configure -> Start
68   * @Allow Start -> {Running, Flush, EOS, Stop}
69   * @Allow Flush -> {Start, Stop}
70   * @Allow Running -> {Running, EOS, Flush, Stop}
71   * @Allow EOS -> {Flush, Stop}
72   * @Allow Stop -> Start
73   * @Allow Reset -> Configure
74   * @Allow {Create, Configure, Start, Running, EOS, Flush, Stop, Reset} -> Reset
75   * @Allow {Create, Configure, Start, Running, EOS, Flush, Stop, Reset} -> Release
76 **/
77 class ADecBufferDemo : public NoCopyable {
78 public:
79     ADecBufferDemo();
80     virtual ~ADecBufferDemo();
81     /**
82       * @functionTest
83       * @input inputFile
84       * @output outputFile
85     **/
86     bool RunCase(std::string inputFile, std::string outputFile);
87 
88     /**
89      * @interfaceTest
90      * @param mime; scope: {OH_AVCODEC_MIMETYPE_AUDIO_AAC, OH_AVCODEC_MIMETYPE_AUDIO_FLAC,
91      *                      OH_AVCODEC_MIMETYPE_AUDIO_MPEG, OH_AVCODEC_MIMETYPE_AUDIO_VORBIS,
92      *                      OH_AVCODEC_MIMETYPE_AUDIO_AMR_NB, OH_AVCODEC_MIMETYPE_AUDIO_AMR_WB,
93      *                      OH_AVCODEC_MIMETYPE_AUDIO_OPUS, OH_AVCODEC_MIMETYPE_AUDIO_G711MU,
94      *                      OH_AVCODEC_MIMETYPE_AUDIO_VIVID};
95      *              default: OH_AVCODEC_MIMETYPE_AUDIO_VIVID;
96      * @Status Create
97      **/
98     OH_AVCodec* CreateByMime(const char* mime);
99 
100     /**
101       * @interfaceTest
102       * @param mime; scope: {"OH.Media.Codec.Decoder.Audio.AAC", "OH.Media.Codec.Decoder.Audio.Flac",
103       *                      "OH.Media.Codec.Decoder.Audio.Mpeg", "OH.Media.Codec.Decoder.Audio.Vorbis",
104       *                      "OH.Media.Codec.Decoder.Audio.Amrnb", "OH.Media.Codec.Decoder.Audio.Amrwb",
105       *                      "OH.Media.Codec.Decoder.Audio.OPUS",
106                              "OH.Media.Codec.Decoder.Audio.G711MU","OH.Media.Codec.Decoder.Audio.Vivid"};
107       *              default: "OH.Media.Codec.Decoder.Audio.Vivid"";
108       * @Status Create
109     **/
110     OH_AVCodec* CreateByName(const char* mime);
111 
112     /**
113       * @interfaceTest
114       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
115       * @free CreateByMime, CreateByName
116       * @Status Release
117       * @return AV_ERR_OK
118     **/
119     OH_AVErrCode Destroy(OH_AVCodec* codec);
120 
121     /**
122       * @interfaceTest
123       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
124       * @return AV_ERR_OK
125     **/
126     OH_AVErrCode SetCallback(OH_AVCodec* codec);
127 
128     /**
129       * @interfaceTest
130       * @Status Configure
131       * @after SetCallback
132       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
133       * @param format; default: OH_AVFormat_Create(); code: AV_ERR_INVALID_VAL;
134       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_AAC
135       * @param channel; scope: [1, 8]; default: 2; code: AV_ERR_INVALID_VAL;
136       * @param sampleRate; scope: {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000};
137       *                    default: 48000; code: AV_ERR_INVALID_VAL;
138       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_FLAC
139       * @param channel; scope: [1, 8]; default: 2; code: AV_ERR_UNSUPPORT;
140       * @param sampleRate; scope: {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000,
141       *                            192000}; default: 48000;
142       *                    code: AV_ERR_UNSUPPORT;
143       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_MPEG
144       * @param channel; scope: [1, 8]; default: 2; code: AV_ERR_INVALID_VAL;
145       * @param sampleRate; scope: {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}; default: 48000;
146       *                    code: AV_ERR_INVALID_VAL;
147       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_VORBIS
148       * @param channel; scope: [1, 8]; default: 2; code: AV_ERR_INVALID_VAL;
149       * @param sampleRate; scope: [8000, 192000]; default: 48000; code: AV_ERR_INVALID_VAL;
150       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_AMR_NB
151       * @param channel; scope: {1}; default: 1; code: AV_ERR_INVALID_VAL;
152       * @param sampleRate; scope: {8000}; default: 8000; code: AV_ERR_INVALID_VAL;
153       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_AMR_WB
154       * @param channel; scope: {1}; default: 1; code: AV_ERR_INVALID_VAL;
155       * @param sampleRate; scope: {16000}; default: 16000; code: AV_ERR_INVALID_VAL;
156       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_OPUS
157       * @param channel; scope: [1, 2]; default: 1; code: AV_ERR_INVALID_VAL;
158       * @param sampleRate; scope: [8000, 12000, 16000, 24000, 48000]; default: 16000; code: AV_ERR_INVALID_VAL;
159       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_G711MU
160       * @param channel; scope: {1}; default: 1; code: AV_ERR_INVALID_VAL;
161       * @param sampleRate; scope: {8000}; default: 8000; code: AV_ERR_INVALID_VAL;
162       * @return AV_ERR_OK
163       * @if mime is OH_AVCODEC_MIMETYPE_AUDIO_VIVID
164       * @param channel; scope: [1,16]; default: 1; code: AV_ERR_INVALID_VAL;
165       * @param sampleRate; scope: {32000,44100,48000,96000,192000}; default: 48000; code: AV_ERR_INVALID_VAL;
166       * @return AV_ERR_OK
167     **/
168     OH_AVErrCode Configure(OH_AVCodec* codec, OH_AVFormat* format, int32_t channel, int32_t sampleRate);
169 
170     /**
171       * @interfaceTest
172       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
173       * @return AV_ERR_OK
174     **/
175     OH_AVErrCode Prepare(OH_AVCodec* codec);
176 
177     /**
178       * @interfaceTest
179       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
180       * @Status Start
181       * @return AV_ERR_OK
182     **/
183     OH_AVErrCode Start(OH_AVCodec* codec);
184 
185     /**
186       * @interfaceTest
187       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
188       * @Status Stop
189       * @return AV_ERR_OK
190     **/
191     OH_AVErrCode Stop(OH_AVCodec* codec);
192 
193     /**
194       * @interfaceTest
195       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
196       * @Status Flush
197       * @return AV_ERR_OK
198     **/
199     OH_AVErrCode Flush(OH_AVCodec* codec);
200 
201     /**
202       * @interfaceTest
203       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
204       * @Status Reset
205       * @return AV_ERR_OK
206     **/
207     OH_AVErrCode Reset(OH_AVCodec* codec);
208 
209     /**
210       * @interfaceTest
211       * @param codec; depend: CreateByMime.return; code: nullptr;
212       * @after Start
213     **/
214     OH_AVFormat* GetOutputDescription(OH_AVCodec* codec);
215 
216     /**
217       * @interfaceTest
218       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
219       * @param index; depend: GetInputIndex.return; scope: [0, 7]; code: AV_ERR_NO_MEMORY;
220       * @param size; scope: [0, 65535]; default: 100; code: AV_ERR_INVALID_VAL;
221       * @param offset; scope: [0, 65535]; default: 0; code: AV_ERR_INVALID_VAL;
222       * @Status Running
223       * @return AV_ERR_OK
224     **/
225     OH_AVErrCode PushInputData(OH_AVCodec* codec, uint32_t index);
226 
227     /**
228       * @interfaceTest
229       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
230       * @param index; depend: GetOutputIndex.return; scope: [0, 7]; code: AV_ERR_NO_MEMORY;
231       * @return AV_ERR_OK
232     **/
233     OH_AVErrCode FreeOutputData(OH_AVCodec* codec, uint32_t index);
234 
235     /**
236       * @interfaceTest
237       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
238       * @param isValid; code: AV_ERR_INVALID_VAL;
239       * @return AV_ERR_OK
240     **/
241     OH_AVErrCode IsValid(OH_AVCodec* codec, bool* isValid);
242 
243     /**
244       * @after Start
245     **/
246     uint32_t GetInputIndex();
247     /**
248       * @interfaceTest
249       * @param codec; depend: CreateByMime.return; code: AV_ERR_INVALID_VAL;
250       * @param index; depend: GetInputIndex.return; scope: [0, 7]; code: AV_ERR_NO_MEMORY;
251       * @Status EOS
252       * @return AV_ERR_OK
253     **/
254     OH_AVErrCode PushInputDataEOS(OH_AVCodec* codec, uint32_t index);
255 
256     /**
257       * @after PushInputDataEOS
258     **/
259     uint32_t GetOutputIndex();
260 
261     OH_AVErrCode SetParameter(OH_AVCodec* codec, OH_AVFormat* format, int32_t channel, int32_t sampleRate);
262 
263    private:
264     int32_t CreateDec();
265     int32_t Configure(OH_AVFormat *format);
266     int32_t Start();
267     int32_t Stop();
268     int32_t Flush();
269     int32_t Reset();
270     int32_t Release();
271     void InputFunc();
272     void OutputFunc();
273     void HandleInputEOS(const uint32_t index);
274     bool InitFile(std::string inputFile, std::string outputFile);
275     void CreatDeMuxer(const std::string inputFile);
276     bool ReadBuffer(OH_AVBuffer *buffer, uint32_t index);
277 
278     std::atomic<bool> isRunning_ = false;
279     std::unique_ptr<std::ifstream> testFile_;
280     std::unique_ptr<std::thread> inputLoop_;
281     std::unique_ptr<std::thread> outputLoop_;
282     OH_AVCodec *audioDec_;
283     ADecBufferSignal *signal_;
284     struct OH_AVCodecCallback cb_;
285     bool isFirstFrame_ = true;
286     uint32_t frameCount_ = 0;
287     std::ifstream inputFile_;
288     std::ofstream pcmOutputFile_;
289     AudioBufferFormatType audioType_;
290     std::string inputFile_str;
291     std::string outputFile_str;
292     int32_t trackIndex_;
293     int fd;
294     OH_AVSource* avsource_ = nullptr;
295     OH_AVDemuxer* avdemuxer_ = nullptr;
296     OH_AVFormat* trackFormat = nullptr;
297     std::unique_ptr<OHOS::AudioStandard::AudioRenderer> audioRenderer = nullptr;
298 };
299 } // namespace AudioBufferDemo
300 } // namespace MediaAVCodec
301 } // namespace OHOS
302 #endif // AVCODEC_AUDIO_AVBUFFER_DECODER_DEMO_H
303