1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Codec2Mapper"
19 #include <utils/Log.h>
20
21 #include <media/stagefright/MediaCodecConstants.h>
22 #include <media/stagefright/SurfaceUtils.h>
23 #include <media/stagefright/foundation/ALookup.h>
24 #include <media/stagefright/foundation/ColorUtils.h>
25 #include <media/stagefright/foundation/MediaDefs.h>
26
27 #include <stdint.h> // for INT32_MAX
28
29 #include "Codec2Mapper.h"
30
31 using namespace android;
32
33 namespace {
34
35 ALookup<C2Config::profile_t, int32_t> sAacProfiles = {
36 { C2Config::PROFILE_AAC_LC, AACObjectLC },
37 { C2Config::PROFILE_AAC_MAIN, AACObjectMain },
38 { C2Config::PROFILE_AAC_SSR, AACObjectSSR },
39 { C2Config::PROFILE_AAC_LTP, AACObjectLTP },
40 { C2Config::PROFILE_AAC_HE, AACObjectHE },
41 { C2Config::PROFILE_AAC_SCALABLE, AACObjectScalable },
42 { C2Config::PROFILE_AAC_ER_LC, AACObjectERLC },
43 { C2Config::PROFILE_AAC_ER_SCALABLE, AACObjectERScalable },
44 { C2Config::PROFILE_AAC_LD, AACObjectLD },
45 { C2Config::PROFILE_AAC_HE_PS, AACObjectHE_PS },
46 { C2Config::PROFILE_AAC_ELD, AACObjectELD },
47 { C2Config::PROFILE_AAC_XHE, AACObjectXHE },
48 };
49
50 ALookup<C2Config::level_t, int32_t> sAvcLevels = {
51 { C2Config::LEVEL_AVC_1, AVCLevel1 },
52 { C2Config::LEVEL_AVC_1B, AVCLevel1b },
53 { C2Config::LEVEL_AVC_1_1, AVCLevel11 },
54 { C2Config::LEVEL_AVC_1_2, AVCLevel12 },
55 { C2Config::LEVEL_AVC_1_3, AVCLevel13 },
56 { C2Config::LEVEL_AVC_2, AVCLevel2 },
57 { C2Config::LEVEL_AVC_2_1, AVCLevel21 },
58 { C2Config::LEVEL_AVC_2_2, AVCLevel22 },
59 { C2Config::LEVEL_AVC_3, AVCLevel3 },
60 { C2Config::LEVEL_AVC_3_1, AVCLevel31 },
61 { C2Config::LEVEL_AVC_3_2, AVCLevel32 },
62 { C2Config::LEVEL_AVC_4, AVCLevel4 },
63 { C2Config::LEVEL_AVC_4_1, AVCLevel41 },
64 { C2Config::LEVEL_AVC_4_2, AVCLevel42 },
65 { C2Config::LEVEL_AVC_5, AVCLevel5 },
66 { C2Config::LEVEL_AVC_5_1, AVCLevel51 },
67 { C2Config::LEVEL_AVC_5_2, AVCLevel52 },
68
69 };
70
71 ALookup<C2Config::profile_t, int32_t> sAvcProfiles = {
72 // treat restricted profiles as full profile if there is no equivalent - which works for
73 // decoders, but not for encoders
74 { C2Config::PROFILE_AVC_BASELINE, AVCProfileBaseline },
75 { C2Config::PROFILE_AVC_CONSTRAINED_BASELINE, AVCProfileConstrainedBaseline },
76 { C2Config::PROFILE_AVC_MAIN, AVCProfileMain },
77 { C2Config::PROFILE_AVC_EXTENDED, AVCProfileExtended },
78 { C2Config::PROFILE_AVC_HIGH, AVCProfileHigh },
79 { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH, AVCProfileHigh },
80 { C2Config::PROFILE_AVC_CONSTRAINED_HIGH, AVCProfileConstrainedHigh },
81 { C2Config::PROFILE_AVC_HIGH_10, AVCProfileHigh10 },
82 { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH_10, AVCProfileHigh10 },
83 { C2Config::PROFILE_AVC_HIGH_422, AVCProfileHigh422 },
84 { C2Config::PROFILE_AVC_HIGH_444_PREDICTIVE, AVCProfileHigh444 },
85 { C2Config::PROFILE_AVC_HIGH_10_INTRA, AVCProfileHigh10 },
86 { C2Config::PROFILE_AVC_HIGH_422_INTRA, AVCProfileHigh422 },
87 { C2Config::PROFILE_AVC_HIGH_444_INTRA, AVCProfileHigh444 },
88 { C2Config::PROFILE_AVC_CAVLC_444_INTRA, AVCProfileHigh444 },
89 };
90
91 ALookup<C2Config::bitrate_mode_t, int32_t> sBitrateModes = {
92 { C2Config::BITRATE_CONST, BITRATE_MODE_CBR },
93 { C2Config::BITRATE_VARIABLE, BITRATE_MODE_VBR },
94 { C2Config::BITRATE_IGNORE, BITRATE_MODE_CQ },
95 };
96
97 ALookup<C2Color::matrix_t, ColorAspects::MatrixCoeffs> sColorMatricesSf = {
98 { C2Color::MATRIX_UNSPECIFIED, ColorAspects::MatrixUnspecified },
99 { C2Color::MATRIX_BT709, ColorAspects::MatrixBT709_5 },
100 { C2Color::MATRIX_FCC47_73_682, ColorAspects::MatrixBT470_6M },
101 { C2Color::MATRIX_BT601, ColorAspects::MatrixBT601_6 },
102 { C2Color::MATRIX_SMPTE240M, ColorAspects::MatrixSMPTE240M },
103 { C2Color::MATRIX_BT2020, ColorAspects::MatrixBT2020 },
104 { C2Color::MATRIX_BT2020_CONSTANT, ColorAspects::MatrixBT2020Constant },
105 { C2Color::MATRIX_OTHER, ColorAspects::MatrixOther },
106 };
107
108 ALookup<C2Color::primaries_t, ColorAspects::Primaries> sColorPrimariesSf = {
109 { C2Color::PRIMARIES_UNSPECIFIED, ColorAspects::PrimariesUnspecified },
110 { C2Color::PRIMARIES_BT709, ColorAspects::PrimariesBT709_5 },
111 { C2Color::PRIMARIES_BT470_M, ColorAspects::PrimariesBT470_6M },
112 { C2Color::PRIMARIES_BT601_625, ColorAspects::PrimariesBT601_6_625 },
113 { C2Color::PRIMARIES_BT601_525, ColorAspects::PrimariesBT601_6_525 },
114 { C2Color::PRIMARIES_GENERIC_FILM, ColorAspects::PrimariesGenericFilm },
115 { C2Color::PRIMARIES_BT2020, ColorAspects::PrimariesBT2020 },
116 // { C2Color::PRIMARIES_RP431, ColorAspects::Primaries... },
117 // { C2Color::PRIMARIES_EG432, ColorAspects::Primaries... },
118 // { C2Color::PRIMARIES_EBU3213, ColorAspects::Primaries... },
119 { C2Color::PRIMARIES_OTHER, ColorAspects::PrimariesOther },
120 };
121
122 ALookup<C2Color::range_t, int32_t> sColorRanges = {
123 { C2Color::RANGE_FULL, COLOR_RANGE_FULL },
124 { C2Color::RANGE_LIMITED, COLOR_RANGE_LIMITED },
125 };
126
127 ALookup<C2Color::range_t, ColorAspects::Range> sColorRangesSf = {
128 { C2Color::RANGE_UNSPECIFIED, ColorAspects::RangeUnspecified },
129 { C2Color::RANGE_FULL, ColorAspects::RangeFull },
130 { C2Color::RANGE_LIMITED, ColorAspects::RangeLimited },
131 { C2Color::RANGE_OTHER, ColorAspects::RangeOther },
132 };
133
134 ALookup<C2Color::transfer_t, int32_t> sColorTransfers = {
135 { C2Color::TRANSFER_LINEAR, COLOR_TRANSFER_LINEAR },
136 { C2Color::TRANSFER_170M, COLOR_TRANSFER_SDR_VIDEO },
137 { C2Color::TRANSFER_ST2084, COLOR_TRANSFER_ST2084 },
138 { C2Color::TRANSFER_HLG, COLOR_TRANSFER_HLG },
139 };
140
141 ALookup<C2Color::transfer_t, ColorAspects::Transfer> sColorTransfersSf = {
142 { C2Color::TRANSFER_UNSPECIFIED, ColorAspects::TransferUnspecified },
143 { C2Color::TRANSFER_LINEAR, ColorAspects::TransferLinear },
144 { C2Color::TRANSFER_SRGB, ColorAspects::TransferSRGB },
145 { C2Color::TRANSFER_170M, ColorAspects::TransferSMPTE170M },
146 { C2Color::TRANSFER_GAMMA22, ColorAspects::TransferGamma22 },
147 { C2Color::TRANSFER_GAMMA28, ColorAspects::TransferGamma28 },
148 { C2Color::TRANSFER_ST2084, ColorAspects::TransferST2084 },
149 { C2Color::TRANSFER_HLG, ColorAspects::TransferHLG },
150 { C2Color::TRANSFER_240M, ColorAspects::TransferSMPTE240M },
151 { C2Color::TRANSFER_XVYCC, ColorAspects::TransferXvYCC },
152 { C2Color::TRANSFER_BT1361, ColorAspects::TransferBT1361 },
153 { C2Color::TRANSFER_ST428, ColorAspects::TransferST428 },
154 { C2Color::TRANSFER_OTHER, ColorAspects::TransferOther },
155 };
156
157 ALookup<C2Config::level_t, int32_t> sDolbyVisionLevels = {
158 { C2Config::LEVEL_DV_MAIN_HD_24, DolbyVisionLevelHd24 },
159 { C2Config::LEVEL_DV_MAIN_HD_30, DolbyVisionLevelHd30 },
160 { C2Config::LEVEL_DV_MAIN_FHD_24, DolbyVisionLevelFhd24 },
161 { C2Config::LEVEL_DV_MAIN_FHD_30, DolbyVisionLevelFhd30 },
162 { C2Config::LEVEL_DV_MAIN_FHD_60, DolbyVisionLevelFhd60 },
163 { C2Config::LEVEL_DV_MAIN_UHD_24, DolbyVisionLevelUhd24 },
164 { C2Config::LEVEL_DV_MAIN_UHD_30, DolbyVisionLevelUhd30 },
165 { C2Config::LEVEL_DV_MAIN_UHD_48, DolbyVisionLevelUhd48 },
166 { C2Config::LEVEL_DV_MAIN_UHD_60, DolbyVisionLevelUhd60 },
167
168 // high tiers are not yet supported on android, for now map them to main tier
169 { C2Config::LEVEL_DV_HIGH_HD_24, DolbyVisionLevelHd24 },
170 { C2Config::LEVEL_DV_HIGH_HD_30, DolbyVisionLevelHd30 },
171 { C2Config::LEVEL_DV_HIGH_FHD_24, DolbyVisionLevelFhd24 },
172 { C2Config::LEVEL_DV_HIGH_FHD_30, DolbyVisionLevelFhd30 },
173 { C2Config::LEVEL_DV_HIGH_FHD_60, DolbyVisionLevelFhd60 },
174 { C2Config::LEVEL_DV_HIGH_UHD_24, DolbyVisionLevelUhd24 },
175 { C2Config::LEVEL_DV_HIGH_UHD_30, DolbyVisionLevelUhd30 },
176 { C2Config::LEVEL_DV_HIGH_UHD_48, DolbyVisionLevelUhd48 },
177 { C2Config::LEVEL_DV_HIGH_UHD_60, DolbyVisionLevelUhd60 },
178 };
179
180 ALookup<C2Config::profile_t, int32_t> sDolbyVisionProfiles = {
181 { C2Config::PROFILE_DV_AV_PER, DolbyVisionProfileDvavPer },
182 { C2Config::PROFILE_DV_AV_PEN, DolbyVisionProfileDvavPen },
183 { C2Config::PROFILE_DV_HE_DER, DolbyVisionProfileDvheDer },
184 { C2Config::PROFILE_DV_HE_DEN, DolbyVisionProfileDvheDen },
185 { C2Config::PROFILE_DV_HE_04, DolbyVisionProfileDvheDtr },
186 { C2Config::PROFILE_DV_HE_05, DolbyVisionProfileDvheStn },
187 { C2Config::PROFILE_DV_HE_DTH, DolbyVisionProfileDvheDth },
188 { C2Config::PROFILE_DV_HE_07, DolbyVisionProfileDvheDtb },
189 { C2Config::PROFILE_DV_HE_08, DolbyVisionProfileDvheSt },
190 { C2Config::PROFILE_DV_AV_09, DolbyVisionProfileDvavSe },
191 };
192
193 ALookup<C2Config::level_t, int32_t> sH263Levels = {
194 { C2Config::LEVEL_H263_10, H263Level10 },
195 { C2Config::LEVEL_H263_20, H263Level20 },
196 { C2Config::LEVEL_H263_30, H263Level30 },
197 { C2Config::LEVEL_H263_40, H263Level40 },
198 { C2Config::LEVEL_H263_45, H263Level45 },
199 { C2Config::LEVEL_H263_50, H263Level50 },
200 { C2Config::LEVEL_H263_60, H263Level60 },
201 { C2Config::LEVEL_H263_70, H263Level70 },
202 };
203
204 ALookup<C2Config::profile_t, int32_t> sH263Profiles = {
205 { C2Config::PROFILE_H263_BASELINE, H263ProfileBaseline },
206 { C2Config::PROFILE_H263_H320, H263ProfileH320Coding },
207 { C2Config::PROFILE_H263_V1BC, H263ProfileBackwardCompatible },
208 { C2Config::PROFILE_H263_ISWV2, H263ProfileISWV2 },
209 { C2Config::PROFILE_H263_ISWV3, H263ProfileISWV3 },
210 { C2Config::PROFILE_H263_HIGH_COMPRESSION, H263ProfileHighCompression },
211 { C2Config::PROFILE_H263_INTERNET, H263ProfileInternet },
212 { C2Config::PROFILE_H263_INTERLACE, H263ProfileInterlace },
213 { C2Config::PROFILE_H263_HIGH_LATENCY, H263ProfileHighLatency },
214 };
215
216 ALookup<C2Config::level_t, int32_t> sHevcLevels = {
217 { C2Config::LEVEL_HEVC_MAIN_1, HEVCMainTierLevel1 },
218 { C2Config::LEVEL_HEVC_MAIN_2, HEVCMainTierLevel2 },
219 { C2Config::LEVEL_HEVC_MAIN_2_1, HEVCMainTierLevel21 },
220 { C2Config::LEVEL_HEVC_MAIN_3, HEVCMainTierLevel3 },
221 { C2Config::LEVEL_HEVC_MAIN_3_1, HEVCMainTierLevel31 },
222 { C2Config::LEVEL_HEVC_MAIN_4, HEVCMainTierLevel4 },
223 { C2Config::LEVEL_HEVC_MAIN_4_1, HEVCMainTierLevel41 },
224 { C2Config::LEVEL_HEVC_MAIN_5, HEVCMainTierLevel5 },
225 { C2Config::LEVEL_HEVC_MAIN_5_1, HEVCMainTierLevel51 },
226 { C2Config::LEVEL_HEVC_MAIN_5_2, HEVCMainTierLevel52 },
227 { C2Config::LEVEL_HEVC_MAIN_6, HEVCMainTierLevel6 },
228 { C2Config::LEVEL_HEVC_MAIN_6_1, HEVCMainTierLevel61 },
229 { C2Config::LEVEL_HEVC_MAIN_6_2, HEVCMainTierLevel62 },
230
231 { C2Config::LEVEL_HEVC_HIGH_4, HEVCHighTierLevel4 },
232 { C2Config::LEVEL_HEVC_HIGH_4_1, HEVCHighTierLevel41 },
233 { C2Config::LEVEL_HEVC_HIGH_5, HEVCHighTierLevel5 },
234 { C2Config::LEVEL_HEVC_HIGH_5_1, HEVCHighTierLevel51 },
235 { C2Config::LEVEL_HEVC_HIGH_5_2, HEVCHighTierLevel52 },
236 { C2Config::LEVEL_HEVC_HIGH_6, HEVCHighTierLevel6 },
237 { C2Config::LEVEL_HEVC_HIGH_6_1, HEVCHighTierLevel61 },
238 { C2Config::LEVEL_HEVC_HIGH_6_2, HEVCHighTierLevel62 },
239
240 // map high tier levels below 4 to main tier
241 { C2Config::LEVEL_HEVC_MAIN_1, HEVCHighTierLevel1 },
242 { C2Config::LEVEL_HEVC_MAIN_2, HEVCHighTierLevel2 },
243 { C2Config::LEVEL_HEVC_MAIN_2_1, HEVCHighTierLevel21 },
244 { C2Config::LEVEL_HEVC_MAIN_3, HEVCHighTierLevel3 },
245 { C2Config::LEVEL_HEVC_MAIN_3_1, HEVCHighTierLevel31 },
246 };
247
248 ALookup<C2Config::profile_t, int32_t> sHevcProfiles = {
249 { C2Config::PROFILE_HEVC_MAIN, HEVCProfileMain },
250 { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10 },
251 { C2Config::PROFILE_HEVC_MAIN_STILL, HEVCProfileMainStill },
252 { C2Config::PROFILE_HEVC_MAIN_INTRA, HEVCProfileMain },
253 { C2Config::PROFILE_HEVC_MAIN_10_INTRA, HEVCProfileMain10 },
254 };
255
256 ALookup<C2Config::level_t, int32_t> sMpeg2Levels = {
257 { C2Config::LEVEL_MP2V_LOW, MPEG2LevelLL },
258 { C2Config::LEVEL_MP2V_MAIN, MPEG2LevelML },
259 { C2Config::LEVEL_MP2V_HIGH_1440, MPEG2LevelH14 },
260 { C2Config::LEVEL_MP2V_HIGH, MPEG2LevelHL },
261 { C2Config::LEVEL_MP2V_HIGHP, MPEG2LevelHP },
262 };
263
264 ALookup<C2Config::profile_t, int32_t> sMpeg2Profiles = {
265 { C2Config::PROFILE_MP2V_SIMPLE, MPEG2ProfileSimple },
266 { C2Config::PROFILE_MP2V_MAIN, MPEG2ProfileMain },
267 { C2Config::PROFILE_MP2V_SNR_SCALABLE, MPEG2ProfileSNR },
268 { C2Config::PROFILE_MP2V_SPATIALLY_SCALABLE, MPEG2ProfileSpatial },
269 { C2Config::PROFILE_MP2V_HIGH, MPEG2ProfileHigh },
270 { C2Config::PROFILE_MP2V_422, MPEG2Profile422 },
271 };
272
273 ALookup<C2Config::level_t, int32_t> sMpeg4Levels = {
274 { C2Config::LEVEL_MP4V_0, MPEG4Level0 },
275 { C2Config::LEVEL_MP4V_0B, MPEG4Level0b },
276 { C2Config::LEVEL_MP4V_1, MPEG4Level1 },
277 { C2Config::LEVEL_MP4V_2, MPEG4Level2 },
278 { C2Config::LEVEL_MP4V_3, MPEG4Level3 },
279 { C2Config::LEVEL_MP4V_3B, MPEG4Level3b },
280 { C2Config::LEVEL_MP4V_4, MPEG4Level4 },
281 { C2Config::LEVEL_MP4V_4A, MPEG4Level4a },
282 { C2Config::LEVEL_MP4V_5, MPEG4Level5 },
283 { C2Config::LEVEL_MP4V_6, MPEG4Level6 },
284 };
285
286 ALookup<C2Config::profile_t, int32_t> sMpeg4Profiles = {
287 { C2Config::PROFILE_MP4V_SIMPLE, MPEG4ProfileSimple },
288 { C2Config::PROFILE_MP4V_SIMPLE_SCALABLE, MPEG4ProfileSimpleScalable },
289 { C2Config::PROFILE_MP4V_CORE, MPEG4ProfileCore },
290 { C2Config::PROFILE_MP4V_MAIN, MPEG4ProfileMain },
291 { C2Config::PROFILE_MP4V_NBIT, MPEG4ProfileNbit },
292 { C2Config::PROFILE_MP4V_ARTS, MPEG4ProfileAdvancedRealTime },
293 { C2Config::PROFILE_MP4V_CORE_SCALABLE, MPEG4ProfileCoreScalable },
294 { C2Config::PROFILE_MP4V_ACE, MPEG4ProfileAdvancedCoding },
295 { C2Config::PROFILE_MP4V_ADVANCED_CORE, MPEG4ProfileAdvancedCore },
296 { C2Config::PROFILE_MP4V_ADVANCED_SIMPLE, MPEG4ProfileAdvancedSimple },
297 };
298
299 ALookup<C2Config::pcm_encoding_t, int32_t> sPcmEncodings = {
300 { C2Config::PCM_8, kAudioEncodingPcm8bit },
301 { C2Config::PCM_16, kAudioEncodingPcm16bit },
302 { C2Config::PCM_FLOAT, kAudioEncodingPcmFloat },
303 };
304
305 ALookup<C2Config::level_t, int32_t> sVp9Levels = {
306 { C2Config::LEVEL_VP9_1, VP9Level1 },
307 { C2Config::LEVEL_VP9_1_1, VP9Level11 },
308 { C2Config::LEVEL_VP9_2, VP9Level2 },
309 { C2Config::LEVEL_VP9_2_1, VP9Level21 },
310 { C2Config::LEVEL_VP9_3, VP9Level3 },
311 { C2Config::LEVEL_VP9_3_1, VP9Level31 },
312 { C2Config::LEVEL_VP9_4, VP9Level4 },
313 { C2Config::LEVEL_VP9_4_1, VP9Level41 },
314 { C2Config::LEVEL_VP9_5, VP9Level5 },
315 { C2Config::LEVEL_VP9_5_1, VP9Level51 },
316 { C2Config::LEVEL_VP9_5_2, VP9Level52 },
317 { C2Config::LEVEL_VP9_6, VP9Level6 },
318 { C2Config::LEVEL_VP9_6_1, VP9Level61 },
319 { C2Config::LEVEL_VP9_6_2, VP9Level62 },
320 };
321
322 ALookup<C2Config::profile_t, int32_t> sVp9Profiles = {
323 { C2Config::PROFILE_VP9_0, VP9Profile0 },
324 { C2Config::PROFILE_VP9_1, VP9Profile1 },
325 { C2Config::PROFILE_VP9_2, VP9Profile2 },
326 { C2Config::PROFILE_VP9_3, VP9Profile3 },
327 };
328
329 /**
330 * A helper that passes through vendor extension profile and level values.
331 */
332 struct ProfileLevelMapperHelper : C2Mapper::ProfileLevelMapper {
333 virtual bool simpleMap(C2Config::level_t from, int32_t *to) = 0;
334 virtual bool simpleMap(int32_t from, C2Config::level_t *to) = 0;
335 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) = 0;
336 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) = 0;
337
338 template<typename T, typename U>
passThroughMap__anon406f9d030111::ProfileLevelMapperHelper339 bool passThroughMap(T from, U *to) {
340 // allow (and pass through) vendor extensions
341 if (from >= (T)C2_PROFILE_LEVEL_VENDOR_START && from < (T)INT32_MAX) {
342 *to = (U)from;
343 return true;
344 }
345 return simpleMap(from, to);
346 }
347
mapLevel__anon406f9d030111::ProfileLevelMapperHelper348 virtual bool mapLevel(C2Config::level_t from, int32_t *to) {
349 return passThroughMap(from, to);
350 }
351
mapLevel__anon406f9d030111::ProfileLevelMapperHelper352 virtual bool mapLevel(int32_t from, C2Config::level_t *to) {
353 return passThroughMap(from, to);
354 }
355
mapProfile__anon406f9d030111::ProfileLevelMapperHelper356 virtual bool mapProfile(C2Config::profile_t from, int32_t *to) {
357 return passThroughMap(from, to);
358 }
359
mapProfile__anon406f9d030111::ProfileLevelMapperHelper360 virtual bool mapProfile(int32_t from, C2Config::profile_t *to) {
361 return passThroughMap(from, to);
362 }
363 };
364
365 // AAC only uses profiles, map all levels to unused or 0
366 struct AacProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::AacProfileLevelMapper367 virtual bool simpleMap(C2Config::level_t, int32_t *to) {
368 *to = 0;
369 return true;
370 }
simpleMap__anon406f9d030111::AacProfileLevelMapper371 virtual bool simpleMap(int32_t, C2Config::level_t *to) {
372 *to = C2Config::LEVEL_UNUSED;
373 return true;
374 }
simpleMap__anon406f9d030111::AacProfileLevelMapper375 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
376 return sAacProfiles.map(from, to);
377 }
simpleMap__anon406f9d030111::AacProfileLevelMapper378 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
379 return sAacProfiles.map(from, to);
380 }
381 };
382
383 struct AvcProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::AvcProfileLevelMapper384 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
385 return sAvcLevels.map(from, to);
386 }
simpleMap__anon406f9d030111::AvcProfileLevelMapper387 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
388 return sAvcLevels.map(from, to);
389 }
simpleMap__anon406f9d030111::AvcProfileLevelMapper390 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
391 return sAvcProfiles.map(from, to);
392 }
simpleMap__anon406f9d030111::AvcProfileLevelMapper393 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
394 return sAvcProfiles.map(from, to);
395 }
396 };
397
398 struct DolbyVisionProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::DolbyVisionProfileLevelMapper399 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
400 return sDolbyVisionLevels.map(from, to);
401 }
simpleMap__anon406f9d030111::DolbyVisionProfileLevelMapper402 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
403 return sDolbyVisionLevels.map(from, to);
404 }
simpleMap__anon406f9d030111::DolbyVisionProfileLevelMapper405 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
406 return sDolbyVisionProfiles.map(from, to);
407 }
simpleMap__anon406f9d030111::DolbyVisionProfileLevelMapper408 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
409 return sDolbyVisionProfiles.map(from, to);
410 }
411 };
412
413 struct H263ProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::H263ProfileLevelMapper414 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
415 return sH263Levels.map(from, to);
416 }
simpleMap__anon406f9d030111::H263ProfileLevelMapper417 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
418 return sH263Levels.map(from, to);
419 }
simpleMap__anon406f9d030111::H263ProfileLevelMapper420 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
421 return sH263Profiles.map(from, to);
422 }
simpleMap__anon406f9d030111::H263ProfileLevelMapper423 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
424 return sH263Profiles.map(from, to);
425 }
426 };
427
428 struct HevcProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::HevcProfileLevelMapper429 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
430 return sHevcLevels.map(from, to);
431 }
simpleMap__anon406f9d030111::HevcProfileLevelMapper432 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
433 return sHevcLevels.map(from, to);
434 }
simpleMap__anon406f9d030111::HevcProfileLevelMapper435 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
436 return sHevcProfiles.map(from, to);
437 }
simpleMap__anon406f9d030111::HevcProfileLevelMapper438 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
439 return sHevcProfiles.map(from, to);
440 }
441 };
442
443 struct Mpeg2ProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::Mpeg2ProfileLevelMapper444 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
445 return sMpeg2Levels.map(from, to);
446 }
simpleMap__anon406f9d030111::Mpeg2ProfileLevelMapper447 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
448 return sMpeg2Levels.map(from, to);
449 }
simpleMap__anon406f9d030111::Mpeg2ProfileLevelMapper450 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
451 return sMpeg2Profiles.map(from, to);
452 }
simpleMap__anon406f9d030111::Mpeg2ProfileLevelMapper453 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
454 return sMpeg2Profiles.map(from, to);
455 }
456 };
457
458 struct Mpeg4ProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::Mpeg4ProfileLevelMapper459 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
460 return sMpeg4Levels.map(from, to);
461 }
simpleMap__anon406f9d030111::Mpeg4ProfileLevelMapper462 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
463 return sMpeg4Levels.map(from, to);
464 }
simpleMap__anon406f9d030111::Mpeg4ProfileLevelMapper465 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
466 return sMpeg4Profiles.map(from, to);
467 }
simpleMap__anon406f9d030111::Mpeg4ProfileLevelMapper468 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
469 return sMpeg4Profiles.map(from, to);
470 }
471 };
472
473 // VP8 has no profiles and levels in Codec 2.0, but we use main profile and level 0 in MediaCodec
474 // map all profiles and levels to that.
475 struct Vp8ProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::Vp8ProfileLevelMapper476 virtual bool simpleMap(C2Config::level_t, int32_t *to) {
477 *to = VP8Level_Version0;
478 return true;
479 }
simpleMap__anon406f9d030111::Vp8ProfileLevelMapper480 virtual bool simpleMap(int32_t, C2Config::level_t *to) {
481 *to = C2Config::LEVEL_UNUSED;
482 return true;
483 }
simpleMap__anon406f9d030111::Vp8ProfileLevelMapper484 virtual bool simpleMap(C2Config::profile_t, int32_t *to) {
485 *to = VP8ProfileMain;
486 return true;
487 }
simpleMap__anon406f9d030111::Vp8ProfileLevelMapper488 virtual bool simpleMap(int32_t, C2Config::profile_t *to) {
489 *to = C2Config::PROFILE_UNUSED;
490 return true;
491 }
492 };
493
494 struct Vp9ProfileLevelMapper : ProfileLevelMapperHelper {
simpleMap__anon406f9d030111::Vp9ProfileLevelMapper495 virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
496 return sVp9Levels.map(from, to);
497 }
simpleMap__anon406f9d030111::Vp9ProfileLevelMapper498 virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
499 return sVp9Levels.map(from, to);
500 }
simpleMap__anon406f9d030111::Vp9ProfileLevelMapper501 virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
502 return sVp9Profiles.map(from, to);
503 }
simpleMap__anon406f9d030111::Vp9ProfileLevelMapper504 virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
505 return sVp9Profiles.map(from, to);
506 }
507 };
508
509 } // namespace
510
511 // static
512 std::shared_ptr<C2Mapper::ProfileLevelMapper>
GetProfileLevelMapper(std::string mediaType)513 C2Mapper::GetProfileLevelMapper(std::string mediaType) {
514 std::transform(mediaType.begin(), mediaType.begin(), mediaType.end(), ::tolower);
515 if (mediaType == MIMETYPE_AUDIO_AAC) {
516 return std::make_shared<AacProfileLevelMapper>();
517 } else if (mediaType == MIMETYPE_VIDEO_AVC) {
518 return std::make_shared<AvcProfileLevelMapper>();
519 } else if (mediaType == MIMETYPE_VIDEO_DOLBY_VISION) {
520 return std::make_shared<DolbyVisionProfileLevelMapper>();
521 } else if (mediaType == MIMETYPE_VIDEO_H263) {
522 return std::make_shared<H263ProfileLevelMapper>();
523 } else if (mediaType == MIMETYPE_VIDEO_HEVC) {
524 return std::make_shared<HevcProfileLevelMapper>();
525 } else if (mediaType == MIMETYPE_VIDEO_MPEG2) {
526 return std::make_shared<Mpeg2ProfileLevelMapper>();
527 } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
528 return std::make_shared<Mpeg4ProfileLevelMapper>();
529 } else if (mediaType == MIMETYPE_VIDEO_VP8) {
530 return std::make_shared<Vp8ProfileLevelMapper>();
531 } else if (mediaType == MIMETYPE_VIDEO_VP9) {
532 return std::make_shared<Vp9ProfileLevelMapper>();
533 }
534 return nullptr;
535 }
536
537 // static
map(C2Config::bitrate_mode_t from,int32_t * to)538 bool C2Mapper::map(C2Config::bitrate_mode_t from, int32_t *to) {
539 return sBitrateModes.map(from, to);
540 }
541
542 // static
map(int32_t from,C2Config::bitrate_mode_t * to)543 bool C2Mapper::map(int32_t from, C2Config::bitrate_mode_t *to) {
544 return sBitrateModes.map(from, to);
545 }
546
547 // static
map(C2Config::pcm_encoding_t from,int32_t * to)548 bool C2Mapper::map(C2Config::pcm_encoding_t from, int32_t *to) {
549 return sPcmEncodings.map(from, to);
550 }
551
552 // static
map(int32_t from,C2Config::pcm_encoding_t * to)553 bool C2Mapper::map(int32_t from, C2Config::pcm_encoding_t *to) {
554 return sPcmEncodings.map(from, to);
555 }
556
557 // static
map(C2Color::range_t from,int32_t * to)558 bool C2Mapper::map(C2Color::range_t from, int32_t *to) {
559 bool res = true;
560 // map SDK defined values directly. For other values, use wrapping from ColorUtils.
561 if (!sColorRanges.map(from, to)) {
562 ColorAspects::Range sfRange;
563
564 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
565 if (!sColorRangesSf.map(from, &sfRange)) {
566 // use static cast and ensure it is in the extension range
567 if (from < C2Color::RANGE_VENDOR_START || from > C2Color::RANGE_OTHER) {
568 sfRange = ColorAspects::RangeOther;
569 res = false;
570 }
571 }
572
573 *to = ColorUtils::wrapColorAspectsIntoColorRange(sfRange);
574 }
575 return res;
576 }
577
578 // static
map(int32_t from,C2Color::range_t * to)579 bool C2Mapper::map(int32_t from, C2Color::range_t *to) {
580 // map SDK defined values directly. For other values, use wrapping from ColorUtils.
581 if (!sColorRanges.map(from, to)) {
582 ColorAspects::Range sfRange;
583 (void)ColorUtils::unwrapColorAspectsFromColorRange(from, &sfRange);
584
585 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
586 if (!sColorRangesSf.map(sfRange, to)) {
587 // use static cast and ensure it is in the extension range
588 *to = (C2Color::range_t)sfRange;
589 if (*to < C2Color::RANGE_VENDOR_START || *to > C2Color::RANGE_OTHER) {
590 *to = C2Color::RANGE_OTHER;
591 return false;
592 }
593 }
594 }
595
596 return true;
597 }
598
599 // static
map(C2Color::range_t from,ColorAspects::Range * to)600 bool C2Mapper::map(C2Color::range_t from, ColorAspects::Range *to) {
601 return sColorRangesSf.map(from, to);
602 }
603
604 // static
map(ColorAspects::Range from,C2Color::range_t * to)605 bool C2Mapper::map(ColorAspects::Range from, C2Color::range_t *to) {
606 return sColorRangesSf.map(from, to);
607 }
608
609 // static
map(C2Color::primaries_t primaries,C2Color::matrix_t matrix,int32_t * standard)610 bool C2Mapper::map(C2Color::primaries_t primaries, C2Color::matrix_t matrix, int32_t *standard) {
611 ColorAspects::Primaries sfPrimaries;
612 ColorAspects::MatrixCoeffs sfMatrix;
613 bool res = true;
614
615 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
616 if (!sColorPrimariesSf.map(primaries, &sfPrimaries)) {
617 // ensure it is in the extension range and use static cast
618 if (primaries < C2Color::PRIMARIES_VENDOR_START || primaries > C2Color::PRIMARIES_OTHER) {
619 // undefined non-extension values map to 'Other'
620 sfPrimaries = ColorAspects::PrimariesOther;
621 res = false;
622 } else {
623 sfPrimaries = (ColorAspects::Primaries)primaries;
624 }
625 }
626
627 if (!sColorMatricesSf.map(matrix, &sfMatrix)) {
628 // use static cast and ensure it is in the extension range
629 if (matrix < C2Color::MATRIX_VENDOR_START || matrix > C2Color::MATRIX_OTHER) {
630 // undefined non-extension values map to 'Other'
631 sfMatrix = ColorAspects::MatrixOther;
632 res = false;
633 } else {
634 sfMatrix = (ColorAspects::MatrixCoeffs)matrix;
635 }
636 }
637
638 *standard = ColorUtils::wrapColorAspectsIntoColorStandard(sfPrimaries, sfMatrix);
639
640 return res;
641 }
642
643 // static
map(int32_t standard,C2Color::primaries_t * primaries,C2Color::matrix_t * matrix)644 bool C2Mapper::map(int32_t standard, C2Color::primaries_t *primaries, C2Color::matrix_t *matrix) {
645 // first map to stagefright foundation aspects => these actually map nearly 1:1 to
646 // Codec 2.0 aspects
647 ColorAspects::Primaries sfPrimaries;
648 ColorAspects::MatrixCoeffs sfMatrix;
649 bool res = true;
650 (void)ColorUtils::unwrapColorAspectsFromColorStandard(standard, &sfPrimaries, &sfMatrix);
651
652 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
653 if (!sColorPrimariesSf.map(sfPrimaries, primaries)) {
654 // use static cast and ensure it is in the extension range
655 *primaries = (C2Color::primaries_t)sfPrimaries;
656 if (*primaries < C2Color::PRIMARIES_VENDOR_START || *primaries > C2Color::PRIMARIES_OTHER) {
657 *primaries = C2Color::PRIMARIES_OTHER;
658 res = false;
659 }
660 }
661
662 if (!sColorMatricesSf.map(sfMatrix, matrix)) {
663 // use static cast and ensure it is in the extension range
664 *matrix = (C2Color::matrix_t)sfMatrix;
665 if (*matrix < C2Color::MATRIX_VENDOR_START || *matrix > C2Color::MATRIX_OTHER) {
666 *matrix = C2Color::MATRIX_OTHER;
667 res = false;
668 }
669 }
670
671 return res;
672 }
673
674 // static
map(C2Color::primaries_t from,ColorAspects::Primaries * to)675 bool C2Mapper::map(C2Color::primaries_t from, ColorAspects::Primaries *to) {
676 return sColorPrimariesSf.map(from, to);
677 }
678
679 // static
map(ColorAspects::Primaries from,C2Color::primaries_t * to)680 bool C2Mapper::map(ColorAspects::Primaries from, C2Color::primaries_t *to) {
681 return sColorPrimariesSf.map(from, to);
682 }
683
684 // static
map(C2Color::matrix_t from,ColorAspects::MatrixCoeffs * to)685 bool C2Mapper::map(C2Color::matrix_t from, ColorAspects::MatrixCoeffs *to) {
686 return sColorMatricesSf.map(from, to);
687 }
688
689 // static
map(ColorAspects::MatrixCoeffs from,C2Color::matrix_t * to)690 bool C2Mapper::map(ColorAspects::MatrixCoeffs from, C2Color::matrix_t *to) {
691 return sColorMatricesSf.map(from, to);
692 }
693
694 // static
map(C2Color::transfer_t from,int32_t * to)695 bool C2Mapper::map(C2Color::transfer_t from, int32_t *to) {
696 bool res = true;
697 // map SDK defined values directly. For other values, use wrapping from ColorUtils.
698 if (!sColorTransfers.map(from, to)) {
699 ColorAspects::Transfer sfTransfer;
700
701 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
702 if (!sColorTransfersSf.map(from, &sfTransfer)) {
703 // use static cast and ensure it is in the extension range
704 if (from < C2Color::TRANSFER_VENDOR_START || from > C2Color::TRANSFER_OTHER) {
705 sfTransfer = ColorAspects::TransferOther;
706 res = false;
707 }
708 }
709
710 *to = ColorUtils::wrapColorAspectsIntoColorTransfer(sfTransfer);
711 }
712 return res;
713 }
714
715 // static
map(int32_t from,C2Color::transfer_t * to)716 bool C2Mapper::map(int32_t from, C2Color::transfer_t *to) {
717 // map SDK defined values directly. For other values, use wrapping from ColorUtils.
718 if (!sColorTransfers.map(from, to)) {
719 ColorAspects::Transfer sfTransfer;
720 (void)ColorUtils::unwrapColorAspectsFromColorTransfer(from, &sfTransfer);
721
722 // map known constants and keep vendor extensions. all other values are mapped to 'Other'
723 if (!sColorTransfersSf.map(sfTransfer, to)) {
724 // use static cast and ensure it is in the extension range
725 *to = (C2Color::transfer_t)sfTransfer;
726 if (*to < C2Color::TRANSFER_VENDOR_START || *to > C2Color::TRANSFER_OTHER) {
727 *to = C2Color::TRANSFER_OTHER;
728 return false;
729 }
730 }
731 }
732
733 return true;
734 }
735
736 // static
map(C2Color::range_t range,C2Color::primaries_t primaries,C2Color::matrix_t matrix,C2Color::transfer_t transfer,uint32_t * dataSpace)737 bool C2Mapper::map(
738 C2Color::range_t range, C2Color::primaries_t primaries,
739 C2Color::matrix_t matrix, C2Color::transfer_t transfer, uint32_t *dataSpace) {
740 #if 0
741 // pure reimplementation
742 *dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
743
744 switch (range) {
745 case C2Color::RANGE_FULL: *dataSpace |= HAL_DATASPACE_RANGE_FULL; break;
746 case C2Color::RANGE_LIMITED: *dataSpace |= HAL_DATASPACE_RANGE_LIMITED; break;
747 default: break;
748 }
749
750 switch (transfer) {
751 case C2Color::TRANSFER_LINEAR: *dataSpace |= HAL_DATASPACE_TRANSFER_LINEAR; break;
752 case C2Color::TRANSFER_SRGB: *dataSpace |= HAL_DATASPACE_TRANSFER_SRGB; break;
753 case C2Color::TRANSFER_170M: *dataSpace |= HAL_DATASPACE_TRANSFER_SMPTE_170M; break;
754 case C2Color::TRANSFER_GAMMA22: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_2; break;
755 case C2Color::TRANSFER_GAMMA28: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_8; break;
756 case C2Color::TRANSFER_ST2084: *dataSpace |= HAL_DATASPACE_TRANSFER_ST2084; break;
757 case C2Color::TRANSFER_HLG: *dataSpace |= HAL_DATASPACE_TRANSFER_HLG; break;
758 default: break;
759 }
760
761 switch (primaries) {
762 case C2Color::PRIMARIES_BT601_525:
763 *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
764 || matrix == C2Color::MATRIX_BT709)
765 ? HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED
766 : HAL_DATASPACE_STANDARD_BT601_525;
767 break;
768 case C2Color::PRIMARIES_BT601_625:
769 *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
770 || matrix == C2Color::MATRIX_BT709)
771 ? HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED
772 : HAL_DATASPACE_STANDARD_BT601_625;
773 break;
774 case C2Color::PRIMARIES_BT2020:
775 *dataSpace |= (matrix == C2Color::MATRIX_BT2020CONSTANT
776 ? HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE
777 : HAL_DATASPACE_STANDARD_BT2020);
778 break;
779 case C2Color::PRIMARIES_BT470_M:
780 *dataSpace |= HAL_DATASPACE_STANDARD_BT470M;
781 break;
782 case C2Color::PRIMARIES_BT709:
783 *dataSpace |= HAL_DATASPACE_STANDARD_BT709;
784 break;
785 default: break;
786 }
787 #else
788 // for now use legacy implementation
789 ColorAspects aspects;
790 if (!sColorRangesSf.map(range, &aspects.mRange)) {
791 aspects.mRange = ColorAspects::RangeUnspecified;
792 }
793 if (!sColorPrimariesSf.map(primaries, &aspects.mPrimaries)) {
794 aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
795 }
796 if (!sColorMatricesSf.map(matrix, &aspects.mMatrixCoeffs)) {
797 aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
798 }
799 if (!sColorTransfersSf.map(transfer, &aspects.mTransfer)) {
800 aspects.mTransfer = ColorAspects::TransferUnspecified;
801 }
802 *dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
803 #endif
804 return true;
805 }
806
807 // static
map(C2Color::transfer_t from,ColorAspects::Transfer * to)808 bool C2Mapper::map(C2Color::transfer_t from, ColorAspects::Transfer *to) {
809 return sColorTransfersSf.map(from, to);
810 }
811
812 // static
map(ColorAspects::Transfer from,C2Color::transfer_t * to)813 bool C2Mapper::map(ColorAspects::Transfer from, C2Color::transfer_t *to) {
814 return sColorTransfersSf.map(from, to);
815 }
816