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 }