1 /*
2  * Copyright (C) 2024 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 AUDIO_DECODER_DEMO_BASE_H
17 #define AUDIO_DECODER_DEMO_BASE_H
18 
19 #include <atomic>
20 #include <fstream>
21 #include <queue>
22 #include <string>
23 #include <thread>
24 
25 #include "native_avcodec_audiodecoder.h"
26 #include "nocopyable.h"
27 #include "avcodec_audio_common.h"
28 
29 namespace OHOS {
30 namespace MediaAVCodec {
31 namespace AudioDemoAuto {
32 extern void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData);
33 extern void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData);
34 extern void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData);
35 extern void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data,
36     OH_AVCodecBufferAttr* attr, void* userData);
37 
38 enum AudioFormatType : int32_t {
39     TYPE_AAC = 0,
40     TYPE_FLAC = 1,
41     TYPE_MP3 = 2,
42     TYPE_VORBIS = 3,
43     TYPE_AMRNB = 4,
44     TYPE_AMRWB = 5,
45     TYPE_OPUS = 6,
46     TYPE_G711MU = 7,
47     TYPE_MAX = 10,
48 };
49 
50 class ADecSignal {
51 public:
52     std::mutex inMutex_;
53     std::mutex outMutex_;
54     std::mutex startMutex_;
55     std::condition_variable inCond_;
56     std::condition_variable outCond_;
57     std::condition_variable startCond_;
58     std::queue<uint32_t> inQueue_;
59     std::queue<uint32_t> outQueue_;
60     std::queue<OH_AVMemory*> inBufferQueue_;
61     std::queue<OH_AVMemory*> outBufferQueue_;
62     std::queue<OH_AVCodecBufferAttr> attrQueue_;
63 };
64 
65 class ADecDemoAuto : public NoCopyable {
66 public:
67     ADecDemoAuto();
68     virtual ~ADecDemoAuto();
69     bool InitFile(std::string inputFile);
70     bool RunCase(const uint8_t *data, size_t size);
71 
72     OH_AVCodec* CreateByMime(const char* mime);
73 
74     OH_AVCodec* CreateByName(const char* mime);
75 
76     OH_AVErrCode Destroy(OH_AVCodec* codec);
77 
78     OH_AVErrCode SetCallback(OH_AVCodec* codec);
79 
80     OH_AVErrCode Configure(OH_AVCodec* codec, OH_AVFormat* format, int32_t channel, int32_t sampleRate);
81 
82     OH_AVErrCode Prepare(OH_AVCodec* codec);
83 
84     OH_AVErrCode Start(OH_AVCodec* codec);
85 
86     OH_AVErrCode Stop(OH_AVCodec* codec);
87 
88     OH_AVErrCode Flush(OH_AVCodec* codec);
89 
90     OH_AVErrCode Reset(OH_AVCodec* codec);
91 
92     OH_AVFormat* GetOutputDescription(OH_AVCodec* codec);
93 
94     OH_AVErrCode PushInputData(OH_AVCodec* codec, uint32_t index, int32_t size, int32_t offset);
95 
96     OH_AVErrCode PushInputDataEOS(OH_AVCodec* codec, uint32_t index);
97 
98     OH_AVErrCode FreeOutputData(OH_AVCodec* codec, uint32_t index);
99 
100     OH_AVErrCode IsValid(OH_AVCodec* codec, bool* isValid);
101 
102     uint32_t GetInputIndex();
103 
104     uint32_t GetOutputIndex();
105 private:
106     void ClearQueue();
107     int32_t CreateDec();
108     int32_t Configure(OH_AVFormat* format);
109     int32_t Start();
110     int32_t Stop();
111     int32_t Flush();
112     int32_t Reset();
113     int32_t Release();
114     void InputFunc();
115     void OutputFunc();
116     void HandleInputEOS(const uint32_t index);
117     bool InitFormat(OH_AVFormat *format);
118     int32_t HandleNormalInput(const uint32_t& index, const int64_t pts, const size_t size);
119 
120     std::atomic<bool> isRunning_ = false;
121     std::unique_ptr<std::thread> inputLoop_;
122     std::unique_ptr<std::thread> outputLoop_;
123     OH_AVCodec* audioDec_;
124     ADecSignal* signal_;
125     struct OH_AVCodecAsyncCallback cb_;
126     bool isFirstFrame_ = true;
127     uint32_t frameCount_ = 0;
128     AudioFormatType audioType_;
129     OH_AVFormat* format_;
130     size_t inputdatasize;
131     std::string inputdata;
132 };
133 } // namespace AudioDemoAuto
134 } // namespace MediaAVCodec
135 } // namespace OHOS
136 #endif // AUDIO_DECODER_DEMO_BASE_H
137