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![](figures/formula-maxmbsperframe.png)
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![](figures/formula-maxmbspersecond.png)
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