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 }