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