1  /*
2   * Copyright (C) 2023 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   *     http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #include <algorithm>
17  #include "native_avmagic.h"
18  #include "avcodec_list.h"
19  #include "avcodec_info.h"
20  #include "avcodec_log.h"
21  #include "avcodec_errors.h"
22  #include "securec.h"
23  #include "native_avcapability.h"
24  #include "common/native_mfmagic.h"
25  
26  namespace {
27  constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "NativeAVCapability"};
28  }
29  using namespace OHOS::MediaAVCodec;
30  
~OH_AVCapability()31  OH_AVCapability::~OH_AVCapability() {}
32  
OH_AVCodec_GetCapability(const char * mime,bool isEncoder)33  OH_AVCapability *OH_AVCodec_GetCapability(const char *mime, bool isEncoder)
34  {
35      CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Get capability failed: mime is nullptr");
36      CHECK_AND_RETURN_RET_LOG(strlen(mime) != 0, nullptr, "Get capability failed: mime is empty");
37      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
38      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, nullptr, "Get capability failed: CreateAVCodecList failed");
39      uint32_t sizeOfCap = sizeof(OH_AVCapability);
40      CapabilityData *capabilityData = codeclist->GetCapability(mime, isEncoder, AVCodecCategory::AVCODEC_NONE);
41      CHECK_AND_RETURN_RET_LOG(capabilityData != nullptr, nullptr,
42                               "Get capability failed: cannot find matched capability");
43      const std::string &name = capabilityData->codecName;
44      CHECK_AND_RETURN_RET_LOG(!name.empty(), nullptr, "Get capability failed: cannot find matched capability");
45      void *addr = codeclist->GetBuffer(name, sizeOfCap);
46      CHECK_AND_RETURN_RET_LOG(addr != nullptr, nullptr, "Get capability failed: malloc capability buffer failed");
47      OH_AVCapability *obj = static_cast<OH_AVCapability *>(addr);
48      obj->capabilityData_ = capabilityData;
49      obj->profiles_ = nullptr;
50      obj->levels_ = nullptr;
51      obj->pixFormats_ = nullptr;
52      obj->sampleRates_ = nullptr;
53      AVCODEC_LOGD("OH_AVCodec_GetCapability successful");
54      return obj;
55  }
56  
OH_AVCodec_GetCapabilityByCategory(const char * mime,bool isEncoder,OH_AVCodecCategory category)57  OH_AVCapability *OH_AVCodec_GetCapabilityByCategory(const char *mime, bool isEncoder, OH_AVCodecCategory category)
58  {
59      CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Get capabilityByCategory failed: mime is nullptr");
60      CHECK_AND_RETURN_RET_LOG(strlen(mime) != 0, nullptr, "Get capabilityByCategory failed: mime is empty");
61      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
62      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, nullptr,
63          "Get capabilityByCategory failed: CreateAVCodecList failed");
64      AVCodecCategory innerCategory;
65      if (category == HARDWARE) {
66          innerCategory = AVCodecCategory::AVCODEC_HARDWARE;
67      } else {
68          innerCategory = AVCodecCategory::AVCODEC_SOFTWARE;
69      }
70      uint32_t sizeOfCap = sizeof(OH_AVCapability);
71      CapabilityData *capabilityData = codeclist->GetCapability(mime, isEncoder, innerCategory);
72      CHECK_AND_RETURN_RET_LOG(capabilityData != nullptr, nullptr,
73                               "Get capabilityByCategory failed: cannot find matched capability");
74      const std::string &name = capabilityData->codecName;
75      CHECK_AND_RETURN_RET_LOG(!name.empty(), nullptr, "Get capabilityByCategory failed: cannot find matched capability");
76      void *addr = codeclist->GetBuffer(name, sizeOfCap);
77      CHECK_AND_RETURN_RET_LOG(addr != nullptr, nullptr,
78                               "Get capabilityByCategory failed: malloc capability buffer failed");
79      OH_AVCapability *obj = static_cast<OH_AVCapability *>(addr);
80      obj->capabilityData_ = capabilityData;
81      obj->profiles_ = nullptr;
82      obj->levels_ = nullptr;
83      obj->pixFormats_ = nullptr;
84      obj->sampleRates_ = nullptr;
85      AVCODEC_LOGD("OH_AVCodec_GetCapabilityByCategory successful");
86      return obj;
87  }
88  
OH_AVCapability_GetName(OH_AVCapability * capability)89  const char *OH_AVCapability_GetName(OH_AVCapability *capability)
90  {
91      if (capability == nullptr) {
92          AVCODEC_LOGE("Get name failed:  null input");
93          return "";
94      }
95      const auto &name = capability->capabilityData_->codecName;
96      return name.data();
97  }
98  
OH_AVCapability_IsHardware(OH_AVCapability * capability)99  bool OH_AVCapability_IsHardware(OH_AVCapability *capability)
100  {
101      if (capability == nullptr) {
102          AVCODEC_LOGE("Varified is hardware failed:  null input");
103          return false;
104      }
105      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
106      return codecInfo->IsHardwareAccelerated();
107  }
108  
OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability * capability)109  int32_t OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability *capability)
110  {
111      if (capability == nullptr) {
112          AVCODEC_LOGE("Get max supported instance failed: null input");
113          return 0;
114      }
115      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
116      return codecInfo->GetMaxSupportedInstances();
117  }
118  
OH_AVCapability_GetSupportedProfiles(OH_AVCapability * capability,const int32_t ** profiles,uint32_t * profileNum)119  OH_AVErrCode OH_AVCapability_GetSupportedProfiles(OH_AVCapability *capability, const int32_t **profiles,
120                                                    uint32_t *profileNum)
121  {
122      CHECK_AND_RETURN_RET_LOG(profileNum != nullptr && profiles != nullptr, AV_ERR_INVALID_VAL,
123                               "Get supported profiles failed: null input");
124      *profiles = nullptr;
125      *profileNum = 0;
126      if (capability == nullptr) {
127          AVCODEC_LOGE("Get supported profiles failed: null input");
128          return AV_ERR_INVALID_VAL;
129      }
130      std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
131      const auto &vec = codecInfo->GetSupportedProfiles();
132      if (vec.size() == 0) {
133          return AV_ERR_OK;
134      }
135  
136      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
137      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
138          "Get supported profiles failed: CreateAVCodecList failed");
139      if (capability->profiles_ != nullptr) {
140          codeclist->DeleteBuffer(capability->profiles_);
141          capability->profiles_ = nullptr;
142      }
143  
144      size_t vecSize = vec.size() * sizeof(int32_t);
145      capability->profiles_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
146      CHECK_AND_RETURN_RET_LOG(capability->profiles_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
147      errno_t ret = memcpy_s(capability->profiles_, vecSize, vec.data(), vecSize);
148      CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
149  
150      *profiles = capability->profiles_;
151      *profileNum = vec.size();
152      return AV_ERR_OK;
153  }
154  
OH_AVCapability_GetSupportedLevelsForProfile(OH_AVCapability * capability,int32_t profile,const int32_t ** levels,uint32_t * levelNum)155  OH_AVErrCode OH_AVCapability_GetSupportedLevelsForProfile(OH_AVCapability *capability, int32_t profile,
156                                                            const int32_t **levels, uint32_t *levelNum)
157  {
158      CHECK_AND_RETURN_RET_LOG(levels != nullptr && levelNum != nullptr, AV_ERR_INVALID_VAL,
159                               "Get supported levels for profile failed: null input");
160      *levels = nullptr;
161      *levelNum = 0;
162      if (capability == nullptr) {
163          AVCODEC_LOGE("Get supported levels for profile failed: null input");
164          return AV_ERR_INVALID_VAL;
165      }
166      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
167      const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
168      const auto &levelsmatch = profileLevelsMap.find(profile);
169      if (levelsmatch == profileLevelsMap.end()) {
170          return AV_ERR_INVALID_VAL;
171      }
172      const auto &vec = levelsmatch->second;
173      if (vec.size() == 0) {
174          return AV_ERR_OK;
175      }
176  
177      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
178      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
179          "Get supported levels for profile failed: CreateAVCodecList failed");
180      if (capability->levels_ != nullptr) {
181          codeclist->DeleteBuffer(capability->levels_);
182          capability->levels_ = nullptr;
183      }
184  
185      size_t vecSize = vec.size() * sizeof(int32_t);
186      capability->levels_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
187      CHECK_AND_RETURN_RET_LOG(capability->levels_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
188      errno_t ret = memcpy_s(capability->levels_, vecSize, vec.data(), vecSize);
189      CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
190  
191      *levels = capability->levels_;
192      *levelNum = vec.size();
193      return AV_ERR_OK;
194  }
195  
OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability * capability,int32_t profile,int32_t level)196  bool OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability *capability, int32_t profile, int32_t level)
197  {
198      if (capability == nullptr) {
199          AVCODEC_LOGE("Varified profiles and level failed: null input");
200          return false;
201      }
202      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
203      const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
204      const auto &levels = profileLevelsMap.find(profile);
205      if (levels == profileLevelsMap.end()) {
206          return false;
207      }
208      return find(levels->second.begin(), levels->second.end(), level) != levels->second.end();
209  }
210  
OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability * capability,OH_AVRange * bitrateRange)211  OH_AVErrCode OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability *capability, OH_AVRange *bitrateRange)
212  {
213      CHECK_AND_RETURN_RET_LOG(bitrateRange != nullptr, AV_ERR_INVALID_VAL,
214                               "Get encoder bitrate range failed: null input");
215      if (capability == nullptr) {
216          bitrateRange->minVal = 0;
217          bitrateRange->maxVal = 0;
218          AVCODEC_LOGE("Get encoder bitrate range failed: null input");
219          return AV_ERR_INVALID_VAL;
220      }
221      std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
222      const auto &bitrate = codecInfo->GetSupportedBitrate();
223      bitrateRange->minVal = bitrate.minVal;
224      bitrateRange->maxVal = bitrate.maxVal;
225      return AV_ERR_OK;
226  }
227  
OH_AVCapability_GetEncoderQualityRange(OH_AVCapability * capability,OH_AVRange * qualityRange)228  OH_AVErrCode OH_AVCapability_GetEncoderQualityRange(OH_AVCapability *capability, OH_AVRange *qualityRange)
229  {
230      CHECK_AND_RETURN_RET_LOG(qualityRange != nullptr, AV_ERR_INVALID_VAL, "Get encoder quality failed: null input");
231      if (capability == nullptr) {
232          qualityRange->minVal = 0;
233          qualityRange->maxVal = 0;
234          AVCODEC_LOGE("Get encoder quality failed: null input");
235          return AV_ERR_INVALID_VAL;
236      }
237      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
238      const auto &quality = codecInfo->GetSupportedEncodeQuality();
239      qualityRange->minVal = quality.minVal;
240      qualityRange->maxVal = quality.maxVal;
241      return AV_ERR_OK;
242  }
243  
OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability * capability,OH_AVRange * complexityRange)244  OH_AVErrCode OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability *capability, OH_AVRange *complexityRange)
245  {
246      CHECK_AND_RETURN_RET_LOG(complexityRange != nullptr, AV_ERR_INVALID_VAL,
247                               "Get encoder complexity range failed: null input");
248      if (capability == nullptr) {
249          complexityRange->minVal = 0;
250          complexityRange->maxVal = 0;
251          AVCODEC_LOGE("Get encoder complexity range failed: null input");
252          return AV_ERR_INVALID_VAL;
253      }
254      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
255      const auto &complexity = codecInfo->GetSupportedComplexity();
256      complexityRange->minVal = complexity.minVal;
257      complexityRange->maxVal = complexity.maxVal;
258      return AV_ERR_OK;
259  }
260  
OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability * capability,OH_BitrateMode bitrateMode)261  bool OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability *capability, OH_BitrateMode bitrateMode)
262  {
263      if (capability == nullptr) {
264          AVCODEC_LOGE("Varified encoder bitrate mode failed: null input");
265          return false;
266      }
267      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
268      const auto &bitrateModeVec = codecInfo->GetSupportedBitrateMode();
269      return find(bitrateModeVec.begin(), bitrateModeVec.end(), bitrateMode) != bitrateModeVec.end();
270  }
271  
OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability * capability,const int32_t ** sampleRates,uint32_t * sampleRateNum)272  OH_AVErrCode OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability *capability, const int32_t **sampleRates,
273                                                            uint32_t *sampleRateNum)
274  {
275      CHECK_AND_RETURN_RET_LOG(sampleRates != nullptr && sampleRateNum != nullptr, AV_ERR_INVALID_VAL,
276                               "Get audio supported samplerates failed: null input");
277      *sampleRates = nullptr;
278      *sampleRateNum = 0;
279      if (capability == nullptr) {
280          AVCODEC_LOGE("Get audio supported samplerates failed: null input");
281          return AV_ERR_INVALID_VAL;
282      }
283      std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
284      const auto &vec = codecInfo->GetSupportedSampleRates();
285      if (vec.size() == 0) {
286          return AV_ERR_OK;
287      }
288  
289      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
290      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
291          "Get audio supported samplerates failed: CreateAVCodecList failed");
292      if (capability->sampleRates_ != nullptr) {
293          codeclist->DeleteBuffer(capability->sampleRates_);
294          capability->sampleRates_ = nullptr;
295      }
296  
297      size_t vecSize = vec.size() * sizeof(int32_t);
298      capability->sampleRates_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
299      CHECK_AND_RETURN_RET_LOG(capability->sampleRates_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
300      errno_t ret = memcpy_s(capability->sampleRates_, vecSize, vec.data(), vecSize);
301      CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
302  
303      *sampleRates = capability->sampleRates_;
304      *sampleRateNum = vec.size();
305      return AV_ERR_OK;
306  }
307  
OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability * capability,OH_AVRange * channelCountRange)308  OH_AVErrCode OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability *capability, OH_AVRange *channelCountRange)
309  {
310      CHECK_AND_RETURN_RET_LOG(channelCountRange != nullptr, AV_ERR_INVALID_VAL,
311                               "Get audio channel count range failed: null input");
312      if (capability == nullptr) {
313          channelCountRange->minVal = 0;
314          channelCountRange->maxVal = 0;
315          AVCODEC_LOGE("Get audio channel count range failed: null input");
316          return AV_ERR_INVALID_VAL;
317      }
318      std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
319      const auto &channels = codecInfo->GetSupportedChannel();
320      channelCountRange->minVal = channels.minVal;
321      channelCountRange->maxVal = channels.maxVal;
322      return AV_ERR_OK;
323  }
324  
OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability * capability,const int32_t ** pixFormats,uint32_t * pixFormatNum)325  OH_AVErrCode OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability *capability, const int32_t **pixFormats,
326                                                             uint32_t *pixFormatNum)
327  {
328      CHECK_AND_RETURN_RET_LOG(pixFormats != nullptr && pixFormatNum != nullptr, AV_ERR_INVALID_VAL,
329                               "Get video supported pixel formats failed: null input");
330      *pixFormats = nullptr;
331      *pixFormatNum = 0;
332      if (capability == nullptr) {
333          AVCODEC_LOGE("Get video supported pixel formats failed: null input");
334          return AV_ERR_INVALID_VAL;
335      }
336  
337      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
338      const auto &vec = codecInfo->GetSupportedFormats();
339      if (vec.size() == 0) {
340          return AV_ERR_OK;
341      }
342  
343      std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
344      CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
345          "Get video supported pixel formats failed: CreateAVCodecList failed");
346      if (capability->pixFormats_ != nullptr) {
347          codeclist->DeleteBuffer(capability->pixFormats_);
348          capability->pixFormats_ = nullptr;
349      }
350  
351      size_t vecSize = vec.size() * sizeof(int32_t);
352      capability->pixFormats_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
353      CHECK_AND_RETURN_RET_LOG(capability->pixFormats_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
354      errno_t ret = memcpy_s(capability->pixFormats_, vecSize, vec.data(), vecSize);
355      CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
356      *pixFormats = capability->pixFormats_;
357      *pixFormatNum = vec.size();
358      return AV_ERR_OK;
359  }
360  
OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability * capability,int32_t * widthAlignment)361  OH_AVErrCode OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability *capability, int32_t *widthAlignment)
362  {
363      CHECK_AND_RETURN_RET_LOG(widthAlignment != nullptr, AV_ERR_INVALID_VAL,
364                               "Get video width alignment failed: null input");
365      if (capability == nullptr) {
366          *widthAlignment = 0;
367          AVCODEC_LOGE("Get video width alignment failed: null input");
368          return AV_ERR_INVALID_VAL;
369      }
370      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
371      *widthAlignment = codecInfo->GetSupportedWidthAlignment();
372      return AV_ERR_OK;
373  }
374  
OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability * capability,int32_t * heightAlignment)375  OH_AVErrCode OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability *capability, int32_t *heightAlignment)
376  {
377      CHECK_AND_RETURN_RET_LOG(heightAlignment != nullptr, AV_ERR_INVALID_VAL,
378                               "Get video height alignment failed: null input");
379      if (capability == nullptr) {
380          *heightAlignment = 0;
381          AVCODEC_LOGE("Get video height alignment failed: null input");
382          return AV_ERR_INVALID_VAL;
383      }
384      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
385      *heightAlignment = codecInfo->GetSupportedHeightAlignment();
386      return AV_ERR_OK;
387  }
388  
OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability * capability,int32_t height,OH_AVRange * widthRange)389  OH_AVErrCode OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability *capability, int32_t height,
390                                                           OH_AVRange *widthRange)
391  {
392      CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL,
393                               "Get video width range for height failed: null input");
394      if (capability == nullptr || height <= 0) {
395          widthRange->minVal = 0;
396          widthRange->maxVal = 0;
397          AVCODEC_LOGE("Get video width range for height failed: invalid input");
398          return AV_ERR_INVALID_VAL;
399      }
400      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
401      const auto &width = codecInfo->GetVideoWidthRangeForHeight(height);
402      widthRange->minVal = width.minVal;
403      widthRange->maxVal = width.maxVal;
404      if (width.minVal == 0 && width.maxVal == 0) {
405          return AV_ERR_INVALID_VAL;
406      }
407      return AV_ERR_OK;
408  }
409  
OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability * capability,int32_t width,OH_AVRange * heightRange)410  OH_AVErrCode OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability *capability, int32_t width,
411                                                           OH_AVRange *heightRange)
412  {
413      CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL,
414                               "Get video height range for width failed: null input");
415      if (capability == nullptr || width <= 0) {
416          heightRange->minVal = 0;
417          heightRange->maxVal = 0;
418          AVCODEC_LOGE("Get video height range for width failed: invalid input");
419          return AV_ERR_INVALID_VAL;
420      }
421      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
422      const auto &height = codecInfo->GetVideoHeightRangeForWidth(width);
423      heightRange->minVal = height.minVal;
424      heightRange->maxVal = height.maxVal;
425      if (height.minVal == 0 && height.maxVal == 0) {
426          return AV_ERR_INVALID_VAL;
427      }
428      return AV_ERR_OK;
429  }
430  
OH_AVCapability_GetVideoWidthRange(OH_AVCapability * capability,OH_AVRange * widthRange)431  OH_AVErrCode OH_AVCapability_GetVideoWidthRange(OH_AVCapability *capability, OH_AVRange *widthRange)
432  {
433      CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL, "Get video width range failed: null input");
434      if (capability == nullptr) {
435          widthRange->minVal = 0;
436          widthRange->maxVal = 0;
437          AVCODEC_LOGE("Get video width range failed: null input");
438          return AV_ERR_INVALID_VAL;
439      }
440      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
441      const auto &width = codecInfo->GetSupportedWidth();
442      widthRange->minVal = width.minVal;
443      widthRange->maxVal = width.maxVal;
444      return AV_ERR_OK;
445  }
446  
OH_AVCapability_GetVideoHeightRange(OH_AVCapability * capability,OH_AVRange * heightRange)447  OH_AVErrCode OH_AVCapability_GetVideoHeightRange(OH_AVCapability *capability, OH_AVRange *heightRange)
448  {
449      CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL, "Get video height range failed: null input");
450      if (capability == nullptr) {
451          heightRange->minVal = 0;
452          heightRange->maxVal = 0;
453          AVCODEC_LOGE("Get video height range failed: null input");
454          return AV_ERR_INVALID_VAL;
455      }
456  
457      std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
458      const auto &height = codecInfo->GetSupportedHeight();
459      heightRange->minVal = height.minVal;
460      heightRange->maxVal = height.maxVal;
461      return AV_ERR_OK;
462  }
463  
OH_AVCapability_IsVideoSizeSupported(OH_AVCapability * capability,int32_t width,int32_t height)464  bool OH_AVCapability_IsVideoSizeSupported(OH_AVCapability *capability, int32_t width, int32_t height)
465  {
466      if (capability == nullptr) {
467          AVCODEC_LOGE("Varified is video size supported failed: null input");
468          return false;
469      }
470      std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
471      return videoCap->IsSizeSupported(width, height);
472  }
473  
OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability * capability,OH_AVRange * frameRateRange)474  OH_AVErrCode OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability *capability, OH_AVRange *frameRateRange)
475  {
476      CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
477                               "Get video framerate range failed: null input");
478      if (capability == nullptr) {
479          frameRateRange->minVal = 0;
480          frameRateRange->maxVal = 0;
481          AVCODEC_LOGE("Get video framerate range failed: null input");
482          return AV_ERR_INVALID_VAL;
483      }
484      std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
485      const auto &frameRate = videoCap->GetSupportedFrameRate();
486      frameRateRange->minVal = frameRate.minVal;
487      frameRateRange->maxVal = frameRate.maxVal;
488      return AV_ERR_OK;
489  }
490  
OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability * capability,int32_t width,int32_t height,OH_AVRange * frameRateRange)491  OH_AVErrCode OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability *capability, int32_t width, int32_t height,
492                                                             OH_AVRange *frameRateRange)
493  {
494      CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
495                               "Get video framerate range for size failed: null input");
496      if (capability == nullptr || width <= 0 || height <= 0) {
497          frameRateRange->minVal = 0;
498          frameRateRange->maxVal = 0;
499          AVCODEC_LOGE("Get video framerate range for size failed: invalid input");
500          return AV_ERR_INVALID_VAL;
501      }
502      std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
503      const auto &frameRate = videoCap->GetSupportedFrameRatesFor(width, height);
504      frameRateRange->minVal = frameRate.minVal;
505      frameRateRange->maxVal = frameRate.maxVal;
506      if (frameRate.minVal == 0 && frameRate.maxVal == 0) {
507          return AV_ERR_INVALID_VAL;
508      }
509      return AV_ERR_OK;
510  }
511  
OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability * capability,int32_t width,int32_t height,int32_t frameRate)512  bool OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability *capability, int32_t width, int32_t height,
513                                                         int32_t frameRate)
514  {
515      if (capability == nullptr) {
516          AVCODEC_LOGE("Varified video framerate and size failed: null input");
517          return false;
518      }
519      std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
520      return videoCap->IsSizeAndRateSupported(width, height, frameRate);
521  }
522  
OH_AVCapability_IsFeatureSupported(OH_AVCapability * capability,OH_AVCapabilityFeature feature)523  bool OH_AVCapability_IsFeatureSupported(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
524  {
525      CHECK_AND_RETURN_RET_LOG(capability != nullptr, false, "Varified feature failed: capability is nullptr");
526      bool isValid = feature >= VIDEO_ENCODER_TEMPORAL_SCALABILITY && feature <= VIDEO_LOW_LATENCY;
527      CHECK_AND_RETURN_RET_LOG(isValid, false, "Varified feature failed: feature %{public}d is invalid", feature);
528      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
529      return codecInfo->IsFeatureSupported(static_cast<AVCapabilityFeature>(feature));
530  }
531  
OH_AVCapability_GetFeatureProperties(OH_AVCapability * capability,OH_AVCapabilityFeature feature)532  OH_AVFormat *OH_AVCapability_GetFeatureProperties(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
533  {
534      CHECK_AND_RETURN_RET_LOG(capability != nullptr, nullptr, "Get feature properties failed: capability is nullptr");
535      std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
536      Format format;
537      if (codecInfo->GetFeatureProperties(static_cast<AVCapabilityFeature>(feature), format) != AVCS_ERR_OK) {
538          return nullptr;
539      }
540      Format::FormatDataMap formatMap = format.GetFormatMap();
541      if (formatMap.size() == 0) {
542          AVCODEC_LOGW("Get feature properties successfully, but feature %{public}d does not have a property", feature);
543          return nullptr;
544      }
545      OH_AVFormat *avFormat = OH_AVFormat_Create();
546      CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Get feature properties failed: create OH_AVFormat failed");
547      avFormat->format_ = format;
548      return avFormat;
549  }