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