1# Obtaining Supported Codecs 2 3<!--Kit: AVCodec Kit--> 4<!--Subsystem: Multimedia--> 5<!--Owner: @yang-xiaoyu5--> 6<!--Designer: @dpy2650--> 7<!--Tester: @cyakee--> 8<!--Adviser: @zengyawen--> 9 10Due to differences in sources, codec protocols, and device capabilities, the available codecs and their capabilities vary across different devices. 11 12To ensure that codec behavior meets expectations, use the audio and video codec capability interface to query the codecs supported by the system and their capabilities, select codecs that align with your development requirements, and configure parameters correctly. 13 14## General Development 151. Link the dynamic libraries in the CMake script. 16 17 ``` cmake 18 target_link_libraries(sample PUBLIC libnative_media_codecbase.so) 19 target_link_libraries(sample PUBLIC libnative_media_core.so) 20 target_link_libraries(sample PUBLIC libnative_media_venc.so) 21 target_link_libraries(sample PUBLIC libnative_media_vdec.so) 22 target_link_libraries(sample PUBLIC libnative_media_acodec.so) 23 ``` 24 > **NOTE** 25 > 26 > The word **sample** in the preceding code snippet is only an example. Use the actual project directory name. 27 > 28 292. Add the header files. 30 31 ```c++ 32 #include <algorithm> 33 #include <multimedia/player_framework/native_avcapability.h> 34 #include <multimedia/player_framework/native_avcodec_audiocodec.h> 35 #include <multimedia/player_framework/native_avcodec_videoencoder.h> 36 #include <multimedia/player_framework/native_avcodec_videodecoder.h> 37 ``` 38 393. Obtain an audio/video codec capability instance. 40 41 You can use either of the following methods to obtain the instance: 42 43 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. 44 ```c++ 45 // Obtain the AAC decoder capability instance recommended by the system. 46 OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, false); 47 ``` 48 49 Method 2: Call **OH_AVCodec_GetCapabilityByCategory** to obtain the codec capability instance for the specified software or hardware. 50 ```c++ 51 // Obtain the AVC encoder capability instance for the specified hardware. 52 OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true, HARDWARE); 53 ``` 54 After obtaining the codec capability instance, you can move on to the next steps. There is no need to manually release the instance. The system automatically reclaims the instance when it is no longer needed. 55 564. Call the query APIs as required. For details, see [AudioCodec](../../reference/apis-avcodec-kit/_a_v_capability.md). 57 58## Scenario-based Development 59This section provides examples to illustrate the use of capability query interfaces in specific scenarios that may be encountered during development. 60 61### Creating a Codec with the Specified Name 62 63If there are multiple codecs of the same MIME type, use the **OH_XXX_CreateByMime** series APIs to create the system-recommended codec. To create other codecs, you must first obtain their name and then call **OH_XXX_CreateByName** series APIs to create the codec with the specified name. 64 65| API | Description | 66| -------- | -------------------------------- | 67| OH_AVCapability_GetName | Obtains the name of a codec corresponding to a capability instance.| 68 69The following is an example of creating an H.264 software decoder when both the H.264 software decoder and H.264 hardware decoder exist: 70 71```c++ 72// 1. Obtain an H.264 software decoder capability instance. 73OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE); 74if (capability != nullptr) { 75 // 2. Obtain the name of the H.264 software decoder. 76 const char *codecName = OH_AVCapability_GetName(capability); 77 // 3. Create an H.264 software decoder instance. 78 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(codecName); 79} 80``` 81 82### Setting Codec Parameters by Software or Hardware 83 84The definitions of software codecs and hardware codecs are as follows: 85 86* **Software codec**: a codec that runs on the CPU, featuring flexible iteration, good compatibility, and strong expandability. 87 88* **Hardware codec**: a codec that runs on dedicated hardware, featuring low-power consumption, high performance, and reduced CPU load. 89 90When hardware codecs are sufficient and meet capability requirements, prioritize their use; otherwise, use software codecs. You can configure different codec parameters based on the codec category. 91 92| API | Description | 93| -------- | -------------------------------- | 94| OH_AVCapability_IsHardware | Checks whether a codec capability instance describes a hardware codec.| 95 96The following is an example of differentiated frame rate configuration for video encoding based on hardware/software categories. 97 98```c++ 99// 1. Check whether the recommended H.264 encoder is a hardware codec. 100OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 101if (capability == nullptr) { 102 // Handle exceptions. 103} 104bool isHardware = OH_AVCapability_IsHardware(capability); 105// 2. Carry out differentiated configuration based on the software or hardware type. 106OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 107if (videoEnc == nullptr) { 108 // Handle exceptions. 109} 110OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 111if (format == nullptr) { 112 // Handle exceptions. 113} 114double frameRate = isHardware ? 60.0 : 30.0; 115if (!OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate)) { 116 // Handle exceptions. 117} 118if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 119 // Handle exceptions. 120} 121OH_AVFormat_Destroy(format); 122``` 123 124### Creating a Multi-Channel Codec 125 126Multiple codecs are required in certain scenarios. However, the number of codec instances that can be created is limited due to constraints on system resources such as memory, processor, and bandwidth. 127 128| API | Description | 129| -------- | -------------------------------- | 130| OH_AVCapability_GetMaxSupportedInstances | Obtains the maximum number of codec instances corresponding to the capability instance. The actual number of codec instances created is also constrained by system resources like memory, processor, and bandwidth.| 131 132Prioritize creating hardware decoder instances; if resources are insufficient, create software decoder instances. An example is as follows: 133 134```c++ 135constexpr int32_t NEEDED_VDEC_NUM = 8; 136// 1. Create hardware decoder instances. 137OH_AVCapability *capHW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, HARDWARE); 138if (capHW == nullptr) { 139 // Handle exceptions. 140} 141int32_t vDecNumHW = std::min(OH_AVCapability_GetMaxSupportedInstances(capHW), NEEDED_VDEC_NUM); 142int32_t createdVDecNum = 0; 143for (int i = 0; i < vDecNumHW; i++) { 144 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capHW)); 145 if (videoDec != nullptr) { 146 // Maintained in videoDecVector. 147 createdVDecNum++; 148 } 149} 150if (createdVDecNum < NEEDED_VDEC_NUM) { 151 // 2. If the hardware decoder instances cannot fully meet the project requirements, create software decoder instances. 152 OH_AVCapability *capSW = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false, SOFTWARE); 153 if (capSW == nullptr) { 154 // Handle exceptions. 155 } 156 int32_t vDecNumSW = std::min(OH_AVCapability_GetMaxSupportedInstances(capSW), NEEDED_VDEC_NUM - createdVDecNum); 157 for (int i = 0; i < vDecNumSW; i++) { 158 OH_AVCodec *videoDec = OH_VideoDecoder_CreateByName(OH_AVCapability_GetName(capSW)); 159 if (videoDec != nullptr) { 160 // Maintained in videoDecVector. 161 createdVDecNum++; 162 } 163 } 164} 165``` 166 167### Controlling the Encoding Quality 168 169 Four bit rate modes are available: Constant Bit Rate (CBR), Dynamic Bit Rate (VBR), Constant Quality (CQ), and Stable Quality (SQR). 170- For CBR and VBR, the encoding quality is determined by the bit rate parameters. 171- For CQ, the encoding quality is determined by the quality parameters. 172- For SQR, the encoding quality is determined by the SQR factor and the maximum bit rate. Currently, only H.265 (HEVC) encoding is supported. 173 174| API | Description | 175| -------- | ---------------------------- | 176| OH_AVCapability_IsEncoderBitrateModeSupported | Checks whether an encoder supports the specified bit rate mode.| 177| OH_AVCapability_GetEncoderBitrateRange | Obtains the bit rate range supported by an encoder. It applies to CBR, VBR, and SQR modes.| 178| OH_AVCapability_GetEncoderQualityRange | Obtains the quality range supported by an encoder. It applies to CQ mode. | 179 180The code snippet below shows the configuration in CBR or VBR mode. 181 182```c++ 183OH_BitrateMode bitrateMode = BITRATE_MODE_CBR; 184int32_t bitrate = 3000000; 185OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 186if (capability == nullptr) { 187 // Handle exceptions. 188} 189// 1. Check whether a bit rate mode is supported. 190bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode); 191if (!isSupported) { 192 // Handle exceptions. 193} 194// 2. Obtain the bit rate range and check whether the bit rate to be configured is within the range. 195OH_AVRange bitrateRange = {-1, -1}; 196int32_t ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange); 197if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) { 198 // Handle exceptions. 199} 200if (bitrate > bitrateRange.maxVal || bitrate < bitrateRange.minVal) { 201 // 3. (Optional) Adjust the bit rate parameters to be configured. 202} 203// 4. Set the encoding parameters. 204OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 205if (videoEnc == nullptr) { 206 // Handle exceptions. 207} 208OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 209if (format == nullptr) { 210 // Handle exceptions. 211} 212if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, bitrateMode) || 213 !OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, static_cast<int64_t>(bitrate))) { 214 // Handle exceptions. 215} 216if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 217 // Handle exceptions. 218} 219OH_AVFormat_Destroy(format); 220``` 221 222The code snippet below shows the configuration in CQ mode. 223 224```c++ 225OH_BitrateMode bitrateMode = BITRATE_MODE_CQ; 226int32_t quality = 0; 227OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 228if (capability == nullptr) { 229 // Handle exceptions. 230} 231// 1. Check whether a bit rate mode is supported. 232bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode); 233if (!isSupported) { 234 // Handle exceptions. 235} 236// 2. Obtain the quality range and determine whether the quality parameters to be configured are within the range. 237OH_AVRange qualityRange = {-1, -1}; 238int32_t ret = OH_AVCapability_GetEncoderQualityRange(capability, &qualityRange); 239if (ret != AV_ERR_OK || qualityRange.maxVal < 0) { 240 // Handle exceptions. 241} 242if (quality > qualityRange.maxVal || quality < qualityRange.minVal) { 243 // 3. (Optional) Adjust the quality parameters to be configured. 244} 245// 5. Set the encoding parameters. 246OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 247if (videoEnc == nullptr) { 248 // Handle exceptions. 249} 250OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 251if (format == nullptr) { 252 // Handle exceptions. 253} 254if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, bitrateMode) || 255 !OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, quality)) { 256 // Handle exceptions. 257} 258if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 259 // Handle exceptions. 260} 261OH_AVFormat_Destroy(format); 262``` 263 264The code snippet below shows the configuration in SQR mode. 265 266```c++ 267OH_BitrateMode bitrateMode = BITRATE_MODE_SQR; 268int32_t sqrFactor = 30; // SQR factor. 269int32_t maxBitrate = 20000000; // Maximum bit rate. 270OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, true); 271if (capability == nullptr) { 272 // Handle exceptions. 273} 274// 1. Check whether a bit rate mode is supported. 275bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode); 276if (!isSupported) { 277 // Handle exceptions. 278} 279// 2. Obtain the bit rate range and check whether the maximum bit rate to be configured is within the range. 280OH_AVRange bitrateRange = {-1, -1}; 281// The value range of the maximum bit rate is the same as that of the bit rate. Therefore, OH_AVCapability_GetEncoderBitrateRange is reused to obtain the value range. 282int32_t ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange); 283if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) { 284 // Handle exceptions. 285} 286 287// The value range of the SQR factor is [0, 51] (same as the QP). 288if (sqrFactor > 51 || sqrFactor < 0) { 289 // 3. (Optional) Adjust the SQR factor to be configured. 290} 291 292if (maxBitrate > bitrateRange.maxVal || maxBitrate < bitrateRange.minVal) { 293 // 4. (Optional) Adjust the maximum bit rate parameters to be configured. 294} 295 296// 5. Set the encoding parameters. 297OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_HEVC); 298if (videoEnc == nullptr) { 299 // Handle exceptions. 300} 301OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, 1920, 1080); 302if (format == nullptr) { 303 // Handle exceptions. 304} 305if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, bitrateMode) || 306 !OH_AVFormat_SetIntValue(format, OH_MD_KEY_SQR_FACTOR, sqrFactor) || 307 !OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_BITRATE, maxBitrate)) { 308 // Handle exceptions. 309} 310if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 311 // Handle exceptions. 312} 313OH_AVFormat_Destroy(format); 314 315// 6. Start the encoder. 316ret = OH_VideoEncoder_Prepare(videoEnc); 317if (ret != AV_ERR_OK) { 318 // Handle exceptions. 319} 320ret = OH_VideoEncoder_Start(videoEnc); 321if (ret != AV_ERR_OK) { 322 // Handle exceptions. 323} 324 325// 7. (Optional) Use OH_VideoEncoder_SetParameter() to dynamically configure the SQR factor and maximum bit rate during the running. 326OH_AVFormat *dynamicFormat = OH_AVFormat_Create(); 327// SQR supports dynamic configuration of the maximum bit rate and SQR factor. 328sqrFactor = 25; // Update the SQR factor. 329maxBitrate = 10000000; // Update the maximum bit rate. 330OH_AVFormat_SetLongValue(dynamicFormat, OH_MD_KEY_MAX_BITRATE, maxBitrate); 331OH_AVFormat_SetIntValue(dynamicFormat, OH_MD_KEY_SQR_FACTOR, sqrFactor); 332ret = OH_VideoEncoder_SetParameter(videoEnc, dynamicFormat); 333if (ret != AV_ERR_OK) { 334 // Handle exceptions. 335} 336OH_AVFormat_Destroy(dynamicFormat); 337``` 338 339### Checking the Complexity Range Supported 340 341The complexity range determines the number of tools used by the encoder. However, not all encoders support this feature. 342 343| API | Description | 344| -------- | ---------------------------- | 345| OH_AVCapability_GetEncoderComplexityRange | Obtains the complexity range supported by an encoder.| 346 347```c++ 348OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 349if (capability == nullptr) { 350 // Handle exceptions. 351} 352// Check the supported encoding complexity range. 353OH_AVRange complexityRange = {-1, -1}; 354int32_t ret = OH_AVCapability_GetEncoderComplexityRange(capability, &complexityRange); 355``` 356 357### Setting Correct Audio Codec Parameters 358 359In audio encoding and decoding scenarios, you need to set the sample rate and number of channels. For audio encoding, you also need to set the bit rate. 360 361| API | Description | 362| -------- | ---------------------------- | 363| OH_AVCapability_GetAudioSupportedSampleRateRanges | Obtains the sample rates supported by an audio codec.| 364| OH_AVCapability_GetAudioChannelCountRange | Obtains the count range of channels supported by an audio codec.| 365| OH_AVCapability_GetEncoderBitrateRange | Obtains the bit rate range supported by an encoder.| 366 367The following is an example of querying audio codec parameters: 368 369```c++ 370int32_t sampleRate = 44100; 371int32_t channelCount = 2; 372int32_t bitrate = 261000; 373OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 374if (capability == nullptr) { 375 // Handle exceptions. 376} 377// 1. Check whether the sample rate to be configured is supported. 378OH_AVRange *sampleRateRanges = nullptr; 379uint32_t rangesNum = 0; 380int32_t ret = OH_AVCapability_GetAudioSupportedSampleRateRanges(capability, &sampleRateRanges, &rangesNum); 381if (ret != AV_ERR_OK || sampleRateRanges == nullptr || rangesNum == 0) { 382 // Handle exceptions. 383} 384bool isMatched = false; 385for (uint32_t i = 0; i < rangesNum; i++) { 386 if (sampleRate >= sampleRateRanges[i].minVal && sampleRate <= sampleRateRanges[i].maxVal) { 387 isMatched = true; 388 break; 389 } 390} 391if (!isMatched) { 392 // 2. (Optional) Adjust the sample rate to be configured. 393} 394// 3. Obtain the count range of channels and check whether the number of channels to be configured is within the range. 395OH_AVRange channelRange = {-1, -1}; 396ret = OH_AVCapability_GetAudioChannelCountRange(capability, &channelRange); 397if (ret != AV_ERR_OK || channelRange.maxVal <= 0) { 398 // Handle exceptions. 399} 400if (channelCount > channelRange.maxVal || channelCount < channelRange.minVal ) { 401 //4. (Optional) Adjust the number of channels to be configured. 402} 403// 5. Obtain the bit rate range and check whether the bit rate to be configured is within the range. 404OH_AVRange bitrateRange = {-1, -1}; 405ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange); 406if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) { 407 // Handle exceptions. 408} 409if (bitrate > bitrateRange.maxVal || bitrate < bitrateRange.minVal ) { 410 //7. (Optional) Adjust the bit rate to be configured. 411} 412// 8. Set the encoding parameters. 413OH_AVCodec *audioEnc = OH_AudioCodec_CreateByMime(OH_AVCODEC_MIMETYPE_AUDIO_AAC, true); 414if (audioEnc == nullptr) { 415 // Handle exceptions. 416} 417OH_AVFormat *format = OH_AVFormat_Create(); 418if (format == nullptr) { 419 // Handle exceptions. 420} 421if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_SAMPLE_RATE, sampleRate) || 422 !OH_AVFormat_SetIntValue(format, OH_MD_KEY_AUD_CHANNEL_COUNT, channelCount) || 423 !OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, static_cast<int64_t>(bitrate))) { 424 // Handle exceptions. 425} 426if (OH_AudioCodec_Configure(audioEnc, format) != AV_ERR_OK) { 427 // Handle exceptions. 428} 429OH_AVFormat_Destroy(format); 430``` 431 432### Checking the Codec Profile and Level Supported 433 434The codec standard contains multiple encoding tools, which are applicable to different encoding scenarios. Codec standards include multiple encoding tools, which are applicable to different encoding scenarios. For specific scenarios, the codec 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). 435 436Codec levels define the processing capability and storage space required by the 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). 437 438| API | Description | 439| -------- | ---------------------------- | 440| OH_AVCapability_GetSupportedProfiles | Obtains the profiles supported by a codec.| 441| OH_AVCapability_GetSupportedLevelsForProfile | Obtains the codec levels supported by a profile.| 442| OH_AVCapability_AreProfileAndLevelSupported | Checks whether a codec supports the combination of a profile and level.| 443 444The code snippet below checks whether a profile is supported and obtains the supported levels. 445 446```c++ 447OH_AVCProfile profile = AVC_PROFILE_MAIN; 448OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 449if (capability == nullptr) { 450 // Handle exceptions. 451} 452// 1. Check whether the profile to be configured is supported. 453const int32_t *profiles = nullptr; 454uint32_t profileNum = 0; 455int32_t ret = OH_AVCapability_GetSupportedProfiles(capability, &profiles, &profileNum); 456if (ret != AV_ERR_OK || profiles == nullptr || profileNum == 0) { 457 // Handle exceptions. 458} 459bool isMatched = false; 460for (int i = 0; i < profileNum; i++) { 461 if (profiles[i] == profile) { 462 isMatched = true; 463 break; 464 } 465} 466// 2. Obtain the codec levels supported by the profile. 467const int32_t *levels = nullptr; 468uint32_t levelNum = 0; 469ret = OH_AVCapability_GetSupportedLevelsForProfile(capability, profile, &levels, &levelNum); 470if (ret != AV_ERR_OK || levels == nullptr || levelNum == 0) { 471 // Handle exceptions. 472} 473OH_AVCLevel maxLevel = static_cast<OH_AVCLevel>(levels[0]); 474for (int32_t i = 1; i < levelNum; i++) { 475 OH_AVCLevel tmp = static_cast<OH_AVCLevel>(levels[i]); 476 if (tmp > maxLevel) { 477 maxLevel = tmp; 478 } 479} 480// 3. (Optional) Use different service logic based on the maximum level supported. 481if (maxLevel >= AVC_LEVEL_51) { 482 // For levels above 5.1, the width and height can be configured to 3840*2160. 483} else if (maxLevel >= AVC_LEVEL_4) { 484 // For levels above 4.0, the width and height can be configured to 1920*1080. 485} else if (maxLevel >= AVC_LEVEL_31) { 486 // For levels above 3.1, the width and height can be configured to 1280*720. 487} else { 488 // An error is reported and no encoding is performed. 489} 490// 4. Set the profile parameters. 491OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 492if (videoEnc == nullptr) { 493 // Handle exceptions. 494} 495OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 496if (format == nullptr) { 497 // Handle exceptions. 498} 499if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, profile)) { 500 // Handle exceptions. 501} 502if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 503 // Handle exceptions. 504} 505OH_AVFormat_Destroy(format); 506``` 507 508If you already know the required profile and level combination, use the code snippet below to check whether the combination is supported. 509 510```c++ 511// 1. Obtain an H.264 encoder capability instance. 512OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 513if (capability == nullptr) { 514 // Handle exceptions. 515} 516// 2. Check whether the combination of the profile and level is supported. 517bool isSupported = OH_AVCapability_AreProfileAndLevelSupported(capability, AVC_PROFILE_MAIN, AVC_LEVEL_51); 518``` 519 520### Setting the Correct Video Width and Height 521 522Video codecs have alignment constraints on width and height. For example, mainstream codecs use YUV420 series as the default codec pixel format, where UV components are downsampled to half the original size in both width and height directions. Therefore, the width and height of video codecs must be aligned to at least 2. Other factors may also lead to more strict alignment constraints. 523 524The width and height of video codecs are not only limited by frame-level codec capabilities but also by protocol-level constraints on frame-level capabilities. Taking H.264 as an example, AVC_LEVEL_51 limits the maximum number of macroblocks per frame to 36864. 525 526The formula for calculating the maximum video width based on the video height is as follows: 527 528 529 530**MaxMBsPerFrameLevelLimits** refers to the maximum number of macroblocks per frame of the codec limited by the protocol, and **MaxMBsPerFrameSubmit** refers to the maximum number of macroblocks per frame reported by the codec. The actual capability is the minimum of the two. 531 532| API | Description | 533| -------- | ---------------------------- | 534| OH_AVCapability_GetVideoWidthAlignment | Obtains the video width alignment supported by a video codec.| 535| OH_AVCapability_GetVideoHeightAlignment | Obtains the video height alignment supported by a video codec.| 536| OH_AVCapability_GetVideoWidthRange | Obtains the video width range supported by a video codec.| 537| OH_AVCapability_GetVideoHeightRange | Obtains the video height range supported by a video codec.| 538| OH_AVCapability_GetVideoWidthRangeForHeight | Obtains the video width range of a video codec based on a given height.| 539| OH_AVCapability_GetVideoHeightRangeForWidth | Obtains the video height range of a video codec based on a given width.| 540| OH_AVCapability_IsVideoSizeSupported | Checks whether a video codec supports the combination of a given width and height.| 541 542The following example shows how to check whether the video height and width are supported: 543 544```c++ 545int32_t width = 1920; 546int32_t height = 1080; 547OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 548if (capability == nullptr) { 549 // Handle exceptions. 550} 551// 1. Check whether the video width and height are supported. 552bool isSupported = OH_AVCapability_IsVideoSizeSupported(capability, width, height); 553if (!isSupported) { 554 // 2. (Optional) Query detailed restrictions based on the video height and width and adjust the video height and width to use. 555} 556``` 557 558If the verification of video height and width fails or the configuration fails, you can try the following methods to determine the correct video width and height range. 559 560If the video width is known, you can find the correct size configuration as shown in the following example: 561 562```c++ 563int32_t width = 1920; 564OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 565if (capability == nullptr) { 566 // Handle exceptions. 567} 568// 1. Check whether the video width meets the width alignment requirements. 569int32_t widthAlignment = 0; 570int32_t ret = OH_AVCapability_GetVideoWidthAlignment(capability, &widthAlignment); 571if (ret != AV_ERR_OK || widthAlignment <= 0) { 572 // Handle exceptions. 573} else if (width % widthAlignment != 0) { 574 // 2. (Optional) Align the video width. 575 width = (width + widthAlignment - 1) / widthAlignment * widthAlignment; 576} 577// 3. Check whether the video width is within the supported range. 578OH_AVRange widthRange = {-1, -1}; 579ret = OH_AVCapability_GetVideoWidthRange(capability, &widthRange); 580if (ret != AV_ERR_OK || widthRange.maxVal <= 0) { 581 // Handle exceptions. 582} else if (width < widthRange.minVal || width > widthRange.maxVal) { 583 // 4. (Optional) Adjust the video width. 584 width = std::min(std::max(width, widthRange.minVal), widthRange.maxVal); 585} 586// 5. Obtain the range of available video heights based on the video width. 587OH_AVRange heightRange = {-1, -1}; 588ret = OH_AVCapability_GetVideoHeightRangeForWidth(capability, width, &heightRange); 589if (ret != AV_ERR_OK || heightRange.maxVal <= 0) { 590 // Handle exceptions. 591} 592// 6. Select a proper video height from the range. 593``` 594 595If the video height is known, you can find the correct size configuration as shown in the following example: 596 597```c++ 598int32_t height = 1080; 599OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 600if (capability == nullptr) { 601 // Handle exceptions. 602} 603// 1. Check whether the video height meets the high alignment requirements. 604int32_t heightAlignment = 0; 605int32_t ret = OH_AVCapability_GetVideoHeightAlignment(capability, &heightAlignment); 606if (ret != AV_ERR_OK || heightAlignment <= 0) { 607 // Handle exceptions. 608} else if (height % heightAlignment != 0) { 609 // 2. (Optional) Align the video height. 610 height = (height + heightAlignment - 1) / heightAlignment * heightAlignment; 611} 612// 3. Check whether the video height is within the supported range. 613OH_AVRange heightRange = {-1, -1}; 614ret = OH_AVCapability_GetVideoHeightRange(capability, &heightRange); 615if (ret != AV_ERR_OK || heightRange.maxVal <= 0) { 616 // Handle exceptions. 617} else if (height < heightRange.minVal || height > heightRange.maxVal) { 618 // 4. (Optional) Adjust the video height. 619 height = std::min(std::max(height, heightRange.minVal), heightRange.maxVal); 620} 621// 5. Obtain the range of available video widths based on the video height. 622OH_AVRange widthRange = {-1, -1}; 623ret = OH_AVCapability_GetVideoWidthRangeForHeight(capability, height, &widthRange); 624if (ret != AV_ERR_OK || widthRange.maxVal <= 0) { 625 // Handle exceptions. 626} 627// 6. Select a proper video width from the range. 628``` 629 630### Setting the Correct Video Frame Rate 631 632The frame rate of a video codec is limited by the codec's per-second codec capability and the protocol-level per-second processing capability. For example, AVC_LEVEL_51 of H.264 limits the maximum number of macroblocks per second to 983040. 633 634The formula for calculating the maximum frame rate based on the video width and height is as follows: 635 636 637 638**MaxMBsPerSecondLevelLimits** refers to the maximum number of macroblocks per second of the codec limited by the protocol, and **MaxMBsPerSecondSubmit** refers to the maximum number of macroblocks per second reported by the codec. The actual capability is the minimum of the two. 639 640| API | Description | 641| -------- | ---------------------------- | 642| OH_AVCapability_GetVideoFrameRateRange | Obtains the video frame rate range supported by a video codec.| 643| OH_AVCapability_GetVideoFrameRateRangeForSize | Obtains the video frame rate range of a video codec based on a given video size.| 644| OH_AVCapability_AreVideoSizeAndFrameRateSupported | Checks whether a video codec supports the combination of a video size and frame rate.| 645 646When there is a requirement about the target frame rate, check whether the frame rate is within the optional range. An example is as follows: 647 648```c++ 649int32_t frameRate = 120; 650OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 651if (capability == nullptr) { 652 // Handle exceptions. 653} 654// 1. Obtain the supported frame rate range. 655OH_AVRange frameRateRange = {-1, -1}; 656int32_t ret = OH_AVCapability_GetVideoFrameRateRange(capability, &frameRateRange); 657if (ret != AV_ERR_OK || frameRateRange.maxVal <= 0) { 658 // Handle exceptions. 659} 660// 2. Check whether the frame rate is within the range. 661bool isSupported = frameRate >= frameRateRange.minVal && frameRate <= frameRateRange.maxVal; 662``` 663 664The code snippet below shows how to select a proper frame rate configuration based on a given video size. 665 666```c++ 667constexpr int32_t width = 1920; 668constexpr int32_t height = 1080; 669int32_t frameRate = 120; 670OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 671if (capability == nullptr) { 672 // Handle exceptions. 673} 674// 1. Check whether the video size to be configured can reach the ideal frame rate. 675bool isSupported = OH_AVCapability_AreVideoSizeAndFrameRateSupported(capability, width, height, frameRate); 676if (!isSupported) { 677 // 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. 678 OH_AVRange frameRateRange = {-1, -1}; 679 int32_t ret = OH_AVCapability_GetVideoFrameRateRangeForSize(capability, width, height, &frameRateRange); 680 if (ret != AV_ERR_OK || frameRateRange.maxVal <= 0) { 681 // Handle exceptions. 682 } 683 frameRate = std::min(std::max(frameRate, frameRateRange.minVal), frameRateRange.maxVal); 684} 685 686// 3. Set the video size and frame rate. 687OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 688if (videoEnc == nullptr) { 689 // Handle exceptions. 690} 691OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, width, height); 692if (format == nullptr) { 693 // Handle exceptions. 694} 695if (!OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, static_cast<double>(frameRate))) { 696 // Handle exceptions. 697} 698if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 699 // Handle exceptions. 700} 701OH_AVFormat_Destroy(format); 702``` 703 704### Setting the Correct Video Pixel Format 705 706The 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). 707 708| API | Description | 709| -------- | ---------------------------- | 710| OH_AVCapability_GetVideoSupportedPixelFormats | Obtains the video pixel formats supported by a video codec.| 711 712```c++ 713constexpr OH_AVPixelFormat DEFAULT_PIXELFORMAT = AV_PIXEL_FORMAT_NV12; 714OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 715if (capability == nullptr) { 716 // Handle exceptions. 717} 718// 1. Obtain the video pixel formats supported by the video codec. 719const int32_t *pixFormats = nullptr; 720uint32_t pixFormatNum = 0; 721int32_t ret = OH_AVCapability_GetVideoSupportedPixelFormats(capability, &pixFormats, &pixFormatNum); 722if (ret != AV_ERR_OK || pixFormats == nullptr || pixFormatNum == 0) { 723 // Handle exceptions. 724} 725// 2. Check whether the pixel format to be configured is supported. 726bool isMatched = false; 727for (int i = 0; i < pixFormatNum; i++) { 728 if (pixFormats[i] == DEFAULT_PIXELFORMAT) { 729 isMatched = true; 730 break; 731 } 732} 733if (!isMatched) { 734 // 3. Replace an unsupported pixel format or select another codec. 735} 736``` 737 738### Checking Whether a Codec Feature Is Supported and Obtaining Its Properties 739 740Codec features refer to optional features used in specific codec scenarios, such as temporal scalable encoding and low-latency codec in video encoding scenarios. For details, see [OH_AVCapabilityFeature](../../reference/apis-avcodec-kit/_a_v_capability.md#oh_avcapabilityfeature-1). 741| API | Description | 742| -------- | ---------------------------- | 743| OH_AVCapability_IsFeatureSupported | Checks whether a codec supports a given feature.| 744| OH_AVCapability_GetFeatureProperties | Obtains the properties of a specified feature supported by a codec.| 745 746The code snippet below is an example of querying whether the H.264 encoder supports the long-term reference frame feature: 747 748```c++ 749constexpr int32_t NEEDED_LTR_NUM = 2; 750OH_AVFormat *format = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1920, 1080); 751OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true); 752if (capability == nullptr) { 753 // Handle exceptions. 754} 755// 1. Check whether the long-term reference frame feature is supported. 756bool isSupported = OH_AVCapability_IsFeatureSupported(capability,VIDEO_ENCODER_LONG_TERM_REFERENCE); 757if (isSupported) { 758 // 2. Obtain the number of supported long-term reference frames. 759 OH_AVFormat *properties = OH_AVCapability_GetFeatureProperties(capability, VIDEO_ENCODER_LONG_TERM_REFERENCE); 760 if (properties == nullptr) { 761 // Handle exceptions. 762 } 763 int32_t maxLTRCount = -1; 764 bool ret = OH_AVFormat_GetIntValue(properties, OH_FEATURE_PROPERTY_KEY_VIDEO_ENCODER_MAX_LTR_FRAME_COUNT, &maxLTRCount); 765 if (ret && maxLTRCount >= NEEDED_LTR_NUM) { 766 if (!OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, NEEDED_LTR_NUM)) { 767 // Handle exceptions. 768 } 769 } 770} 771// 3. Create and configure an encoder. 772OH_AVCodec *videoEnc = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 773if (OH_VideoEncoder_Configure(videoEnc, format) != AV_ERR_OK) { 774 // Handle exceptions. 775} 776``` 777