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_GetAudioChannelCountRange(OH_AVCapability * capability,OH_AVRange * channelCountRange)291 OH_AVErrCode OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability *capability, OH_AVRange *channelCountRange)
292 {
293 CHECK_AND_RETURN_RET_LOG(channelCountRange != nullptr, AV_ERR_INVALID_VAL,
294 "Get audio channel count range failed: null input");
295 channelCountRange->minVal = 0;
296 channelCountRange->maxVal = 0;
297 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
298 AV_ERR_INVALID_VAL, "Invalid parameter");
299 CapabilityData *capData = capability->capabilityData_;
300 if (!AVCodecInfo::isAudio(capData->codecType)) {
301 AVCODEC_LOGW("The capability provided is not expected, should be the audio capability");
302 }
303 std::shared_ptr<AudioCaps> codecInfo = std::make_shared<AudioCaps>(capData);
304 const auto &channels = codecInfo->GetSupportedChannel();
305 channelCountRange->minVal = channels.minVal;
306 channelCountRange->maxVal = channels.maxVal;
307 return AV_ERR_OK;
308 }
309
OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability * capability,const int32_t ** pixFormats,uint32_t * pixFormatNum)310 OH_AVErrCode OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability *capability, const int32_t **pixFormats,
311 uint32_t *pixFormatNum)
312 {
313 CHECK_AND_RETURN_RET_LOG(pixFormats != nullptr && pixFormatNum != nullptr, AV_ERR_INVALID_VAL,
314 "Get video supported pixel formats failed: null input");
315 *pixFormats = nullptr;
316 *pixFormatNum = 0;
317 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
318 AV_ERR_INVALID_VAL, "Invalid parameter");
319 CapabilityData *capData = capability->capabilityData_;
320 if (!AVCodecInfo::isVideo(capData->codecType)) {
321 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
322 }
323 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
324 const auto &vec = codecInfo->GetSupportedFormats();
325 if (vec.size() == 0) {
326 return AV_ERR_OK;
327 }
328 std::shared_ptr<AVCodecList> codeclist = AVCodecListFactory::CreateAVCodecList();
329 CHECK_AND_RETURN_RET_LOG(codeclist != nullptr, AV_ERR_UNKNOWN,
330 "Get video supported pixel formats failed: CreateAVCodecList failed");
331 size_t vecSize = vec.size() * sizeof(int32_t);
332 int32_t *buf = static_cast<int32_t *>(codeclist->NewBuffer(vecSize));
333 CHECK_AND_RETURN_RET_LOG(buf != nullptr, AV_ERR_NO_MEMORY, "new buffer failed");
334 errno_t ret = memcpy_s(buf, vecSize, vec.data(), vecSize);
335 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_UNKNOWN, "memcpy_s failed");
336 *pixFormats = buf;
337 *pixFormatNum = vec.size();
338 return AV_ERR_OK;
339 }
340
OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability * capability,int32_t * widthAlignment)341 OH_AVErrCode OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability *capability, int32_t *widthAlignment)
342 {
343 CHECK_AND_RETURN_RET_LOG(widthAlignment != nullptr, AV_ERR_INVALID_VAL,
344 "Get video width alignment failed: null input");
345 *widthAlignment = 0;
346 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
347 AV_ERR_INVALID_VAL, "Invalid parameter");
348 CapabilityData *capData = capability->capabilityData_;
349 if (!AVCodecInfo::isVideo(capData->codecType)) {
350 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
351 }
352 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
353 *widthAlignment = codecInfo->GetSupportedWidthAlignment();
354 return AV_ERR_OK;
355 }
356
OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability * capability,int32_t * heightAlignment)357 OH_AVErrCode OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability *capability, int32_t *heightAlignment)
358 {
359 CHECK_AND_RETURN_RET_LOG(heightAlignment != nullptr, AV_ERR_INVALID_VAL,
360 "Get video height alignment failed: null input");
361 *heightAlignment = 0;
362 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
363 AV_ERR_INVALID_VAL, "Invalid parameter");
364 CapabilityData *capData = capability->capabilityData_;
365 if (!AVCodecInfo::isVideo(capData->codecType)) {
366 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
367 }
368 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
369 *heightAlignment = codecInfo->GetSupportedHeightAlignment();
370 return AV_ERR_OK;
371 }
372
OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability * capability,int32_t height,OH_AVRange * widthRange)373 OH_AVErrCode OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability *capability, int32_t height,
374 OH_AVRange *widthRange)
375 {
376 CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL,
377 "Get video width range for height failed: null input");
378 widthRange->minVal = 0;
379 widthRange->maxVal = 0;
380 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
381 AV_ERR_INVALID_VAL, "Invalid parameter");
382 CapabilityData *capData = capability->capabilityData_;
383 if (!AVCodecInfo::isVideo(capData->codecType)) {
384 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
385 }
386 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
387 const auto &width = codecInfo->GetVideoWidthRangeForHeight(height);
388 widthRange->minVal = width.minVal;
389 widthRange->maxVal = width.maxVal;
390 CHECK_AND_RETURN_RET_LOG(width.minVal != 0 || width.maxVal != 0, AV_ERR_INVALID_VAL, "width range is [0, 0]");
391 AVCODEC_LOGD("Success to get width range [%{public}d, %{public}d], by height %{public}d",
392 width.minVal, width.maxVal, height);
393 return AV_ERR_OK;
394 }
395
OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability * capability,int32_t width,OH_AVRange * heightRange)396 OH_AVErrCode OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability *capability, int32_t width,
397 OH_AVRange *heightRange)
398 {
399 CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL,
400 "Get video height range for width failed: null input");
401 heightRange->minVal = 0;
402 heightRange->maxVal = 0;
403 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
404 AV_ERR_INVALID_VAL, "Invalid parameter");
405 CapabilityData *capData = capability->capabilityData_;
406 if (!AVCodecInfo::isVideo(capData->codecType)) {
407 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
408 }
409 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
410 const auto &height = codecInfo->GetVideoHeightRangeForWidth(width);
411 heightRange->minVal = height.minVal;
412 heightRange->maxVal = height.maxVal;
413 CHECK_AND_RETURN_RET_LOG(height.minVal != 0 || height.maxVal != 0, AV_ERR_INVALID_VAL, "height range is [0, 0]");
414 AVCODEC_LOGD("Success to get height range [%{public}d, %{public}d], by width %{public}d",
415 height.minVal, height.maxVal, width);
416 return AV_ERR_OK;
417 }
418
OH_AVCapability_GetVideoWidthRange(OH_AVCapability * capability,OH_AVRange * widthRange)419 OH_AVErrCode OH_AVCapability_GetVideoWidthRange(OH_AVCapability *capability, OH_AVRange *widthRange)
420 {
421 CHECK_AND_RETURN_RET_LOG(widthRange != nullptr, AV_ERR_INVALID_VAL, "Get video width range failed: null input");
422 widthRange->minVal = 0;
423 widthRange->maxVal = 0;
424 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
425 AV_ERR_INVALID_VAL, "Invalid parameter");
426 CapabilityData *capData = capability->capabilityData_;
427 if (!AVCodecInfo::isVideo(capData->codecType)) {
428 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
429 }
430 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
431 const auto &width = codecInfo->GetSupportedWidth();
432 widthRange->minVal = width.minVal;
433 widthRange->maxVal = width.maxVal;
434 return AV_ERR_OK;
435 }
436
OH_AVCapability_GetVideoHeightRange(OH_AVCapability * capability,OH_AVRange * heightRange)437 OH_AVErrCode OH_AVCapability_GetVideoHeightRange(OH_AVCapability *capability, OH_AVRange *heightRange)
438 {
439 CHECK_AND_RETURN_RET_LOG(heightRange != nullptr, AV_ERR_INVALID_VAL, "Get video height range failed: null input");
440 heightRange->minVal = 0;
441 heightRange->maxVal = 0;
442 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
443 AV_ERR_INVALID_VAL, "Invalid parameter");
444 CapabilityData *capData = capability->capabilityData_;
445 if (!AVCodecInfo::isVideo(capData->codecType)) {
446 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
447 }
448 std::shared_ptr<VideoCaps> codecInfo = std::make_shared<VideoCaps>(capData);
449 const auto &height = codecInfo->GetSupportedHeight();
450 heightRange->minVal = height.minVal;
451 heightRange->maxVal = height.maxVal;
452 return AV_ERR_OK;
453 }
454
OH_AVCapability_IsVideoSizeSupported(OH_AVCapability * capability,int32_t width,int32_t height)455 bool OH_AVCapability_IsVideoSizeSupported(OH_AVCapability *capability, int32_t width, int32_t height)
456 {
457 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
458 false, "Invalid parameter");
459 CapabilityData *capData = capability->capabilityData_;
460 if (!AVCodecInfo::isVideo(capData->codecType)) {
461 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
462 }
463 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
464 return videoCap->IsSizeSupported(width, height);
465 }
466
OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability * capability,OH_AVRange * frameRateRange)467 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability *capability, OH_AVRange *frameRateRange)
468 {
469 CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
470 "Get video framerate range failed: null input");
471 frameRateRange->minVal = 0;
472 frameRateRange->maxVal = 0;
473 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
474 AV_ERR_INVALID_VAL, "Invalid parameter");
475 CapabilityData *capData = capability->capabilityData_;
476 if (!AVCodecInfo::isVideo(capData->codecType)) {
477 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
478 }
479 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
480 const auto &frameRate = videoCap->GetSupportedFrameRate();
481 frameRateRange->minVal = frameRate.minVal;
482 frameRateRange->maxVal = frameRate.maxVal;
483 return AV_ERR_OK;
484 }
485
OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability * capability,int32_t width,int32_t height,OH_AVRange * frameRateRange)486 OH_AVErrCode OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability *capability, int32_t width, int32_t height,
487 OH_AVRange *frameRateRange)
488 {
489 CHECK_AND_RETURN_RET_LOG(frameRateRange != nullptr, AV_ERR_INVALID_VAL,
490 "Get video framerate range for size failed: null input");
491 frameRateRange->minVal = 0;
492 frameRateRange->maxVal = 0;
493 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
494 AV_ERR_INVALID_VAL, "Invalid parameter");
495 CapabilityData *capData = capability->capabilityData_;
496 if (!AVCodecInfo::isVideo(capData->codecType)) {
497 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
498 }
499 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
500 const auto &frameRate = videoCap->GetSupportedFrameRatesFor(width, height);
501 frameRateRange->minVal = frameRate.minVal;
502 frameRateRange->maxVal = frameRate.maxVal;
503 CHECK_AND_RETURN_RET_LOG(frameRate.minVal != 0 || frameRate.maxVal != 0, AV_ERR_INVALID_VAL,
504 "frameRate range is [0, 0]");
505 AVCODEC_LOGD("Success to get frameRate range [%{public}d, %{public}d], by width %{public}d and height %{public}d",
506 frameRate.minVal, frameRate.maxVal, width, height);
507 return AV_ERR_OK;
508 }
509
OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability * capability,int32_t width,int32_t height,int32_t frameRate)510 bool OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability *capability, int32_t width, int32_t height,
511 int32_t frameRate)
512 {
513 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
514 false, "Invalid parameter");
515 CapabilityData *capData = capability->capabilityData_;
516 if (!AVCodecInfo::isVideo(capData->codecType)) {
517 AVCODEC_LOGW("The capability provided is not expected, should be the video capability");
518 }
519 std::shared_ptr<VideoCaps> videoCap = std::make_shared<VideoCaps>(capData);
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 && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
526 false, "Invalid parameter");
527 bool isValid = feature >= VIDEO_ENCODER_TEMPORAL_SCALABILITY && feature <= VIDEO_LOW_LATENCY;
528 CHECK_AND_RETURN_RET_LOG(isValid, false, "Varified feature failed: feature %{public}d is invalid", feature);
529 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
530 return codecInfo->IsFeatureSupported(static_cast<AVCapabilityFeature>(feature));
531 }
532
OH_AVCapability_GetFeatureProperties(OH_AVCapability * capability,OH_AVCapabilityFeature feature)533 OH_AVFormat *OH_AVCapability_GetFeatureProperties(OH_AVCapability *capability, OH_AVCapabilityFeature feature)
534 {
535 CHECK_AND_RETURN_RET_LOG(capability != nullptr && capability->magic_ == AVMagic::AVCODEC_MAGIC_AVCAPABILITY,
536 nullptr, "Invalid parameter");
537 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(capability->capabilityData_);
538 Format format;
539 if (codecInfo->GetFeatureProperties(static_cast<AVCapabilityFeature>(feature), format) != AVCS_ERR_OK) {
540 return nullptr;
541 }
542 Format::FormatDataMap formatMap = format.GetFormatMap();
543 if (formatMap.size() == 0) {
544 AVCODEC_LOGW("Get feature properties successfully, but feature %{public}d does not have a property", feature);
545 return nullptr;
546 }
547 OH_AVFormat *avFormat = OH_AVFormat_Create();
548 CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Get feature properties failed: create OH_AVFormat failed");
549 avFormat->format_ = format;
550 return avFormat;
551 }