• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &dividend, 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