1 /*
2 * Copyright (C) 2021 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 <cmath>
17 #include "avcodec_log.h"
18 #include "avcodec_errors.h"
19 #include "avcodec_info.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecInfo"};
23 constexpr int32_t FRAME_RATE_30 = 30;
24 constexpr int32_t BLOCK_SIZE_MIN = 2;
25 constexpr int32_t BASE_BLOCK_PER_FRAME = 99;
26 constexpr int32_t BASE_BLOCK_PER_SECOND = 1485;
27 } // namespace
28 namespace OHOS {
29 namespace MediaAVCodec {
30 const std::map<int32_t, LevelParams> AVC_PARAMS_MAP = {
31 {AVC_LEVEL_1, LevelParams(1485, 99)}, {AVC_LEVEL_1b, LevelParams(1485, 99)},
32 {AVC_LEVEL_11, LevelParams(3000, 396)}, {AVC_LEVEL_12, LevelParams(6000, 396)},
33 {AVC_LEVEL_13, LevelParams(11880, 396)}, {AVC_LEVEL_2, LevelParams(11880, 396)},
34 {AVC_LEVEL_21, LevelParams(19800, 792)}, {AVC_LEVEL_22, LevelParams(20250, 1620)},
35 {AVC_LEVEL_3, LevelParams(40500, 1620)}, {AVC_LEVEL_31, LevelParams(108000, 3600)},
36 {AVC_LEVEL_32, LevelParams(216000, 5120)}, {AVC_LEVEL_4, LevelParams(245760, 8192)},
37 {AVC_LEVEL_41, LevelParams(245760, 8192)}, {AVC_LEVEL_42, LevelParams(522240, 8704)},
38 {AVC_LEVEL_5, LevelParams(589824, 22080)}, {AVC_LEVEL_51, LevelParams(983040, 36864)},
39 };
40
41 const std::map<int32_t, LevelParams> MPEG2_SIMPLE_PARAMS_MAP = {
42 {MPEG2_LEVEL_ML, LevelParams(40500, 1620, 30, 45, 36)},
43 };
44
45 const std::map<int32_t, LevelParams> MPEG2_MAIN_PARAMS_MAP = {
46 {MPEG2_LEVEL_LL, LevelParams(11880, 396, 30, 22, 18)},
47 {MPEG2_LEVEL_ML, LevelParams(40500, 1620, 30, 45, 36)},
48 {MPEG2_LEVEL_H14, LevelParams(183600, 6120, 60, 90, 68)},
49 {MPEG2_LEVEL_HL, LevelParams(244800, 8160, 60, 120, 68)},
50 };
51
52 const std::map<int32_t, LevelParams> MPEG4_ADVANCED_SIMPLE_PARAMS_MAP = {
53 {MPEG4_LEVEL_0, LevelParams(2970, 99, 30, 11, 9)}, {MPEG4_LEVEL_1, LevelParams(2970, 99, 30, 11, 9)},
54 {MPEG4_LEVEL_2, LevelParams(5940, 396, 30, 22, 18)}, {MPEG4_LEVEL_3, LevelParams(11880, 396, 30, 22, 18)},
55 {MPEG4_LEVEL_4, LevelParams(23760, 1200, 30, 44, 36)}, {MPEG4_LEVEL_5, LevelParams(48600, 1620, 30, 45, 36)},
56 };
57
58 const std::map<int32_t, LevelParams> MPEG4_SIMPLE_PARAMS_MAP = {
59 {MPEG4_LEVEL_0, LevelParams(1485, 99, 15, 11, 9)}, {MPEG4_LEVEL_0B, LevelParams(1485, 99, 15, 11, 9)},
60 {MPEG4_LEVEL_1, LevelParams(1485, 99, 30, 11, 9)}, {MPEG4_LEVEL_2, LevelParams(5940, 396, 30, 22, 18)},
61 {MPEG4_LEVEL_3, LevelParams(11880, 396, 30, 22, 18)}, {MPEG4_LEVEL_4A, LevelParams(36000, 1200, 30, 40, 30)},
62 {MPEG4_LEVEL_5, LevelParams(40500, 1620, 30, 40, 36)},
63 };
64
VideoCaps(CapabilityData * capabilityData)65 VideoCaps::VideoCaps(CapabilityData *capabilityData) : data_(capabilityData)
66 {
67 InitParams();
68 LoadLevelParams();
69 AVCODEC_LOGD("VideoCaps:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
70 }
71
~VideoCaps()72 VideoCaps::~VideoCaps()
73 {
74 AVCODEC_LOGD("VideoCaps:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
75 }
76
GetCodecInfo()77 std::shared_ptr<AVCodecInfo> VideoCaps::GetCodecInfo()
78 {
79 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(data_);
80 CHECK_AND_RETURN_RET_LOG(codecInfo != nullptr, nullptr, "create codecInfo failed");
81
82 return codecInfo;
83 }
84
GetSupportedBitrate()85 Range VideoCaps::GetSupportedBitrate()
86 {
87 return data_->bitrate;
88 }
89
GetSupportedFormats()90 std::vector<int32_t> VideoCaps::GetSupportedFormats()
91 {
92 std::vector<int32_t> pixFormat = data_->pixFormat;
93 CHECK_AND_RETURN_RET_LOG(pixFormat.size() != 0, pixFormat, "GetSupportedFormats failed: format is null");
94 return pixFormat;
95 }
96
GetSupportedHeightAlignment()97 int32_t VideoCaps::GetSupportedHeightAlignment()
98 {
99 return data_->alignment.height;
100 }
101
GetSupportedWidthAlignment()102 int32_t VideoCaps::GetSupportedWidthAlignment()
103 {
104 return data_->alignment.width;
105 }
106
GetSupportedWidth()107 Range VideoCaps::GetSupportedWidth()
108 {
109 return data_->width;
110 }
111
GetSupportedHeight()112 Range VideoCaps::GetSupportedHeight()
113 {
114 return data_->height;
115 }
116
GetSupportedProfiles()117 std::vector<int32_t> VideoCaps::GetSupportedProfiles()
118 {
119 std::vector<int32_t> profiles = data_->profiles;
120 CHECK_AND_RETURN_RET_LOG(profiles.size() != 0, profiles, "GetSupportedProfiles failed: profiles is null");
121 return profiles;
122 }
123
GetSupportedLevels()124 std::vector<int32_t> VideoCaps::GetSupportedLevels()
125 {
126 std::vector<int32_t> levels;
127 return levels;
128 }
129
GetSupportedEncodeQuality()130 Range VideoCaps::GetSupportedEncodeQuality()
131 {
132 return data_->encodeQuality;
133 }
134
IsSizeSupported(int32_t width,int32_t height)135 bool VideoCaps::IsSizeSupported(int32_t width, int32_t height)
136 {
137 UpdateParams();
138 if (width <= 0 || height <= 0) {
139 return false;
140 }
141 if (data_->alignment.width == 0 || data_->alignment.height == 0 || width % data_->alignment.width != 0 ||
142 height % data_->alignment.height != 0) {
143 return false;
144 }
145 if (data_->width.minVal > width || data_->width.maxVal < width || data_->height.minVal > height ||
146 data_->height.maxVal < height) {
147 return false;
148 }
149 if (blockWidth_ != 0 && blockHeight_ != 0) {
150 int64_t blockPerFrame =
151 static_cast<int64_t>(DivCeil(width, blockWidth_)) * static_cast<int64_t>(DivCeil(height, blockHeight_));
152 if (blockPerFrame < blockPerFrameRange_.minVal || blockPerFrame > blockPerFrameRange_.maxVal) {
153 return false;
154 }
155 }
156 return true;
157 }
158
GetVideoWidthRangeForHeight(int32_t height)159 Range VideoCaps::GetVideoWidthRangeForHeight(int32_t height)
160 {
161 if (height < data_->height.minVal || height > data_->height.maxVal) {
162 return Range(0, 0);
163 }
164 UpdateParams();
165 Range ret = data_->width;
166 if (blockWidth_ != 0 && blockHeight_ != 0) {
167 int64_t verticalBlockNum = static_cast<int64_t>(DivCeil(height, blockHeight_));
168 if (verticalBlockNum < verticalBlockRange_.minVal || verticalBlockNum > verticalBlockRange_.maxVal) {
169 return Range(0, 0);
170 }
171 Range horizontalBlockNum = horizontalBlockRange_.Intersect(
172 Range(blockPerFrameRange_.minVal / verticalBlockNum, blockPerFrameRange_.maxVal / verticalBlockNum));
173 ret = ret.Intersect(Range(horizontalBlockNum.minVal * blockWidth_, horizontalBlockNum.maxVal * blockWidth_));
174 }
175 return ret;
176 }
177
GetVideoHeightRangeForWidth(int32_t width)178 Range VideoCaps::GetVideoHeightRangeForWidth(int32_t width)
179 {
180 if (width < data_->width.minVal || width > data_->width.maxVal) {
181 return Range(0, 0);
182 }
183 UpdateParams();
184 Range ret = data_->height;
185 if (blockWidth_ != 0 && blockHeight_ != 0) {
186 int64_t horizontalBlockNum = static_cast<int64_t>(DivCeil(width, blockWidth_));
187 if (horizontalBlockNum < horizontalBlockRange_.minVal || horizontalBlockNum > horizontalBlockRange_.maxVal) {
188 return Range(0, 0);
189 }
190 Range verticalBlockNum = verticalBlockRange_.Intersect(
191 Range(blockPerFrameRange_.minVal / horizontalBlockNum, blockPerFrameRange_.maxVal / horizontalBlockNum));
192 ret = ret.Intersect(Range(verticalBlockNum.minVal * blockHeight_, verticalBlockNum.maxVal * blockHeight_));
193 }
194 return ret;
195 }
196
GetSupportedFrameRate()197 Range VideoCaps::GetSupportedFrameRate()
198 {
199 return data_->frameRate;
200 }
201
GetSupportedFrameRatesFor(int32_t width,int32_t height)202 Range VideoCaps::GetSupportedFrameRatesFor(int32_t width, int32_t height)
203 {
204 if (!IsSizeSupported(width, height)) {
205 AVCODEC_LOGD("The %{public}s can not support of:%{public}d * %{public}d", data_->codecName.c_str(), width,
206 height);
207 return Range(0, 0);
208 }
209 Range frameRatesRange;
210 int64_t blockPerFrame = DivCeil(width, blockWidth_) * static_cast<int64_t>(DivCeil(height, blockHeight_));
211 if (blockPerFrame != 0) {
212 frameRatesRange =
213 Range(std::max(static_cast<int32_t>(blockPerSecondRange_.minVal / blockPerFrame), frameRateRange_.minVal),
214 std::min(static_cast<int32_t>(blockPerSecondRange_.maxVal / blockPerFrame), frameRateRange_.maxVal));
215 }
216 if (frameRatesRange.minVal > frameRatesRange.maxVal) {
217 return Range(0, 0);
218 }
219 return frameRatesRange;
220 }
221
LoadLevelParams()222 void VideoCaps::LoadLevelParams()
223 {
224 if (this->GetCodecInfo()->IsSoftwareOnly()) {
225 return;
226 }
227 if (data_->mimeType == CodecMimeType::VIDEO_AVC) {
228 LoadAVCLevelParams();
229 } else {
230 LoadMPEGLevelParams(data_->mimeType);
231 }
232 }
233
LoadAVCLevelParams()234 void VideoCaps::LoadAVCLevelParams()
235 {
236 int32_t maxBlockPerFrame = BASE_BLOCK_PER_FRAME;
237 int32_t maxBlockPerSecond = BASE_BLOCK_PER_SECOND;
238 for (auto iter = data_->profileLevelsMap.begin(); iter != data_->profileLevelsMap.end(); iter++) {
239 for (auto levelIter = iter->second.begin(); levelIter != iter->second.end(); levelIter++) {
240 if (AVC_PARAMS_MAP.find(*levelIter) != AVC_PARAMS_MAP.end()) {
241 maxBlockPerFrame = std::max(maxBlockPerFrame, AVC_PARAMS_MAP.at(*levelIter).maxBlockPerFrame);
242 maxBlockPerSecond = std::max(maxBlockPerSecond, AVC_PARAMS_MAP.at(*levelIter).maxBlockPerSecond);
243 }
244 }
245 }
246 Range blockPerFrameRange = Range(1, maxBlockPerFrame);
247 Range blockPerSecondRange = Range(1, maxBlockPerSecond);
248 UpdateBlockParams(16, 16, blockPerFrameRange, blockPerSecondRange); // set AVC block size as 16x16
249 }
250
LoadMPEGLevelParams(const std::string & mime)251 void VideoCaps::LoadMPEGLevelParams(const std::string &mime)
252 {
253 std::map<int32_t, LevelParams> PARAMS_MAP;
254 bool isMpeg2 = false;
255 if (mime == CodecMimeType::VIDEO_MPEG2) {
256 isMpeg2 = true;
257 } else if (mime != CodecMimeType::VIDEO_MPEG4) {
258 return;
259 }
260 int32_t firstSample = isMpeg2 ? MPEG2_PROFILE_SIMPLE : MPEG4_PROFILE_SIMPLE;
261 int32_t secondSample = isMpeg2 ? MPEG2_PROFILE_MAIN : MPEG4_PROFILE_ADVANCED_SIMPLE;
262 int32_t maxBlockPerFrame = BASE_BLOCK_PER_FRAME;
263 int32_t maxBlockPerSecond = BASE_BLOCK_PER_SECOND;
264 int32_t maxFrameRate = 0;
265 int32_t maxWidth = 0;
266 int32_t maxHeight = 0;
267 for (auto iter = data_->profileLevelsMap.begin(); iter != data_->profileLevelsMap.end(); iter++) {
268 if (iter->first == firstSample) {
269 PARAMS_MAP = isMpeg2 ? MPEG2_SIMPLE_PARAMS_MAP : MPEG4_SIMPLE_PARAMS_MAP;
270 } else if (iter->first == secondSample) {
271 PARAMS_MAP = isMpeg2 ? MPEG2_MAIN_PARAMS_MAP : MPEG4_ADVANCED_SIMPLE_PARAMS_MAP;
272 } else {
273 continue;
274 }
275 for (auto levelIter = iter->second.begin(); levelIter != iter->second.end(); levelIter++) {
276 if (PARAMS_MAP.find(*levelIter) != PARAMS_MAP.end()) {
277 maxBlockPerFrame = std::max(maxBlockPerFrame, PARAMS_MAP.at(*levelIter).maxBlockPerFrame);
278 maxBlockPerSecond = std::max(maxBlockPerSecond, PARAMS_MAP.at(*levelIter).maxBlockPerSecond);
279 maxFrameRate = std::max(maxFrameRate, PARAMS_MAP.at(*levelIter).maxFrameRate);
280 maxWidth = std::max(maxWidth, PARAMS_MAP.at(*levelIter).maxWidth);
281 maxHeight = std::max(maxHeight, PARAMS_MAP.at(*levelIter).maxHeight);
282 }
283 }
284 }
285
286 frameRateRange_ = frameRateRange_.Intersect(Range(1, maxFrameRate));
287 Range blockPerFrameRange = Range(1, maxBlockPerFrame);
288 Range blockPerSecondRange = Range(1, maxBlockPerSecond);
289 UpdateBlockParams(maxWidth, maxHeight, blockPerFrameRange, blockPerSecondRange);
290 }
291
UpdateBlockParams(const int32_t & blockWidth,const int32_t & blockHeight,Range & blockPerFrameRange,Range & blockPerSecondRange)292 void VideoCaps::UpdateBlockParams(const int32_t &blockWidth, const int32_t &blockHeight, Range &blockPerFrameRange,
293 Range &blockPerSecondRange)
294 {
295 int32_t factor;
296 if (blockWidth > blockWidth_ && blockHeight > blockHeight_) {
297 if (blockWidth_ == 0 || blockHeight_ == 0) {
298 return;
299 }
300 factor = blockWidth * blockHeight / blockWidth_ / blockHeight_;
301 blockPerFrameRange_ = DivRange(blockPerFrameRange_, factor);
302 blockPerSecondRange_ = DivRange(blockPerSecondRange_, factor);
303 horizontalBlockRange_ = DivRange(horizontalBlockRange_, blockWidth / blockWidth_);
304 verticalBlockRange_ = DivRange(verticalBlockRange_, blockHeight / blockHeight_);
305 } else if (blockWidth < blockWidth_ && blockHeight < blockHeight_) {
306 if (blockWidth == 0 || blockHeight == 0) {
307 return;
308 }
309 factor = blockWidth_ * blockHeight_ / blockWidth / blockHeight;
310 blockPerFrameRange = DivRange(blockPerFrameRange, factor);
311 blockPerSecondRange = DivRange(blockPerSecondRange, factor);
312 }
313
314 blockWidth_ = std::max(blockWidth_, blockWidth);
315 blockHeight_ = std::max(blockHeight_, blockHeight);
316 blockPerFrameRange_ = blockPerFrameRange_.Intersect(blockPerFrameRange);
317 blockPerSecondRange_ = blockPerSecondRange_.Intersect(blockPerSecondRange);
318 }
319
InitParams()320 void VideoCaps::InitParams()
321 {
322 if (data_->blockPerSecond.minVal == 0 || data_->blockPerSecond.maxVal == 0) {
323 data_->blockPerSecond = Range(1, INT32_MAX);
324 }
325 if (data_->blockPerFrame.minVal == 0 || data_->blockPerFrame.maxVal == 0) {
326 data_->blockPerFrame = Range(1, INT32_MAX);
327 }
328 if (data_->width.minVal == 0 || data_->width.maxVal == 0) {
329 data_->width = Range(1, INT32_MAX);
330 }
331 if (data_->height.minVal == 0 || data_->height.maxVal == 0) {
332 data_->height = Range(1, INT32_MAX);
333 }
334 if (data_->frameRate.maxVal == 0) {
335 data_->frameRate = Range(0, FRAME_RATE_30);
336 }
337 if (data_->blockSize.width == 0 || data_->blockSize.height == 0) {
338 data_->blockSize.width = BLOCK_SIZE_MIN;
339 data_->blockSize.height = BLOCK_SIZE_MIN;
340 }
341
342 blockWidth_ = data_->blockSize.width;
343 blockHeight_ = data_->blockSize.height;
344 frameRateRange_ = data_->frameRate;
345 horizontalBlockRange_ = Range(1, INT32_MAX);
346 verticalBlockRange_ = Range(1, INT32_MAX);
347 blockPerFrameRange_ = Range(1, INT32_MAX);
348 blockPerSecondRange_ = Range(1, INT32_MAX);
349 widthRange_ = Range(1, INT32_MAX);
350 heightRange_ = Range(1, INT32_MAX);
351 }
352
UpdateParams()353 void VideoCaps::UpdateParams()
354 {
355 if (data_->blockSize.width == 0 || data_->blockSize.height == 0 || blockWidth_ == 0 || blockHeight_ == 0 ||
356 verticalBlockRange_.maxVal == 0 || verticalBlockRange_.minVal == 0 || horizontalBlockRange_.maxVal == 0 ||
357 horizontalBlockRange_.minVal == 0 || blockPerFrameRange_.minVal == 0 || blockPerFrameRange_.maxVal == 0) {
358 AVCODEC_LOGE("Invalid param");
359 return;
360 }
361
362 int32_t factor = (blockWidth_ * blockHeight_) / (data_->blockSize.width * data_->blockSize.height);
363
364 blockPerFrameRange_ = blockPerFrameRange_.Intersect(DivRange(data_->blockPerFrame, factor));
365 blockPerSecondRange_ = blockPerSecondRange_.Intersect(DivRange(data_->blockPerSecond, factor));
366 horizontalBlockRange_ = horizontalBlockRange_.Intersect(
367 Range(data_->width.minVal / blockWidth_, DivCeil(data_->width.maxVal, blockWidth_)));
368 if (verticalBlockRange_.maxVal != 0 && verticalBlockRange_.minVal != 0) {
369 horizontalBlockRange_ =
370 horizontalBlockRange_.Intersect(Range(blockPerFrameRange_.minVal / verticalBlockRange_.maxVal,
371 blockPerFrameRange_.maxVal / verticalBlockRange_.minVal));
372 }
373 verticalBlockRange_ = verticalBlockRange_.Intersect(
374 Range(data_->height.minVal / blockHeight_, DivCeil(data_->height.maxVal, blockHeight_)));
375 if (horizontalBlockRange_.maxVal != 0 && horizontalBlockRange_.minVal != 0) {
376 verticalBlockRange_ =
377 verticalBlockRange_.Intersect(Range(blockPerFrameRange_.minVal / horizontalBlockRange_.maxVal,
378 blockPerFrameRange_.maxVal / horizontalBlockRange_.minVal));
379 }
380 blockPerFrameRange_ =
381 blockPerFrameRange_.Intersect(Range(horizontalBlockRange_.minVal * verticalBlockRange_.minVal,
382 horizontalBlockRange_.maxVal * verticalBlockRange_.maxVal));
383 blockPerSecondRange_ = blockPerSecondRange_.Intersect(blockPerFrameRange_.minVal * frameRateRange_.minVal,
384 blockPerFrameRange_.maxVal * frameRateRange_.maxVal);
385 if (blockPerFrameRange_.maxVal != 0 && blockPerFrameRange_.minVal != 0) {
386 frameRateRange_ = frameRateRange_.Intersect(blockPerSecondRange_.minVal / blockPerFrameRange_.maxVal,
387 blockPerSecondRange_.maxVal / blockPerFrameRange_.minVal);
388 }
389 }
390
DivRange(const Range & range,const int32_t & divisor)391 Range VideoCaps::DivRange(const Range &range, const int32_t &divisor)
392 {
393 if (divisor == 0) {
394 AVCODEC_LOGD("The denominator cannot be 0");
395 return range;
396 } else if (divisor == 1) {
397 return range;
398 }
399 return Range(DivCeil(range.minVal, divisor), range.maxVal / divisor);
400 }
401
DivCeil(const int32_t & dividend,const int32_t & divisor)402 int32_t VideoCaps::DivCeil(const int32_t ÷nd, const int32_t &divisor)
403 {
404 if (divisor == 0) {
405 AVCODEC_LOGE("The denominator cannot be 0");
406 return INT32_MAX;
407 }
408 return (dividend + divisor - 1) / divisor;
409 }
410
IsSizeAndRateSupported(int32_t width,int32_t height,double frameRate)411 bool VideoCaps::IsSizeAndRateSupported(int32_t width, int32_t height, double frameRate)
412 {
413 if (!IsSizeSupported(width, height)) {
414 AVCODEC_LOGD("The %{public}s can not support of:%{public}d * %{public}d", data_->codecName.c_str(), width,
415 height);
416 return false;
417 }
418 const auto &frameRateRange = GetSupportedFrameRatesFor(width, height);
419 if (frameRateRange.minVal >= frameRate || frameRate > frameRateRange.maxVal) {
420 AVCODEC_LOGD("The %{public}s can not support frameRate:%{public}lf", data_->codecName.c_str(), frameRate);
421 return false;
422 }
423 return true;
424 }
425
GetPreferredFrameRate(int32_t width,int32_t height)426 Range VideoCaps::GetPreferredFrameRate(int32_t width, int32_t height)
427 {
428 Range range;
429 if (!IsSizeSupported(width, height)) {
430 AVCODEC_LOGD("The %{public}s can not support of:%{public}d * %{public}d", data_->codecName.c_str(), width,
431 height);
432 return range;
433 }
434
435 if (data_->measuredFrameRate.size() == 0) {
436 AVCODEC_LOGD("The measuredFrameRate of %{public}s is null:", data_->codecName.c_str());
437 return range;
438 }
439 ImgSize closestSize = MatchClosestSize(ImgSize(width, height));
440 if (data_->measuredFrameRate.find(closestSize) == data_->measuredFrameRate.end()) {
441 AVCODEC_LOGD("can not match measuredFrameRate of %{public}d x %{public}d :", width, width);
442 return range;
443 }
444 int64_t targetBlockNum = DivCeil(width, blockWidth_) * static_cast<int64_t>(DivCeil(height, blockHeight_));
445 int64_t closestBlockNum =
446 DivCeil(closestSize.width, blockWidth_) * static_cast<int64_t>(DivCeil(closestSize.height, blockHeight_));
447 Range closestFrameRate = data_->measuredFrameRate.at(closestSize);
448 int64_t minTargetBlockNum = 1;
449 double factor = static_cast<double>(closestBlockNum) / std::max(targetBlockNum, minTargetBlockNum);
450 return Range(closestFrameRate.minVal * factor, closestFrameRate.maxVal * factor);
451 }
452
MatchClosestSize(const ImgSize & imgSize)453 ImgSize VideoCaps::MatchClosestSize(const ImgSize &imgSize)
454 {
455 int64_t targetBlockNum =
456 DivCeil(imgSize.width, blockWidth_) * static_cast<int64_t>(DivCeil(imgSize.height, blockHeight_));
457 int64_t minDiffBlockNum = INT32_MAX;
458
459 ImgSize closestSize;
460 for (auto iter = data_->measuredFrameRate.begin(); iter != data_->measuredFrameRate.end(); iter++) {
461 int64_t blockNum =
462 DivCeil(iter->first.width, blockWidth_) * static_cast<int64_t>(DivCeil(iter->first.height, blockHeight_));
463 int64_t diffBlockNum = abs(targetBlockNum - blockNum);
464 if (minDiffBlockNum > diffBlockNum) {
465 minDiffBlockNum = diffBlockNum;
466 closestSize = iter->first;
467 }
468 }
469 AVCODEC_LOGD("%{public}s: The ClosestSize of %{public}d x %{public}d is %{public}d x %{public}d:",
470 data_->codecName.c_str(), imgSize.width, imgSize.height, closestSize.width, closestSize.height);
471 return closestSize;
472 }
473
GetSupportedBitrateMode()474 std::vector<int32_t> VideoCaps::GetSupportedBitrateMode()
475 {
476 std::vector<int32_t> bitrateMode = data_->bitrateMode;
477 CHECK_AND_RETURN_RET_LOG(bitrateMode.size() != 0, bitrateMode, "GetSupportedBitrateMode failed: get null");
478 return bitrateMode;
479 }
480
GetSupportedQuality()481 Range VideoCaps::GetSupportedQuality()
482 {
483 Range quality;
484 return quality;
485 }
486
GetSupportedComplexity()487 Range VideoCaps::GetSupportedComplexity()
488 {
489 return data_->complexity;
490 }
491
IsSupportDynamicIframe()492 bool VideoCaps::IsSupportDynamicIframe()
493 {
494 return false;
495 }
496
AudioCaps(CapabilityData * capabilityData)497 AudioCaps::AudioCaps(CapabilityData *capabilityData) : data_(capabilityData)
498 {
499 AVCODEC_LOGD("AudioCaps:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
500 }
501
~AudioCaps()502 AudioCaps::~AudioCaps()
503 {
504 AVCODEC_LOGD("AudioCaps:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
505 }
506
GetCodecInfo()507 std::shared_ptr<AVCodecInfo> AudioCaps::GetCodecInfo()
508 {
509 std::shared_ptr<AVCodecInfo> codecInfo = std::make_shared<AVCodecInfo>(data_);
510 CHECK_AND_RETURN_RET_LOG(codecInfo != nullptr, nullptr, "create codecInfo failed");
511 return codecInfo;
512 }
513
GetSupportedBitrate()514 Range AudioCaps::GetSupportedBitrate()
515 {
516 return data_->bitrate;
517 }
518
GetSupportedChannel()519 Range AudioCaps::GetSupportedChannel()
520 {
521 return data_->channels;
522 }
523
GetSupportedFormats()524 std::vector<int32_t> AudioCaps::GetSupportedFormats()
525 {
526 std::vector<int32_t> bitDepth = data_->bitDepth;
527 CHECK_AND_RETURN_RET_LOG(bitDepth.size() != 0, bitDepth, "GetSupportedFormats failed: format is null");
528 return bitDepth;
529 }
530
GetSupportedSampleRates()531 std::vector<int32_t> AudioCaps::GetSupportedSampleRates()
532 {
533 std::vector<int32_t> sampleRate = data_->sampleRate;
534 CHECK_AND_RETURN_RET_LOG(sampleRate.size() != 0, sampleRate, "GetSupportedSampleRates failed: sampleRate is null");
535 return sampleRate;
536 }
537
GetSupportedProfiles()538 std::vector<int32_t> AudioCaps::GetSupportedProfiles()
539 {
540 std::vector<int32_t> profiles = data_->profiles;
541 CHECK_AND_RETURN_RET_LOG(profiles.size() != 0, profiles, "GetSupportedProfiles failed: profiles is null");
542 return profiles;
543 }
544
GetSupportedLevels()545 std::vector<int32_t> AudioCaps::GetSupportedLevels()
546 {
547 std::vector<int32_t> empty;
548 return empty;
549 }
550
GetSupportedComplexity()551 Range AudioCaps::GetSupportedComplexity()
552 {
553 return data_->complexity;
554 }
555
AVCodecInfo(CapabilityData * capabilityData)556 AVCodecInfo::AVCodecInfo(CapabilityData *capabilityData) : data_(capabilityData)
557 {
558 AVCODEC_LOGD("AVCodecInfo:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
559 }
560
~AVCodecInfo()561 AVCodecInfo::~AVCodecInfo()
562 {
563 AVCODEC_LOGD("AVCodecInfo:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
564 }
565
GetName()566 std::string AVCodecInfo::GetName()
567 {
568 std::string name = data_->codecName;
569 CHECK_AND_RETURN_RET_LOG(name != "", "", "get codec name is null");
570 return name;
571 }
572
GetType()573 AVCodecType AVCodecInfo::GetType()
574 {
575 AVCodecType codecType = AVCodecType(data_->codecType);
576 CHECK_AND_RETURN_RET_LOG(codecType != AVCODEC_TYPE_NONE, AVCODEC_TYPE_NONE, "can not find codec type");
577 return codecType;
578 }
579
GetMimeType()580 std::string AVCodecInfo::GetMimeType()
581 {
582 std::string mimeType = data_->mimeType;
583 CHECK_AND_RETURN_RET_LOG(mimeType != "", "", "get mimeType is null");
584 return mimeType;
585 }
586
IsHardwareAccelerated()587 bool AVCodecInfo::IsHardwareAccelerated()
588 {
589 return data_->isVendor;
590 }
591
GetMaxSupportedInstances()592 int32_t AVCodecInfo::GetMaxSupportedInstances()
593 {
594 return data_->maxInstance;
595 }
596
IsSoftwareOnly()597 bool AVCodecInfo::IsSoftwareOnly()
598 {
599 return !data_->isVendor;
600 }
601
IsVendor()602 bool AVCodecInfo::IsVendor()
603 {
604 return data_->isVendor;
605 }
606
GetSupportedLevelsForProfile()607 std::map<int32_t, std::vector<int32_t>> AVCodecInfo::GetSupportedLevelsForProfile()
608 {
609 return data_->profileLevelsMap;
610 }
611 } // namespace MediaAVCodec
612 } // namespace OHOS