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