1# Audio Decoding 2 3You can call the native APIs provided by the AudioCodec module to decode audio, that is, to decode media data into PCM streams. 4 5Currently, the following decoding capabilities are supported: 6 7| Container Format| Audio Decoding Type | 8| -------- | :--------------------------- | 9| mp4 | AAC, MPEG (MP3), FLAC, Vorbis<!--RP1--><!--RP1End--> | 10| m4a | AAC | 11| flac | FLAC | 12| ogg | Vorbis<!--RP2--><!--RP2End--> | 13| aac | AAC | 14| mp3 | MPEG (MP3) | 15| amr | AMR (AMR-NB and AMR-WB) | 16| raw | G711mu | 17| ape | APE | 18 19**Usage Scenario** 20 21- Audio playback 22 23 Decode audio and transmit the data to the speaker for playing. 24- Audio rendering 25 26 Decode audio and transmit the data to the audio processing module for audio rendering. 27- Audio editing 28 29 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. 30> **NOTE** 31> 32> Streams generated in the MP3 audio encoding process cannot be directly decoded through the MP3 audio decoding process. The following process is recommended: PCM stream -> MP3 audio encoding -> muxing -> demuxing -> MP3 audio decoding. 33 34## How to Develop 35 36Read [AudioCodec](../../reference/apis-avcodec-kit/_audio_codec.md) for the API reference. 37 38Refer 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. 39 40During application development, you must call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur. 41 42The figure below shows the call relationship of audio decoding. 43 44- The dotted line indicates an optional operation. 45 46- The solid line indicates a mandatory operation. 47 48 49 50### Linking the Dynamic Libraries in the CMake Script 51 52```cmake 53target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 54target_link_libraries(sample PUBLIC libnative_media_core.so) 55target_link_libraries(sample PUBLIC libnative_media_acodec.so) 56``` 57 58### How to Develop 59 601. Add the header files. 61 62 ```cpp 63 #include <multimedia/player_framework/native_avcodec_audiocodec.h> 64 #include <multimedia/native_audio_channel_layout.h> 65 #include <multimedia/player_framework/native_avcapability.h> 66 #include <multimedia/player_framework/native_avcodec_base.h> 67 #include <multimedia/player_framework/native_avformat.h> 68 #include <multimedia/player_framework/native_avbuffer.h> 69 ``` 70 712. Create a decoder instance. In the code snippet below, **OH_AVCodec *** is the pointer to the decoder instance created. 72 73 ```cpp 74 // Namespace of the C++ standard library. 75 using namespace std; 76 // Create a decoder by name. 77 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_MPEG, false); 78 const char *name = OH_AVCapability_GetName(capability); 79 OH_AVCodec *audioDec_ = OH_AudioCodec_CreateByName(name); 80 ``` 81 82 ```cpp 83 // Specify whether encoding is used. The value false means decoding. 84 bool isEncoder = false; 85 // Create a decoder by MIME type. 86 OH_AVCodec *audioDec_ = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_MPEG, isEncoder); 87 ``` 88 89 ```cpp 90 // Initialize the queues. 91 class ADecBufferSignal { 92 public: 93 std::mutex inMutex_; 94 std::mutex outMutex_; 95 std::mutex startMutex_; 96 std::condition_variable inCond_; 97 std::condition_variable outCond_; 98 std::condition_variable startCond_; 99 std::queue<uint32_t> inQueue_; 100 std::queue<uint32_t> outQueue_; 101 std::queue<OH_AVBuffer *> inBufferQueue_; 102 std::queue<OH_AVBuffer *> outBufferQueue_; 103 }; 104 ADecBufferSignal *signal_; 105 ``` 106 1073. Call **OH_AudioCodec_RegisterCallback()** to register callback functions. 108 109 Register the **OH_AVCodecCallback** struct that defines the following callback function pointers: 110 111 - **OH_AVCodecOnError**, a callback used to report a codec operation error 112 - **OH_AVCodecOnStreamChanged**, a callback used to report a codec stream change, for example, audio channel change 113 - **OH_AVCodecOnNeedInputBuffer**, a callback used to report input data required, which means that the decoder is ready for receiving data 114 - **OH_AVCodecOnNewOutputBuffer**, a callback used to report output data generated, which means that decoding is complete 115 116 You need to process the callback functions to ensure that the decoder runs properly. 117 118 ```cpp 119 // Implement the OH_AVCodecOnError callback function. 120 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) 121 { 122 (void)codec; 123 (void)errorCode; 124 (void)userData; 125 } 126 // Implement the OH_AVCodecOnStreamChanged callback function. 127 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) 128 { 129 (void)codec; 130 (void)format; 131 (void)userData; 132 } 133 // Implement the OH_AVCodecOnNeedInputBuffer callback function. 134 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 135 { 136 (void)codec; 137 ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData); 138 unique_lock<mutex> lock(signal->inMutex_); 139 signal->inQueue_.push(index); 140 signal->inBufferQueue_.push(data); 141 signal->inCond_.notify_all(); 142 // The input stream is sent to inBufferQueue_. 143 } 144 // Implement the OH_AVCodecOnNewOutputBuffer callback function. 145 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 146 { 147 (void)codec; 148 ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData); 149 unique_lock<mutex> lock(signal->outMutex_); 150 signal->outQueue_.push(index); 151 signal->outBufferQueue_.push(data); 152 signal->outCond_.notify_all(); 153 // The index of the output buffer is sent to outQueue_. 154 // The decoded data is sent to outBufferQueue_. 155 } 156 signal_ = new ADecBufferSignal(); 157 OH_AVCodecCallback cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; 158 int32_t ret = OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_); 159 if (ret != AVCS_ERR_OK) { 160 // Exception handling. 161 } 162 ``` 163 1644. (Optional) Call **OH_AudioCodec_SetDecryptionConfig** to set the decryption configuration. Call this API after the media key system information is obtained but before **Prepare()** is called. For details about how to obtain such information, see step 3 in [Media Data Demuxing](audio-video-demuxer.md). For details about DRM APIs, see [DRM](../../reference/apis-drm-kit/_drm.md). 165 166 Add the header files. 167 168 ```c++ 169 #include <multimedia/drm_framework/native_mediakeysystem.h> 170 #include <multimedia/drm_framework/native_mediakeysession.h> 171 #include <multimedia/drm_framework/native_drm_err.h> 172 #include <multimedia/drm_framework/native_drm_common.h> 173 ``` 174 Link the dynamic library in the CMake script. 175 176 ``` cmake 177 target_link_libraries(sample PUBLIC libnative_drm.so) 178 ``` 179 180 The following is the sample code: 181 ```c++ 182 // Create a media key system based on the media key system information. The following uses com.clearplay.drm as an example. 183 MediaKeySystem *system = nullptr; 184 int32_t ret = OH_MediaKeySystem_Create("com.clearplay.drm", &system); 185 if (system == nullptr) { 186 printf("create media key system failed"); 187 return; 188 } 189 190 // Create a media key session. 191 MediaKeySession *session = nullptr; 192 DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; 193 ret = OH_MediaKeySystem_CreateMediaKeySession(system, &contentProtectionLevel, &session); 194 if (ret != DRM_OK) { 195 // If the creation fails, refer to the DRM interface document and check logs. 196 printf("create media key session failed."); 197 return; 198 } 199 if (session == nullptr) { 200 printf("media key session is nullptr."); 201 return; 202 } 203 // Generate a media key request and set the response to the media key request. 204 // Set the decryption configuration, that is, set the decryption session and secure channel flag to the decoder. (Currently, the secure channel is not supported for audio decryption and therefore the secure channel flag should be set to false.) 205 bool secureAudio = false; 206 ret = OH_AudioCodec_SetDecryptionConfig(audioDec_, session, secureAudio); 207 ``` 208 2095. Call **OH_AudioCodec_Configure()** to configure the decoder. 210 211 Key values of configuration options are described as follows: 212 213 | | Description | AAC | FLAC| Vorbis | MPEG | G711mu | AMR (AMR-NB and AMR-WB) | APE | 214 | ---------------------------- | :----------------------------------------------------------: | :--------------------------------: | :--: | :--------------------------------: | :--: | :-----------------: | :-------------------------------: | :-------------------------------: | 215 | OH_MD_KEY_AUD_SAMPLE_RATE | Sampling rate | Mandatory | Mandatory| Mandatory | Mandatory| Mandatory | Mandatory | Mandatory | 216 | OH_MD_KEY_AUD_CHANNEL_COUNT | Number of audio channels | Mandatory | Mandatory| Mandatory | Mandatory| Mandatory | Mandatory | Mandatory | 217 | OH_MD_KEY_MAX_INPUT_SIZE | Maximum input size | Optional | Optional| Optional | Optional| Optional | Optional | Optional | 218 | OH_MD_KEY_AAC_IS_ADTS | ADTS or not | Optional (Default value: 1 latm) | - | - | - | - | - | - | 219 | MD_KEY_AUDIO_SAMPLE_FORMAT | Output audio stream format | Optional (SAMPLE_S16LE, SAMPLE_F32LE)| - | Optional (SAMPLE_S16LE, SAMPLE_F32LE)| Optional| Optional (default: SAMPLE_S16LE)| Optional (SAMPLE_S16LE, SAMPLE_F32LE)| Optional | 220 | MD_KEY_BITRATE | Optional | Optional | Optional| Optional | Optional| Optional | Optional | Optional | 221 | MD_KEY_IDENTIFICATION_HEADER | ID Header | - | - | Mandatory (Either this parameter or **MD_KEY_CODEC_CONFIG** must be set.) | - | - | - | - | 222 | MD_KEY_SETUP_HEADER | Setup Header | - | - | Mandatory (Either this parameter or **MD_KEY_CODEC_CONFIG** must be set.) | - | - | - | - | 223 | MD_KEY_CODEC_CONFIG | MD_KEY_SETUP_HEADERID Header+Common Header+Setup Header stitching| - | | Mandatory (Either this parameter or the combination of **MD_KEY_IDENTIFICATION_HEADER** and **MD_KEY_SETUP_HEADER** must be selected.) | - | - | - | - | 224 225 The sample below lists the value range of each audio decoding type. 226 | Audio Decoding Type| Sampling Rate (Hz) | Audio Channel Count| 227 | ----------- | ---------------------------------------------------------------------------------------------- | :----: | 228 | AAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 | 1–8 | 229 | FLAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 | 1–8 | 230 | Vorbis | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000| 1–8 | 231 | MPEG (MP3) | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 | 1–2 | 232 | G711mu | 8000 | 1 | 233 | AMR (amrnb) | 8000 | 1 | 234 | AMR (amrwb) | 16000 | 1 | 235 | APE | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000| 1–2 | 236 237 ```cpp 238 // Set the decoding resolution. 239 int32_t ret; 240 // (Mandatory) Configure the audio sampling rate. 241 constexpr uint32_t DEFAULT_SAMPLERATE = 44100; 242 // (Mandatory) Configure the audio bit rate. 243 constexpr uint32_t DEFAULT_BITRATE = 32000; 244 // (Mandatory) Configure the number of audio channels. 245 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 246 // (Optional) Configure the maximum input length. 247 constexpr uint32_t DEFAULT_MAX_INPUT_SIZE = 1152; 248 // Configure whether to use ADTS decoding (ACC). 249 constexpr uint32_t DEFAULT_AAC_TYPE = 1; 250 OH_AVFormat *format = OH_AVFormat_Create(); 251 // Set the format. 252 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE); 253 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE); 254 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT); 255 OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE, DEFAULT_MAX_INPUT_SIZE); 256 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE); 257 // Configure the decoder. 258 ret = OH_AudioCodec_Configure(audioDec_, format); 259 if (ret != AV_ERR_OK) { 260 // Exception handling. 261 } 262 ``` 263 2646. Call **OH_AudioCodec_Prepare()** to prepare internal resources for the decoder. 265 266 ```cpp 267 ret = OH_AudioCodec_Prepare(audioDec_); 268 if (ret != AV_ERR_OK) { 269 // Exception handling. 270 } 271 ``` 272 2737. Call **OH_AudioCodec_Start()** to start the decoder. 274 275 ```c++ 276 unique_ptr<ifstream> inputFile_ = make_unique<ifstream>(); 277 unique_ptr<ofstream> outFile_ = make_unique<ofstream>(); 278 // Open the path of the binary file to be decoded. 279 inputFile_->open(inputFilePath.data(), ios::in | ios::binary); 280 // Configure the path of the output file. 281 outFile_->open(outputFilePath.data(), ios::out | ios::binary); 282 // Start decoding. 283 ret = OH_AudioCodec_Start(audioDec_); 284 if (ret != AV_ERR_OK) { 285 // Exception handling. 286 } 287 ``` 288 2898. (Optional) Call **OH_AVCencInfo_SetAVBuffer()** to set the Common Encryption Scheme (CENC) information. 290 291 If the content being played is DRM encrypted and demuxing is performed by the upper-layer application, call **OH_AVCencInfo_SetAVBuffer()** to set the CENC information to the AVBuffer so that the media data can be decrypted in the AVBuffer. 292 293 Add the header file. 294 295 ```c++ 296 #include <multimedia/player_framework/native_cencinfo.h> 297 ``` 298 Link the dynamic library in the CMake script. 299 300 ``` cmake 301 target_link_libraries(sample PUBLIC libnative_media_avcencinfo.so) 302 ``` 303 304 The following is the sample code: 305 ```c++ 306 auto buffer = signal_->inBufferQueue_.front(); 307 int64_t size; 308 int64_t pts; 309 uint32_t keyIdLen = DRM_KEY_ID_SIZE; 310 uint8_t keyId[] = { 311 0xd4, 0xb2, 0x01, 0xe4, 0x61, 0xc8, 0x98, 0x96, 312 0xcf, 0x05, 0x22, 0x39, 0x8d, 0x09, 0xe6, 0x28}; 313 uint32_t ivLen = DRM_KEY_IV_SIZE; 314 uint8_t iv[] = { 315 0xbf, 0x77, 0xed, 0x51, 0x81, 0xde, 0x36, 0x3e, 316 0x52, 0xf7, 0x20, 0x4f, 0x72, 0x14, 0xa3, 0x95}; 317 uint32_t encryptedBlockCount = 0; 318 uint32_t skippedBlockCount = 0; 319 uint32_t firstEncryptedOffset = 0; 320 uint32_t subsampleCount = 1; 321 DrmSubsample subsamples[1] = { {0x10, 0x16} }; 322 inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size)); 323 inputFile_.read(reinterpret_cast<char *>(&pts), sizeof(pts)); 324 inputFile_.read((char *)OH_AVMemory_GetAddr(buffer), size); 325 OH_AVCencInfo *cencInfo = OH_AVCencInfo_Create(); 326 if (cencInfo == nullptr) { 327 // Exception handling. 328 } 329 OH_AVErrCode errNo = OH_AVCencInfo_SetAlgorithm(cencInfo, DRM_ALG_CENC_AES_CTR); 330 if (errNo != AV_ERR_OK) { 331 // Exception handling. 332 } 333 errNo = OH_AVCencInfo_SetKeyIdAndIv(cencInfo, keyId, keyIdLen, iv, ivLen); 334 if (errNo != AV_ERR_OK) { 335 // Exception handling. 336 } 337 errNo = OH_AVCencInfo_SetSubsampleInfo(cencInfo, encryptedBlockCount, skippedBlockCount, firstEncryptedOffset, 338 subsampleCount, subsamples); 339 if (errNo != AV_ERR_OK) { 340 // Exception handling. 341 } 342 errNo = OH_AVCencInfo_SetMode(cencInfo, DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET); 343 if (errNo != AV_ERR_OK) { 344 // Exception handling. 345 } 346 errNo = OH_AVCencInfo_SetAVBuffer(cencInfo, buffer); 347 if (errNo != AV_ERR_OK) { 348 // Exception handling. 349 } 350 errNo = OH_AVCencInfo_Destroy(cencInfo); 351 if (errNo != AV_ERR_OK) { 352 // Exception handling. 353 } 354 ``` 355 3569. Call **OH_AudioCodec_PushInputBuffer()** to write the data to decode. 357 358 To indicate the End of Stream (EOS), pass in the **AVCODEC_BUFFER_FLAGS_EOS** flag. 359 360 ```c++ 361 uint32_t index = signal_->inQueue_.front(); 362 auto buffer = signal_->inBufferQueue_.front(); 363 int64_t size; 364 int64_t pts; 365 // size is the length of each frame of the data to decode. pts is the timestamp of each frame and is used to indicate when the audio should be played. 366 // The values of size and pts are obtained from an audio and video resource file or data stream to decode. 367 // In the case of an audio and video resource file, the values are obtained from the buffer in the decapsulated OH_AVDemuxer_ReadSampleBuffer. 368 // In the case of a data stream, the values are obtained from the data stream provider. 369 // In this example, the values of size and pts are obtained from the test file. 370 inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size)); 371 inputFile_.read(reinterpret_cast<char *>(&pts), sizeof(pts)); 372 inputFile_.read((char *)OH_AVBuffer_GetAddr(buffer), size); 373 OH_AVCodecBufferAttr attr = {0}; 374 if (inputFile_->eof()) { 375 attr.size = 0; 376 attr.flags = AVCODEC_BUFFER_FLAGS_EOS; 377 } else { 378 attr.size = size; 379 attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 380 } 381 attr.pts = pts; 382 OH_AVBuffer_SetBufferAttr(buffer, &attr); 383 int32_t ret = OH_AudioCodec_PushInputBuffer(audioDec_, index); 384 if (ret != AV_ERR_OK) { 385 // Exception handling. 386 } 387 ``` 388 38910. Call **OH_AudioCodec_FreeOutputBuffer()** to output decoded PCM streams. 390 391 <!--RP3--> 392 ```c++ 393 uint32_t index = signal_->outQueue_.front(); 394 OH_AVBuffer *data = signal_->outBufferQueue_.front(); 395 // Obtain the buffer attributes. 396 OH_AVCodecBufferAttr attr = {0}; 397 ret = OH_AVBuffer_GetBufferAttr(data, &attr); 398 if (ret != AV_ERR_OK) { 399 // Exception handling. 400 } 401 // Write the decoded data (specified by data) to the output file. 402 pcmOutputFile_.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)), attr.size); 403 ret = OH_AudioCodec_FreeOutputBuffer(audioDec_, index); 404 if (ret != AV_ERR_OK) { 405 // Exception handling. 406 } 407 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 408 // End 409 } 410 ``` 411 <!--RP3End--> 412 41311. (Optional) Call **OH_AudioCodec_Flush()** to refresh the decoder. 414 415 After **OH_AudioCodec_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_AudioCodec_Start()** again. 416 417 You need to call **OH_AudioCodec_Start()** in the following cases: 418 419 * The EOS of the file is reached. 420 * An error with **OH_AudioCodec_IsValid** set to **true** (indicating that the execution can continue) occurs. 421 422 ```c++ 423 // Refresh the decoder. 424 ret = OH_AudioCodec_Flush(audioDec_); 425 if (ret != AV_ERR_OK) { 426 // Exception handling. 427 } 428 // Start decoding again. 429 ret = OH_AudioCodec_Start(audioDec_); 430 if (ret != AV_ERR_OK) { 431 // Exception handling. 432 } 433 ``` 434 43512. (Optional) Call **OH_AudioCodec_Reset()** to reset the decoder. 436 437 After **OH_AudioCodec_Reset()** is called, the decoder returns to the initialized state. To continue decoding, you must call **OH_AudioCodec_Configure()** and then **OH_AudioCodec_Start()**. 438 439 ```c++ 440 // Reset the decoder. 441 ret = OH_AudioCodec_Reset(audioDec_); 442 if (ret != AV_ERR_OK) { 443 // Exception handling. 444 } 445 // Reconfigure the decoder. 446 ret = OH_AudioCodec_Configure(audioDec_, format); 447 if (ret != AV_ERR_OK) { 448 // Exception handling. 449 } 450 ``` 451 45213. Call **OH_AudioCodec_Stop()** to stop the decoder. 453 454 ```c++ 455 // Stop the decoder. 456 ret = OH_AudioCodec_Stop(audioDec_); 457 if (ret != AV_ERR_OK) { 458 // Exception handling. 459 } 460 ``` 461 46214. Call **OH_AudioCodec_Destroy()** to destroy the decoder instance and release resources. 463 464 > **NOTE** 465 > 466 > You only need to call this API once. 467 468 ```c++ 469 // Call OH_AudioCodec_Destroy to destroy the decoder. 470 ret = OH_AudioCodec_Destroy(audioDec_); 471 if (ret != AV_ERR_OK) { 472 // Exception handling. 473 } else { 474 audioDec_ = NULL; // The decoder cannot be destroyed repeatedly. 475 } 476 ``` 477 478