1# Obtaining Supported Codecs 2 3The codecs and their capabilities that you can use for your application on a device vary according to the codec source, codec protocol, and codec capabilities deployed on that device. 4 5To ensure that the encoding and decoding behavior meets your expectations, first query the audio and video codecs supported by the system and their capability parameters through a series of APIs. Then find the codecs that are suitable for the development scenario, and correctly configure the codec parameters. 6 7## General Development 81. Link the dynamic libraries in the CMake script. 9 10 ``` cmake 11 target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 12 target_link_libraries(sample PUBLIC libnative_media_core.so) 13 target_link_libraries(sample PUBLIC libnative_media_venc.so) 14 target_link_libraries(sample PUBLIC libnative_media_vdec.so) 15 ``` 16 > **NOTE** 17 > 18 > The word **sample** in the preceding code snippet is only an example. Use the actual project directory name. 19 > 20 212. Add the header files. 22 23 ```c++ 24 #include <multimedia/player_framework/native_avcapability.h> 25 #include <multimedia/player_framework/native_avcodec_base.h> 26 #include <multimedia/player_framework/native_avformat.h> 27 #include <multimedia/player_framework/native_avcodec_videoencoder.h> 28 #include <multimedia/player_framework/native_avcodec_videodecoder.h> 29 ``` 30 313. Obtain the audio/video codec capability instance. 32 33 You can use either of the following methods to obtain the instance: 34 35 Method 1: Call **OH_AVCodec_GetCapability** to obtain the codec capability instance recommended by the system. The recommendation policy is the same as that of the **OH_XXX_CreateByMime** series APIs. 36 ```c++ 37 // Obtain the AAC decoder capability instance recommended by the system. 38 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, false); 39 ``` 40 41 Method 2: Call **OH_AVCodec_GetCapabilityByCategory** to obtain the codec capability instance of the specified software or hardware. 42 ```c++ 43 // Obtain the AVC encoder capability instance of the specified hardware. 44 OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true, HARDWARE); 45 ``` 46 The system automatically recycles the instance when it is no longer needed. 47 484. Call the query APIs as required. For details, see the [API Reference](../../reference/apis-avcodec-kit/_a_v_capability.md). 49 50## Scenario-specific Development 51This section describes how to use the capability query APIs in specific scenarios. 52 53### Creating a Codec with the Specified Name 54 55If multiple encoders or decoders with the same MIME type exist, using the **OH_XXX_CreateByMime** series APIs creates only codecs recommended by the system. To create a non-recommended codec, you must first obtain the codec name and then call **OH_XXX_CreateByName** series APIs to create a codec with the given name. 56 57| API | Description | 58| -------- | -------------------------------- | 59| OH_AVCapability_GetName | Obtains the name of a codec corresponding to a capability instance.| 60 61The code snippet below creates an H.264 software decoder when there are an H.264 software decoder and H.264 hardware decoder: 62```c++ 63// 1. Obtain an H.264 software decoder capability instance. 64OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE); 65if (capability != nullptr) { 66 // 2. Obtain the name of the H.264 software decoder. 67 const char *codecName = OH_AVCapability_GetName(capability); 68 // 3. Create an H.264 software decoder instance. 69 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(codecName); 70} 71``` 72 73### Setting Codec Parameters by Software or Hardware 74 75A software codec and hardware codec are defined as follows: 76 77* A software codec performs encoding and decoding on the CPU. Its capabilities can be flexibly iterated. It provides better compatibility and better protocol and specification extension capabilities over a hardware codec. 78 79* A hardware codec performs encoding and decoding on dedicated hardware. It has been hardened on the hardware platform and its capabilities are iterated with the hardware platform. Compared with a software codec, a hardware codec has better power consumption, time consumption, and throughput performance, as well as lower CPU load. 80 81A hardware codec is preferred as long as it meets your project requirements. You can configure codec parameters based on the software or hardware type. 82 83| API | Description | 84| -------- | -------------------------------- | 85| OH_AVCapability_IsHardware | Checks whether a codec capability instance describes a hardware codec.| 86 87The code snippet below shows the differentiated frame rate configuration for software and hardware video encoders. 88 89```c++ 90// 1. Check whether the recommended H.264 encoder is a hardware codec. 91OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 92bool isHardward = OH_AVCapability_IsHardware(capability); 93// 2. Carry out differentiated configuration based on the software or hardware type. 94OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 95OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 96double frameRate = isHardward ? 60.0 : 30.0; 97if (!OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate)) { 98 // Exception handling. 99} 100if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 101 // Exception handling. 102} 103OH_AVFormat_Destroy(format); 104``` 105 106### Creating a Multi-Channel Codec 107 108Multiple codecs are required in certain scenarios. However, the number of codec instances that can be created is limited due to the restrictions of system resources. 109 110| API | Description | 111| -------- | -------------------------------- | 112| OH_AVCapability_GetMaxSupportedInstances | Obtains the maximum number of codec instances that can be concurrently run corresponding to a capability instance. The actual number of codec instances that can be created is restricted by other system resources.| 113 114Create hardware decoder instances first. If the hardware decoder instances cannot fully meet the project requirements, create software decoder instances. The following is an example: 115 116```c++ 117constexpr int32_t NEEDED_VDEC_NUM = 8; 118// 1. Create hardware decoder instances. 119OH_AVCapability *capHW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, HARDWARE); 120int32_t vDecNumHW = min(OH_AVCapability_GetMaxSupportedInstances(capHW), NEEDED_VDEC_NUM); 121int32_t createdVDecNum = 0; 122for (int i = 0; i < vDecNumHW; i++) { 123 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capHW)); 124 if (videoDec != nullptr) { 125 // Maintained in videoDecVector. 126 createdVDecNum++; 127 } 128} 129if (createdVDecNum < NEEDED_VDEC_NUM) { 130 // 2. If the hardware decoder instances cannot fully meet the project requirements, create software decoder instances. 131 OH_AVCapability *capSW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE); 132 int32_t vDecNumSW = min(OH_AVCapability_GetMaxSupportedInstances(capSW), NEEDED_VDEC_NUM - createdVDecNum); 133 for (int i = 0; i < vDecNumSW; i++) { 134 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capSW)); 135 if (videoDec != nullptr) { 136 // Maintained in videoDecVector. 137 createdVDecNum++; 138 } 139 } 140} 141``` 142 143### Controlling the Encoding Quality 144 145Three bit rate modes are available: Constant Bit Rate (CBR), Dynamic Bit Rate (VBR), and Constant Quality (CQ). For CBR and VBR, the encoding quality is determined by the bit rate parameters. For CQ, the encoding quality is determined by the quality parameters. 146 147| API | Description | 148| -------- | ---------------------------- | 149| OH_AVCapability_IsEncoderBitrateModeSupported | Checks whether a codec supports the specified bit rate mode.| 150| OH_AVCapability_GetEncoderBitrateRange | Obtains the bit rate range supported by a codec. This API can be used in CBR or VBR mode.| 151| OH_AVCapability_GetEncoderQualityRange | Obtains the quality range supported by a codec. This API can be used in CQ mode. | 152 153The code snippet below shows the configuration in CBR or VBR mode. 154 155```c++ 156OH_BitrateMode bitrateMode = BITRATE_MODE_CBR; 157int32_t bitrate = 3000000; 158OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 159if (capability == nullptr) { 160 // Exception handling. 161} 162// 1. Check whether a bit rate mode is supported. 163bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode); 164if (!isSupported) { 165 // Exception handling. 166} 167// 2. Obtain the bit rate range and check whether the bit rate to be configured is within the range. 168OH_AVRange bitrateRange = {-1, -1}; 169int32_t ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange); 170if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) { 171 // Exception handling. 172} 173if (bitrate > bitrateRange.maxVal || bitrate < bitrateRange.minVal) { 174 // 3. (Optional) Adjust the bit rate parameters to be configured. 175} 176// 4. Set the encoding parameters. 177OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 178OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 179if (OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, bitrateMode) && 180 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, static_cast<int64_t>(bitrate)) == false) { 181 // Exception handling. 182} 183if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 184 // Exception handling. 185} 186OH_AVFormat_Destroy(format); 187``` 188 189The code snippet below shows the configuration in CQ mode. 190 191```c++ 192OH_BitrateMode bitrateMode = BITRATE_MODE_CQ; 193int32_t quality = 0; 194OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 195if (capability == nullptr) { 196 // Exception handling. 197} 198// 1. Check whether a bit rate mode is supported. 199bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode); 200if (!isSupported) { 201 // Exception handling. 202} 203// 2. Obtain the quality range and determine whether the quality parameters to be configured are within the range. 204OH_AVRange qualityRange = {-1, -1}; 205int32_t ret = OH_AVCapability_GetEncoderQualityRange(capability, &qualityRange); 206if (ret != AV_ERR_OK || qualityRange.maxVal < 0) { 207 // Exception handling. 208} 209if (quality > qualityRange.maxVal || quality < qualityRange.minVal) { 210 // 3. (Optional) Adjust the quality parameters to be configured. 211} 212// 5. Set the encoding parameters. 213OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 214OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 215if (OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, bitrateMode) && 216 OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, quality) == false) { 217 // Exception handling. 218} 219if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 220 // Exception handling. 221} 222OH_AVFormat_Destroy(format); 223``` 224 225### Checking the Complexity Range Supported 226 227The complexity range determines the number of tools used by the codec. It is supported only by some codecs. 228 229| API | Description | 230| -------- | ---------------------------- | 231| OH_AVCapability_GetEncoderComplexityRange | Obtains the complexity range supported by a codec.| 232 233```c++ 234OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 235if (capability == nullptr) { 236 // Exception handling. 237} 238// Check the supported encoding complexity range. 239OH_AVRange complexityRange = {-1, -1}; 240int32_t ret = OH_AVCapability_GetEncoderComplexityRange(capability, &complexityRange); 241``` 242 243### Setting the Correct Audio Codec Parameters 244 245In audio encoding or decoding scenarios, you need to query and set parameters such as the sampling rate, number of channels, and bit rate (required only for audio encoding). 246 247| API | Description | 248| -------- | ---------------------------- | 249| OH_AVCapability_GetAudioSupportedSampleRates | Obtains the sample rates supported by an audio codec.| 250| OH_AVCapability_GetAudioChannelCountRange | Obtains the count range of channels supported by an audio codec.| 251| OH_AVCapability_GetEncoderBitrateRange | Obtains the bit rate range supported by an encoder.| 252 253The code snippet below shows how to correctly set the encoding parameters in the audio encoding scenario. 254 255```c++ 256int32_t sampleRate = 44100; 257int32_t channelCount = 2; 258int32_t bitrate = 261000; 259OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 260if (capability == nullptr) { 261 // Exception handling. 262} 263// 1. Check whether the sample rate to be configured is supported. 264const int32_t *sampleRates = nullptr; 265uint32_t sampleRateNum = -1; 266int32_t ret = OH_AVCapability_GetAudioSupportedSampleRates(capability, &sampleRates, &sampleRateNum); 267if (ret != AV_ERR_OK || sampleRates == nullptr || sampleRateNum <= 0) { 268 // Exception handling. 269} 270bool isMatched = false; 271for (int i = 0; i < sampleRateNum; i++) { 272 if (sampleRates[i] == sampleRate) { 273 isMatched = true; 274 } 275} 276if (!isMatched) { 277 // 2. (Optional) Adjust the sample rate to be configured. 278} 279// 3. Obtain the count range of channels and check whether the number of channels to be configured is within the range. 280OH_AVRange channelRange = {-1, -1}; 281ret = OH_AVCapability_GetAudioChannelCountRange(capability, &channelRange); 282if (ret != AV_ERR_OK || channelRange.maxVal <= 0) { 283 // Exception handling. 284} 285if (channelCount > channelRange.maxVal || channelCount < channelRange.minVal ) { 286 //4. (Optional) Adjust the number of channels to be configured. 287} 288// 5. Obtain the bit rate range and check whether the bit rate to be configured is within the range. 289OH_AVRange bitrateRange = {-1, -1}; 290ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange); 291if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) { 292 // Exception handling. 293} 294if (bitrate > bitrateRange.maxVal || bitrate < bitrateRange.minVal ) { 295 //7. (Optional) Adjust the bit rate to be configured. 296} 297// 8. Set the encoding parameters. 298OH_AVCodec *audioEnc = OH_AudioEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC); 299OH_AVFormat *format = OH_AVFormat_Create(); 300if (OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate) && 301 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channelCount) && 302 OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, static_cast<int64_t>(bitrate)) == false) { 303 // Exception handling. 304} 305if (OH_AudioEncoder_Configure(audioEnc, format) != AV_ERR_OK) { 306 // Exception handling. 307} 308OH_AVFormat_Destroy(format); 309``` 310 311### Checking the Codec Profile and Level Supported 312 313The codec standard provides lots of encoding tools to deal with various encoding scenarios. However, not all tools are required in a specific scenario. Therefore, the standard uses the codec profile to specify the enabled status of these encoding tools. For example, for H.264, there are baseline, main, and high profiles. For details, see [OH_AVCProfile](../../reference/apis-avcodec-kit/_codec_base.md#oh_avcprofile-1). 314 315A codec level is a division of the processing capability and storage space required by a codec. For example, for H.264, there are 20 levels ranging from 1 to 6.2. For details, see [OH_AVCLevel](../../reference/apis-avcodec-kit/_codec_base.md#oh_avclevel-1). 316 317| API | Description | 318| -------- | ---------------------------- | 319| OH_AVCapability_GetSupportedProfiles | Obtains the profiles supported by a codec.| 320| OH_AVCapability_GetSupportedLevelsForProfile | Obtains the codec levels supported by a profile.| 321| OH_AVCapability_AreProfileAndLevelSupported | Checks whether a codec supports the combination of a profile and level.| 322 323The code snippet below checks whether a profile is supported and obtains the supported levels. 324 325```c++ 326OH_AVCProfile profile = AVC_PROFILE_MAIN; 327OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 328if (capability == nullptr) { 329 // Exception handling. 330} 331// 1. Check whether the profile to be configured is supported. 332const int32_t *profiles = nullptr; 333uint32_t profileNum = -1; 334int32_t ret = OH_AVCapability_GetSupportedProfiles(capability, &profiles, &profileNum); 335if (ret != AV_ERR_OK || profiles == nullptr || profileNum <= 0) { 336 // Exception handling. 337} 338bool isMatched = false; 339for (int i = 0; i < profileNum; i++) { 340 if (profiles[i] == profile) { 341 isMatched = true; 342 } 343} 344// 2. Obtain the codec levels supported by the profile. 345const int32_t *levels = nullptr; 346uint32_t levelNum = -1; 347ret = OH_AVCapability_GetSupportedLevelsForProfile(capability, profile, &levels, &levelNum); 348if (ret != AV_ERR_OK || levels == nullptr || levelNum <= 0) { 349 // Exception handling. 350} 351OH_AVCLevel maxLevel = static_cast<OH_AVCLevel>(levels[levelNum -1]); 352// 3. (Optional) Use different service logic based on the maximum level supported. 353switch (maxLevel) { 354 case AVC_LEVEL_31: 355 // Level 3.1-3.2, with the maximum width and height of 1280 x 720. 356 break; 357 case AVC_LEVEL_51: 358 // Level 4.0 or higher, with the maximum width and height of 1920 x 1080. 359 break; 360 default: 361 // An error is reported and no encoding is performed. 362} 363// 4. Set the profile parameters. 364OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 365OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 366if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile)) { 367 // Exception handling. 368} 369if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 370 // Exception handling. 371} 372OH_AVFormat_Destroy(format); 373``` 374 375If you already know the required profile and level combination, use the code snippet below to check whether the combination is supported. 376 377```c++ 378// 1. Obtain an H.264 encoder capability instance. 379OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 380if (capability == nullptr) { 381 // Exception handling. 382} 383// 2. Check whether the combination of the profile and level is supported. 384bool isSupported = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_MAIN, AVC_LEVEL_51); 385``` 386 387### Setting the Correct Video Width and Height 388 389The video codec has restrictions on width and height alignment. For example, for YUV420 series, the default codec pixel format of popular codecs, downsampling is performed on the UV component. In this case, the width and height of the video codec must be 2-pixel aligned at least. There are other factors that may lead to stricter alignment restrictions. 390 391The width and height of a video codec are restricted by the frame-level encoding and decoding capability of the codec and the frame-level capability defined in the protocol. For example, for H.264, AVC_LEVEL_51 limits the maximum number of macroblocks per frame to 36864. 392 393The formula for calculating the maximum frame rate based on the image width and height is as follows, where *MaxMBsPerFrameLevelLimits* indicates the maximum number of macroblocks per frame defined in the protocol that can be supported by the codec, and *MaxMBsPerFrameSubmit* indicates the maximum number of macroblocks per frame reported by the codec. In practice, the intersection of the two values is used. 394 395 396 397| API | Description | 398| -------- | ---------------------------- | 399| OH_AVCapability_GetVideoWidthAlignment | Obtains the video width alignment supported by a video codec.| 400| OH_AVCapability_GetVideoHeightAlignment | Obtains the video height alignment supported by a video codec.| 401| OH_AVCapability_GetVideoWidthRange | Obtains the video width range supported by a video codec.| 402| OH_AVCapability_GetVideoHeightRange | Obtains the video height range supported by a video codec.| 403| OH_AVCapability_GetVideoWidthRangeForHeight | Obtains the video width range of a video codec based on a given height.| 404| OH_AVCapability_GetVideoHeightRangeForWidth | Obtains the video height range of a video codec based on a given width.| 405| OH_AVCapability_IsVideoSizeSupported | Checks whether a video codec supports the combination of a given width and height.| 406 407If you already know the video height and width, use the code snippet below to check whether they are supported. 408 409```c++ 410int32_t width = 1920; 411int32_t height = 1080; 412OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 413// 1. Check whether the video width and height are supported. 414bool isSupported = OH_AVCapability_IsVideoSizeSupported(capability, width, height); 415if (!isSupported) { 416 // 2. (Optional) Query detailed restrictions based on the video height and width and adjust the video height and width to use. 417} 418``` 419 420If the video height or width is not supported or the configuration fails, use the following methods to find the supported video width and height range. 421 422Find the supported size configuration when the video width is known. The following is an example: 423 424```c++ 425int32_t width = 1920; 426OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 427// 1. Check whether the video width meets the width alignment requirements. 428int32_t widthAlignment = 0; 429int32_t ret = OH_AVCapability_GetVideoWidthAlignment(capability, &widthAlignment); 430if (ret != AV_ERR_OK || widthAlignment <= 0) { 431 // Exception handling. 432} else if (width % widthAlignment != 0) { 433 // 2. (Optional) Align the video width. 434 width = (width + widthAlignment - 1) / widthAlignment * widthAlignment; 435} 436// 3. Check whether the video width is within the supported range. 437OH_AVRange widthRange = {-1, -1}; 438ret = OH_AVCapability_GetVideoWidthRange(capability, &widthRange); 439if (ret != AV_ERR_OK || widthRange.maxVal <= 0) { 440 // Exception handling. 441} else if (width < widthRange.minVal || width > widthRange.maxVal) { 442 // 4. (Optional) Adjust the video width. 443 width = min(max(width, widthRange.minVal), widthRange.maxVal); 444} 445// 5. Obtain the range of available video heights based on the video width. 446OH_AVRange heightRange = {-1, -1}; 447ret = OH_AVCapability_GetVideoHeightRangeForWidth(capability, width, &heightRange); 448if (ret != AV_ERR_OK || heightRange.maxVal <= 0) { 449 // Exception handling. 450} 451// 6. Select a proper video height from the range. 452``` 453 454Find the supported size configuration when the video height is known. The following is an example: 455 456```c++ 457int32_t height = 1080; 458OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 459// 1. Check whether the video height meets the high alignment requirements. 460int32_t heightAlignment = 0; 461int32_t ret = OH_AVCapability_GetVideoHeightAlignment(capability, &heightAlignment); 462if (ret != AV_ERR_OK || heightAlignment <= 0) { 463 // Exception handling. 464} else if (height % heightAlignment != 0) { 465 // 2. (Optional) Align the video height. 466 height = (height + heightAlignment - 1) / heightAlignment * heightAlignment; 467} 468// 3. Check whether the video height is within the supported range. 469OH_AVRange heightRange = {-1, -1}; 470ret = OH_AVCapability_GetVideoHeightRange(capability, &heightRange); 471if (ret != AV_ERR_OK || heightRange.maxVal <= 0) { 472 // Exception handling. 473} else if (height < heightRange.minVal || height > heightRange.maxVal) { 474 // 4. (Optional) Adjust the video height. 475 height = min(max(height, heightRange.minVal), heightRange.maxVal); 476} 477// 5. Obtain the range of available video widths based on the video height. 478OH_AVRange widthRange = {-1, -1}; 479ret = OH_AVCapability_GetVideoWidthRangeForHeight(capability, height, &widthRange); 480if (ret != AV_ERR_OK || widthRange.maxVal <= 0) { 481 // Exception handling. 482} 483// 6. Select a proper video width from the range. 484``` 485 486### Setting the Correct Video Frame Rate 487 488The frame rate of a video codec is restricted by the second-level encoding and decoding capability of the codec and the second-level capability defined in the protocol. For example, for H.264, AVC_LEVEL_51 limits the maximum number of macroblocks per second to 983040. 489 490The formula for calculating the maximum frame rate based on the image width and height is as follows, where *MaxMBsPerSecondLevelLimits* indicates the maximum number of macroblocks per second defined in the protocol that can be supported by the codec, and *MaxMBsPerSecondSubmit* indicates the maximum number of macroblocks per second reported by the codec. In practice, the intersection of the two values is used. 491 492 493 494| API | Description | 495| -------- | ---------------------------- | 496| OH_AVCapability_GetVideoFrameRateRange | Obtains the video frame rate range supported by a video codec.| 497| OH_AVCapability_GetVideoFrameRateRangeForSize | Obtains the video frame rate range of a video codec based on a given video size.| 498| OH_AVCapability_AreVideoSizeAndFrameRateSupported | Checks whether a video codec supports the combination of a video size and frame rate.| 499 500If a specific frame rate is required, you can use the code snippet below to check whether the frame rate is supported. 501 502```c++ 503int32_t frameRate = 120; 504OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 505// 1. Obtain the supported frame rate range. 506OH_AVRange frameRateRange = {-1, -1}; 507int32_t ret = OH_AVCapability_GetVideoFrameRateRange(capability, &frameRateRange); 508if (ret != AV_ERR_OK || frameRateRange.maxVal <= 0) { 509 // Exception handling. 510} 511// 2. Check whether the frame rate is within the range. 512bool isSupported = frameRate >= frameRateRange.minVal && frameRate <= frameRateRange.maxVal; 513``` 514 515The code snippet below shows how to find a proper frame rate configuration based on a given video size. 516 517```c++ 518constexpr int32_t width = 1920; 519constexpr int32_t height = 1080; 520int32_t frameRate = 120; 521OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 522// 1. Check whether the video size to be configured can reach the ideal frame rate. 523bool isSupported = OH_AVCapability_AreVideoSizeAndFrameRateSupported(capability, width, height, frameRate); 524if (!isSupported) { 525 // 2. Query the supported frame rate range based on the video size, and adjust the frame rate to be configured based on the query result. 526 OH_AVRange frameRateRange = {-1, -1}; 527 int32_t ret = OH_AVCapability_GetVideoFrameRateRangeForSize(capability, width, height, &frameRateRange); 528 if (ret != AV_ERR_OK || frameRateRange.maxVal <= 0) { 529 // Exception handling. 530 } 531 frameRate = min(max(frameRate, frameRateRange.minVal), frameRateRange.maxVal); 532} 533 534// 3. Set the video size and frame rate. 535OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 536OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, width, height); 537if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_FRAME_RATE, frameRate)) { 538 // Exception handling. 539} 540if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 541 // Exception handling. 542} 543OH_AVFormat_Destroy(format); 544``` 545 546### Setting the Correct Video Pixel Format 547 548The video pixel format determines the pixel layout of an image that is encoded as input or decoded as output. For details, see [OH_AVPixelFormat](../../reference/apis-avcodec-kit/_core.md#oh_avpixelformat-1). 549 550| API | Description | 551| -------- | ---------------------------- | 552| OH_AVCapability_GetVideoSupportedPixelFormats | Obtains the video pixel formats supported by a video codec.| 553 554```c++ 555constexpr OH_AVPixelFormat DEFAULT_PIXELFORMAT = AV_PIXEL_FORMAT_NV12; 556OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 557if (capability == nullptr) { 558 // Exception handling. 559} 560// 1. Obtain the video pixel formats supported by the video codec. 561const int32_t *pixFormats = nullptr; 562uint32_t pixFormatNum = -1; 563int32_t ret = OH_AVCapability_GetVideoSupportedPixelFormats(capability, &pixFormats, &pixFormatNum); 564if (ret != AV_ERR_OK || pixFormats == nullptr || pixFormatNum <= 0) { 565 // Exception handling. 566} 567// 2. Check whether the pixel format to be configured is supported. 568bool isMatched = false; 569for (int i = 0; i < pixFormatNum; i++) { 570 if (pixFormats[i] == DEFAULT_PIXELFORMAT) { 571 isMatched = true; 572 } 573} 574if (!isMatched) { 575 // 3. Replace an unsupported pixel format or select another codec. 576} 577``` 578 579### Checking Whether a Codec Feature Is Supported and Obtaining Its Properties 580 581A codec feature refers to an optional feature used only in specific encoding and decoding scenarios. For details, see [OH_AVCapabilityFeature](../../reference/apis-avcodec-kit/_a_v_capability.md#oh_avcapabilityfeature-1). 582 583| API | Description | 584| -------- | ---------------------------- | 585| OH_AVCapability_IsFeatureSupported | Check whether a codec supports a given feature.| 586| OH_AVCapability_GetFeatureProperties | Obtains the properties of a feature. Only some features have property information.| 587 588The code snippet below is an example of querying whether the H.264 encoder supports the long-term reference frame feature: 589 590```c++ 591constexpr int32_t NEEDED_LTR_NUM = 2; 592OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 593OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 594if (capability == nullptr) { 595 // Exception handling. 596} 597// 1. Check whether the long-term reference frame feature is supported. 598bool isSupported = OH_AVCapability_IsFeatureSupported(capability,VIDEO_ENCODER_LONG_TERM_REFERENCE); 599if (isSupported) { 600 // 2. Obtain the number of supported long-term reference frames. 601 OH_AVFormat *properties = OH_AVCapability_GetFeatureProperties(capability, VIDEO_ENCODER_LONG_TERM_REFERENCE); 602 int32_t maxLTRCount = -1; 603 bool ret = OH_AVFormat_GetIntValue(properties, OH_FEATURE_PROPERTY_KEY_VIDEO_ENCODER_MAX_LTR_FRAME_COUNT, &maxLTRCount); 604 if (ret && maxLTRCount >= NEEDED_LTR_NUM) { 605 if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, NEEDED_LTR_NUM)) { 606 // Exception handling. 607 } 608 } 609} 610// 3. Create and configure an encoder. 611OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 612if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 613 // Exception handling. 614} 615``` 616