1# Audio Encoding 2 3You can call the native APIs provided by the AudioCodec module to encode audio, that is, to compress audio PCM data into a desired format. 4 5PCM 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. 6 7For details about the supported encoding capabilities, see [AVCodec Supported Formats](avcodec-support-formats.md#audio-encoding). 8 9**Usage Scenario** 10 11- Audio recording 12 13 Record incoming PCM data, encode it into the desired stream format, and then [wrap](audio-video-muxer.md#media-data-multiplexing) it in the target file format. 14- Audio editing 15 16 When exporting edited PCM data as an audio file, the PCM data must be encoded into the appropriate audio format and then [wrapped](audio-video-muxer.md#media-data-multiplexing) into a file. 17> **NOTE** 18> 19> AAC encoders adopt the VBR mode by default, which may differ in the configured parameters. 20 21## How to Develop 22 23Read [AudioCodec](../../reference/apis-avcodec-kit/_audio_codec.md) for the API reference. 24 25Refer to the code snippet below to complete the entire audio encoding process, including creating an encoder, setting encoding parameters (such as the sampling rate, bit rate, and number of audio channels), and starting, refreshing, resetting, and destroying the encoder. 26 27During application development, you must call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur. 28 29The figure below shows the call relationship of audio encoding. 30 31- The dotted line indicates an optional operation. 32 33- The solid line indicates a mandatory operation. 34 35 36 37### Linking the Dynamic Libraries in the CMake Script 38 39```cmake 40target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 41target_link_libraries(sample PUBLIC libnative_media_core.so) 42target_link_libraries(sample PUBLIC libnative_media_acodec.so) 43``` 44 45### How to Develop 46 471. Add the header files. 48 49 ```cpp 50 #include <multimedia/player_framework/native_avcodec_audiocodec.h> 51 #include <multimedia/native_audio_channel_layout.h> 52 #include <multimedia/player_framework/native_avcapability.h> 53 #include <multimedia/player_framework/native_avcodec_base.h> 54 #include <multimedia/player_framework/native_avformat.h> 55 #include <multimedia/player_framework/native_avbuffer.h> 56 ``` 57 582. Create an encoder instance. In the code snippet below, **OH_AVCodec *** is the pointer to the encoder instance created. 59 60 You can create an encoder by name or MIME type. 61 62 ```cpp 63 // Namespace of the C++ standard library. 64 using namespace std; 65 // Create an encoder by name. 66 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 67 const char *name = OH_AVCapability_GetName(capability); 68 OH_AVCodec *audioEnc_ = OH_AudioCodec_CreateByName(name); 69 ``` 70 71 ```cpp 72 // Specify whether encoding is used. The value true means encoding. 73 bool isEncoder = true; 74 // Create an encoder by MIME type. 75 OH_AVCodec *audioEnc_ = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC, isEncoder); 76 ``` 77 78 ```cpp 79 // Initialize the queues. 80 class AEncBufferSignal { 81 public: 82 std::mutex inMutex_; 83 std::mutex outMutex_; 84 std::mutex startMutex_; 85 std::condition_variable inCond_; 86 std::condition_variable outCond_; 87 std::condition_variable startCond_; 88 std::queue<uint32_t> inQueue_; 89 std::queue<uint32_t> outQueue_; 90 std::queue<OH_AVBuffer *> inBufferQueue_; 91 std::queue<OH_AVBuffer *> outBufferQueue_; 92 }; 93 AEncBufferSignal *signal_; 94 ``` 95 963. Call **OH_AudioCodec_RegisterCallback()** to register callback functions. 97 98 Register the **OH_AVCodecCallback** struct that defines the following callback function pointers: 99 100 - **OH_AVCodecOnError**, a callback used to report a codec operation error 101 - **OH_AVCodecOnStreamChanged**, a callback not supported by the audio encoder yet 102 - **OH_AVCodecOnNeedInputBuffer**, a callback used to report input data required, which means that the encoder is ready for receiving PCM data 103 - **OH_AVCodecOnNewOutputBuffer**, a callback used to report output data generated, which means that encoding is complete 104 105 You need to process the callback functions to ensure that the encoder runs properly. 106 107 > **NOTE** 108 > 109 > You are not advised to perform time-consuming operations in the callback. 110 111 ```cpp 112 // Implement the OH_AVCodecOnError callback function. 113 static void OnError(OH_AVCodec *codec, int32_t errorCode, void *userData) 114 { 115 (void)codec; 116 (void)errorCode; 117 (void)userData; 118 } 119 // Implement the OH_AVCodecOnStreamChanged callback function. 120 static void OnOutputFormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData) 121 { 122 (void)codec; 123 (void)format; 124 (void)userData; 125 } 126 // Implement the OH_AVCodecOnNeedInputBuffer callback function. 127 static void OnInputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 128 { 129 (void)codec; 130 // The input stream is sent to the InputBuffer queue. 131 AEncBufferSignal *signal = static_cast<AEncBufferSignal *>(userData); 132 unique_lock<mutex> lock(signal->inMutex_); 133 signal->inQueue_.push(index); 134 signal->inBufferQueue_.push(data); 135 signal->inCond_.notify_all(); 136 } 137 // Implement the OH_AVCodecOnNewOutputBuffer callback function. 138 static void OnOutputBufferAvailable(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData) 139 { 140 (void)codec; 141 // The index of the output buffer is sent to OutputQueue_. 142 // The encoded data is sent to the outBuffer queue. 143 AEncBufferSignal *signal = static_cast<AEncBufferSignal *>(userData); 144 unique_lock<mutex> lock(signal->outMutex_); 145 signal->outQueue_.push(index); 146 signal->outBufferQueue_.push(data); 147 } 148 signal_ = new AEncBufferSignal(); 149 OH_AVCodecCallback cb_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable}; 150 // Set the asynchronous callbacks. 151 int32_t ret = OH_AudioCodec_RegisterCallback(audioEnc_, cb_, signal_); 152 if (ret != AV_ERR_OK) { 153 // Handle exceptions. 154 } 155 ``` 156 1574. Call **OH_AudioCodec_Configure** to configure the encoder. 158 159 The following options are mandatory: sampling rate, bit rate, number of audio channels, audio channel type, and bit depth. 160 161 The maximum input length is optional. 162 163 For FLAC encoding, the compliance level and sampling precision are also mandatory. 164 165 The sample below lists the value range of each audio encoding type. 166 | Audio Encoding Type| Sampling Rate (Hz) | Audio Channel Count | 167 | ----------- | ------------------------------------------------------------------------------- | :----------------: | 168 | <!--DelRow-->AAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000| 1, 2, 3, 4, 5, 6, and 8| 169 | FLAC | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000| 1–8 | 170 | MP3 | 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 | 1–2 | 171 | G711mu | 8000 | 1 | 172 <!--RP3--><!--RP3End--> 173 174 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 sampling rate, 2-channel stereo, and SAMPLE_S16LE sampling format. 175 <!--RP4--> 176 ```cpp 177 int32_t ret; 178 // (Mandatory) Configure the audio sampling rate. 179 constexpr uint32_t DEFAULT_SAMPLERATE = 44100; 180 // (Mandatory) Configure the audio bit rate. 181 constexpr uint64_t DEFAULT_BITRATE = 32000; 182 // (Mandatory) Configure the number of audio channels. 183 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 184 // (Mandatory) Configure the audio channel type. 185 constexpr OH_AudioChannelLayout CHANNEL_LAYOUT = OH_AudioChannelLayout::CH_LAYOUT_STEREO; 186 // (Mandatory) Configure the audio bit depth. 187 constexpr OH_BitsPerSample SAMPLE_FORMAT = OH_BitsPerSample::SAMPLE_S16LE; 188 // A frame of audio data takes 20 ms. 189 constexpr float TIME_PER_FRAME = 0.02; 190 // (Optional) Configure the maximum input length and the size of each audio frame. 191 constexpr uint32_t DEFAULT_MAX_INPUT_SIZE = DEFAULT_SAMPLERATE * TIME_PER_FRAME * DEFAULT_CHANNEL_COUNT * sizeof(short); // aac 192 OH_AVFormat *format = OH_AVFormat_Create(); 193 // Set the format. 194 OH_AVFormat_SetIntValue(format,OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT); 195 OH_AVFormat_SetIntValue(format,OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE); 196 OH_AVFormat_SetLongValue(format,OH_MD_KEY_BITRATE, DEFAULT_BITRATE); 197 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_FORMAT); 198 OH_AVFormat_SetLongValue(format,OH_MD_KEY_CHANNEL_LAYOUT, CHANNEL_LAYOUT); 199 OH_AVFormat_SetIntValue(format,OH_MD_KEY_MAX_INPUT_SIZE, DEFAULT_MAX_INPUT_SIZE); 200 // Configure the encoder. 201 ret = OH_AudioCodec_Configure(audioEnc_, format); 202 if (ret != AV_ERR_OK) { 203 // Handle exceptions. 204 } 205 ``` 206 <!--RP4End--> 207 The following shows the API call process in the case of FLAC encoding. 208 209 ```cpp 210 int32_t ret; 211 // (Mandatory) Configure the audio sampling rate. 212 constexpr uint32_t DEFAULT_SAMPLERATE = 44100; 213 // (Mandatory) Configure the audio bit rate. 214 constexpr uint64_t DEFAULT_BITRATE = 261000; 215 // (Mandatory) Configure the number of audio channels. 216 constexpr uint32_t DEFAULT_CHANNEL_COUNT = 2; 217 // (Mandatory) Configure the audio channel type. 218 constexpr OH_AudioChannelLayout CHANNEL_LAYOUT = OH_AudioChannelLayout::CH_LAYOUT_STEREO; 219 // (Mandatory) Configure the audio bit depth. Only SAMPLE_S16LE and SAMPLE_S32LE are available for FLAC encoding. 220 constexpr OH_BitsPerSample SAMPLE_FORMAT = OH_BitsPerSample::SAMPLE_S32LE; 221 // Configure the audio compliance level. The default value is 0, and the value ranges from -2 to 2. 222 constexpr int32_t COMPLIANCE_LEVEL = 0; 223 // (Mandatory) Configure the audio sampling precision. SAMPLE_S16LE, SAMPLE_S24LE, and SAMPLE_S32LE are available. 224 constexpr OH_BitsPerSample BITS_PER_CODED_SAMPLE = OH_BitsPerSample::SAMPLE_S24LE; 225 OH_AVFormat *format = OH_AVFormat_Create(); 226 // Set the format. 227 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, DEFAULT_CHANNEL_COUNT); 228 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, DEFAULT_SAMPLERATE); 229 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, DEFAULT_BITRATE); 230 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, BITS_PER_CODED_SAMPLE); 231 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_FORMAT); 232 OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, CHANNEL_LAYOUT); 233 OH_AVFormat_SetLongValue(format, OH_MD_KEY_COMPLIANCE_LEVEL, COMPLIANCE_LEVEL); 234 // Configure the encoder. 235 ret = OH_AudioCodec_Configure(audioEnc_, format); 236 if (ret != AV_ERR_OK) { 237 // Handle exceptions. 238 } 239 ``` 240 241 <!--RP2--><!--RP2End--> 242 2435. Call **OH_AudioCodec_Prepare()** to prepare internal resources for the encoder. 244 245 ```cpp 246 ret = OH_AudioCodec_Prepare(audioEnc_); 247 if (ret != AV_ERR_OK) { 248 // Handle exceptions. 249 } 250 ``` 251 2526. Call **OH_AudioCodec_Start()** to start the encoder. 253 254 ```c++ 255 unique_ptr<ifstream> inputFile_ = make_unique<ifstream>(); 256 unique_ptr<ofstream> outFile_ = make_unique<ofstream>(); 257 // Open the path of the binary file to be encoded. (A PCM file is used as an example.) 258 inputFile_->open(inputFilePath.data(), ios::in | ios::binary); 259 // Configure the path of the output file. (An encoded stream file is used as an example.) 260 outFile_->open(outputFilePath.data(), ios::out | ios::binary); 261 // Start encoding. 262 ret = OH_AudioCodec_Start(audioEnc_); 263 if (ret != AV_ERR_OK) { 264 // Handle exceptions. 265 } 266 ``` 267 2687. Call **OH_AudioCodec_PushInputBuffer()** to write the data to encode. You should fill in complete input data before calling this API. 269 270 Set **SAMPLES_PER_FRAME** as follows: 271 272 For AAC encoding, set **SAMPLES_PER_FRAME** to the number of PCM samples every 20 ms, that is, sampling rate x 0.02. 273 274 For FLAC encoding, set **SAMPLES_PER_FRAME** based on the table below. 275 276 | Sampling Rate| Sample Count| 277 | :----: | :----: | 278 | 8000 | 576 | 279 | 16000 | 1152 | 280 | 22050 | 2304 | 281 | 24000 | 2304 | 282 | 32000 | 2304 | 283 | 44100 | 4608 | 284 | 48000 | 4608 | 285 | 88200 | 8192 | 286 | 96000 | 8192 | 287 288 > **NOTE** 289 > 290 > It is recommended that **SAMPLES_PER_FRAME** in AAC encoding be the number of PCM samples every 20 ms, that is, sampling rate x 0.02. In the case of FLAC encoding, if the number of samples is greater than the corresponding value provided in the table, an error code is returned. If the number is less than the corresponding value provided in the table, the encoded file may be damaged. 291 292 ```c++ 293 // Number of samples per frame. 294 constexpr int32_t SAMPLES_PER_FRAME = DEFAULT_SAMPLERATE * TIME_PER_FRAME; 295 // Number of audio channels. For AMR encoding, only mono audio input is supported. 296 constexpr int32_t DEFAULT_CHANNEL_COUNT = 2; 297 // Length of the input data of each frame, that is, number of audio channels x number of samples per frame x number of bytes per sample (SAMPLE_S16LE used as an example). 298 // If the last frame of data does not meet the required length,you are advised to discard it or add padding. 299 constexpr int32_t INPUT_FRAME_BYTES = DEFAULT_CHANNEL_COUNT * SAMPLES_PER_FRAME * sizeof(short); 300 uint32_t index = signal_->inQueue_.front(); 301 auto buffer = signal_->inBufferQueue_.front(); 302 OH_AVCodecBufferAttr attr = {0}; 303 if (!inputFile_->eof()) { 304 inputFile_->read((char *)OH_AVBuffer_GetAddr(buffer), INPUT_FRAME_BYTES); 305 attr.size = INPUT_FRAME_BYTES; 306 attr.flags = AVCODEC_BUFFER_FLAGS_NONE; 307 } else { 308 attr.size = 0; 309 attr.flags = AVCODEC_BUFFER_FLAGS_EOS; 310 } 311 OH_AVBuffer_SetBufferAttr(buffer, &attr); 312 // Send the data to the input queue for encoding. The index is the subscript of the queue. 313 ret = OH_AudioCodec_PushInputBuffer(audioEnc_, index); 314 if (ret != AV_ERR_OK) { 315 // Handle exceptions. 316 } 317 ``` 318 In the preceding example, **attr.flags** indicates the type of the buffer flag. 319 320 To indicate the End of Stream (EOS), pass in the **AVCODEC_BUFFER_FLAGS_EOS** flag. 321 322 | Value| Description| 323 | -------- | -------- | 324 | AVCODEC_BUFFER_FLAGS_NONE | Common frame.| 325 | AVCODEC_BUFFER_FLAGS_EOS | The buffer is an end-of-stream frame.| 326 | AVCODEC_BUFFER_FLAGS_CODEC_DATA | The buffer contains codec-specific data.| 327 3288. Call **OH_AudioCodec_FreeOutputBuffer()** to release the encoded data. 329 330 Once you have retrieved the encoded stream, call **OH_AudioCodec_FreeOutputBuffer()** to free up the data. 331 332 ```c++ 333 uint32_t index = signal_->outQueue_.front(); 334 OH_AVBuffer *avBuffer = signal_->outBufferQueue_.front(); 335 // Obtain the buffer attributes. 336 OH_AVCodecBufferAttr attr = {0}; 337 ret = OH_AVBuffer_GetBufferAttr(avBuffer, &attr); 338 if (ret != AV_ERR_OK) { 339 // Handle exceptions. 340 } 341 // Write the encoded data (specified by data) to the output file. 342 outputFile_->write(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(avBuffer)), attr.size); 343 // Release the output buffer. 344 ret = OH_AudioCodec_FreeOutputBuffer(audioEnc_, index); 345 if (ret != AV_ERR_OK) { 346 // Handle exceptions. 347 } 348 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 349 // End. 350 } 351 ``` 352 3539. (Optional) Call **OH_AudioCodec_Flush()** to refresh the encoder. 354 355 After **OH_AudioCodec_Flush()** is called, the current encoding queue is cleared. 356 357 To continue encoding, you must call **OH_AudioCodec_Start()** again. 358 359 You need to call **OH_AudioCodec_Flush()** in the following cases: 360 361 * The EOS of the file is reached. 362 * An error with **OH_AudioCodec_IsValid** set to **true** (indicating that the execution can continue) occurs. 363 364 ```c++ 365 // Refresh the encoder. 366 ret = OH_AudioCodec_Flush(audioEnc_); 367 if (ret != AV_ERR_OK) { 368 // Handle exceptions. 369 } 370 // Start encoding again. 371 ret = OH_AudioCodec_Start(audioEnc_); 372 if (ret != AV_ERR_OK) { 373 // Handle exceptions. 374 } 375 ``` 376 37710. (Optional) Call **OH_AudioCodec_Reset()** to reset the encoder. 378 379 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()**. 380 381 ```c++ 382 // Reset the encoder. 383 ret = OH_AudioCodec_Reset(audioEnc_); 384 if (ret != AV_ERR_OK) { 385 // Handle exceptions. 386 } 387 // Reconfigure the encoder. 388 ret = OH_AudioCodec_Configure(audioEnc_, format); 389 if (ret != AV_ERR_OK) { 390 // Handle exceptions. 391 } 392 ``` 393 39411. Call **OH_AudioCodec_Stop()** to stop the encoder. 395 396 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. 397 398 ```c++ 399 // Stop the encoder. 400 ret = OH_AudioCodec_Stop(audioEnc_); 401 if (ret != AV_ERR_OK) { 402 // Handle exceptions. 403 } 404 ``` 405 40612. Call **OH_AudioCodec_Destroy()** to destroy the encoder instance and release resources. 407 408 > **NOTE** 409 > 410 > You only need to call the API once. 411 412 ```c++ 413 // Call OH_AudioCodec_Destroy to destroy the encoder. 414 ret = OH_AudioCodec_Destroy(audioEnc_); 415 if (ret != AV_ERR_OK) { 416 // Handle exceptions. 417 } else { 418 audioEnc_ = NULL; // The encoder cannot be destroyed repeatedly. 419 } 420 ``` 421