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 "avcodeclist_engine_gst_impl.h"
17 #include "avcodec_ability_singleton.h"
18 #include "media_errors.h"
19 #include "media_log.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecListEngineGstImpl"};
23 }
24
25 namespace OHOS {
26 namespace Media {
AVCodecListEngineGstImpl()27 AVCodecListEngineGstImpl::AVCodecListEngineGstImpl()
28 {
29 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
30 }
31
~AVCodecListEngineGstImpl()32 AVCodecListEngineGstImpl::~AVCodecListEngineGstImpl()
33 {
34 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
35 }
36
IsSupportMimeType(const Format & format,const CapabilityData & data)37 bool AVCodecListEngineGstImpl::IsSupportMimeType(const Format &format, const CapabilityData &data)
38 {
39 std::string targetMimeType;
40 if (!format.ContainKey("codec_mime")) {
41 MEDIA_LOGD("Get MimeType from format failed");
42 return false;
43 }
44 (void)format.GetStringValue("codec_mime", targetMimeType);
45 if (data.mimeType != targetMimeType) {
46 return false;
47 }
48 return true;
49 }
50
IsSupportBitrate(const Format & format,const CapabilityData & data)51 bool AVCodecListEngineGstImpl::IsSupportBitrate(const Format &format, const CapabilityData &data)
52 {
53 int32_t targetBitrate;
54 if (!format.ContainKey("bitrate")) {
55 MEDIA_LOGD("The bitrate of the format are not specified");
56 return true;
57 }
58 (void)format.GetIntValue("bitrate", targetBitrate);
59 if (data.bitrate.minVal > targetBitrate || data.bitrate.maxVal < targetBitrate) {
60 return false;
61 }
62 return true;
63 }
64
IsSupportSize(const Format & format,const CapabilityData & data)65 bool AVCodecListEngineGstImpl::IsSupportSize(const Format &format, const CapabilityData &data)
66 {
67 int32_t targetWidth;
68 int32_t targetHeight;
69 if ((!format.ContainKey("width")) || (!format.ContainKey("height"))) {
70 MEDIA_LOGD("The width and height of the format are not specified");
71 return true;
72 }
73 (void)format.GetIntValue("width", targetWidth);
74 (void)format.GetIntValue("height", targetHeight);
75 if (data.width.minVal > targetWidth || data.width.maxVal < targetWidth
76 || data.height.minVal > targetHeight || data.height.maxVal < targetHeight) {
77 return false;
78 }
79 return true;
80 }
81
IsSupportPixelFormat(const Format & format,const CapabilityData & data)82 bool AVCodecListEngineGstImpl::IsSupportPixelFormat(const Format &format, const CapabilityData &data)
83 {
84 if (data.codecType == AVCODEC_TYPE_AUDIO_ENCODER || data.codecType == AVCODEC_TYPE_AUDIO_DECODER) {
85 return true;
86 }
87 int32_t targetPixelFormat;
88 if (!format.ContainKey("pixel_format")) {
89 MEDIA_LOGD("The pixel_format of the format are not specified");
90 return true;
91 }
92 (void)format.GetIntValue("pixel_format", targetPixelFormat);
93 if (find(data.format.begin(), data.format.end(), targetPixelFormat) == data.format.end()) {
94 return false;
95 }
96 return true;
97 }
98
IsSupportFrameRate(const Format & format,const CapabilityData & data)99 bool AVCodecListEngineGstImpl::IsSupportFrameRate(const Format &format, const CapabilityData &data)
100 {
101 if (!format.ContainKey("frame_rate")) {
102 MEDIA_LOGD("The frame_rate of the format are not specified");
103 return true;
104 }
105
106 switch (format.GetValueType(std::string_view("frame_rate"))) {
107 case FORMAT_TYPE_INT32:
108 int32_t targetFrameRateInt;
109 (void)format.GetIntValue("frame_rate", targetFrameRateInt);
110 if (data.frameRate.minVal > targetFrameRateInt ||
111 data.frameRate.maxVal < targetFrameRateInt) {
112 return false;
113 }
114 break;
115 case FORMAT_TYPE_DOUBLE:
116 double targetFrameRateDouble;
117 (void)format.GetDoubleValue("frame_rate", targetFrameRateDouble);
118 if (static_cast<double>(data.frameRate.minVal) > targetFrameRateDouble ||
119 static_cast<double>(data.frameRate.maxVal) < targetFrameRateDouble) {
120 return false;
121 }
122 break;
123 default:
124 break;
125 }
126 return true;
127 }
128
IsSupportChannel(const Format & format,const CapabilityData & data)129 bool AVCodecListEngineGstImpl::IsSupportChannel(const Format &format, const CapabilityData &data)
130 {
131 if (data.codecType == AVCODEC_TYPE_VIDEO_ENCODER || data.codecType == AVCODEC_TYPE_VIDEO_DECODER) {
132 return true;
133 }
134 int32_t targetChannel;
135 if (!format.ContainKey("channel_count")) {
136 MEDIA_LOGD("The channel_count of the format are not specified");
137 return true;
138 }
139 (void)format.GetIntValue("channel_count", targetChannel);
140 if (data.channels.minVal > targetChannel || data.channels.maxVal < targetChannel) {
141 return false;
142 }
143 return true;
144 }
145
IsSupportSampleRate(const Format & format,const CapabilityData & data)146 bool AVCodecListEngineGstImpl::IsSupportSampleRate(const Format &format, const CapabilityData &data)
147 {
148 if (data.codecType == AVCODEC_TYPE_VIDEO_ENCODER || data.codecType == AVCODEC_TYPE_VIDEO_DECODER) {
149 return true;
150 }
151 int32_t targetSampleRate;
152 if (!format.ContainKey("samplerate")) {
153 MEDIA_LOGD("The samplerate of the format are not specified");
154 return true;
155 }
156 (void)format.GetIntValue("samplerate", targetSampleRate);
157 if (find(data.sampleRate.begin(), data.sampleRate.end(), targetSampleRate) == data.sampleRate.end()) {
158 return false;
159 }
160 return true;
161 }
162
FindTargetCodec(const Format & format,const std::vector<CapabilityData> & capabilityDataArray,const AVCodecType & codecType)163 std::string AVCodecListEngineGstImpl::FindTargetCodec(const Format &format,
164 const std::vector<CapabilityData> &capabilityDataArray, const AVCodecType &codecType)
165 {
166 for (auto iter = capabilityDataArray.begin(); iter != capabilityDataArray.end(); ++iter) {
167 if ((*iter).codecType != codecType || !IsSupportMimeType(format, *iter) ||
168 !IsSupportBitrate(format, *iter) || !IsSupportSize(format, *iter) ||
169 !IsSupportPixelFormat(format, *iter) || !IsSupportFrameRate(format, *iter) ||
170 !IsSupportSampleRate(format, *iter) || !IsSupportChannel(format, *iter)) {
171 continue;
172 }
173 return (*iter).codecName;
174 }
175 return "";
176 }
177
FindVideoDecoder(const Format & format)178 std::string AVCodecListEngineGstImpl::FindVideoDecoder(const Format &format)
179 {
180 std::vector<CapabilityData> capabilityDataArray = GetCodecCapabilityInfos();
181 return FindTargetCodec(format, capabilityDataArray, AVCODEC_TYPE_VIDEO_DECODER);
182 }
183
FindVideoEncoder(const Format & format)184 std::string AVCodecListEngineGstImpl::FindVideoEncoder(const Format &format)
185 {
186 std::vector<CapabilityData> capabilityDataArray = GetCodecCapabilityInfos();
187 return FindTargetCodec(format, capabilityDataArray, AVCODEC_TYPE_VIDEO_ENCODER);
188 }
189
FindAudioDecoder(const Format & format)190 std::string AVCodecListEngineGstImpl::FindAudioDecoder(const Format &format)
191 {
192 std::vector<CapabilityData> capabilityDataArray = GetCodecCapabilityInfos();
193 return FindTargetCodec(format, capabilityDataArray, AVCODEC_TYPE_AUDIO_DECODER);
194 }
195
FindAudioEncoder(const Format & format)196 std::string AVCodecListEngineGstImpl::FindAudioEncoder(const Format &format)
197 {
198 std::vector<CapabilityData> capabilityDataArray = GetCodecCapabilityInfos();
199 return FindTargetCodec(format, capabilityDataArray, AVCODEC_TYPE_AUDIO_ENCODER);
200 }
201
GetCodecCapabilityInfos()202 std::vector<CapabilityData> AVCodecListEngineGstImpl::GetCodecCapabilityInfos()
203 {
204 AVCodecAbilitySingleton& codecAbilityInstance = AVCodecAbilitySingleton::GetInstance();
205 if (!codecAbilityInstance.IsParsered()) {
206 bool ret = codecAbilityInstance.ParseHardwareCapability();
207 if (!ret) {
208 MEDIA_LOGD("ParseHardwareCapability failed");
209 }
210 ret = codecAbilityInstance.ParseCodecXml();
211 if (!ret) {
212 MEDIA_LOGD("ParseCodecXml failed");
213 }
214 }
215 return codecAbilityInstance.capabilityDataArray_;
216 }
217 } // namespace Media
218 } // namespace OHOS