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 obj->profiles_ = nullptr;
53 obj->levels_ = nullptr;
54 obj->pixFormats_ = nullptr;
55 obj->sampleRates_ = nullptr;
56 AVCODEC_LOGD("OH_AVCodec_GetCapability successful");
57 return obj;
58 }
59
OH_AVCodec_GetCapabilityByCategory(const char * mime,bool isEncoder,OH_AVCodecCategory category)60 OH_AVCapability *OH_AVCodec_GetCapabilityByCategory(const char *mime, bool isEncoder, OH_AVCodecCategory category)
61 {
62 CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Get capabilityByCategory failed: mime is nullptr");
63 CHECK_AND_RETURN_RET_LOG(strlen(mime) != 0 && strlen(mime) < MAX_LENGTH, nullptr,
64 "Get capabilityByCategory failed: invalid mime strlen, %{public}zu", strlen(mime));
65 std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
66 CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, nullptr,
67 "Get capabilityByCategory failed: CreateAVCodecList failed");
68 AVCodecCategory innerCategory;
69 if (category == HARDWARE) {
70 innerCategory = AVCodecCategory::AVCODEC_HARDWARE;
71 } else if (category == SOFTWARE) {
72 innerCategory = AVCodecCategory::AVCODEC_SOFTWARE;
73 } else {
74 AVCODEC_LOGE("Unsupported category {public}%d", static_cast<int32_t>(category));
75 return nullptr;
76 }
77 uint32_t sizeOfCap = sizeof(OH_AVCapability);
78 CapabilityData *capabilityData = codeclist->GetCapability(mime, isEncoder, innerCategory);
79 CHECK_AND_RETURN_RET_LOG(capabilityData != nullptr, nullptr,
80 "Get capabilityByCategory failed: cannot find matched capability");
81 const std::string &name = capabilityData->codecName;
82 CHECK_AND_RETURN_RET_LOG(!name.empty(), nullptr, "Get capabilityByCategory failed: cannot find matched capability");
83 void *addr = codeclist->GetBuffer(name, sizeOfCap);
84 CHECK_AND_RETURN_RET_LOG(addr != nullptr, nullptr,
85 "Get capabilityByCategory failed: malloc capability buffer failed");
86 OH_AVCapability *obj = static_cast<OH_AVCapability *>(addr);
87 obj->magic_ = AVMagic::AVCODEC_MAGIC_AVCAPABILITY;
88 obj->capabilityData_ = capabilityData;
89 obj->profiles_ = nullptr;
90 obj->levels_ = nullptr;
91 obj->pixFormats_ = nullptr;
92 obj->sampleRates_ = nullptr;
93 AVCODEC_LOGD("OH_AVCodec_GetCapabilityByCategory successful");
94 return obj;
95 }
96
OH_AVCapability_GetName(OH_AVCapability * capability)97 const char *OH_AVCapability_GetName(OH_AVCapability *capability)
98 {
99 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
100 "", "Invalid parameter");
101 const auto &name = capability->capabilityData_->codecName;
102 return name.data();
103 }
104
OH_AVCapability_IsHardware(OH_AVCapability * capability)105 bool OH_AVCapability_IsHardware(OH_AVCapability *capability)
106 {
107 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
108 false, "Invalid parameter");
109 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
110 return codecInfo->IsHardwareAccelerated();
111 }
112
OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability * capability)113 int32_t OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability *capability)
114 {
115 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
116 0, "Invalid parameter");
117 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
118 return codecInfo->GetMaxSupportedInstances();
119 }
120
OH_AVCapability_GetSupportedProfiles(OH_AVCapability * capability,const int32_t ** profiles,uint32_t * profileNum)121 OH_AVErrCode OH_AVCapability_GetSupportedProfiles(OH_AVCapability *capability, const int32_t **profiles,
122 uint32_t *profileNum)
123 {
124 CHECK_AND_RETURN_RET_LOG(profileNum != nullptr && profiles != nullptr, AV_ERR_INVALID_VAL,
125 "Get supported profiles failed: null input");
126 *profiles = nullptr;
127 *profileNum = 0;
128 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
129 AV_ERR_INVALID_VAL, "Invalid parameter");
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 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
163 AV_ERR_INVALID_VAL, "Invalid parameter");
164 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
165 const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
166 const auto &levelsmatch = profileLevelsMap.find(profile);
167 if (levelsmatch == profileLevelsMap.end()) {
168 return AV_ERR_INVALID_VAL;
169 }
170 const auto &vec = levelsmatch->second;
171 if (vec.size() == 0) {
172 return AV_ERR_OK;
173 }
174
175 std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
176 CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
177 "Get supported levels for profile failed: CreateAVCodecList failed");
178 if (capability->levels_ != nullptr) {
179 codeclist->DeleteBuffer(capability->levels_);
180 capability->levels_ = nullptr;
181 }
182
183 size_t vecSize = vec.size() * sizeof(int32_t);
184 capability->levels_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
185 CHECK_AND_RETURN_RET_LOG(capability->levels_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
186 errno_t ret = memcpy_s(capability->levels_, vecSize, vec.data(), vecSize);
187 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
188
189 *levels = capability->levels_;
190 *levelNum = vec.size();
191 return AV_ERR_OK;
192 }
193
OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability * capability,int32_t profile,int32_t level)194 bool OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability *capability, int32_t profile, int32_t level)
195 {
196 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
197 false, "Invalid parameter");
198 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
199 const auto &profileLevelsMap = codecInfo->GetSupportedLevelsForProfile();
200 const auto &levels = profileLevelsMap.find(profile);
201 if (levels == profileLevelsMap.end()) {
202 return false;
203 }
204 return find(levels->second.begin(), levels->second.end(), level) != levels->second.end();
205 }
206
OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability * capability,OH_AVRange * bitrateRange)207 OH_AVErrCode OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability *capability, OH_AVRange *bitrateRange)
208 {
209 CHECK_AND_RETURN_RET_LOG(bitrateRange != nullptr, AV_ERR_INVALID_VAL,
210 "Get encoder bitrate range failed: null input");
211 bitrateRange->minVal = 0;
212 bitrateRange->maxVal = 0;
213 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
214 AV_ERR_INVALID_VAL, "Invalid parameter");
215 std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
216 const auto &bitrate = codecInfo->GetSupportedBitrate();
217 bitrateRange->minVal = bitrate.minVal;
218 bitrateRange->maxVal = bitrate.maxVal;
219 return AV_ERR_OK;
220 }
221
OH_AVCapability_GetEncoderQualityRange(OH_AVCapability * capability,OH_AVRange * qualityRange)222 OH_AVErrCode OH_AVCapability_GetEncoderQualityRange(OH_AVCapability *capability, OH_AVRange *qualityRange)
223 {
224 CHECK_AND_RETURN_RET_LOG(qualityRange != nullptr, AV_ERR_INVALID_VAL, "Get encoder quality failed: null input");
225 qualityRange->minVal = 0;
226 qualityRange->maxVal = 0;
227 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
228 AV_ERR_INVALID_VAL, "Invalid parameter");
229 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
230 const auto &quality = codecInfo->GetSupportedEncodeQuality();
231 qualityRange->minVal = quality.minVal;
232 qualityRange->maxVal = quality.maxVal;
233 return AV_ERR_OK;
234 }
235
OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability * capability,OH_AVRange * complexityRange)236 OH_AVErrCode OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability *capability, OH_AVRange *complexityRange)
237 {
238 CHECK_AND_RETURN_RET_LOG(complexityRange != nullptr, AV_ERR_INVALID_VAL,
239 "Get encoder complexity range failed: null input");
240 complexityRange->minVal = 0;
241 complexityRange->maxVal = 0;
242 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
243 AV_ERR_INVALID_VAL, "Invalid parameter");
244 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
245 const auto &complexity = codecInfo->GetSupportedComplexity();
246 complexityRange->minVal = complexity.minVal;
247 complexityRange->maxVal = complexity.maxVal;
248 return AV_ERR_OK;
249 }
250
OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability * capability,OH_BitrateMode bitrateMode)251 bool OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability *capability, OH_BitrateMode bitrateMode)
252 {
253 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
254 false, "Invalid parameter");
255 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
256 const auto &bitrateModeVec = codecInfo->GetSupportedBitrateMode();
257 return find(bitrateModeVec.begin(), bitrateModeVec.end(), bitrateMode) != bitrateModeVec.end();
258 }
259
OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability * capability,const int32_t ** sampleRates,uint32_t * sampleRateNum)260 OH_AVErrCode OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability *capability, const int32_t **sampleRates,
261 uint32_t *sampleRateNum)
262 {
263 CHECK_AND_RETURN_RET_LOG(sampleRates != nullptr && sampleRateNum != nullptr, AV_ERR_INVALID_VAL,
264 "Get audio supported samplerates failed: null input");
265 *sampleRates = nullptr;
266 *sampleRateNum = 0;
267 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
268 AV_ERR_INVALID_VAL, "Invalid parameter");
269 std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
270 const auto &vec = codecInfo->GetSupportedSampleRates();
271 if (vec.size() == 0) {
272 return AV_ERR_OK;
273 }
274
275 std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
276 CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
277 "Get audio supported samplerates failed: CreateAVCodecList failed");
278 if (capability->sampleRates_ != nullptr) {
279 codeclist->DeleteBuffer(capability->sampleRates_);
280 capability->sampleRates_ = nullptr;
281 }
282
283 size_t vecSize = vec.size() * sizeof(int32_t);
284 capability->sampleRates_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
285 CHECK_AND_RETURN_RET_LOG(capability->sampleRates_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
286 errno_t ret = memcpy_s(capability->sampleRates_, vecSize, vec.data(), vecSize);
287 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
288
289 *sampleRates = capability->sampleRates_;
290 *sampleRateNum = vec.size();
291 return AV_ERR_OK;
292 }
293
OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability * capability,OH_AVRange * channelCountRange)294 OH_AVErrCode OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability *capability, OH_AVRange *channelCountRange)
295 {
296 CHECK_AND_RETURN_RET_LOG(channelCountRange != nullptr, AV_ERR_INVALID_VAL,
297 "Get audio channel count range failed: null input");
298 channelCountRange->minVal = 0;
299 channelCountRange->maxVal = 0;
300 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
301 AV_ERR_INVALID_VAL, "Invalid parameter");
302 std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capability->capabilityData_);
303 const auto &channels = codecInfo->GetSupportedChannel();
304 channelCountRange->minVal = channels.minVal;
305 channelCountRange->maxVal = channels.maxVal;
306 return AV_ERR_OK;
307 }
308
OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability * capability,const int32_t ** pixFormats,uint32_t * pixFormatNum)309 OH_AVErrCode OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability *capability, const int32_t **pixFormats,
310 uint32_t *pixFormatNum)
311 {
312 CHECK_AND_RETURN_RET_LOG(pixFormats != nullptr && pixFormatNum != nullptr, AV_ERR_INVALID_VAL,
313 "Get video supported pixel formats failed: null input");
314 *pixFormats = nullptr;
315 *pixFormatNum = 0;
316 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
317 AV_ERR_INVALID_VAL, "Invalid parameter");
318 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
319 const auto &vec = codecInfo->GetSupportedFormats();
320 if (vec.size() == 0) {
321 return AV_ERR_OK;
322 }
323 std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
324 CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
325 "Get video supported pixel formats failed: CreateAVCodecList failed");
326 if (capability->pixFormats_ != nullptr) {
327 codeclist->DeleteBuffer(capability->pixFormats_);
328 capability->pixFormats_ = nullptr;
329 }
330 size_t vecSize = vec.size() * sizeof(int32_t);
331 capability->pixFormats_ = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
332 CHECK_AND_RETURN_RET_LOG(capability->pixFormats_ != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
333 errno_t ret = memcpy_s(capability->pixFormats_, vecSize, vec.data(), vecSize);
334 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
335 *pixFormats = capability->pixFormats_;
336 *pixFormatNum = vec.size();
337 return AV_ERR_OK;
338 }
339
OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability * capability,int32_t * widthAlignment)340 OH_AVErrCode OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability *capability, int32_t *widthAlignment)
341 {
342 CHECK_AND_RETURN_RET_LOG(widthAlignment != nullptr, AV_ERR_INVALID_VAL,
343 "Get video width alignment failed: null input");
344 *widthAlignment = 0;
345 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
346 AV_ERR_INVALID_VAL, "Invalid parameter");
347 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
348 *widthAlignment = codecInfo->GetSupportedWidthAlignment();
349 return AV_ERR_OK;
350 }
351
OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability * capability,int32_t * heightAlignment)352 OH_AVErrCode OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability *capability, int32_t *heightAlignment)
353 {
354 CHECK_AND_RETURN_RET_LOG(heightAlignment != nullptr, AV_ERR_INVALID_VAL,
355 "Get video height alignment failed: null input");
356 *heightAlignment = 0;
357 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
358 AV_ERR_INVALID_VAL, "Invalid parameter");
359 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
360 *heightAlignment = codecInfo->GetSupportedHeightAlignment();
361 return AV_ERR_OK;
362 }
363
OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability * capability,int32_t height,OH_AVRange * widthRange)364 OH_AVErrCode OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability *capability, int32_t height,
365 OH_AVRange *widthRange)
366 {
367 CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL,
368 "Get video width range for height failed: null input");
369 widthRange->minVal = 0;
370 widthRange->maxVal = 0;
371 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
372 AV_ERR_INVALID_VAL, "Invalid parameter");
373 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
374 const auto &width = codecInfo->GetVideoWidthRangeForHeight(height);
375 widthRange->minVal = width.minVal;
376 widthRange->maxVal = width.maxVal;
377 CHECK_AND_RETURN_RET_LOG(width.minVal != 0 || width.maxVal != 0, AV_ERR_INVALID_VAL, "width range is [0, 0]");
378 AVCODEC_LOGD("Success to get width range [%{public}d, %{public}d], by height %{public}d",
379 width.minVal, width.maxVal, height);
380 return AV_ERR_OK;
381 }
382
OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability * capability,int32_t width,OH_AVRange * heightRange)383 OH_AVErrCode OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability *capability, int32_t width,
384 OH_AVRange *heightRange)
385 {
386 CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL,
387 "Get video height range for width failed: null input");
388 heightRange->minVal = 0;
389 heightRange->maxVal = 0;
390 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
391 AV_ERR_INVALID_VAL, "Invalid parameter");
392 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
393 const auto &height = codecInfo->GetVideoHeightRangeForWidth(width);
394 heightRange->minVal = height.minVal;
395 heightRange->maxVal = height.maxVal;
396 CHECK_AND_RETURN_RET_LOG(height.minVal != 0 || height.maxVal != 0, AV_ERR_INVALID_VAL, "height range is [0, 0]");
397 AVCODEC_LOGD("Success to get height range [%{public}d, %{public}d], by width %{public}d",
398 height.minVal, height.maxVal, width);
399 return AV_ERR_OK;
400 }
401
OH_AVCapability_GetVideoWidthRange(OH_AVCapability * capability,OH_AVRange * widthRange)402 OH_AVErrCode OH_AVCapability_GetVideoWidthRange(OH_AVCapability *capability, OH_AVRange *widthRange)
403 {
404 CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL, "Get video width range failed: null input");
405 widthRange->minVal = 0;
406 widthRange->maxVal = 0;
407 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
408 AV_ERR_INVALID_VAL, "Invalid parameter");
409 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
410 const auto &width = codecInfo->GetSupportedWidth();
411 widthRange->minVal = width.minVal;
412 widthRange->maxVal = width.maxVal;
413 return AV_ERR_OK;
414 }
415
OH_AVCapability_GetVideoHeightRange(OH_AVCapability * capability,OH_AVRange * heightRange)416 OH_AVErrCode OH_AVCapability_GetVideoHeightRange(OH_AVCapability *capability, OH_AVRange *heightRange)
417 {
418 CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL, "Get video height range failed: null input");
419 heightRange->minVal = 0;
420 heightRange->maxVal = 0;
421 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
422 AV_ERR_INVALID_VAL, "Invalid parameter");
423 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capability->capabilityData_);
424 const auto &height = codecInfo->GetSupportedHeight();
425 heightRange->minVal = height.minVal;
426 heightRange->maxVal = height.maxVal;
427 return AV_ERR_OK;
428 }
429
OH_AVCapability_IsVideoSizeSupported(OH_AVCapability * capability,int32_t width,int32_t height)430 bool OH_AVCapability_IsVideoSizeSupported(OH_AVCapability *capability, int32_t width, int32_t height)
431 {
432 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
433 false, "Invalid parameter");
434 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
435 return videoCap->IsSizeSupported(width, height);
436 }
437
OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability * capability,OH_AVRange * frameRateRange)438 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability *capability, OH_AVRange *frameRateRange)
439 {
440 CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
441 "Get video framerate range failed: null input");
442 frameRateRange->minVal = 0;
443 frameRateRange->maxVal = 0;
444 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
445 AV_ERR_INVALID_VAL, "Invalid parameter");
446 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
447 const auto &frameRate = videoCap->GetSupportedFrameRate();
448 frameRateRange->minVal = frameRate.minVal;
449 frameRateRange->maxVal = frameRate.maxVal;
450 return AV_ERR_OK;
451 }
452
OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability * capability,int32_t width,int32_t height,OH_AVRange * frameRateRange)453 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability *capability, int32_t width, int32_t height,
454 OH_AVRange *frameRateRange)
455 {
456 CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
457 "Get video framerate range for size failed: null input");
458 frameRateRange->minVal = 0;
459 frameRateRange->maxVal = 0;
460 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
461 AV_ERR_INVALID_VAL, "Invalid parameter");
462 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
463 const auto &frameRate = videoCap->GetSupportedFrameRatesFor(width, height);
464 frameRateRange->minVal = frameRate.minVal;
465 frameRateRange->maxVal = frameRate.maxVal;
466 CHECK_AND_RETURN_RET_LOG(frameRate.minVal != 0 || frameRate.maxVal != 0, AV_ERR_INVALID_VAL,
467 "frameRate range is [0, 0]");
468 AVCODEC_LOGD("Success to get frameRate range [%{public}d, %{public}d], by width %{public}d and height %{public}d",
469 frameRate.minVal, frameRate.maxVal, width, height);
470 return AV_ERR_OK;
471 }
472
OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability * capability,int32_t width,int32_t height,int32_t frameRate)473 bool OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability *capability, int32_t width, int32_t height,
474 int32_t frameRate)
475 {
476 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
477 false, "Invalid parameter");
478 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capability->capabilityData_);
479 return videoCap->IsSizeAndRateSupported(width, height, frameRate);
480 }
481
OH_AVCapability_IsFeatureSupported(OH_AVCapability * capability,OH_AVCapabilityFeature feature)482 bool OH_AVCapability_IsFeatureSupported(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
483 {
484 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
485 false, "Invalid parameter");
486 bool isValid = feature >= VIDEO_ENCODER_TEMPORAL_SCALABILITY && feature <= VIDEO_LOW_LATENCY;
487 CHECK_AND_RETURN_RET_LOG(isValid, false, "Varified feature failed: feature %{public}d is invalid", feature);
488 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
489 return codecInfo->IsFeatureSupported(static_cast<AVCapabilityFeature>(feature));
490 }
491
OH_AVCapability_GetFeatureProperties(OH_AVCapability * capability,OH_AVCapabilityFeature feature)492 OH_AVFormat *OH_AVCapability_GetFeatureProperties(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
493 {
494 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
495 nullptr, "Invalid parameter");
496 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
497 Format format;
498 if (codecInfo->GetFeatureProperties(static_cast<AVCapabilityFeature>(feature), format) != AVCS_ERR_OK) {
499 return nullptr;
500 }
501 Format::FormatDataMap formatMap = format.GetFormatMap();
502 if (formatMap.size() == 0) {
503 AVCODEC_LOGW("Get feature properties successfully, but feature %{public}d does not have a property", feature);
504 return nullptr;
505 }
506 OH_AVFormat *avFormat = OH_AVFormat_Create();
507 CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Get feature properties failed: create OH_AVFormat failed");
508 avFormat->format_ = format;
509 return avFormat;
510 }