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