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