1# Audio Encoding 2 3<!--Kit: AVCodec Kit--> 4<!--Subsystem: Multimedia--> 5<!--Owner: @mr-chencxy--> 6<!--Designer: @dpy2650---> 7<!--Tester: @baotianhao--> 8<!--Adviser: @zengyawen--> 9 10You can call native APIs to perform audio encoding, which compresses audio PCM data into a desired format. 11 12PCM data can be from any source. For example, you can use a microphone to record audio data or import edited PCM data. After audio encoding, you can output streams in the desired format and encapsulate the streams into a target file. 13 14For details about the supported encoding capabilities, see [AVCodec Supported Formats](avcodec-support-formats.md#audio-encoding). 15 16**When to Use** 17 18- Audio recording 19 20 Record PCM data, encode it into the desired format, and then [multiplex](audio-video-muxer.md) it in the target file format. 21- Audio editing 22 23 Export edited PCM data, encode it into the corresponding audio format, and then [multiplex](audio-video-muxer.md) it into a file. 24> **NOTE** 25> 26> AAC encoders adopt the VBR mode by default. This may result in differences from the configured parameters. 27 28## Development Guidelines 29 30Read [AudioCodec](../../reference/apis-avcodec-kit/_audio_codec.md) for the API reference. 31 32Refer to the code snippet below to complete the entire audio encoding process, including creating an encoder, setting encoding parameters (such as the sample rate, bit rate, and audio channel count), and starting, refreshing, resetting, and destroying the encoder. 33 34During application development, you must call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur. 35 36The figure below shows the call relationship of audio encoding. 37 38- The dotted line indicates an optional operation. 39 40- The solid line indicates a mandatory operation. 41 42 43 44### Linking the Dynamic Libraries in the CMake Script 45 46```cmake 47target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 48target_link_libraries(sample PUBLIC libnative_media_core.so) 49target_link_libraries(sample PUBLIC libnative_media_acodec.so) 50``` 51> **NOTE** 52> 53> The word **sample** in the preceding code snippet is only an example. Use the actual project directory name. 54 55### How to Develop 56 571. Add the header files. 58 59 ```cpp 60 #include <multimedia/player_framework/native_avcodec_audiocodec.h> 61 #include <multimedia/native_audio_channel_layout.h> 62 #include <multimedia/player_framework/native_avcapability.h> 63 #include <multimedia/player_framework/native_avcodec_base.h> 64 #include <multimedia/player_framework/native_avformat.h> 65 #include <multimedia/player_framework/native_avbuffer.h> 66 ``` 67 682. Create an encoder instance. In the code snippet below, **OH_AVCodec *** is the pointer to the encoder instance created. 69 70 You can create an encoder by MIME type or codec name. 71 72 Method 1: Create an encoder by MIME type. 73 ```cpp 74 // Specify whether encoding is used. The value true means encoding. 75 bool isEncoder = true; 76 // Create an encoder by MIME type. 77 OH_AVCodec *audioEnc_ = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC, isEncoder); 78 ``` 79 Method 2: Create an encoder by codec name. 80 ```cpp 81 // Create an encoder by name. 82 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 83 const char *name = OH_AVCapability_GetName(capability); 84 OH_AVCodec *audioEnc_ = OH_AudioCodec_CreateByName(name); 85 ``` 86 Add the header file and namespace. 87 ```cpp 88 #include <mutex> 89 #include <queue> 90 // Namespace of the C++ standard library. 91 using namespace std; 92 ``` 93 The sample code is as follows: 94 ```cpp 95 // Initialize the queues. 96 class AEncBufferSignal { 97 public: 98 std::mutex inMutex_; 99 std::mutex outMutex_; 100 std::mutex startMutex_; 101 std::condition_variable inCond_; 102 std::condition_variable outCond_; 103 std::condition_variable startCond_; 104 std::queue<uint32_t> inQueue_; 105 std::queue<uint32_t> outQueue_; 106 std::queue<OH_AVBuffer *> inBufferQueue_; 107 std::queue<OH_AVBuffer *> outBufferQueue_; 108 }; 109 AEncBufferSignal *signal_; 110 ``` 111 1123. Call **OH_AudioCodec_RegisterCallback()** to register callback functions. 113 114 Register the **OH_AVCodecCallback** struct that defines the following callback function pointers: 115 116 - **OH_AVCodecOnError**, a callback used to report a codec operation error 117 - **OH_AVCodecOnStreamChanged**, a callback not supported by the audio encoder yet 118 - **OH_AVCodecOnNeedInputBuffer**, a callback used to report input data required, which means that the encoder is ready for receiving PCM data 119 - **OH_AVCodecOnNewOutputBuffer**, a callback used to report output data generated, which means that encoding is complete 120 121 You need to process the callback functions to ensure that the encoder runs properly. 122 123 > **NOTE** 124 > 125 > You are not advised to perform time-consuming operations in the callback. 126 127 ```cpp 128 // Implement the OH_AVCodecOnError callback function. 129 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) 130 { 131 (void)codec; 132 (void)errorCode; 133 (void)userData; 134 } 135 // Implement the OH_AVCodecOnStreamChanged callback function. 136 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) 137 { 138 (void)codec; 139 (void)format; 140 (void)userData; 141 } 142 // Implement the OH_AVCodecOnNeedInputBuffer callback function. 143 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 144 { 145 (void)codec; 146 // The input stream is sent to the InputBuffer queue. 147 AEncBufferSignal *signal = static_cast<AEncBufferSignal *>(userData); 148 unique_lock<mutex> lock(signal->inMutex_); 149 signal->inQueue_.push(index); 150 signal->inBufferQueue_.push(data); 151 signal->inCond_.notify_all(); 152 } 153 // Implement the OH_AVCodecOnNewOutputBuffer callback function. 154 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 155 { 156 (void)codec; 157 // The index of the output buffer is sent to OutputQueue_. 158 // The encoded data is sent to the outBuffer queue. 159 AEncBufferSignal *signal = static_cast<AEncBufferSignal *>(userData); 160 unique_lock<mutex> lock(signal->outMutex_); 161 signal->outQueue_.push(index); 162 signal->outBufferQueue_.push(data); 163 signal->outCond_.notify_all(); 164 } 165 ``` 166 Configure the callback information. 167 ```cpp 168 signal_ = new AEncBufferSignal(); 169 OH_AVCodecCallback cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; 170 // Set the asynchronous callbacks. 171 int32_t ret = OH_AudioCodec_RegisterCallback(audioEnc_, cb_, signal_); 172 if (ret != AV_ERR_OK) { 173 // Handle exceptions. 174 } 175 ``` 176 1774. Call **OH_AudioCodec_Configure** to configure the encoder. 178 179 Key values of configuration options are described as follows: 180 181 <!--RP2--> 182 | key | Description | AAC | FLAC| MPEG (MP3) | G711mu | 183 | ----------------------------- | :--------------: | :---: | :---: | :------: | :---: | 184 | OH_MD_KEY_AUD_SAMPLE_RATE | Sample rate. | Mandatory | Mandatory| Mandatory | Mandatory | 185 | OH_MD_KEY_AUD_CHANNEL_COUNT | Audio channel count. | Mandatory | Mandatory| Mandatory | Mandatory | 186 | OH_MD_KEY_AUDIO_SAMPLE_FORMAT | Output audio stream format. | Mandatory | Mandatory| Mandatory | Mandatory | 187 | OH_MD_KEY_BITRATE | Bit rate. | Optional | Mandatory| Mandatory | - | 188 | OH_MD_KEY_CHANNEL_LAYOUT | Audio channel layout. | Optional | Mandatory| - | - | 189 | OH_MD_KEY_MAX_INPUT_SIZE | Maximum input size. | Optional | Optional| Optional | Optional | 190 | OH_MD_KEY_AAC_IS_ADTS | ADTS or not. | Optional | - | - | - | 191 | OH_MD_KEY_COMPLIANCE_LEVEL | Compatibility level. | - | Optional| - | - | 192 <!--RP2End--> 193 194 The sample below lists the value range of each audio encoding type. 195 | Audio Encoding Type| Sample Rate (Hz) | Audio Channel Count | 196 | ----------- | ------------------------------------------------------------------------------- | :----------------: | 197 | <!--DelRow-->AAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000| 1, 2, 3, 4, 5, 6, and 8| 198 | FLAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000| 1–8 | 199 | MP3 | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 | 1–2 | 200 | G711mu | 8000 | 1 | 201 <!--RP3--><!--RP3End--> 202 203 The code snippet below shows the API call process, where AAC encoding at the bit rate of 32000 bit/s is carried out on the PCM audio with the 44100 Hz sample rate, 2-channel stereo, and SAMPLE_S16LE sample format. 204 <!--RP4--> 205 ```cpp 206 int32_t ret; 207 // (Mandatory) Configure the audio sample rate. 208 constexpr uint32_t DEFAULT_SAMPLERATE = 44100; 209 // (Mandatory) Configure the audio bit rate. 210 constexpr uint64_t DEFAULT_BITRATE = 32000; 211 // (Mandatory) Configure the audio channel count. 212 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 213 // (Mandatory) Configure the layout of audio channels. 214 constexpr OH_AudioChannelLayout CHANNEL_LAYOUT = OH_AudioChannelLayout::CH_LAYOUT_STEREO; 215 // (Mandatory) Configure the audio bit depth. 216 constexpr OH_BitsPerSample SAMPLE_FORMAT = OH_BitsPerSample::SAMPLE_S16LE; 217 218 OH_AVFormat *format = OH_AVFormat_Create(); 219 // Set the format. 220 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT); 221 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE); 222 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE); 223 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_FORMAT); 224 OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, CHANNEL_LAYOUT); 225 226 // Configure the encoder. 227 ret = OH_AudioCodec_Configure(audioEnc_, format); 228 if (ret != AV_ERR_OK) { 229 // Handle exceptions. 230 } 231 ``` 232 <!--RP4End--> 233 The following shows the API call process in the case of FLAC encoding. 234 235 ```cpp 236 int32_t ret; 237 // (Mandatory) Configure the audio sample rate. 238 constexpr uint32_t DEFAULT_SAMPLERATE = 44100; 239 // (Mandatory) Configure the audio bit rate. 240 constexpr uint64_t DEFAULT_BITRATE = 261000; 241 // (Mandatory) Configure the audio channel count. 242 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 243 // (Mandatory) Configure the layout of audio channels. 244 // The value can be CH_LAYOUT_MONO, CH_LAYOUT_STEREO, CH_LAYOUT_SURROUND, CH_LAYOUT_QUAD, CH_LAYOUT_5POINT0, CH_LAYOUT_5POINT1, CH_LAYOUT_6POINT1, or CH_LAYOUT_7POINT1. 245 constexpr OH_AudioChannelLayout CHANNEL_LAYOUT = OH_AudioChannelLayout::CH_LAYOUT_STEREO; 246 // (Mandatory) Configure the audio bit depth. Only SAMPLE_S16LE and SAMPLE_S32LE are available for FLAC encoding. 247 constexpr OH_BitsPerSample SAMPLE_FORMAT = OH_BitsPerSample::SAMPLE_S32LE; 248 // Configure the audio compliance level. The default value is 0, and the value ranges from -2 to 2. 249 constexpr int32_t COMPLIANCE_LEVEL = 0; 250 251 OH_AVFormat *format = OH_AVFormat_Create(); 252 // Set the format. 253 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT); 254 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE); 255 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE); 256 // Configure the audio sampling precision. In versions earlier than API version 20, this parameter must be set to 1 for FLAC encoding. Otherwise, OH_AudioCodec_Configure returns the error code AV_ERR_INVALID_VAL. However, this parameter has no actual effect and does not affect the encoding result. Starting from API version 20, you do not need to set it anymore. 257 // constexpr int32_t BITS_PER_CODED_SAMPLE = 1; 258 // OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, BITS_PER_CODED_SAMPLE); 259 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_FORMAT); 260 OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, CHANNEL_LAYOUT); 261 OH_AVFormat_SetLongValue(format, OH_MD_KEY_COMPLIANCE_LEVEL, COMPLIANCE_LEVEL); 262 // Configure the encoder. 263 ret = OH_AudioCodec_Configure(audioEnc_, format); 264 if (ret != AV_ERR_OK) { 265 // Handle exceptions. 266 } 267 ``` 268 269 <!--RP1--><!--RP1End--> 270 2715. Call **OH_AudioCodec_Prepare()** to prepare internal resources for the encoder. 272 273 ```cpp 274 int32_t ret = OH_AudioCodec_Prepare(audioEnc_); 275 if (ret != AV_ERR_OK) { 276 // Handle exceptions. 277 } 278 ``` 279 2806. Call **OH_AudioCodec_Start()** to start the encoder. 281 282 Add the header file. 283 ```c++ 284 #include <fstream> 285 ``` 286 The sample code is as follows: 287 ```c++ 288 ifstream inputFile_; 289 ofstream outFile_; 290 291 // Set the input file path based on the actual situation. 292 const char* inputFilePath = "/"; 293 // Set the output file path based on the actual situation. 294 const char* outputFilePath = "/"; 295 // Open the path of the binary file to be encoded. (A PCM file is used as an example.) 296 inputFile_.open(inputFilePath, ios::in | ios::binary); 297 // Set the path of the output file. (An encoded stream file is used as an example.) 298 outFile_.open(outputFilePath, ios::out | ios::binary); 299 // Start encoding. 300 int32_t ret = OH_AudioCodec_Start(audioEnc_); 301 if (ret != AV_ERR_OK) { 302 // Handle exceptions. 303 } 304 ``` 305 3067. Call **OH_AudioCodec_PushInputBuffer()** to write the data to encode. You should fill in complete input data before calling this API. 307 308 The method for determining the number of samples per frame (**SAMPLES_PER_FRAME**) is as follows: 309 310 AAC-LC encodes 1024 PCM samples per frame. Therefore, you are advised to input exactly 1024 samples at a time. 311 312 <!--RP5--><!--RP5End--> 313 314 For FLAC encoding, set **SAMPLES_PER_FRAME** based on the table below. 315 316 | Sample Rate| Sample Count| 317 | :----: | :----: | 318 | 8000 | 576 | 319 | 16000 | 1152 | 320 | 22050 | 2304 | 321 | 24000 | 2304 | 322 | 32000 | 2304 | 323 | 44100 | 4608 | 324 | 48000 | 4608 | 325 | 88200 | 8192 | 326 | 96000 | 8192 | 327 328 > **NOTE** 329 > 330 > Data volume (in bytes) of a single encoding input: Number of samples (**SAMPLES_PER_FRAME**) * Number of channels * Number of bytes per sample. 331 > 332 > In the case of FLAC encoding, use the table below to set the number of samples based on the sample rate to prevent possible file corruption. 333 334 ```c++ 335 // Audio channel count. 336 constexpr int32_t DEFAULT_CHANNEL_COUNT = 2; 337 // Number of samples. For example, the number of samples for AAC-LC is 1024. 338 constexpr int32_t SAMPLES_PER_FRAME = 1024; 339 // Data volume (in bytes) of a single encoding input: Number of samples * Number of channels * Number of bytes per sample. (The sample format SAMPLE_S16LE is used as an example.) 340 // If the last frame of data does not meet the required length,you are advised to discard it or add padding. 341 constexpr int32_t INPUT_FRAME_BYTES = SAMPLES_PER_FRAME * DEFAULT_CHANNEL_COUNT * sizeof(short); 342 uint32_t index = signal_->inQueue_.front(); 343 auto buffer = signal_->inBufferQueue_.front(); 344 OH_AVCodecBufferAttr attr = {0}; 345 if (!inputFile_.eof()) { 346 inputFile_.read((char *)OH_AVBuffer_GetAddr(buffer), INPUT_FRAME_BYTES); 347 attr.size = INPUT_FRAME_BYTES; 348 attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 349 } else { 350 attr.size = 0; 351 attr.flags = AVCODEC_BUFFER_FLAGS_EOS; 352 } 353 OH_AVBuffer_SetBufferAttr(buffer, &attr); 354 // Send the data to the input queue for encoding. The index is the subscript of the queue. 355 int32_t ret = OH_AudioCodec_PushInputBuffer(audioEnc_, index); 356 if (ret != AV_ERR_OK) { 357 // Handle exceptions. 358 } 359 ``` 360 In the preceding example, **attr.flags** indicates the type of the buffer flag. 361 362 To indicate the End of Stream (EOS), pass in the **AVCODEC_BUFFER_FLAGS_EOS** flag. 363 364 | Value| Description| 365 | -------- | -------- | 366 | AVCODEC_BUFFER_FLAGS_NONE | Common frame.| 367 | AVCODEC_BUFFER_FLAGS_EOS | The buffer is an end-of-stream frame.| 368 | AVCODEC_BUFFER_FLAGS_CODEC_DATA | The buffer contains codec-specific data.| 369 3708. Call **OH_AudioCodec_FreeOutputBuffer()** to release the encoded data. 371 372 Once you have retrieved the encoded stream, call **OH_AudioCodec_FreeOutputBuffer()** to free up the data. 373 374 ```c++ 375 uint32_t index = signal_->outQueue_.front(); 376 OH_AVBuffer *avBuffer = signal_->outBufferQueue_.front(); 377 if (avBuffer == nullptr) { 378 // Handle exceptions. 379 } 380 // Obtain the buffer attributes. 381 OH_AVCodecBufferAttr attr = {0}; 382 int32_t ret = OH_AVBuffer_GetBufferAttr(avBuffer, &attr); 383 if (ret != AV_ERR_OK) { 384 // Handle exceptions. 385 } 386 // Write the encoded data (specified by data) to the output file. 387 outFile_.write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(avBuffer)), attr.size); 388 // Release the output buffer. 389 ret = OH_AudioCodec_FreeOutputBuffer(audioEnc_, index); 390 if (ret != AV_ERR_OK) { 391 // Handle exceptions. 392 } 393 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 394 // End. 395 } 396 ``` 397 3989. (Optional) Call **OH_AudioCodec_Flush()** to refresh the encoder. 399 400 After **OH_AudioCodec_Flush()** is called, the current encoding queue is cleared. 401 402 To continue encoding, you must call **OH_AudioCodec_Start()** again. 403 404 You need to call **OH_AudioCodec_Flush()** in the following cases: 405 406 * The EOS of the file is reached. 407 * An error with **OH_AudioCodec_IsValid** set to **true** (indicating that the execution can continue) occurs. 408 409 ```c++ 410 // Refresh the encoder. 411 int32_t ret = OH_AudioCodec_Flush(audioEnc_); 412 if (ret != AV_ERR_OK) { 413 // Handle exceptions. 414 } 415 // Start encoding again. 416 ret = OH_AudioCodec_Start(audioEnc_); 417 if (ret != AV_ERR_OK) { 418 // Handle exceptions. 419 } 420 ``` 421 42210. (Optional) Call **OH_AudioCodec_Reset()** to reset the encoder. 423 424 After **OH_AudioCodec_Reset()** is called, the encoder returns to the initialized state. To continue encoding, you must call **OH_AudioCodec_Configure()** and then **OH_AudioCodec_Start()**. 425 426 ```c++ 427 // Reset the encoder. 428 int32_t ret = OH_AudioCodec_Reset(audioEnc_); 429 if (ret != AV_ERR_OK) { 430 // Handle exceptions. 431 } 432 // Reconfigure the encoder. 433 ret = OH_AudioCodec_Configure(audioEnc_, format); 434 if (ret != AV_ERR_OK) { 435 // Handle exceptions. 436 } 437 ``` 438 43911. Call **OH_AudioCodec_Stop()** to stop the encoder. 440 441 After the encoder is stopped, you can call **Start** to start it again. If you have passed specific data in the previous **Start** for the encoder, you must pass it again. 442 443 ```c++ 444 // Stop the encoder. 445 int32_t ret = OH_AudioCodec_Stop(audioEnc_); 446 if (ret != AV_ERR_OK) { 447 // Handle exceptions. 448 } 449 ``` 450 45112. Call **OH_AudioCodec_Destroy()** to destroy the encoder instance and release resources. 452 453 > **NOTE** 454 > 455 > You only need to call this API once. 456 457 ```c++ 458 // Call OH_AudioCodec_Destroy to destroy the encoder. 459 int32_t ret = OH_AudioCodec_Destroy(audioEnc_); 460 if (ret != AV_ERR_OK) { 461 // Handle exceptions. 462 } else { 463 audioEnc_ = NULL; // The encoder cannot be destroyed repeatedly. 464 } 465 ``` 466