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![Call relationship of audio decoding](figures/audio-codec.png)
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