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