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 -> muxing -> demuxing -> 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![Call relationship of audio decoding](figures/audio-codec.png)
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 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 a codec stream change, for example, audio channel change
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    ```cpp
107    // Implement the OH_AVCodecOnError callback function.
108    static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData)
109    {
110        (void)codec;
111        (void)errorCode;
112        (void)userData;
113    }
114    // Implement the OH_AVCodecOnStreamChanged callback function.
115    static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
116    {
117        (void)codec;
118        (void)format;
119        (void)userData;
120    }
121    // Implement the OH_AVCodecOnNeedInputBuffer callback function.
122    static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
123    {
124        (void)codec;
125        ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
126        unique_lock<mutex> lock(signal->inMutex_);
127        signal->inQueue_.push(index);
128        signal->inBufferQueue_.push(data);
129        signal->inCond_.notify_all();
130        // The input stream is sent to inBufferQueue_.
131    }
132    // Implement the OH_AVCodecOnNewOutputBuffer callback function.
133    static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
134    {
135        (void)codec;
136        ADecBufferSignal *signal = static_cast<ADecBufferSignal *>(userData);
137        unique_lock<mutex> lock(signal->outMutex_);
138        signal->outQueue_.push(index);
139        signal->outBufferQueue_.push(data);
140        signal->outCond_.notify_all();
141        // The index of the output buffer is sent to outQueue_.
142        // The decoded data is sent to outBufferQueue_.
143    }
144    signal_ = new ADecBufferSignal();
145    OH_AVCodecCallback cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
146    int32_t ret = OH_AudioCodec_RegisterCallback(audioDec_, cb_, signal_);
147    if (ret != AVCS_ERR_OK) {
148        // Exception handling.
149    }
150    ```
151
1524. (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 4 in [Media Data Demuxing](audio-video-demuxer.md). For details about DRM APIs, see [DRM](../../reference/apis-drm-kit/_drm.md).
153
154    Add the header files.
155
156    ```c++
157    #include <multimedia/drm_framework/native_mediakeysystem.h>
158    #include <multimedia/drm_framework/native_mediakeysession.h>
159    #include <multimedia/drm_framework/native_drm_err.h>
160    #include <multimedia/drm_framework/native_drm_common.h>
161    ```
162    Link the dynamic library in the CMake script.
163
164    ``` cmake
165    target_link_libraries(sample PUBLIC libnative_drm.so)
166    ```
167
168    The following is the sample code:
169    ```c++
170    // Create a media key system based on the media key system information. The following uses com.clearplay.drm as an example.
171    MediaKeySystem *system = nullptr;
172    int32_t ret = OH_MediaKeySystem_Create("com.clearplay.drm", &system);
173    if (system == nullptr) {
174        printf("create media key system failed");
175        return;
176    }
177
178    // Create a media key session.
179    MediaKeySession *session = nullptr;
180    DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO;
181    ret = OH_MediaKeySystem_CreateMediaKeySession(system, &contentProtectionLevel, &session);
182    if (ret != DRM_OK) {
183        // If the creation fails, refer to the DRM interface document and check logs.
184        printf("create media key session failed.");
185        return;
186    }
187    if (session == nullptr) {
188        printf("media key session is nullptr.");
189        return;
190    }
191    // Generate a media key request and set the response to the media key request.
192    // 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.)
193    bool secureAudio = false;
194    ret = OH_AudioCodec_SetDecryptionConfig(audioDec_, session, secureAudio);
195    ```
196
1975. Call **OH_AudioCodec_Configure()** to configure the decoder.
198
199   Key values of configuration options are described as follows:
200
201   |                              |                             Description                            |                AAC                 | FLAC|               Vorbis               | MPEG |       G711mu        |          AMR (AMR-NB and AMR-WB)        |          APE                      |
202   | ---------------------------- | :----------------------------------------------------------: | :--------------------------------: | :--: | :--------------------------------: | :--: | :-----------------: | :-------------------------------: | :-------------------------------: |
203   | OH_MD_KEY_AUD_SAMPLE_RATE    |                            Sampling rate                           |                Mandatory               | Mandatory|                Mandatory                | Mandatory|        Mandatory         |                Mandatory               |                Mandatory               |
204   | OH_MD_KEY_AUD_CHANNEL_COUNT  |                            Number of audio channels                           |                Mandatory               | Mandatory|                Mandatory                | Mandatory|        Mandatory         |                Mandatory               |                Mandatory               |
205   | OH_MD_KEY_MAX_INPUT_SIZE     |                         Maximum input size                        |                Optional               | Optional|                Optional                | Optional|        Optional          |               Optional               |                Optional               |
206   | OH_MD_KEY_AAC_IS_ADTS        |                           ADTS or not                          |        Optional (Default value: 1 latm)        |  -   |                 -                  |  -   |         -             |               -                  |                 -                  |
207   | 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               |
208   | MD_KEY_BITRATE               |                             Optional                            |                Optional               | Optional|                Optional               | Optional|         Optional          |              Optional                |               Optional               |
209   | MD_KEY_IDENTIFICATION_HEADER |                          ID Header                           |                 -                  |  -   |    Mandatory (Either this parameter or **MD_KEY_CODEC_CONFIG** must be set.)   |  -   |          -            |                -                  |                -                  |
210   | MD_KEY_SETUP_HEADER          |                         Setup Header                         |                 -                  |  -   |    Mandatory (Either this parameter or **MD_KEY_CODEC_CONFIG** must be set.)   |  -   |          -            |                -                 |                -                  |
211   | 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.)   |  -   |           -            |                -                 |                -                  |
212
213   The sample below lists the value range of each audio decoding type.
214   | Audio Decoding Type|                                          Sampling Rate (Hz)                                             | Audio Channel Count|
215   | ----------- | ----------------------------------------------------------------------------------------------  | :----: |
216   | AAC         | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000                |  1–8  |
217   | FLAC       | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000        |  1–8  |
218   | Vorbis      | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000|  1–8  |
219   | MPEG (MP3)   | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000                                    |  1–2  |
220   | G711mu      | 8000                                                                                            |   1    |
221   | AMR (amrnb)  | 8000                                                                                            |   1    |
222   | AMR (amrwb)  | 16000                                                                                           |   1    |
223   | APE         | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000|  1–2  |
224   <!--RP4-->
225   <!--RP4End-->
226
227   ```cpp
228   // Set the decoding resolution.
229   int32_t ret;
230   // (Mandatory) Configure the audio sampling rate.
231   constexpr uint32_t DEFAULT_SAMPLERATE = 44100;
232   // (Optional) Configure the audio bit rate.
233   constexpr uint32_t DEFAULT_BITRATE = 32000;
234   // (Mandatory) Configure the number of audio channels.
235   constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2;
236   // (Optional) Configure the maximum input length.
237   constexpr uint32_t DEFAULT_MAX_INPUT_SIZE = 1152;
238   // Configure whether to use ADTS decoding (optional for AAC decoding).
239   constexpr uint32_t DEFAULT_AAC_TYPE = 1;
240   OH_AVFormat *format = OH_AVFormat_Create();
241   // Set the format.
242   OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE);
243   OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE);
244   OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT);
245   OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE, DEFAULT_MAX_INPUT_SIZE);
246   OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE);
247   // Configure the decoder.
248   ret = OH_AudioCodec_Configure(audioDec_, format);
249   if (ret != AV_ERR_OK) {
250       // Exception handling.
251   }
252   ```
253
2546. Call **OH_AudioCodec_Prepare()** to prepare internal resources for the decoder.
255
256   ```cpp
257   ret = OH_AudioCodec_Prepare(audioDec_);
258   if (ret != AV_ERR_OK) {
259       // Exception handling.
260   }
261   ```
262
2637. Call **OH_AudioCodec_Start()** to start the decoder.
264
265    ```c++
266    unique_ptr<ifstream> inputFile_ = make_unique<ifstream>();
267    unique_ptr<ofstream> outFile_ = make_unique<ofstream>();
268    // Open the path of the binary file to be decoded.
269    inputFile_->open(inputFilePath.data(), ios::in | ios::binary);
270    // Configure the path of the output file.
271    outFile_->open(outputFilePath.data(), ios::out | ios::binary);
272    // Start decoding.
273    ret = OH_AudioCodec_Start(audioDec_);
274    if (ret != AV_ERR_OK) {
275        // Exception handling.
276    }
277    ```
278
2798. (Optional) Call **OH_AVCencInfo_SetAVBuffer()** to set the Common Encryption Scheme (CENC) information.
280
281    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.
282
283    Add the header file.
284
285    ```c++
286    #include <multimedia/player_framework/native_cencinfo.h>
287    ```
288    Link the dynamic library in the CMake script.
289
290    ``` cmake
291    target_link_libraries(sample PUBLIC libnative_media_avcencinfo.so)
292    ```
293
294    The following is the sample code:
295    ```c++
296    auto buffer = signal_->inBufferQueue_.front();
297    uint32_t keyIdLen = DRM_KEY_ID_SIZE;
298    uint8_t keyId[] = {
299        0xd4, 0xb2, 0x01, 0xe4, 0x61, 0xc8, 0x98, 0x96,
300        0xcf, 0x05, 0x22, 0x39, 0x8d, 0x09, 0xe6, 0x28};
301    uint32_t ivLen = DRM_KEY_IV_SIZE;
302    uint8_t iv[] = {
303        0xbf, 0x77, 0xed, 0x51, 0x81, 0xde, 0x36, 0x3e,
304        0x52, 0xf7, 0x20, 0x4f, 0x72, 0x14, 0xa3, 0x95};
305    uint32_t encryptedBlockCount = 0;
306    uint32_t skippedBlockCount = 0;
307    uint32_t firstEncryptedOffset = 0;
308    uint32_t subsampleCount = 1;
309    DrmSubsample subsamples[1] = { {0x10, 0x16} };
310    // Create a CencInfo instance.
311    OH_AVCencInfo *cencInfo = OH_AVCencInfo_Create();
312    if (cencInfo == nullptr) {
313        // Exception handling.
314    }
315    // Set the decryption algorithm.
316    OH_AVErrCode errNo = OH_AVCencInfo_SetAlgorithm(cencInfo, DRM_ALG_CENC_AES_CTR);
317    if (errNo != AV_ERR_OK) {
318        // Exception handling.
319    }
320    // Set KeyId and Iv.
321    errNo = OH_AVCencInfo_SetKeyIdAndIv(cencInfo, keyId, keyIdLen, iv, ivLen);
322    if (errNo != AV_ERR_OK) {
323        // Exception handling.
324    }
325    // Set the sample information.
326    errNo = OH_AVCencInfo_SetSubsampleInfo(cencInfo, encryptedBlockCount, skippedBlockCount, firstEncryptedOffset,
327        subsampleCount, subsamples);
328    if (errNo != AV_ERR_OK) {
329        // Exception handling.
330    }
331    // Set the mode. KeyId, Iv, and SubSamples have been set.
332    errNo = OH_AVCencInfo_SetMode(cencInfo, DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET);
333    if (errNo != AV_ERR_OK) {
334        // Exception handling.
335    }
336    // Set CencInfo to the AVBuffer.
337    errNo = OH_AVCencInfo_SetAVBuffer(cencInfo, buffer);
338    if (errNo != AV_ERR_OK) {
339        // Exception handling.
340    }
341    // Destroy the CencInfo instance.
342    errNo = OH_AVCencInfo_Destroy(cencInfo);
343    if (errNo != AV_ERR_OK) {
344        // Exception handling.
345    }
346    ```
347
3489. Call **OH_AudioCodec_PushInputBuffer()** to write the data to decode.
349
350   To indicate the End of Stream (EOS), pass in the **AVCODEC_BUFFER_FLAGS_EOS** flag.
351
352    ```c++
353    uint32_t index = signal_->inQueue_.front();
354    auto buffer = signal_->inBufferQueue_.front();
355    int64_t size;
356    int64_t pts;
357    // 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.
358    // The values of size and pts are obtained from an audio and video resource file or data stream to decode.
359    // In the case of an audio and video resource file, the values are obtained from the buffer in the decapsulated OH_AVDemuxer_ReadSampleBuffer.
360    // In the case of a data stream, the values are obtained from the data stream provider.
361    // In this example, the values of size and pts are obtained from the test file.
362    inputFile_.read(reinterpret_cast<char *>(&size), sizeof(size));
363    inputFile_.read(reinterpret_cast<char *>(&pts), sizeof(pts));
364    inputFile_.read((char *)OH_AVBuffer_GetAddr(buffer), size);
365    OH_AVCodecBufferAttr attr = {0};
366    if (inputFile_->eof()) {
367        attr.size = 0;
368        attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
369    } else {
370        attr.size = size;
371        attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
372    }
373    attr.pts = pts;
374    OH_AVBuffer_SetBufferAttr(buffer, &attr);
375    int32_t ret = OH_AudioCodec_PushInputBuffer(audioDec_, index);
376    if (ret != AV_ERR_OK) {
377        // Exception handling.
378    }
379    ```
380
38110. Call **OH_AudioCodec_FreeOutputBuffer()** to output decoded PCM streams.
382
383    <!--RP3-->
384    ```c++
385    uint32_t index = signal_->outQueue_.front();
386    OH_AVBuffer *data = signal_->outBufferQueue_.front();
387    // Obtain the buffer attributes.
388    OH_AVCodecBufferAttr attr = {0};
389    ret = OH_AVBuffer_GetBufferAttr(data, &attr);
390    if (ret != AV_ERR_OK) {
391        // Exception handling.
392    }
393    // Write the decoded data (specified by data) to the output file.
394    pcmOutputFile_.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)), attr.size);
395    ret = OH_AudioCodec_FreeOutputBuffer(audioDec_, index);
396    if (ret != AV_ERR_OK) {
397        // Exception handling.
398    }
399    if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) {
400        // End
401    }
402    ```
403    <!--RP3End-->
404
40511. (Optional) Call **OH_AudioCodec_Flush()** to refresh the decoder.
406
407   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.
408
409   You need to call **OH_AudioCodec_Start()** in the following cases:
410
411   * The EOS of the file is reached.
412   * An error with **OH_AudioCodec_IsValid** set to **true** (indicating that the execution can continue) occurs.
413
414    ```c++
415    // Refresh the decoder.
416    ret = OH_AudioCodec_Flush(audioDec_);
417    if (ret != AV_ERR_OK) {
418        // Exception handling.
419    }
420    // Start decoding again.
421    ret = OH_AudioCodec_Start(audioDec_);
422    if (ret != AV_ERR_OK) {
423        // Exception handling.
424    }
425    ```
426
42712. (Optional) Call **OH_AudioCodec_Reset()** to reset the decoder.
428
429    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()**.
430
431    ```c++
432    // Reset the decoder.
433    ret = OH_AudioCodec_Reset(audioDec_);
434    if (ret != AV_ERR_OK) {
435        // Exception handling.
436    }
437    // Reconfigure the decoder.
438    ret = OH_AudioCodec_Configure(audioDec_, format);
439    if (ret != AV_ERR_OK) {
440    // Exception handling.
441    }
442    ```
443
44413. Call **OH_AudioCodec_Stop()** to stop the decoder.
445
446    ```c++
447    // Stop the decoder.
448    ret = OH_AudioCodec_Stop(audioDec_);
449    if (ret != AV_ERR_OK) {
450        // Exception handling.
451    }
452    ```
453
45414. Call **OH_AudioCodec_Destroy()** to destroy the decoder instance and release resources.
455
456    > **NOTE**
457    >
458    > You only need to call this API once.
459
460    ```c++
461    // Call OH_AudioCodec_Destroy to destroy the decoder.
462    ret = OH_AudioCodec_Destroy(audioDec_);
463    if (ret != AV_ERR_OK) {
464        // Exception handling.
465    } else {
466        audioDec_ = NULL; // The decoder cannot be destroyed repeatedly.
467    }
468    ```
469
470