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 "type_converter.h"
17 #include "hcodec_log.h"
18
19 namespace OHOS::MediaAVCodec {
20 using namespace std;
21 using namespace OHOS::HDI::Codec::V1_0;
22
23 struct Protocol {
24 OMX_VIDEO_CODINGTYPE omxCodingType;
25 OHOS::HDI::Codec::V1_0::AvCodecRole hdiRole;
26 string mime;
27 };
28 vector<Protocol> g_protocolTable = {
29 {
30 OMX_VIDEO_CodingAVC,
31 OHOS::HDI::Codec::V1_0::AvCodecRole::MEDIA_ROLETYPE_VIDEO_AVC,
32 string(CodecMimeType::VIDEO_AVC),
33 },
34 {
35 static_cast<OMX_VIDEO_CODINGTYPE>(CODEC_OMX_VIDEO_CodingHEVC),
36 OHOS::HDI::Codec::V1_0::AvCodecRole::MEDIA_ROLETYPE_VIDEO_HEVC,
37 string(CodecMimeType::VIDEO_HEVC),
38 },
39 };
40
41 vector<PixelFmt> g_pixelFmtTable = {
42 { GRAPHIC_PIXEL_FMT_YCBCR_420_P, YUVI420 },
43 { GRAPHIC_PIXEL_FMT_YCBCR_420_SP, NV12 },
44 { GRAPHIC_PIXEL_FMT_YCRCB_420_SP, NV21 },
45 { GRAPHIC_PIXEL_FMT_RGBA_8888, RGBA },
46 };
47
48 struct AVCProfileMapping {
49 OMX_VIDEO_AVCPROFILETYPE omxProfile;
50 AVCProfile innerProfile;
51 };
52 vector<AVCProfileMapping> g_avcProfileTable = {
53 { OMX_VIDEO_AVCProfileBaseline, AVC_PROFILE_BASELINE },
54 { OMX_VIDEO_AVCProfileMain, AVC_PROFILE_MAIN },
55 { OMX_VIDEO_AVCProfileExtended, AVC_PROFILE_EXTENDED },
56 { OMX_VIDEO_AVCProfileHigh, AVC_PROFILE_HIGH },
57 { OMX_VIDEO_AVCProfileHigh10, AVC_PROFILE_HIGH_10 },
58 { OMX_VIDEO_AVCProfileHigh422, AVC_PROFILE_HIGH_422 },
59 { OMX_VIDEO_AVCProfileHigh444, AVC_PROFILE_HIGH_444 },
60 };
61
62 struct AVCLevelMapping {
63 OMX_VIDEO_AVCLEVELTYPE omxLevel;
64 AVCLevel innerLevel;
65 };
66 vector<AVCLevelMapping> g_avcLevelTable = {
67 { OMX_VIDEO_AVCLevel1, AVC_LEVEL_1 },
68 { OMX_VIDEO_AVCLevel1b, AVC_LEVEL_1b },
69 { OMX_VIDEO_AVCLevel11, AVC_LEVEL_11 },
70 { OMX_VIDEO_AVCLevel12, AVC_LEVEL_12 },
71 { OMX_VIDEO_AVCLevel13, AVC_LEVEL_13 },
72 { OMX_VIDEO_AVCLevel2, AVC_LEVEL_2 },
73 { OMX_VIDEO_AVCLevel21, AVC_LEVEL_21 },
74 { OMX_VIDEO_AVCLevel22, AVC_LEVEL_22 },
75 { OMX_VIDEO_AVCLevel3, AVC_LEVEL_3 },
76 { OMX_VIDEO_AVCLevel31, AVC_LEVEL_31 },
77 { OMX_VIDEO_AVCLevel32, AVC_LEVEL_32 },
78 { OMX_VIDEO_AVCLevel4, AVC_LEVEL_4 },
79 { OMX_VIDEO_AVCLevel41, AVC_LEVEL_41 },
80 { OMX_VIDEO_AVCLevel42, AVC_LEVEL_42 },
81 { OMX_VIDEO_AVCLevel5, AVC_LEVEL_5 },
82 { OMX_VIDEO_AVCLevel51, AVC_LEVEL_51 },
83 };
84
85 struct HEVCProfileMapping {
86 CodecHevcProfile omxProfile;
87 HEVCProfile innerProfile;
88 };
89 vector<HEVCProfileMapping> g_hevcProfileTable = {
90 { CODEC_HEVC_PROFILE_MAIN, HEVC_PROFILE_MAIN },
91 { CODEC_HEVC_PROFILE_MAIN10, HEVC_PROFILE_MAIN_10 },
92 { CODEC_HEVC_PROFILE_MAIN_STILL, HEVC_PROFILE_MAIN_STILL },
93 { CODEC_HEVC_PROFILE_MAIN10_HDR10, HEVC_PROFILE_MAIN_10_HDR10 },
94 { CODEC_HEVC_PROFILE_MAIN10_HDR10_PLUS, HEVC_PROFILE_MAIN_10_HDR10_PLUS },
95 };
96
97 struct HEVCLevelMapping {
98 CodecHevcLevel omxLevel;
99 HEVCLevel innerLevel;
100 };
101 vector<HEVCLevelMapping> g_hevcLevelTable = {
102 { CODEC_HEVC_MAIN_TIER_LEVEL1, HEVC_LEVEL_1 },
103 { CODEC_HEVC_HIGH_TIER_LEVEL1, HEVC_LEVEL_1 },
104 { CODEC_HEVC_MAIN_TIER_LEVEL2, HEVC_LEVEL_2 },
105 { CODEC_HEVC_HIGH_TIER_LEVEL2, HEVC_LEVEL_2 },
106 { CODEC_HEVC_MAIN_TIER_LEVEL21, HEVC_LEVEL_21 },
107 { CODEC_HEVC_HIGH_TIER_LEVEL21, HEVC_LEVEL_21 },
108 { CODEC_HEVC_MAIN_TIER_LEVEL3, HEVC_LEVEL_3 },
109 { CODEC_HEVC_HIGH_TIER_LEVEL3, HEVC_LEVEL_3 },
110 { CODEC_HEVC_MAIN_TIER_LEVEL31, HEVC_LEVEL_31 },
111 { CODEC_HEVC_HIGH_TIER_LEVEL31, HEVC_LEVEL_31 },
112 { CODEC_HEVC_MAIN_TIER_LEVEL4, HEVC_LEVEL_4 },
113 { CODEC_HEVC_HIGH_TIER_LEVEL4, HEVC_LEVEL_4 },
114 { CODEC_HEVC_MAIN_TIER_LEVEL41, HEVC_LEVEL_41 },
115 { CODEC_HEVC_HIGH_TIER_LEVEL41, HEVC_LEVEL_41 },
116 { CODEC_HEVC_MAIN_TIER_LEVEL5, HEVC_LEVEL_5 },
117 { CODEC_HEVC_HIGH_TIER_LEVEL5, HEVC_LEVEL_5 },
118 { CODEC_HEVC_MAIN_TIER_LEVEL51, HEVC_LEVEL_51 },
119 { CODEC_HEVC_HIGH_TIER_LEVEL51, HEVC_LEVEL_51 },
120 { CODEC_HEVC_MAIN_TIER_LEVEL52, HEVC_LEVEL_52 },
121 { CODEC_HEVC_HIGH_TIER_LEVEL52, HEVC_LEVEL_52 },
122 { CODEC_HEVC_MAIN_TIER_LEVEL6, HEVC_LEVEL_6 },
123 { CODEC_HEVC_HIGH_TIER_LEVEL6, HEVC_LEVEL_6 },
124 { CODEC_HEVC_MAIN_TIER_LEVEL61, HEVC_LEVEL_61 },
125 { CODEC_HEVC_HIGH_TIER_LEVEL61, HEVC_LEVEL_61 },
126 { CODEC_HEVC_MAIN_TIER_LEVEL62, HEVC_LEVEL_62 },
127 { CODEC_HEVC_HIGH_TIER_LEVEL62, HEVC_LEVEL_62 },
128 };
129
HdiCodecTypeToInnerCodecType(OHOS::HDI::Codec::V1_0::CodecType type)130 optional<AVCodecType> TypeConverter::HdiCodecTypeToInnerCodecType(OHOS::HDI::Codec::V1_0::CodecType type)
131 {
132 static const map<CodecType, AVCodecType> table = {
133 {VIDEO_DECODER, AVCODEC_TYPE_VIDEO_DECODER},
134 {VIDEO_ENCODER, AVCODEC_TYPE_VIDEO_ENCODER}
135 };
136 auto it = table.find(type);
137 if (it == table.end()) {
138 LOGW("unknown codecType %{public}d", type);
139 return std::nullopt;
140 }
141 return it->second;
142 }
143
HdiRoleToOmxCodingType(AvCodecRole role)144 std::optional<OMX_VIDEO_CODINGTYPE> TypeConverter::HdiRoleToOmxCodingType(AvCodecRole role)
145 {
146 auto it = find_if(g_protocolTable.begin(), g_protocolTable.end(), [role](const Protocol& p) {
147 return p.hdiRole == role;
148 });
149 if (it != g_protocolTable.end()) {
150 return it->omxCodingType;
151 }
152 LOGW("unknown AvCodecRole %{public}d", role);
153 return nullopt;
154 }
155
HdiRoleToMime(AvCodecRole role)156 string TypeConverter::HdiRoleToMime(AvCodecRole role)
157 {
158 auto it = find_if(g_protocolTable.begin(), g_protocolTable.end(), [role](const Protocol& p) {
159 return p.hdiRole == role;
160 });
161 if (it != g_protocolTable.end()) {
162 return it->mime;
163 }
164 LOGW("unknown AvCodecRole %{public}d", role);
165 return {};
166 }
167
GraphicFmtToFmt(GraphicPixelFormat format)168 std::optional<PixelFmt> TypeConverter::GraphicFmtToFmt(GraphicPixelFormat format)
169 {
170 auto it = find_if(g_pixelFmtTable.begin(), g_pixelFmtTable.end(), [format](const PixelFmt& p) {
171 return p.graphicFmt == format;
172 });
173 if (it != g_pixelFmtTable.end()) {
174 return *it;
175 }
176 LOGW("unknown GraphicPixelFormat %{public}d", format);
177 return nullopt;
178 }
179
InnerFmtToFmt(VideoPixelFormat format)180 std::optional<PixelFmt> TypeConverter::InnerFmtToFmt(VideoPixelFormat format)
181 {
182 auto it = find_if(g_pixelFmtTable.begin(), g_pixelFmtTable.end(), [format](const PixelFmt& p) {
183 return p.innerFmt == format;
184 });
185 if (it != g_pixelFmtTable.end()) {
186 return *it;
187 }
188 LOGW("unknown VideoPixelFormat %{public}d", format);
189 return nullopt;
190 }
191
InnerFmtToDisplayFmt(VideoPixelFormat format)192 std::optional<GraphicPixelFormat> TypeConverter::InnerFmtToDisplayFmt(VideoPixelFormat format)
193 {
194 auto it = find_if(g_pixelFmtTable.begin(), g_pixelFmtTable.end(), [format](const PixelFmt& p) {
195 return p.innerFmt == format;
196 });
197 if (it != g_pixelFmtTable.end()) {
198 return it->graphicFmt;
199 }
200 LOGW("unknown VideoPixelFormat %{public}d", format);
201 return nullopt;
202 }
203
DisplayFmtToInnerFmt(GraphicPixelFormat format)204 std::optional<VideoPixelFormat> TypeConverter::DisplayFmtToInnerFmt(GraphicPixelFormat format)
205 {
206 auto it = find_if(g_pixelFmtTable.begin(), g_pixelFmtTable.end(), [format](const PixelFmt& p) {
207 return p.graphicFmt == format;
208 });
209 if (it != g_pixelFmtTable.end()) {
210 return it->innerFmt;
211 }
212 LOGW("unknown GraphicPixelFormat %{public}d", format);
213 return nullopt;
214 }
215
InnerRotateToDisplayRotate(VideoRotation rotate)216 std::optional<GraphicTransformType> TypeConverter::InnerRotateToDisplayRotate(VideoRotation rotate)
217 {
218 static const map<VideoRotation, GraphicTransformType> table = {
219 { VIDEO_ROTATION_0, GRAPHIC_ROTATE_NONE },
220 { VIDEO_ROTATION_90, GRAPHIC_ROTATE_90 },
221 { VIDEO_ROTATION_180, GRAPHIC_ROTATE_180 },
222 { VIDEO_ROTATION_270, GRAPHIC_ROTATE_270 },
223 };
224 auto it = table.find(rotate);
225 if (it == table.end()) {
226 LOGW("unknown VideoRotation %{public}u", rotate);
227 return std::nullopt;
228 }
229 return it->second;
230 }
231
InnerPrimaryToOmxPrimary(ColorPrimary primary)232 Primaries TypeConverter::InnerPrimaryToOmxPrimary(ColorPrimary primary)
233 {
234 static const map<ColorPrimary, Primaries> table = {
235 { COLOR_PRIMARY_BT709, PRIMARIES_BT709 },
236 { COLOR_PRIMARY_UNSPECIFIED, PRIMARIES_UNSPECIFIED },
237 { COLOR_PRIMARY_BT470_M, PRIMARIES_BT470_6M },
238 { COLOR_PRIMARY_BT601_625, PRIMARIES_BT601_625 },
239 { COLOR_PRIMARY_BT601_525, PRIMARIES_BT601_525 },
240 { COLOR_PRIMARY_SMPTE_ST240, PRIMARIES_BT601_525 },
241 { COLOR_PRIMARY_GENERIC_FILM, PRIMARIES_GENERICFILM },
242 { COLOR_PRIMARY_BT2020, PRIMARIES_BT2020 },
243 { COLOR_PRIMARY_SMPTE_ST428, PRIMARIES_MAX },
244 { COLOR_PRIMARY_P3DCI, PRIMARIES_MAX },
245 { COLOR_PRIMARY_P3D65, PRIMARIES_MAX },
246 };
247 auto it = table.find(primary);
248 if (it == table.end()) {
249 LOGW("unknown ColorPrimary %{public}d, use unspecified instead", primary);
250 return PRIMARIES_UNSPECIFIED;
251 }
252 return it->second;
253 }
254
InnerTransferToOmxTransfer(TransferCharacteristic transfer)255 Transfer TypeConverter::InnerTransferToOmxTransfer(TransferCharacteristic transfer)
256 {
257 static const map<TransferCharacteristic, Transfer> table = {
258 { TRANSFER_CHARACTERISTIC_BT709, TRANSFER_SMPTE170 },
259 { TRANSFER_CHARACTERISTIC_UNSPECIFIED, TRANSFER_UNSPECIFIED },
260 { TRANSFER_CHARACTERISTIC_GAMMA_2_2, TRANSFER_GAMMA22 },
261 { TRANSFER_CHARACTERISTIC_GAMMA_2_8, TRANSFER_GAMMA28 },
262 { TRANSFER_CHARACTERISTIC_BT601, TRANSFER_SMPTE170 },
263 { TRANSFER_CHARACTERISTIC_SMPTE_ST240, TRANSFER_SMPTE240 },
264 { TRANSFER_CHARACTERISTIC_LINEAR, TRANSFER_LINEAR },
265 { TRANSFER_CHARACTERISTIC_LOG, TRANSFER_MAX },
266 { TRANSFER_CHARACTERISTIC_LOG_SQRT, TRANSFER_MAX },
267 { TRANSFER_CHARACTERISTIC_IEC_61966_2_4, TRANSFER_XVYCC },
268 { TRANSFER_CHARACTERISTIC_BT1361, TRANSFER_BT1361 },
269 { TRANSFER_CHARACTERISTIC_IEC_61966_2_1, TRANSFER_MAX },
270 { TRANSFER_CHARACTERISTIC_BT2020_10BIT, TRANSFER_SMPTE170 },
271 { TRANSFER_CHARACTERISTIC_BT2020_12BIT, TRANSFER_SMPTE170 },
272 { TRANSFER_CHARACTERISTIC_PQ, TRANSFER_PQ },
273 { TRANSFER_CHARACTERISTIC_SMPTE_ST428, TRANSFER_ST428 },
274 { TRANSFER_CHARACTERISTIC_HLG, TRANSFER_HLG },
275 };
276 auto it = table.find(transfer);
277 if (it == table.end()) {
278 LOGW("unknown TransferCharacteristic %{public}d, use unspecified instead", transfer);
279 return TRANSFER_UNSPECIFIED;
280 }
281 return it->second;
282 }
283
InnerMatrixToOmxMatrix(MatrixCoefficient matrix)284 MatrixCoeffs TypeConverter::InnerMatrixToOmxMatrix(MatrixCoefficient matrix)
285 {
286 static const map<MatrixCoefficient, MatrixCoeffs> table = {
287 { MATRIX_COEFFICIENT_IDENTITY, MATRIX_MAX },
288 { MATRIX_COEFFICIENT_BT709, MATRIX_BT709 },
289 { MATRIX_COEFFICIENT_UNSPECIFIED, MATRIX_UNSPECIFED },
290 { MATRIX_COEFFICIENT_FCC, MATRIX_FCC },
291 { MATRIX_COEFFICIENT_BT601_625, MATRIX_BT601 },
292 { MATRIX_COEFFICIENT_BT601_525, MATRIX_BT601 },
293 { MATRIX_COEFFICIENT_SMPTE_ST240, MATRIX_SMPTE240 },
294 { MATRIX_COEFFICIENT_YCGCO, MATRIX_MAX },
295 { MATRIX_COEFFICIENT_BT2020_NCL, MATRIX_BT2020 },
296 { MATRIX_COEFFICIENT_BT2020_CL, MATRIX_BT2020CONSTANT },
297 { MATRIX_COEFFICIENT_SMPTE_ST2085, MATRIX_MAX },
298 { MATRIX_COEFFICIENT_CHROMATICITY_NCL, MATRIX_BT2020 },
299 { MATRIX_COEFFICIENT_CHROMATICITY_CL, MATRIX_BT2020CONSTANT },
300 { MATRIX_COEFFICIENT_ICTCP, MATRIX_MAX },
301 };
302 auto it = table.find(matrix);
303 if (it == table.end()) {
304 LOGW("unknown MatrixCoefficient %{public}d, use unspecified instead", matrix);
305 return MATRIX_UNSPECIFED;
306 }
307 return it->second;
308 }
309
OmxAvcProfileToInnerProfile(OMX_VIDEO_AVCPROFILETYPE profile)310 std::optional<AVCProfile> TypeConverter::OmxAvcProfileToInnerProfile(OMX_VIDEO_AVCPROFILETYPE profile)
311 {
312 auto it = find_if(g_avcProfileTable.begin(), g_avcProfileTable.end(), [profile](const AVCProfileMapping& p) {
313 return p.omxProfile == profile;
314 });
315 if (it != g_avcProfileTable.end()) {
316 return it->innerProfile;
317 }
318 LOGW("unknown OMX_VIDEO_AVCPROFILETYPE %{public}d", profile);
319 return nullopt;
320 }
321
OmxAvcLevelToInnerLevel(OMX_VIDEO_AVCLEVELTYPE level)322 std::optional<AVCLevel> TypeConverter::OmxAvcLevelToInnerLevel(OMX_VIDEO_AVCLEVELTYPE level)
323 {
324 auto it = find_if(g_avcLevelTable.begin(), g_avcLevelTable.end(), [level](const AVCLevelMapping& p) {
325 return p.omxLevel == level;
326 });
327 if (it != g_avcLevelTable.end()) {
328 return it->innerLevel;
329 }
330 LOGW("unknown OMX_VIDEO_AVCLEVELTYPE %{public}d", level);
331 return nullopt;
332 }
333
OmxHevcProfileToInnerProfile(CodecHevcProfile profile)334 std::optional<HEVCProfile> TypeConverter::OmxHevcProfileToInnerProfile(CodecHevcProfile profile)
335 {
336 auto it = find_if(g_hevcProfileTable.begin(), g_hevcProfileTable.end(), [profile](const HEVCProfileMapping& p) {
337 return p.omxProfile == profile;
338 });
339 if (it != g_hevcProfileTable.end()) {
340 return it->innerProfile;
341 }
342 LOGW("unknown CodecHevcProfile %{public}d", profile);
343 return nullopt;
344 }
345
OmxHevcLevelToInnerLevel(CodecHevcLevel level)346 std::optional<HEVCLevel> TypeConverter::OmxHevcLevelToInnerLevel(CodecHevcLevel level)
347 {
348 auto it = find_if(g_hevcLevelTable.begin(), g_hevcLevelTable.end(), [level](const HEVCLevelMapping& p) {
349 return p.omxLevel == level;
350 });
351 if (it != g_hevcLevelTable.end()) {
352 return it->innerLevel;
353 }
354 LOGW("unknown CodecHevcLevel %{public}d", level);
355 return nullopt;
356 }
357
InnerAvcProfileToOmxProfile(AVCProfile profile)358 std::optional<OMX_VIDEO_AVCPROFILETYPE> TypeConverter::InnerAvcProfileToOmxProfile(AVCProfile profile)
359 {
360 auto it = find_if(g_avcProfileTable.begin(), g_avcProfileTable.end(), [profile](const AVCProfileMapping& p) {
361 return p.innerProfile == profile;
362 });
363 if (it != g_avcProfileTable.end()) {
364 return it->omxProfile;
365 }
366 LOGW("unknown AVCProfile %{public}d", profile);
367 return nullopt;
368 }
369
InnerHevcProfileToOmxProfile(HEVCProfile profile)370 std::optional<CodecHevcProfile> TypeConverter::InnerHevcProfileToOmxProfile(HEVCProfile profile)
371 {
372 auto it = find_if(g_hevcProfileTable.begin(), g_hevcProfileTable.end(), [profile](const HEVCProfileMapping& p) {
373 return p.innerProfile == profile;
374 });
375 if (it != g_hevcProfileTable.end()) {
376 return it->omxProfile;
377 }
378 LOGW("unknown CodecHevcProfile %{public}d", profile);
379 return nullopt;
380 }
381
HdiBitrateModeToInnerMode(BitRateMode mode)382 std::optional<VideoEncodeBitrateMode> TypeConverter::HdiBitrateModeToInnerMode(BitRateMode mode)
383 {
384 static const map<BitRateMode, VideoEncodeBitrateMode> table = {
385 {BIT_RATE_MODE_VBR, VBR},
386 {BIT_RATE_MODE_CBR, CBR},
387 {BIT_RATE_MODE_CQ, CQ},
388 };
389 auto it = table.find(mode);
390 if (it == table.end()) {
391 LOGW("unknown BitRateMode %{public}d", mode);
392 return std::nullopt;
393 }
394 return it->second;
395 }
396 }