• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![](figures/formula-maxmbsperframe.png)
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![](figures/formula-maxmbspersecond.png)
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