1# Audio Decoding 2 3You can call the native APIs provided by the **AudioDecoder** module to decode audio, that is, to decode media data into PCM streams. 4 5Currently, the following decoding capabilities are supported: 6 7| Container Specification| Audio Decoding Type | 8| -------- | :--------------------------- | 9| mp4 | AAC, MPEG (MP3), FLAC, Vorbis| 10| m4a | AAC | 11| flac | FLAC | 12| ogg | Vorbis | 13| aac | AAC | 14| mp3 | MPEG (MP3) | 15 16**Usage Scenario** 17 18- Audio playback 19 20 Decode audio and transmit the data to the speaker for playing. 21- Audio rendering 22 23 Decode audio and transmit the data to the audio processing module for audio rendering. 24- Audio editing 25 26 Decode audio and transmit the data for audio editing (for example, adjusting the playback speed of a channel). Audio editing is performed based on PCM streams. 27 28## How to Develop 29 30Read [AudioDecoder](../reference/native-apis/_audio_decoder.md) for the API reference. 31 32Refer to the code snippet below to complete the entire audio decoding process, including creating a decoder, setting decoding parameters (such as the sampling rate, bit rate, and number of audio channels), and starting, refreshing, resetting, and destroying the decoder. 33 34During application development, you must call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur. 35 36For details about the complete code, see [Sample](https://gitee.com/openharmony/multimedia_av_codec/blob/master/test/nativedemo/audio_demo/avcodec_audio_decoder_demo.cpp). 37 38The figure below shows the call relationship of audio decoding. 39 40 41 42### Linking the Dynamic Library in the CMake Script 43``` cmake 44target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 45target_link_libraries(sample PUBLIC libnative_media_core.so) 46target_link_libraries(sample PUBLIC libnative_media_adec.so) 47``` 48 49### How to Develop 50 511. Create a decoder instance. 52 53 ```cpp 54 // Namespace of the C++ standard library. 55 using namespace std; 56 // Create a decoder by name. 57 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_MPEG, false); 58 const char *name = OH_AVCapability_GetName(capability); 59 OH_AVCodec *audioDec = OH_AudioDecoder_CreateByName(name); 60 ``` 61 62 ```cpp 63 // Create a decoder by MIME type. 64 OH_AVCodec *audioDec = OH_AudioDecoder_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_MPEG); 65 ``` 66 67 ```cpp 68 // Initialize the queues. 69 class ADecSignal { 70 public: 71 mutex inMutex_; 72 mutex outMutex_; 73 mutex startMutex_; 74 condition_variable inCond_; 75 condition_variable outCond_; 76 condition_variable startCond_; 77 queue<uint32_t> inQueue_; 78 queue<uint32_t> outQueue_; 79 queue<OH_AVMemory *> inBufferQueue_; 80 queue<OH_AVMemory *> outBufferQueue_; 81 queue<OH_AVCodecBufferAttr> attrQueue_; 82 }; 83 ADecSignal *signal_; 84 ``` 85 862. Call **OH_AudioDecoder_SetCallback()** to set callback functions. 87 88 Register the **OH_AVCodecAsyncCallback** struct that defines the following callback function pointers: 89 90 - **OH_AVCodecOnError**, a callback used to report a codec operation error 91 - **OH_AVCodecOnStreamChanged**, a callback used to report a codec stream change, for example, audio channel change 92 - **OH_AVCodecOnNeedInputData**, a callback used to report input data required, which means that the decoder is ready for receiving data 93 - **OH_AVCodecOnNewOutputData**, a callback used to report output data generated, which means that decoding is complete 94 95 You need to process the callback functions to ensure that the decoder runs properly. 96 97 ```cpp 98 // Implement the OH_AVCodecOnError callback function. 99 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) 100 { 101 (void)codec; 102 (void)errorCode; 103 (void)userData; 104 } 105 // Implement the OH_AVCodecOnStreamChanged callback function. 106 static void OnStreamChanged(OH_AVCodec *codec, OH_AVFormat *format, void*userData) 107 { 108 (void)codec; 109 (void)format; 110 (void)userData; 111 } 112 // Implement the OH_AVCodecOnNeedInputData callback function. 113 static void onNeedInputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory*data, void *userData) 114 { 115 (void)codec; 116 ADecSignal *signal = static_cast<ADecSignal *>(userData); 117 unique_lock<mutex> lock(signal->inMutex_); 118 signal->inQueue_.push(index); 119 signal->inBufferQueue_.push(data); 120 signal->inCond_.notify_all(); 121 // The input stream is sent to the InputBuffer queue. 122 } 123 // Implement the OH_AVCodecOnNewOutputData callback function. 124 static void onNeedOutputData(OH_AVCodec *codec, uint32_t index, OH_AVMemory*data, OH_AVCodecBufferAttr *attr, 125 void *userData) 126 { 127 (void)codec; 128 ADecSignal *signal = static_cast<ADecSignal *>(userData); 129 unique_lock<mutex> lock(signal->outMutex_); 130 signal->outQueue_.push(index); 131 signal->outBufferQueue_.push(data); 132 if (attr) { 133 signal->attrQueue_.push(*attr); 134 } 135 signal->outCond_.notify_all(); 136 // The index of the output buffer is sent to OutputQueue_. 137 // The decoded data is sent to the OutputBuffer queue. 138 } 139 signal_ = new ADecSignal(); 140 OH_AVCodecAsyncCallback cb = {&OnError, &OnStreamChanged, &onNeedInputData, &onNeedOutputData}; 141 // Set the asynchronous callbacks. 142 int32_t ret = OH_AudioDecoder_SetCallback(audioDec, cb, signal_); 143 if (ret != AV_ERR_OK) { 144 // Exception handling. 145 } 146 ``` 1473. Call **OH_AudioDecoder_Configure()** to configure the decoder. 148 149 The following options are mandatory: sampling rate, bit rate, and number of audio channels. The maximum input length is optional. 150 151 - For AAC decoding, the parameter that specifies whether the data type is Audio Data Transport Stream (ADTS) must be specified. If this parameter is not specified, the data type is considered as Low Overhead Audio Transport Multiplex (LATM). 152 153 ```cpp 154 // Set the decoding resolution. 155 int32_t ret; 156 // (Mandatory) Configure the audio sampling rate. 157 constexpr uint32_t DEFAULT_SMAPLERATE = 44100; 158 // (Mandatory) Configure the audio bit rate. 159 constexpr uint32_t DEFAULT_BITRATE = 32000; 160 // (Mandatory) Configure the number of audio channels. 161 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 162 // (Optional) Configure the maximum input length. 163 constexpr uint32_t DEFAULT_MAX_INPUT_SIZE = 1152; 164 // Configure whether to use ADTS decoding (ACC). 165 constexpr uint32_t DEFAULT_AAC_TYPE = 1; 166 OH_AVFormat *format = OH_AVFormat_Create(); 167 // Set the format. 168 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE,DEFAULT_SMAPLERATE); 169 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITRATE,DEFAULT_BITRATE); 170 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT,DEFAULT_CHANNEL_COUNT); 171 OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE,DEFAULT_MAX_INPUT_SIZE); 172 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE); 173 // Configure the decoder. 174 ret = OH_AudioDecoder_Configure(audioDec, format); 175 if (ret != AV_ERR_OK) { 176 // Exception handling. 177 } 178 ``` 179 1804. Call **OH_AudioDecoder_Prepare()** to prepare internal resources for the decoder. 181 182 ```cpp 183 ret = OH_AudioDecoder_Prepare(audioDec); 184 if (ret != AV_ERR_OK) { 185 // Exception handling. 186 } 187 ``` 1885. Call **OH_AudioDecoder_Start()** to start the decoder. 189 190 ```c++ 191 unique_ptr<ifstream> inputFile_ = make_unique<ifstream>(); 192 unique_ptr<ofstream> outFile_ = make_unique<ofstream>(); 193 // Open the path of the binary file to be decoded. 194 inputFile_->open(inputFilePath.data(), ios::in | ios::binary); 195 // Configure the path of the output file. 196 outFile_->open(outputFilePath.data(), ios::out | ios::binary); 197 // Start decoding. 198 ret = OH_AudioDecoder_Start(audioDec); 199 if (ret != AV_ERR_OK) { 200 // Exception handling. 201 } 202 ``` 2036. Call **OH_AudioDecoder_PushInputData()** to write the data to decode. 204 205 To indicate the End of Stream (EOS), pass in the **AVCODEC_BUFFER_FLAGS_EOS** flag. 206 ```c++ 207 // Configure the buffer information. 208 OH_AVCodecBufferAttr info; 209 // Set the size, offset, and timestamp. 210 auto buffer = signal_->inBufferQueue_.front(); 211 int64_t size; 212 int64_t pts; 213 inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size)); 214 if (inputFile_->eof()) { 215 size = 0; 216 info.flags = AVCODEC_BUFFER_FLAGS_EOS; 217 } else { 218 inputFile_.read(reinterpret_cast<char *>(&pts), sizeof(pts)); 219 inputFile_.read((char *)OH_AVMemory_GetAddr(buffer), size); 220 info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; 221 } 222 info.size = size; 223 info.offset = 0; 224 info.pts = pts; 225 uint32_t index = signal_->inQueue_.front(); 226 // Send the data to the input queue for decoding. The index is the subscript of the queue. 227 int32_t ret = OH_AudioDecoder_PushInputData(audioDec, index, info); 228 if (ret != AV_ERR_OK) { 229 // Exception handling. 230 } 231 ``` 2327. Call **OH_AudioDecoder_FreeOutputData()** to output decoded PCM streams. 233 234 ```c++ 235 OH_AVCodecBufferAttr attr = signal_->attrQueue_.front(); 236 OH_AVMemory *data = signal_->outBufferQueue_.front(); 237 uint32_t index = signal_->outQueue_.front(); 238 // Write the decoded data (specified by data) to the output file. 239 outFile_->write(reinterpret_cast<char *>(OH_AVMemory_GetAddr(data)), attr.size); 240 // Free the buffer that stores the data. 241 ret = OH_AudioDecoder_FreeOutputData(audioDec, index); 242 if (ret != AV_ERR_OK) { 243 // Exception handling. 244 } 245 ``` 2468. (Optional) Call **OH_AudioDecoder_Flush()** to refresh the decoder. 247 248 After **OH_AudioDecoder_Flush()** is called, the decoder remains in the running state, but the current queue is cleared and the buffer storing the decoded data is freed. To continue decoding, you must call **OH_AudioDecoder_Start()** again. 249 250 You need to call **OH_AudioDecoder_Start()** in the following cases: 251 * The EOS of the file is reached. 252 * An error with **OH_AudioDecoder_IsValid** set to **true** (indicating that the execution can continue) occurs. 253 ```c++ 254 // Refresh the decoder. 255 ret = OH_AudioDecoder_Flush(audioDec); 256 if (ret != AV_ERR_OK) { 257 // Exception handling. 258 } 259 // Start decoding again. 260 ret = OH_AudioDecoder_Start(audioDec); 261 if (ret != AV_ERR_OK) { 262 // Exception handling. 263 } 264 ``` 2659. (Optional) Call **OH_AudioDecoder_Reset()** to reset the decoder. 266 267 After **OH_AudioDecoder_Reset()** is called, the decoder returns to the initialized state. To continue decoding, you must call **OH_AudioDecoder_Configure()** and then **OH_AudioDecoder_Start()**. 268 269 ```c++ 270 // Reset the decoder. 271 ret = OH_AudioDecoder_Reset(audioDec); 272 if (ret != AV_ERR_OK) { 273 // Exception handling. 274 } 275 // Reconfigure the decoder. 276 ret = OH_AudioDecoder_Configure(audioDec, format); 277 if (ret != AV_ERR_OK) { 278 // Exception handling. 279 } 280 ``` 28110. Call **OH_AudioDecoder_Stop()** to stop the decoder. 282 283 ```c++ 284 // Stop the decoder. 285 ret = OH_AudioDecoder_Stop(audioDec); 286 if (ret != AV_ERR_OK) { 287 // Exception handling. 288 } 289 ``` 29011. Call **OH_AudioDecoder_Destroy()** to destroy the decoder instance and release resources. 291 292 **NOTE**: You only need to call this API once. 293 294 ```c++ 295 // Call OH_AudioDecoder_Destroy to destroy the decoder. 296 ret = OH_AudioDecoder_Destroy(audioDec); 297 if (ret != AV_ERR_OK) { 298 // Exception handling. 299 } else { 300 audioDec = NULL; // The decoder cannot be destroyed repeatedly. 301 } 302 ``` 303