• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 constexpr uint32_t MAX_LENGTH = 255;
29 }
30 using namespace OHOS::MediaAVCodec;
31 
~OH_AVCapability()32 OH_AVCapability::~OH_AVCapability() {}
33 
OH_AVCodec_GetCapability(const char * mime,bool isEncoder)34 OH_AVCapability *OH_AVCodec_GetCapability(const char *mime, bool isEncoder)
35 {
36     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Get capability failed: mime is nullptr");
37     CHECK_AND_RETURN_RET_LOG(strlen(mime) != 0 && strlen(mime) < MAX_LENGTH, nullptr,
38         "Get capability failed: invalid mime strlen, %{public}zu", strlen(mime));
39     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
40     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, nullptr, "Get capability failed: CreateAVCodecList failed");
41     uint32_t sizeOfCap = sizeof(OH_AVCapability);
42     CapabilityData *capabilityData = codeclist->GetCapability(mime, isEncoder, AVCodecCategory::AVCODEC_NONE);
43     CHECK_AND_RETURN_RET_LOG(capabilityData != nullptr, nullptr,
44                              "Get capability failed: cannot find matched capability");
45     const std::string &name = capabilityData->codecName;
46     CHECK_AND_RETURN_RET_LOG(!name.empty(), nullptr, "Get capability failed: cannot find matched capability");
47     void *addr = codeclist->GetBuffer(name, sizeOfCap);
48     CHECK_AND_RETURN_RET_LOG(addr != nullptr, nullptr, "Get capability failed: malloc capability buffer failed");
49     OH_AVCapability *obj = static_cast<OH_AVCapability *>(addr);
50     obj->magic_ = AVMagic::AVCODEC_MAGIC_AVCAPABILITY;
51     obj->capabilityData_ = capabilityData;
52     AVCODEC_LOGD("OH_AVCodec_GetCapability successful");
53     return obj;
54 }
55 
OH_AVCodec_GetCapabilityByCategory(const char * mime,bool isEncoder,OH_AVCodecCategory category)56 OH_AVCapability *OH_AVCodec_GetCapabilityByCategory(const char *mime, bool isEncoder, OH_AVCodecCategory category)
57 {
58     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Get capabilityByCategory failed: mime is nullptr");
59     CHECK_AND_RETURN_RET_LOG(strlen(mime) != 0 && strlen(mime) < MAX_LENGTH, nullptr,
60         "Get capabilityByCategory failed: invalid mime strlen, %{public}zu", strlen(mime));
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 if (category == SOFTWARE) {
68         innerCategory = AVCodecCategory::AVCODEC_SOFTWARE;
69     } else {
70         AVCODEC_LOGE("Unsupported category {public}%d", static_cast<int32_t>(category));
71         return nullptr;
72     }
73     uint32_t sizeOfCap = sizeof(OH_AVCapability);
74     CapabilityData *capabilityData = codeclist->GetCapability(mime, isEncoder, innerCategory);
75     CHECK_AND_RETURN_RET_LOG(capabilityData != nullptr, nullptr,
76                              "Get capabilityByCategory failed: cannot find matched capability");
77     const std::string &name = capabilityData->codecName;
78     CHECK_AND_RETURN_RET_LOG(!name.empty(), nullptr, "Get capabilityByCategory failed: cannot find matched capability");
79     void *addr = codeclist->GetBuffer(name, sizeOfCap);
80     CHECK_AND_RETURN_RET_LOG(addr != nullptr, nullptr,
81                              "Get capabilityByCategory failed: malloc capability buffer failed");
82     OH_AVCapability *obj = static_cast<OH_AVCapability *>(addr);
83     obj->magic_ = AVMagic::AVCODEC_MAGIC_AVCAPABILITY;
84     obj->capabilityData_ = capabilityData;
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     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
92         "", "Invalid parameter");
93     const auto &name = capability->capabilityData_->codecName;
94     return name.data();
95 }
96 
OH_AVCapability_IsHardware(OH_AVCapability * capability)97 bool OH_AVCapability_IsHardware(OH_AVCapability *capability)
98 {
99     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
100         false, "Invalid parameter");
101     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
102     return codecInfo->IsHardwareAccelerated();
103 }
104 
OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability * capability)105 int32_t OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability *capability)
106 {
107     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
108         0, "Invalid parameter");
109     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
110     return codecInfo->GetMaxSupportedInstances();
111 }
112 
OH_AVCapability_GetSupportedProfiles(OH_AVCapability * capability,const int32_t ** profiles,uint32_t * profileNum)113 OH_AVErrCode OH_AVCapability_GetSupportedProfiles(OH_AVCapability *capability, const int32_t **profiles,
114                                                   uint32_t *profileNum)
115 {
116     CHECK_AND_RETURN_RET_LOG(profileNum != nullptr && profiles != nullptr, AV_ERR_INVALID_VAL,
117                              "Get supported profiles failed: null input");
118     *profiles = nullptr;
119     *profileNum = 0;
120     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
121         AV_ERR_INVALID_VAL, "Invalid parameter");
122     std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
123     const auto &vec = codecInfo->GetSupportedProfiles();
124     if (vec.size() == 0) {
125         return AV_ERR_OK;
126     }
127 
128     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
129     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
130         "Get supported profiles failed: CreateAVCodecList failed");
131     size_t vecSize = vec.size() * sizeof(int32_t);
132     int32_t *buf = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
133     CHECK_AND_RETURN_RET_LOG(buf != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
134     errno_t ret = memcpy_s(buf, vecSize, vec.data(), vecSize);
135     CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
136 
137     *profiles = buf;
138     *profileNum = vec.size();
139     return AV_ERR_OK;
140 }
141 
OH_AVCapability_GetSupportedLevelsForProfile(OH_AVCapability * capability,int32_t profile,const int32_t ** levels,uint32_t * levelNum)142 OH_AVErrCode OH_AVCapability_GetSupportedLevelsForProfile(OH_AVCapability *capability, int32_t profile,
143                                                           const int32_t **levels, uint32_t *levelNum)
144 {
145     CHECK_AND_RETURN_RET_LOG(levels != nullptr && levelNum != nullptr, AV_ERR_INVALID_VAL,
146                              "Get supported levels for profile failed: null input");
147     *levels = nullptr;
148     *levelNum = 0;
149     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
150         AV_ERR_INVALID_VAL, "Invalid parameter");
151     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
152     const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
153     const auto &levelsmatch = profileLevelsMap.find(profile);
154     if (levelsmatch == profileLevelsMap.end()) {
155         return AV_ERR_INVALID_VAL;
156     }
157     const auto &vec = levelsmatch->second;
158     if (vec.size() == 0) {
159         return AV_ERR_OK;
160     }
161 
162     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
163     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
164         "Get supported levels for profile failed: CreateAVCodecList failed");
165     size_t vecSize = vec.size() * sizeof(int32_t);
166     int32_t *buf = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
167     CHECK_AND_RETURN_RET_LOG(buf != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
168     errno_t ret = memcpy_s(buf, vecSize, vec.data(), vecSize);
169     CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
170 
171     *levels = buf;
172     *levelNum = vec.size();
173     return AV_ERR_OK;
174 }
175 
OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability * capability,int32_t profile,int32_t level)176 bool OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability *capability, int32_t profile, int32_t level)
177 {
178     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
179         false, "Invalid parameter");
180     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
181     const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
182     const auto &levels = profileLevelsMap.find(profile);
183     if (levels == profileLevelsMap.end()) {
184         return false;
185     }
186     return find(levels->second.begin(), levels->second.end(), level) != levels->second.end();
187 }
188 
OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability * capability,OH_AVRange * bitrateRange)189 OH_AVErrCode OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability *capability, OH_AVRange *bitrateRange)
190 {
191     CHECK_AND_RETURN_RET_LOG(bitrateRange != nullptr, AV_ERR_INVALID_VAL,
192                              "Get encoder bitrate range failed: null input");
193     bitrateRange->minVal = 0;
194     bitrateRange->maxVal = 0;
195     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
196         AV_ERR_INVALID_VAL, "Invalid parameter");
197     CapabilityData *capData = capability->capabilityData_;
198     if (!AVCodecInfo::isEncoder(capData->codecType)) {
199         AVCODEC_LOGW("The capability provided is not expected, should be the encoder capability");
200     }
201     std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capData);
202     const auto &bitrate = codecInfo->GetSupportedBitrate();
203     bitrateRange->minVal = bitrate.minVal;
204     bitrateRange->maxVal = bitrate.maxVal;
205     return AV_ERR_OK;
206 }
207 
OH_AVCapability_GetEncoderQualityRange(OH_AVCapability * capability,OH_AVRange * qualityRange)208 OH_AVErrCode OH_AVCapability_GetEncoderQualityRange(OH_AVCapability *capability, OH_AVRange *qualityRange)
209 {
210     CHECK_AND_RETURN_RET_LOG(qualityRange != nullptr, AV_ERR_INVALID_VAL, "Get encoder quality failed: null input");
211     qualityRange->minVal = 0;
212     qualityRange->maxVal = 0;
213     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
214         AV_ERR_INVALID_VAL, "Invalid parameter");
215     CapabilityData *capData = capability->capabilityData_;
216     if (!AVCodecInfo::isEncoder(capData->codecType)) {
217         AVCODEC_LOGW("The capability provided is not expected, should be the encoder capability");
218     }
219     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
220     const auto &quality = codecInfo->GetSupportedEncodeQuality();
221     qualityRange->minVal = quality.minVal;
222     qualityRange->maxVal = quality.maxVal;
223     return AV_ERR_OK;
224 }
225 
OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability * capability,OH_AVRange * complexityRange)226 OH_AVErrCode OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability *capability, OH_AVRange *complexityRange)
227 {
228     CHECK_AND_RETURN_RET_LOG(complexityRange != nullptr, AV_ERR_INVALID_VAL,
229                              "Get encoder complexity range failed: null input");
230     complexityRange->minVal = 0;
231     complexityRange->maxVal = 0;
232     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
233         AV_ERR_INVALID_VAL, "Invalid parameter");
234     CapabilityData *capData = capability->capabilityData_;
235     if (!AVCodecInfo::isEncoder(capData->codecType)) {
236         AVCODEC_LOGW("The capability provided is not expected, should be the encoder capability");
237     }
238     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
239     const auto &complexity = codecInfo->GetSupportedComplexity();
240     complexityRange->minVal = complexity.minVal;
241     complexityRange->maxVal = complexity.maxVal;
242     return AV_ERR_OK;
243 }
244 
OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability * capability,OH_BitrateMode bitrateMode)245 bool OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability *capability, OH_BitrateMode bitrateMode)
246 {
247     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
248         false, "Invalid parameter");
249     CapabilityData *capData = capability->capabilityData_;
250     if (!AVCodecInfo::isEncoder(capData->codecType)) {
251         AVCODEC_LOGW("The capability provided is not expected, should be the encoder capability");
252     }
253     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
254     const auto &bitrateModeVec = codecInfo->GetSupportedBitrateMode();
255     return find(bitrateModeVec.begin(), bitrateModeVec.end(), bitrateMode) != bitrateModeVec.end();
256 }
257 
OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability * capability,const int32_t ** sampleRates,uint32_t * sampleRateNum)258 OH_AVErrCode OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability *capability, const int32_t **sampleRates,
259                                                           uint32_t *sampleRateNum)
260 {
261     CHECK_AND_RETURN_RET_LOG(sampleRates != nullptr && sampleRateNum != nullptr, AV_ERR_INVALID_VAL,
262                              "Get audio supported samplerates failed: null input");
263     *sampleRates = nullptr;
264     *sampleRateNum = 0;
265     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
266         AV_ERR_INVALID_VAL, "Invalid parameter");
267     CapabilityData *capData = capability->capabilityData_;
268     if (!AVCodecInfo::isAudio(capData->codecType)) {
269         AVCODEC_LOGW("The capability provided is not expected, should be the audio capability");
270     }
271     std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capData);
272     const auto &vec = codecInfo->GetSupportedSampleRates();
273     if (vec.size() == 0) {
274         return AV_ERR_OK;
275     }
276 
277     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
278     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
279         "Get audio supported samplerates failed: CreateAVCodecList failed");
280     size_t vecSize = vec.size() * sizeof(int32_t);
281     int32_t *buf = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
282     CHECK_AND_RETURN_RET_LOG(buf != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
283     errno_t ret = memcpy_s(buf, vecSize, vec.data(), vecSize);
284     CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
285 
286     *sampleRates = buf;
287     *sampleRateNum = vec.size();
288     return AV_ERR_OK;
289 }
290 
OH_AVCapability_GetAudioSupportedSampleRateRanges(OH_AVCapability * capability,OH_AVRange ** sampleRateRanges,uint32_t * rangesNum)291 OH_AVErrCode OH_AVCapability_GetAudioSupportedSampleRateRanges(OH_AVCapability *capability,
292                                                                OH_AVRange **sampleRateRanges, uint32_t *rangesNum)
293 {
294     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
295         AV_ERR_INVALID_VAL, "Invalid parameter");
296     CHECK_AND_RETURN_RET_LOG(sampleRateRanges != nullptr && rangesNum != nullptr, AV_ERR_INVALID_VAL,
297                              "Get audio supported samplerate ranges failed: null input");
298     *sampleRateRanges = nullptr;
299     *rangesNum = 0;
300     CapabilityData *capData = capability->capabilityData_;
301     if (!AVCodecInfo::isAudio(capData->codecType)) {
302         AVCODEC_LOGW("The capability provided is not expected, should be the audio capability");
303     }
304     std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capData);
305     const std::vector<Range> &vec = codecInfo->GetSupportedSampleRateRanges();
306 
307     if (vec.size() == 0) {
308         return AV_ERR_OK;
309     }
310     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
311     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
312         "Get audio supported samplerates failed: CreateAVCodecList failed");
313     if (capability->sampleRateRanges_ != nullptr) {
314         capability->sampleRateRanges_ = nullptr;
315     }
316 
317     size_t vecSize = vec.size() * sizeof(OH_AVRange);
318     capability->sampleRateRanges_ = static_cast<OH_AVRange *>(codeclist->NewBuffer(vecSize));
319     CHECK_AND_RETURN_RET_LOG(capability->sampleRateRanges_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
320     for (size_t i = 0; i < vec.size(); i++) {
321         capability->sampleRateRanges_[i].minVal = vec[i].minVal;
322         capability->sampleRateRanges_[i].maxVal = vec[i].maxVal;
323     }
324     *sampleRateRanges = capability->sampleRateRanges_;
325     *rangesNum = vec.size();
326     return AV_ERR_OK;
327 }
328 
OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability * capability,OH_AVRange * channelCountRange)329 OH_AVErrCode OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability *capability, OH_AVRange *channelCountRange)
330 {
331     CHECK_AND_RETURN_RET_LOG(channelCountRange != nullptr, AV_ERR_INVALID_VAL,
332                              "Get audio channel count range failed: null input");
333     channelCountRange->minVal = 0;
334     channelCountRange->maxVal = 0;
335     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
336         AV_ERR_INVALID_VAL, "Invalid parameter");
337     CapabilityData *capData = capability->capabilityData_;
338     if (!AVCodecInfo::isAudio(capData->codecType)) {
339         AVCODEC_LOGW("The capability provided is not expected, should be the audio capability");
340     }
341     std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capData);
342     const auto &channels = codecInfo->GetSupportedChannel();
343     channelCountRange->minVal = channels.minVal;
344     channelCountRange->maxVal = channels.maxVal;
345     return AV_ERR_OK;
346 }
347 
OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability * capability,const int32_t ** pixFormats,uint32_t * pixFormatNum)348 OH_AVErrCode OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability *capability, const int32_t **pixFormats,
349                                                            uint32_t *pixFormatNum)
350 {
351     CHECK_AND_RETURN_RET_LOG(pixFormats != nullptr && pixFormatNum != nullptr, AV_ERR_INVALID_VAL,
352                              "Get video supported pixel formats failed: null input");
353     *pixFormats = nullptr;
354     *pixFormatNum = 0;
355     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
356         AV_ERR_INVALID_VAL, "Invalid parameter");
357     CapabilityData *capData = capability->capabilityData_;
358     if (!AVCodecInfo::isVideo(capData->codecType)) {
359         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
360     }
361     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
362     const auto &vec = codecInfo->GetSupportedFormats();
363     if (vec.size() == 0) {
364         return AV_ERR_OK;
365     }
366     std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
367     CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
368         "Get video supported pixel formats failed: CreateAVCodecList failed");
369     size_t vecSize = vec.size() * sizeof(int32_t);
370     int32_t *buf = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
371     CHECK_AND_RETURN_RET_LOG(buf != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
372     errno_t ret = memcpy_s(buf, vecSize, vec.data(), vecSize);
373     CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
374     *pixFormats = buf;
375     *pixFormatNum = vec.size();
376     return AV_ERR_OK;
377 }
378 
OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability * capability,int32_t * widthAlignment)379 OH_AVErrCode OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability *capability, int32_t *widthAlignment)
380 {
381     CHECK_AND_RETURN_RET_LOG(widthAlignment != nullptr, AV_ERR_INVALID_VAL,
382                              "Get video width alignment failed: null input");
383     *widthAlignment = 0;
384     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
385         AV_ERR_INVALID_VAL, "Invalid parameter");
386     CapabilityData *capData = capability->capabilityData_;
387     if (!AVCodecInfo::isVideo(capData->codecType)) {
388         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
389     }
390     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
391     *widthAlignment = codecInfo->GetSupportedWidthAlignment();
392     return AV_ERR_OK;
393 }
394 
OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability * capability,int32_t * heightAlignment)395 OH_AVErrCode OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability *capability, int32_t *heightAlignment)
396 {
397     CHECK_AND_RETURN_RET_LOG(heightAlignment != nullptr, AV_ERR_INVALID_VAL,
398                              "Get video height alignment failed: null input");
399     *heightAlignment = 0;
400     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
401         AV_ERR_INVALID_VAL, "Invalid parameter");
402     CapabilityData *capData = capability->capabilityData_;
403     if (!AVCodecInfo::isVideo(capData->codecType)) {
404         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
405     }
406     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
407     *heightAlignment = codecInfo->GetSupportedHeightAlignment();
408     return AV_ERR_OK;
409 }
410 
OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability * capability,int32_t height,OH_AVRange * widthRange)411 OH_AVErrCode OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability *capability, int32_t height,
412                                                          OH_AVRange *widthRange)
413 {
414     CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL,
415                              "Get video width range for height failed: null input");
416     widthRange->minVal = 0;
417     widthRange->maxVal = 0;
418     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
419         AV_ERR_INVALID_VAL, "Invalid parameter");
420     CapabilityData *capData = capability->capabilityData_;
421     if (!AVCodecInfo::isVideo(capData->codecType)) {
422         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
423     }
424     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
425     const auto &width = codecInfo->GetVideoWidthRangeForHeight(height);
426     widthRange->minVal = width.minVal;
427     widthRange->maxVal = width.maxVal;
428     CHECK_AND_RETURN_RET_LOG(width.minVal != 0 || width.maxVal != 0, AV_ERR_INVALID_VAL, "width range is [0, 0]");
429     AVCODEC_LOGD("Success to get width range [%{public}d, %{public}d], by height %{public}d",
430         width.minVal, width.maxVal, height);
431     return AV_ERR_OK;
432 }
433 
OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability * capability,int32_t width,OH_AVRange * heightRange)434 OH_AVErrCode OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability *capability, int32_t width,
435                                                          OH_AVRange *heightRange)
436 {
437     CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL,
438                              "Get video height range for width failed: null input");
439     heightRange->minVal = 0;
440     heightRange->maxVal = 0;
441     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
442         AV_ERR_INVALID_VAL, "Invalid parameter");
443     CapabilityData *capData = capability->capabilityData_;
444     if (!AVCodecInfo::isVideo(capData->codecType)) {
445         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
446     }
447     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
448     const auto &height = codecInfo->GetVideoHeightRangeForWidth(width);
449     heightRange->minVal = height.minVal;
450     heightRange->maxVal = height.maxVal;
451     CHECK_AND_RETURN_RET_LOG(height.minVal != 0 || height.maxVal != 0, AV_ERR_INVALID_VAL, "height range is [0, 0]");
452     AVCODEC_LOGD("Success to get height range [%{public}d, %{public}d], by width %{public}d",
453         height.minVal, height.maxVal, width);
454     return AV_ERR_OK;
455 }
456 
OH_AVCapability_GetVideoWidthRange(OH_AVCapability * capability,OH_AVRange * widthRange)457 OH_AVErrCode OH_AVCapability_GetVideoWidthRange(OH_AVCapability *capability, OH_AVRange *widthRange)
458 {
459     CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL, "Get video width range failed: null input");
460     widthRange->minVal = 0;
461     widthRange->maxVal = 0;
462     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
463         AV_ERR_INVALID_VAL, "Invalid parameter");
464     CapabilityData *capData = capability->capabilityData_;
465     if (!AVCodecInfo::isVideo(capData->codecType)) {
466         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
467     }
468     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
469     const auto &width = codecInfo->GetSupportedWidth();
470     widthRange->minVal = width.minVal;
471     widthRange->maxVal = width.maxVal;
472     return AV_ERR_OK;
473 }
474 
OH_AVCapability_GetVideoHeightRange(OH_AVCapability * capability,OH_AVRange * heightRange)475 OH_AVErrCode OH_AVCapability_GetVideoHeightRange(OH_AVCapability *capability, OH_AVRange *heightRange)
476 {
477     CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL, "Get video height range failed: null input");
478     heightRange->minVal = 0;
479     heightRange->maxVal = 0;
480     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
481         AV_ERR_INVALID_VAL, "Invalid parameter");
482     CapabilityData *capData = capability->capabilityData_;
483     if (!AVCodecInfo::isVideo(capData->codecType)) {
484         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
485     }
486     std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
487     const auto &height = codecInfo->GetSupportedHeight();
488     heightRange->minVal = height.minVal;
489     heightRange->maxVal = height.maxVal;
490     return AV_ERR_OK;
491 }
492 
OH_AVCapability_IsVideoSizeSupported(OH_AVCapability * capability,int32_t width,int32_t height)493 bool OH_AVCapability_IsVideoSizeSupported(OH_AVCapability *capability, int32_t width, int32_t height)
494 {
495     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
496         false, "Invalid parameter");
497     CapabilityData *capData = capability->capabilityData_;
498     if (!AVCodecInfo::isVideo(capData->codecType)) {
499         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
500     }
501     std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
502     return videoCap->IsSizeSupported(width, height);
503 }
504 
OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability * capability,OH_AVRange * frameRateRange)505 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability *capability, OH_AVRange *frameRateRange)
506 {
507     CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
508                              "Get video framerate range failed: null input");
509     frameRateRange->minVal = 0;
510     frameRateRange->maxVal = 0;
511     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
512         AV_ERR_INVALID_VAL, "Invalid parameter");
513     CapabilityData *capData = capability->capabilityData_;
514     if (!AVCodecInfo::isVideo(capData->codecType)) {
515         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
516     }
517     std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
518     const auto &frameRate = videoCap->GetSupportedFrameRate();
519     frameRateRange->minVal = frameRate.minVal;
520     frameRateRange->maxVal = frameRate.maxVal;
521     return AV_ERR_OK;
522 }
523 
OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability * capability,int32_t width,int32_t height,OH_AVRange * frameRateRange)524 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability *capability, int32_t width, int32_t height,
525                                                            OH_AVRange *frameRateRange)
526 {
527     CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
528                              "Get video framerate range for size failed: null input");
529     frameRateRange->minVal = 0;
530     frameRateRange->maxVal = 0;
531     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
532         AV_ERR_INVALID_VAL, "Invalid parameter");
533     CapabilityData *capData = capability->capabilityData_;
534     if (!AVCodecInfo::isVideo(capData->codecType)) {
535         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
536     }
537     std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
538     const auto &frameRate = videoCap->GetSupportedFrameRatesFor(width, height);
539     frameRateRange->minVal = frameRate.minVal;
540     frameRateRange->maxVal = frameRate.maxVal;
541     CHECK_AND_RETURN_RET_LOG(frameRate.minVal != 0 || frameRate.maxVal != 0, AV_ERR_INVALID_VAL,
542         "frameRate range is [0, 0]");
543     AVCODEC_LOGD("Success to get frameRate range [%{public}d, %{public}d], by width %{public}d and height %{public}d",
544         frameRate.minVal, frameRate.maxVal, width, height);
545     return AV_ERR_OK;
546 }
547 
OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability * capability,int32_t width,int32_t height,int32_t frameRate)548 bool OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability *capability, int32_t width, int32_t height,
549                                                        int32_t frameRate)
550 {
551     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
552         false, "Invalid parameter");
553     CapabilityData *capData = capability->capabilityData_;
554     if (!AVCodecInfo::isVideo(capData->codecType)) {
555         AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
556     }
557     std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
558     return videoCap->IsSizeAndRateSupported(width, height, frameRate);
559 }
560 
OH_AVCapability_IsFeatureSupported(OH_AVCapability * capability,OH_AVCapabilityFeature feature)561 bool OH_AVCapability_IsFeatureSupported(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
562 {
563     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
564         false, "Invalid parameter");
565     bool isValid = (feature >= VIDEO_ENCODER_TEMPORAL_SCALABILITY && feature <= VIDEO_LOW_LATENCY) ||
566         feature == VIDEO_ENCODER_B_FRAME;
567     CHECK_AND_RETURN_RET_LOG(isValid, false, "Varified feature failed: feature %{public}d is invalid", feature);
568     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
569     return codecInfo->IsFeatureSupported(static_cast<AVCapabilityFeature>(feature));
570 }
571 
OH_AVCapability_GetFeatureProperties(OH_AVCapability * capability,OH_AVCapabilityFeature feature)572 OH_AVFormat *OH_AVCapability_GetFeatureProperties(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
573 {
574     CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
575         nullptr, "Invalid parameter");
576     std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
577     Format format;
578     if (codecInfo->GetFeatureProperties(static_cast<AVCapabilityFeature>(feature), format) != AVCS_ERR_OK) {
579         return nullptr;
580     }
581     Format::FormatDataMap formatMap = format.GetFormatMap();
582     if (formatMap.size() == 0) {
583         AVCODEC_LOGW("Get feature properties successfully, but feature %{public}d does not have a property", feature);
584         return nullptr;
585     }
586     OH_AVFormat *avFormat = OH_AVFormat_Create();
587     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Get feature properties failed: create OH_AVFormat failed");
588     avFormat->format_ = format;
589     return avFormat;
590 }