1 /*
2 * Copyright (C) 2009 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 "Utils"
19 #include <utils/Log.h>
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <sys/stat.h>
23
24 #include <utility>
25 #include <vector>
26
27 #include "include/ESDS.h"
28 #include "include/HevcUtils.h"
29
30 #include <cutils/properties.h>
31 #include <media/openmax/OMX_Audio.h>
32 #include <media/openmax/OMX_Video.h>
33 #include <media/openmax/OMX_VideoExt.h>
34 #include <media/stagefright/CodecBase.h>
35 #include <media/stagefright/foundation/ABuffer.h>
36 #include <media/stagefright/foundation/ADebug.h>
37 #include <media/stagefright/foundation/ALookup.h>
38 #include <media/stagefright/foundation/AMessage.h>
39 #include <media/stagefright/foundation/ByteUtils.h>
40 #include <media/stagefright/foundation/OpusHeader.h>
41 #include <media/stagefright/MetaData.h>
42 #include <media/stagefright/MediaCodecConstants.h>
43 #include <media/stagefright/MediaDefs.h>
44 #include <media/AudioSystem.h>
45 #include <media/MediaPlayerInterface.h>
46 #include <media/stagefright/Utils.h>
47 #include <media/AudioParameter.h>
48 #include <system/audio.h>
49
50 // TODO : Remove the defines once mainline media is built against NDK >= 31.
51 // The mp4 extractor is part of mainline and builds against NDK 29 as of
52 // writing. These keys are available only from NDK 31:
53 #define AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION \
54 "mpegh-profile-level-indication"
55 #define AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT \
56 "mpegh-reference-channel-layout"
57 #define AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS \
58 "mpegh-compatible-sets"
59
60 namespace android {
61
copyNALUToABuffer(sp<ABuffer> * buffer,const uint8_t * ptr,size_t length)62 static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
63 if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
64 sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
65 if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
66 return NO_MEMORY;
67 }
68 memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
69 tmpBuffer->setRange(0, (*buffer)->size());
70 (*buffer) = tmpBuffer;
71 }
72
73 memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
74 memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
75 (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
76 return OK;
77 }
78
79 #if 0
80 static void convertMetaDataToMessageInt32(
81 const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
82 int32_t value;
83 if (meta->findInt32(key, &value)) {
84 msg->setInt32(name, value);
85 }
86 }
87 #endif
88
convertMetaDataToMessageColorAspects(const MetaDataBase * meta,sp<AMessage> & msg)89 static void convertMetaDataToMessageColorAspects(const MetaDataBase *meta, sp<AMessage> &msg) {
90 // 0 values are unspecified
91 int32_t range = 0;
92 int32_t primaries = 0;
93 int32_t transferFunction = 0;
94 int32_t colorMatrix = 0;
95 meta->findInt32(kKeyColorRange, &range);
96 meta->findInt32(kKeyColorPrimaries, &primaries);
97 meta->findInt32(kKeyTransferFunction, &transferFunction);
98 meta->findInt32(kKeyColorMatrix, &colorMatrix);
99 ColorAspects colorAspects;
100 memset(&colorAspects, 0, sizeof(colorAspects));
101 colorAspects.mRange = (ColorAspects::Range)range;
102 colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
103 colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
104 colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
105
106 int32_t rangeMsg, standardMsg, transferMsg;
107 if (CodecBase::convertCodecColorAspectsToPlatformAspects(
108 colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
109 return;
110 }
111
112 // save specified values to msg
113 if (rangeMsg != 0) {
114 msg->setInt32("color-range", rangeMsg);
115 }
116 if (standardMsg != 0) {
117 msg->setInt32("color-standard", standardMsg);
118 }
119 if (transferMsg != 0) {
120 msg->setInt32("color-transfer", transferMsg);
121 }
122 }
123
isHdr(const sp<AMessage> & format)124 static bool isHdr(const sp<AMessage> &format) {
125 // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR
126 // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key
127 // in the format.
128 int32_t isHdr;
129 if (format->findInt32("android._is-hdr", &isHdr)) {
130 return isHdr;
131 }
132
133 // if user/container supplied HDR static info without transfer set, assume true
134 if ((format->contains("hdr-static-info") || format->contains("hdr10-plus-info"))
135 && !format->contains("color-transfer")) {
136 return true;
137 }
138 // otherwise, verify that an HDR transfer function is set
139 int32_t transfer;
140 if (format->findInt32("color-transfer", &transfer)) {
141 return transfer == ColorUtils::kColorTransferST2084
142 || transfer == ColorUtils::kColorTransferHLG;
143 }
144 return false;
145 }
146
parseAacProfileFromCsd(const sp<ABuffer> & csd,sp<AMessage> & format)147 static void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
148 if (csd->size() < 2) {
149 return;
150 }
151
152 uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
153 if ((audioObjectType & 0xF800) == 0xF800) {
154 audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
155 } else {
156 audioObjectType >>= 11;
157 }
158
159 const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
160 { 1, OMX_AUDIO_AACObjectMain },
161 { 2, OMX_AUDIO_AACObjectLC },
162 { 3, OMX_AUDIO_AACObjectSSR },
163 { 4, OMX_AUDIO_AACObjectLTP },
164 { 5, OMX_AUDIO_AACObjectHE },
165 { 6, OMX_AUDIO_AACObjectScalable },
166 { 17, OMX_AUDIO_AACObjectERLC },
167 { 23, OMX_AUDIO_AACObjectLD },
168 { 29, OMX_AUDIO_AACObjectHE_PS },
169 { 39, OMX_AUDIO_AACObjectELD },
170 { 42, OMX_AUDIO_AACObjectXHE },
171 };
172
173 OMX_AUDIO_AACPROFILETYPE profile;
174 if (profiles.map(audioObjectType, &profile)) {
175 format->setInt32("profile", profile);
176 }
177 }
178
parseAvcProfileLevelFromAvcc(const uint8_t * ptr,size_t size,sp<AMessage> & format)179 static void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
180 if (size < 4 || ptr[0] != 1) { // configurationVersion == 1
181 return;
182 }
183 const uint8_t profile = ptr[1];
184 const uint8_t constraints = ptr[2];
185 const uint8_t level = ptr[3];
186
187 const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
188 { 9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
189 { 10, OMX_VIDEO_AVCLevel1 },
190 { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
191 { 11, OMX_VIDEO_AVCLevel1b },
192 { 12, OMX_VIDEO_AVCLevel12 },
193 { 13, OMX_VIDEO_AVCLevel13 },
194 { 20, OMX_VIDEO_AVCLevel2 },
195 { 21, OMX_VIDEO_AVCLevel21 },
196 { 22, OMX_VIDEO_AVCLevel22 },
197 { 30, OMX_VIDEO_AVCLevel3 },
198 { 31, OMX_VIDEO_AVCLevel31 },
199 { 32, OMX_VIDEO_AVCLevel32 },
200 { 40, OMX_VIDEO_AVCLevel4 },
201 { 41, OMX_VIDEO_AVCLevel41 },
202 { 42, OMX_VIDEO_AVCLevel42 },
203 { 50, OMX_VIDEO_AVCLevel5 },
204 { 51, OMX_VIDEO_AVCLevel51 },
205 { 52, OMX_VIDEO_AVCLevel52 },
206 { 60, OMX_VIDEO_AVCLevel6 },
207 { 61, OMX_VIDEO_AVCLevel61 },
208 { 62, OMX_VIDEO_AVCLevel62 },
209 };
210 const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
211 { 66, OMX_VIDEO_AVCProfileBaseline },
212 { 77, OMX_VIDEO_AVCProfileMain },
213 { 88, OMX_VIDEO_AVCProfileExtended },
214 { 100, OMX_VIDEO_AVCProfileHigh },
215 { 110, OMX_VIDEO_AVCProfileHigh10 },
216 { 122, OMX_VIDEO_AVCProfileHigh422 },
217 { 244, OMX_VIDEO_AVCProfileHigh444 },
218 };
219
220 // set profile & level if they are recognized
221 OMX_VIDEO_AVCPROFILETYPE codecProfile;
222 OMX_VIDEO_AVCLEVELTYPE codecLevel;
223 if (profiles.map(profile, &codecProfile)) {
224 if (profile == 66 && (constraints & 0x40)) {
225 codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
226 } else if (profile == 100 && (constraints & 0x0C) == 0x0C) {
227 codecProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
228 }
229 format->setInt32("profile", codecProfile);
230 if (levels.map(level, &codecLevel)) {
231 // for 9 && 11 decide level based on profile and constraint_set3 flag
232 if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
233 codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
234 }
235 format->setInt32("level", codecLevel);
236 }
237 }
238 }
239
parseDolbyVisionProfileLevelFromDvcc(const uint8_t * ptr,size_t size,sp<AMessage> & format)240 static void parseDolbyVisionProfileLevelFromDvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
241 // dv_major.dv_minor Should be 1.0 or 2.1
242 if (size != 24 || ((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1))) {
243 ALOGV("Size %zu, dv_major %d, dv_minor %d", size, ptr[0], ptr[1]);
244 return;
245 }
246
247 const uint8_t profile = ptr[2] >> 1;
248 const uint8_t level = ((ptr[2] & 0x1) << 5) | ((ptr[3] >> 3) & 0x1f);
249 const uint8_t rpu_present_flag = (ptr[3] >> 2) & 0x01;
250 const uint8_t el_present_flag = (ptr[3] >> 1) & 0x01;
251 const uint8_t bl_present_flag = (ptr[3] & 0x01);
252 const int32_t bl_compatibility_id = (int32_t)(ptr[4] >> 4);
253
254 ALOGV("profile-level-compatibility value in dv(c|v)c box %d-%d-%d",
255 profile, level, bl_compatibility_id);
256
257 // All Dolby Profiles will have profile and level info in MediaFormat
258 // Profile 8 and 9 will have bl_compatibility_id too.
259 const static ALookup<uint8_t, OMX_VIDEO_DOLBYVISIONPROFILETYPE> profiles{
260 {1, OMX_VIDEO_DolbyVisionProfileDvavPen},
261 {3, OMX_VIDEO_DolbyVisionProfileDvheDen},
262 {4, OMX_VIDEO_DolbyVisionProfileDvheDtr},
263 {5, OMX_VIDEO_DolbyVisionProfileDvheStn},
264 {6, OMX_VIDEO_DolbyVisionProfileDvheDth},
265 {7, OMX_VIDEO_DolbyVisionProfileDvheDtb},
266 {8, OMX_VIDEO_DolbyVisionProfileDvheSt},
267 {9, OMX_VIDEO_DolbyVisionProfileDvavSe},
268 {10, OMX_VIDEO_DolbyVisionProfileDvav110},
269 };
270
271 const static ALookup<uint8_t, OMX_VIDEO_DOLBYVISIONLEVELTYPE> levels{
272 {0, OMX_VIDEO_DolbyVisionLevelUnknown},
273 {1, OMX_VIDEO_DolbyVisionLevelHd24},
274 {2, OMX_VIDEO_DolbyVisionLevelHd30},
275 {3, OMX_VIDEO_DolbyVisionLevelFhd24},
276 {4, OMX_VIDEO_DolbyVisionLevelFhd30},
277 {5, OMX_VIDEO_DolbyVisionLevelFhd60},
278 {6, OMX_VIDEO_DolbyVisionLevelUhd24},
279 {7, OMX_VIDEO_DolbyVisionLevelUhd30},
280 {8, OMX_VIDEO_DolbyVisionLevelUhd48},
281 {9, OMX_VIDEO_DolbyVisionLevelUhd60},
282 };
283 // set rpuAssoc
284 if (rpu_present_flag && el_present_flag && !bl_present_flag) {
285 format->setInt32("rpuAssoc", 1);
286 }
287 // set profile & level if they are recognized
288 OMX_VIDEO_DOLBYVISIONPROFILETYPE codecProfile;
289 OMX_VIDEO_DOLBYVISIONLEVELTYPE codecLevel;
290 if (profiles.map(profile, &codecProfile)) {
291 format->setInt32("profile", codecProfile);
292 if (codecProfile == OMX_VIDEO_DolbyVisionProfileDvheSt ||
293 codecProfile == OMX_VIDEO_DolbyVisionProfileDvavSe) {
294 format->setInt32("bl_compatibility_id", bl_compatibility_id);
295 }
296 if (levels.map(level, &codecLevel)) {
297 format->setInt32("level", codecLevel);
298 }
299 }
300 }
301
parseH263ProfileLevelFromD263(const uint8_t * ptr,size_t size,sp<AMessage> & format)302 static void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
303 if (size < 7) {
304 return;
305 }
306
307 const uint8_t profile = ptr[6];
308 const uint8_t level = ptr[5];
309
310 const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
311 { 0, OMX_VIDEO_H263ProfileBaseline },
312 { 1, OMX_VIDEO_H263ProfileH320Coding },
313 { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
314 { 3, OMX_VIDEO_H263ProfileISWV2 },
315 { 4, OMX_VIDEO_H263ProfileISWV3 },
316 { 5, OMX_VIDEO_H263ProfileHighCompression },
317 { 6, OMX_VIDEO_H263ProfileInternet },
318 { 7, OMX_VIDEO_H263ProfileInterlace },
319 { 8, OMX_VIDEO_H263ProfileHighLatency },
320 };
321
322 const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
323 { 10, OMX_VIDEO_H263Level10 },
324 { 20, OMX_VIDEO_H263Level20 },
325 { 30, OMX_VIDEO_H263Level30 },
326 { 40, OMX_VIDEO_H263Level40 },
327 { 45, OMX_VIDEO_H263Level45 },
328 { 50, OMX_VIDEO_H263Level50 },
329 { 60, OMX_VIDEO_H263Level60 },
330 { 70, OMX_VIDEO_H263Level70 },
331 };
332
333 // set profile & level if they are recognized
334 OMX_VIDEO_H263PROFILETYPE codecProfile;
335 OMX_VIDEO_H263LEVELTYPE codecLevel;
336 if (profiles.map(profile, &codecProfile)) {
337 format->setInt32("profile", codecProfile);
338 if (levels.map(level, &codecLevel)) {
339 format->setInt32("level", codecLevel);
340 }
341 }
342 }
343
parseHevcProfileLevelFromHvcc(const uint8_t * ptr,size_t size,sp<AMessage> & format)344 static void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
345 if (size < 13 || ptr[0] != 1) { // configurationVersion == 1
346 return;
347 }
348
349 const uint8_t profile = ptr[1] & 0x1F;
350 const uint8_t tier = (ptr[1] & 0x20) >> 5;
351 const uint8_t level = ptr[12];
352
353 const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
354 { { 0, 30 }, OMX_VIDEO_HEVCMainTierLevel1 },
355 { { 0, 60 }, OMX_VIDEO_HEVCMainTierLevel2 },
356 { { 0, 63 }, OMX_VIDEO_HEVCMainTierLevel21 },
357 { { 0, 90 }, OMX_VIDEO_HEVCMainTierLevel3 },
358 { { 0, 93 }, OMX_VIDEO_HEVCMainTierLevel31 },
359 { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4 },
360 { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
361 { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5 },
362 { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
363 { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
364 { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6 },
365 { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
366 { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
367 { { 1, 30 }, OMX_VIDEO_HEVCHighTierLevel1 },
368 { { 1, 60 }, OMX_VIDEO_HEVCHighTierLevel2 },
369 { { 1, 63 }, OMX_VIDEO_HEVCHighTierLevel21 },
370 { { 1, 90 }, OMX_VIDEO_HEVCHighTierLevel3 },
371 { { 1, 93 }, OMX_VIDEO_HEVCHighTierLevel31 },
372 { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4 },
373 { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
374 { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5 },
375 { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
376 { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
377 { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6 },
378 { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
379 { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
380 };
381
382 const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
383 { 1, OMX_VIDEO_HEVCProfileMain },
384 { 2, OMX_VIDEO_HEVCProfileMain10 },
385 // use Main for Main Still Picture decoding
386 { 3, OMX_VIDEO_HEVCProfileMain },
387 };
388
389 // set profile & level if they are recognized
390 OMX_VIDEO_HEVCPROFILETYPE codecProfile;
391 OMX_VIDEO_HEVCLEVELTYPE codecLevel;
392 if (!profiles.map(profile, &codecProfile)) {
393 if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
394 // Note that this case covers Main Still Picture too
395 codecProfile = OMX_VIDEO_HEVCProfileMain;
396 } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
397 codecProfile = OMX_VIDEO_HEVCProfileMain10;
398 } else {
399 return;
400 }
401 }
402
403 // bump to HDR profile
404 if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) {
405 codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
406 }
407
408 format->setInt32("profile", codecProfile);
409 if (levels.map(std::make_pair(tier, level), &codecLevel)) {
410 format->setInt32("level", codecLevel);
411 }
412 }
413
parseMpeg2ProfileLevelFromHeader(const uint8_t * data,size_t size,sp<AMessage> & format)414 static void parseMpeg2ProfileLevelFromHeader(
415 const uint8_t *data, size_t size, sp<AMessage> &format) {
416 // find sequence extension
417 const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
418 if (seq != NULL && seq + 5 < data + size) {
419 const uint8_t start_code = seq[4] >> 4;
420 if (start_code != 1 /* sequence extension ID */) {
421 return;
422 }
423 const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);
424
425 const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
426 { 0x50, OMX_VIDEO_MPEG2ProfileSimple },
427 { 0x40, OMX_VIDEO_MPEG2ProfileMain },
428 { 0x30, OMX_VIDEO_MPEG2ProfileSNR },
429 { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
430 { 0x10, OMX_VIDEO_MPEG2ProfileHigh },
431 };
432
433 const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
434 { 0x0A, OMX_VIDEO_MPEG2LevelLL },
435 { 0x08, OMX_VIDEO_MPEG2LevelML },
436 { 0x06, OMX_VIDEO_MPEG2LevelH14 },
437 { 0x04, OMX_VIDEO_MPEG2LevelHL },
438 { 0x02, OMX_VIDEO_MPEG2LevelHP },
439 };
440
441 const static ALookup<uint8_t,
442 std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
443 /* unsupported
444 { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL } },
445 { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML } },
446 { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
447 { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL } }, */
448 { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML } },
449 { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL } },
450 };
451
452 OMX_VIDEO_MPEG2PROFILETYPE profile;
453 OMX_VIDEO_MPEG2LEVELTYPE level;
454 std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
455 if (escapes.map(indication, &profileLevel)) {
456 format->setInt32("profile", profileLevel.first);
457 format->setInt32("level", profileLevel.second);
458 } else if (profiles.map(indication & 0x70, &profile)) {
459 format->setInt32("profile", profile);
460 if (levels.map(indication & 0xF, &level)) {
461 format->setInt32("level", level);
462 }
463 }
464 }
465 }
466
parseMpeg2ProfileLevelFromEsds(ESDS & esds,sp<AMessage> & format)467 static void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
468 // esds seems to only contain the profile for MPEG-2
469 uint8_t objType;
470 if (esds.getObjectTypeIndication(&objType) == OK) {
471 const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
472 { 0x60, OMX_VIDEO_MPEG2ProfileSimple },
473 { 0x61, OMX_VIDEO_MPEG2ProfileMain },
474 { 0x62, OMX_VIDEO_MPEG2ProfileSNR },
475 { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
476 { 0x64, OMX_VIDEO_MPEG2ProfileHigh },
477 { 0x65, OMX_VIDEO_MPEG2Profile422 },
478 };
479
480 OMX_VIDEO_MPEG2PROFILETYPE profile;
481 if (profiles.map(objType, &profile)) {
482 format->setInt32("profile", profile);
483 }
484 }
485 }
486
parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> & csd,sp<AMessage> & format)487 static void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
488 const uint8_t *data = csd->data();
489 // find visual object sequence
490 const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
491 if (seq != NULL && seq + 4 < data + csd->size()) {
492 const uint8_t indication = seq[4];
493
494 const static ALookup<uint8_t,
495 std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
496 { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1 } },
497 { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2 } },
498 { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3 } },
499 { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a } },
500 { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5 } },
501 { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level6 } },
502 { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0 } },
503 { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b } },
504 { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level0 } },
505 { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level1 } },
506 { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable, OMX_VIDEO_MPEG4Level2 } },
507 /* unsupported
508 { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level0 } },
509 { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level1 } },
510 { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER, OMX_VIDEO_MPEG4Level2 } }, */
511 { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level1 } },
512 { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 } },
513 { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level2 } },
514 { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level3 } },
515 { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain, OMX_VIDEO_MPEG4Level4 } },
516 /* deprecated
517 { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit, OMX_VIDEO_MPEG4Level2 } }, */
518 { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture, OMX_VIDEO_MPEG4Level1 } },
519 { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level1 } },
520 { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace, OMX_VIDEO_MPEG4Level2 } },
521 { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_MPEG4Level1 } },
522 { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA, OMX_VIDEO_MPEG4Level2 } },
523 { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level1 } },
524 { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated, OMX_VIDEO_MPEG4Level2 } },
525 { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level1 } },
526 { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid, OMX_VIDEO_MPEG4Level2 } },
527 { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level1 } },
528 { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level2 } },
529 { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level3 } },
530 { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime, OMX_VIDEO_MPEG4Level4 } },
531 { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level1 } },
532 { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level2 } },
533 { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable, OMX_VIDEO_MPEG4Level3 } },
534 { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level1 } },
535 { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level2 } },
536 { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level3 } },
537 { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding, OMX_VIDEO_MPEG4Level4 } },
538 { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level1 } },
539 { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore, OMX_VIDEO_MPEG4Level2 } },
540 { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level1 } },
541 { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level2 } },
542 { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable, OMX_VIDEO_MPEG4Level3 } },
543 /* unsupported
544 { 0b11100001, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level1 } },
545 { 0b11100010, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level2 } },
546 { 0b11100011, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level3 } },
547 { 0b11100100, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level4 } },
548 { 0b11100101, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level1 } },
549 { 0b11100110, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level2 } },
550 { 0b11100111, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level3 } },
551 { 0b11101000, { XXX_MPEG4ProfileCoreStudio, OMX_VIDEO_MPEG4Level4 } },
552 { 0b11101011, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level5 } },
553 { 0b11101100, { XXX_MPEG4ProfileSimpleStudio, OMX_VIDEO_MPEG4Level6 } }, */
554 { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0 } },
555 { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1 } },
556 { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2 } },
557 { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3 } },
558 { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4 } },
559 { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5 } },
560 { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3b } },
561 /* deprecated
562 { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0 } },
563 { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1 } },
564 { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2 } },
565 { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3 } },
566 { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4 } },
567 { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5 } }, */
568 };
569
570 std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
571 if (table.map(indication, &profileLevel)) {
572 format->setInt32("profile", profileLevel.first);
573 format->setInt32("level", profileLevel.second);
574 }
575 }
576 }
577
parseVp9ProfileLevelFromCsd(const sp<ABuffer> & csd,sp<AMessage> & format)578 static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
579 const uint8_t *data = csd->data();
580 size_t remaining = csd->size();
581
582 while (remaining >= 2) {
583 const uint8_t id = data[0];
584 const uint8_t length = data[1];
585 remaining -= 2;
586 data += 2;
587 if (length > remaining) {
588 break;
589 }
590 switch (id) {
591 case 1 /* profileId */:
592 if (length >= 1) {
593 const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
594 { 0, OMX_VIDEO_VP9Profile0 },
595 { 1, OMX_VIDEO_VP9Profile1 },
596 { 2, OMX_VIDEO_VP9Profile2 },
597 { 3, OMX_VIDEO_VP9Profile3 },
598 };
599
600 const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr {
601 { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR },
602 { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR },
603 };
604
605 OMX_VIDEO_VP9PROFILETYPE profile;
606 if (profiles.map(data[0], &profile)) {
607 // convert to HDR profile
608 if (isHdr(format)) {
609 toHdr.lookup(profile, &profile);
610 }
611
612 format->setInt32("profile", profile);
613 }
614 }
615 break;
616 case 2 /* levelId */:
617 if (length >= 1) {
618 const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
619 { 10, OMX_VIDEO_VP9Level1 },
620 { 11, OMX_VIDEO_VP9Level11 },
621 { 20, OMX_VIDEO_VP9Level2 },
622 { 21, OMX_VIDEO_VP9Level21 },
623 { 30, OMX_VIDEO_VP9Level3 },
624 { 31, OMX_VIDEO_VP9Level31 },
625 { 40, OMX_VIDEO_VP9Level4 },
626 { 41, OMX_VIDEO_VP9Level41 },
627 { 50, OMX_VIDEO_VP9Level5 },
628 { 51, OMX_VIDEO_VP9Level51 },
629 { 52, OMX_VIDEO_VP9Level52 },
630 { 60, OMX_VIDEO_VP9Level6 },
631 { 61, OMX_VIDEO_VP9Level61 },
632 { 62, OMX_VIDEO_VP9Level62 },
633 };
634
635 OMX_VIDEO_VP9LEVELTYPE level;
636 if (levels.map(data[0], &level)) {
637 format->setInt32("level", level);
638 }
639 }
640 break;
641 default:
642 break;
643 }
644 remaining -= length;
645 data += length;
646 }
647 }
648
parseAV1ProfileLevelFromCsd(const sp<ABuffer> & csd,sp<AMessage> & format)649 static void parseAV1ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
650 // Parse CSD structure to extract profile level information
651 // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox
652 const uint8_t *data = csd->data();
653 size_t remaining = csd->size();
654 if (remaining < 4 || data[0] != 0x81) { // configurationVersion == 1
655 return;
656 }
657 uint8_t profileData = (data[1] & 0xE0) >> 5;
658 uint8_t levelData = data[1] & 0x1F;
659 uint8_t highBitDepth = (data[2] & 0x40) >> 6;
660
661 const static ALookup<std::pair<uint8_t, uint8_t>, int32_t> profiles {
662 { { 0, 0 }, AV1ProfileMain8 },
663 { { 1, 0 }, AV1ProfileMain10 },
664 };
665
666 int32_t profile;
667 if (profiles.map(std::make_pair(highBitDepth, profileData), &profile)) {
668 // bump to HDR profile
669 if (isHdr(format) && profile == AV1ProfileMain10) {
670 if (format->contains("hdr10-plus-info")) {
671 profile = AV1ProfileMain10HDR10Plus;
672 } else {
673 profile = AV1ProfileMain10HDR10;
674 }
675 }
676 format->setInt32("profile", profile);
677 }
678 const static ALookup<uint8_t, int32_t> levels {
679 { 0, AV1Level2 },
680 { 1, AV1Level21 },
681 { 2, AV1Level22 },
682 { 3, AV1Level23 },
683 { 4, AV1Level3 },
684 { 5, AV1Level31 },
685 { 6, AV1Level32 },
686 { 7, AV1Level33 },
687 { 8, AV1Level4 },
688 { 9, AV1Level41 },
689 { 10, AV1Level42 },
690 { 11, AV1Level43 },
691 { 12, AV1Level5 },
692 { 13, AV1Level51 },
693 { 14, AV1Level52 },
694 { 15, AV1Level53 },
695 { 16, AV1Level6 },
696 { 17, AV1Level61 },
697 { 18, AV1Level62 },
698 { 19, AV1Level63 },
699 { 20, AV1Level7 },
700 { 21, AV1Level71 },
701 { 22, AV1Level72 },
702 { 23, AV1Level73 },
703 };
704
705 int32_t level;
706 if (levels.map(levelData, &level)) {
707 format->setInt32("level", level);
708 }
709 }
710
711
712 static std::vector<std::pair<const char *, uint32_t>> stringMappings {
713 {
714 { "album", kKeyAlbum },
715 { "albumartist", kKeyAlbumArtist },
716 { "artist", kKeyArtist },
717 { "author", kKeyAuthor },
718 { "cdtracknum", kKeyCDTrackNumber },
719 { "compilation", kKeyCompilation },
720 { "composer", kKeyComposer },
721 { "date", kKeyDate },
722 { "discnum", kKeyDiscNumber },
723 { "genre", kKeyGenre },
724 { "location", kKeyLocation },
725 { "lyricist", kKeyWriter },
726 { "manufacturer", kKeyManufacturer },
727 { "title", kKeyTitle },
728 { "year", kKeyYear },
729 }
730 };
731
732 static std::vector<std::pair<const char *, uint32_t>> floatMappings {
733 {
734 { "capture-rate", kKeyCaptureFramerate },
735 }
736 };
737
738 static std::vector<std::pair<const char*, uint32_t>> int64Mappings {
739 {
740 { "exif-offset", kKeyExifOffset},
741 { "exif-size", kKeyExifSize},
742 { "xmp-offset", kKeyXmpOffset},
743 { "xmp-size", kKeyXmpSize},
744 { "target-time", kKeyTargetTime},
745 { "thumbnail-time", kKeyThumbnailTime},
746 { "timeUs", kKeyTime},
747 { "durationUs", kKeyDuration},
748 { "sample-file-offset", kKeySampleFileOffset},
749 { "last-sample-index-in-chunk", kKeyLastSampleIndexInChunk},
750 { "sample-time-before-append", kKeySampleTimeBeforeAppend},
751 }
752 };
753
754 static std::vector<std::pair<const char *, uint32_t>> int32Mappings {
755 {
756 { "loop", kKeyAutoLoop },
757 { "time-scale", kKeyTimeScale },
758 { "crypto-mode", kKeyCryptoMode },
759 { "crypto-default-iv-size", kKeyCryptoDefaultIVSize },
760 { "crypto-encrypted-byte-block", kKeyEncryptedByteBlock },
761 { "crypto-skip-byte-block", kKeySkipByteBlock },
762 { "frame-count", kKeyFrameCount },
763 { "max-bitrate", kKeyMaxBitRate },
764 { "pcm-big-endian", kKeyPcmBigEndian },
765 { "temporal-layer-count", kKeyTemporalLayerCount },
766 { "temporal-layer-id", kKeyTemporalLayerId },
767 { "thumbnail-width", kKeyThumbnailWidth },
768 { "thumbnail-height", kKeyThumbnailHeight },
769 { "track-id", kKeyTrackID },
770 { "valid-samples", kKeyValidSamples },
771 }
772 };
773
774 static std::vector<std::pair<const char *, uint32_t>> bufferMappings {
775 {
776 { "albumart", kKeyAlbumArt },
777 { "audio-presentation-info", kKeyAudioPresentationInfo },
778 { "pssh", kKeyPssh },
779 { "crypto-iv", kKeyCryptoIV },
780 { "crypto-key", kKeyCryptoKey },
781 { "crypto-encrypted-sizes", kKeyEncryptedSizes },
782 { "crypto-plain-sizes", kKeyPlainSizes },
783 { "icc-profile", kKeyIccProfile },
784 { "sei", kKeySEI },
785 { "text-format-data", kKeyTextFormatData },
786 { "thumbnail-csd-hevc", kKeyThumbnailHVCC },
787 { "slow-motion-markers", kKeySlowMotionMarkers },
788 { "thumbnail-csd-av1c", kKeyThumbnailAV1C },
789 }
790 };
791
792 static std::vector<std::pair<const char *, uint32_t>> CSDMappings {
793 {
794 { "csd-0", kKeyOpaqueCSD0 },
795 { "csd-1", kKeyOpaqueCSD1 },
796 { "csd-2", kKeyOpaqueCSD2 },
797 }
798 };
799
convertMessageToMetaDataFromMappings(const sp<AMessage> & msg,sp<MetaData> & meta)800 void convertMessageToMetaDataFromMappings(const sp<AMessage> &msg, sp<MetaData> &meta) {
801 for (auto elem : stringMappings) {
802 AString value;
803 if (msg->findString(elem.first, &value)) {
804 meta->setCString(elem.second, value.c_str());
805 }
806 }
807
808 for (auto elem : floatMappings) {
809 float value;
810 if (msg->findFloat(elem.first, &value)) {
811 meta->setFloat(elem.second, value);
812 }
813 }
814
815 for (auto elem : int64Mappings) {
816 int64_t value;
817 if (msg->findInt64(elem.first, &value)) {
818 meta->setInt64(elem.second, value);
819 }
820 }
821
822 for (auto elem : int32Mappings) {
823 int32_t value;
824 if (msg->findInt32(elem.first, &value)) {
825 meta->setInt32(elem.second, value);
826 }
827 }
828
829 for (auto elem : bufferMappings) {
830 sp<ABuffer> value;
831 if (msg->findBuffer(elem.first, &value)) {
832 meta->setData(elem.second,
833 MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
834 }
835 }
836
837 for (auto elem : CSDMappings) {
838 sp<ABuffer> value;
839 if (msg->findBuffer(elem.first, &value)) {
840 meta->setData(elem.second,
841 MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
842 }
843 }
844 }
845
convertMetaDataToMessageFromMappings(const MetaDataBase * meta,sp<AMessage> format)846 void convertMetaDataToMessageFromMappings(const MetaDataBase *meta, sp<AMessage> format) {
847 for (auto elem : stringMappings) {
848 const char *value;
849 if (meta->findCString(elem.second, &value)) {
850 format->setString(elem.first, value, strlen(value));
851 }
852 }
853
854 for (auto elem : floatMappings) {
855 float value;
856 if (meta->findFloat(elem.second, &value)) {
857 format->setFloat(elem.first, value);
858 }
859 }
860
861 for (auto elem : int64Mappings) {
862 int64_t value;
863 if (meta->findInt64(elem.second, &value)) {
864 format->setInt64(elem.first, value);
865 }
866 }
867
868 for (auto elem : int32Mappings) {
869 int32_t value;
870 if (meta->findInt32(elem.second, &value)) {
871 format->setInt32(elem.first, value);
872 }
873 }
874
875 for (auto elem : bufferMappings) {
876 uint32_t type;
877 const void* data;
878 size_t size;
879 if (meta->findData(elem.second, &type, &data, &size)) {
880 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
881 format->setBuffer(elem.first, buf);
882 }
883 }
884
885 for (auto elem : CSDMappings) {
886 uint32_t type;
887 const void* data;
888 size_t size;
889 if (meta->findData(elem.second, &type, &data, &size)) {
890 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
891 buf->meta()->setInt32("csd", true);
892 buf->meta()->setInt64("timeUs", 0);
893 format->setBuffer(elem.first, buf);
894 }
895 }
896 }
897
convertMetaDataToMessage(const sp<MetaData> & meta,sp<AMessage> * format)898 status_t convertMetaDataToMessage(
899 const sp<MetaData> &meta, sp<AMessage> *format) {
900 return convertMetaDataToMessage(meta.get(), format);
901 }
902
convertMetaDataToMessage(const MetaDataBase * meta,sp<AMessage> * format)903 status_t convertMetaDataToMessage(
904 const MetaDataBase *meta, sp<AMessage> *format) {
905
906 format->clear();
907
908 if (meta == NULL) {
909 ALOGE("convertMetaDataToMessage: NULL input");
910 return BAD_VALUE;
911 }
912
913 const char *mime;
914 if (!meta->findCString(kKeyMIMEType, &mime)) {
915 return BAD_VALUE;
916 }
917
918 sp<AMessage> msg = new AMessage;
919 msg->setString("mime", mime);
920
921 convertMetaDataToMessageFromMappings(meta, msg);
922
923 uint32_t type;
924 const void *data;
925 size_t size;
926 if (meta->findData(kKeyCASessionID, &type, &data, &size)) {
927 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
928 if (buffer.get() == NULL || buffer->base() == NULL) {
929 return NO_MEMORY;
930 }
931
932 msg->setBuffer("ca-session-id", buffer);
933 memcpy(buffer->data(), data, size);
934 }
935
936 if (meta->findData(kKeyCAPrivateData, &type, &data, &size)) {
937 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
938 if (buffer.get() == NULL || buffer->base() == NULL) {
939 return NO_MEMORY;
940 }
941
942 msg->setBuffer("ca-private-data", buffer);
943 memcpy(buffer->data(), data, size);
944 }
945
946 int32_t systemId;
947 if (meta->findInt32(kKeyCASystemID, &systemId)) {
948 msg->setInt32("ca-system-id", systemId);
949 }
950
951 if (!strncasecmp("video/scrambled", mime, 15)
952 || !strncasecmp("audio/scrambled", mime, 15)) {
953
954 *format = msg;
955 return OK;
956 }
957
958 int64_t durationUs;
959 if (meta->findInt64(kKeyDuration, &durationUs)) {
960 msg->setInt64("durationUs", durationUs);
961 }
962
963 int32_t avgBitRate = 0;
964 if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
965 msg->setInt32("bitrate", avgBitRate);
966 }
967
968 int32_t maxBitRate;
969 if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
970 && maxBitRate > 0 && maxBitRate >= avgBitRate) {
971 msg->setInt32("max-bitrate", maxBitRate);
972 }
973
974 int32_t isSync;
975 if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
976 msg->setInt32("is-sync-frame", 1);
977 }
978
979 const char *lang;
980 if (meta->findCString(kKeyMediaLanguage, &lang)) {
981 msg->setString("language", lang);
982 }
983
984 if (!strncasecmp("video/", mime, 6) ||
985 !strncasecmp("image/", mime, 6)) {
986 int32_t width, height;
987 if (!meta->findInt32(kKeyWidth, &width)
988 || !meta->findInt32(kKeyHeight, &height)) {
989 return BAD_VALUE;
990 }
991
992 msg->setInt32("width", width);
993 msg->setInt32("height", height);
994
995 int32_t displayWidth, displayHeight;
996 if (meta->findInt32(kKeyDisplayWidth, &displayWidth)
997 && meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
998 msg->setInt32("display-width", displayWidth);
999 msg->setInt32("display-height", displayHeight);
1000 }
1001
1002 int32_t sarWidth, sarHeight;
1003 if (meta->findInt32(kKeySARWidth, &sarWidth)
1004 && meta->findInt32(kKeySARHeight, &sarHeight)) {
1005 msg->setInt32("sar-width", sarWidth);
1006 msg->setInt32("sar-height", sarHeight);
1007 }
1008
1009 if (!strncasecmp("image/", mime, 6)) {
1010 int32_t tileWidth, tileHeight, gridRows, gridCols;
1011 if (meta->findInt32(kKeyTileWidth, &tileWidth)
1012 && meta->findInt32(kKeyTileHeight, &tileHeight)
1013 && meta->findInt32(kKeyGridRows, &gridRows)
1014 && meta->findInt32(kKeyGridCols, &gridCols)) {
1015 msg->setInt32("tile-width", tileWidth);
1016 msg->setInt32("tile-height", tileHeight);
1017 msg->setInt32("grid-rows", gridRows);
1018 msg->setInt32("grid-cols", gridCols);
1019 }
1020 int32_t isPrimary;
1021 if (meta->findInt32(kKeyTrackIsDefault, &isPrimary) && isPrimary) {
1022 msg->setInt32("is-default", 1);
1023 }
1024 }
1025
1026 int32_t colorFormat;
1027 if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
1028 msg->setInt32("color-format", colorFormat);
1029 }
1030
1031 int32_t cropLeft, cropTop, cropRight, cropBottom;
1032 if (meta->findRect(kKeyCropRect,
1033 &cropLeft,
1034 &cropTop,
1035 &cropRight,
1036 &cropBottom)) {
1037 msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
1038 }
1039
1040 int32_t rotationDegrees;
1041 if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
1042 msg->setInt32("rotation-degrees", rotationDegrees);
1043 }
1044
1045 uint32_t type;
1046 const void *data;
1047 size_t size;
1048 if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
1049 && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
1050 ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
1051 }
1052
1053 if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size)
1054 && size > 0) {
1055 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1056 if (buffer.get() == NULL || buffer->base() == NULL) {
1057 return NO_MEMORY;
1058 }
1059 memcpy(buffer->data(), data, size);
1060 msg->setBuffer("hdr10-plus-info", buffer);
1061 }
1062
1063 convertMetaDataToMessageColorAspects(meta, msg);
1064 } else if (!strncasecmp("audio/", mime, 6)) {
1065 int32_t numChannels, sampleRate;
1066 if (!meta->findInt32(kKeyChannelCount, &numChannels)
1067 || !meta->findInt32(kKeySampleRate, &sampleRate)) {
1068 return BAD_VALUE;
1069 }
1070
1071 msg->setInt32("channel-count", numChannels);
1072 msg->setInt32("sample-rate", sampleRate);
1073
1074 int32_t bitsPerSample;
1075 if (meta->findInt32(kKeyBitsPerSample, &bitsPerSample)) {
1076 msg->setInt32("bits-per-sample", bitsPerSample);
1077 }
1078
1079 int32_t channelMask;
1080 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
1081 msg->setInt32("channel-mask", channelMask);
1082 }
1083
1084 int32_t delay = 0;
1085 if (meta->findInt32(kKeyEncoderDelay, &delay)) {
1086 msg->setInt32("encoder-delay", delay);
1087 }
1088 int32_t padding = 0;
1089 if (meta->findInt32(kKeyEncoderPadding, &padding)) {
1090 msg->setInt32("encoder-padding", padding);
1091 }
1092
1093 int32_t isADTS;
1094 if (meta->findInt32(kKeyIsADTS, &isADTS)) {
1095 msg->setInt32("is-adts", isADTS);
1096 }
1097
1098 int32_t mpeghProfileLevelIndication;
1099 if (meta->findInt32(kKeyMpeghProfileLevelIndication, &mpeghProfileLevelIndication)) {
1100 msg->setInt32(AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
1101 mpeghProfileLevelIndication);
1102 }
1103 int32_t mpeghReferenceChannelLayout;
1104 if (meta->findInt32(kKeyMpeghReferenceChannelLayout, &mpeghReferenceChannelLayout)) {
1105 msg->setInt32(AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
1106 mpeghReferenceChannelLayout);
1107 }
1108 if (meta->findData(kKeyMpeghCompatibleSets, &type, &data, &size)) {
1109 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1110 if (buffer.get() == NULL || buffer->base() == NULL) {
1111 return NO_MEMORY;
1112 }
1113 msg->setBuffer(AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS, buffer);
1114 memcpy(buffer->data(), data, size);
1115 }
1116
1117 int32_t aacProfile = -1;
1118 if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
1119 msg->setInt32("aac-profile", aacProfile);
1120 }
1121
1122 int32_t pcmEncoding;
1123 if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
1124 msg->setInt32("pcm-encoding", pcmEncoding);
1125 }
1126
1127 int32_t hapticChannelCount;
1128 if (meta->findInt32(kKeyHapticChannelCount, &hapticChannelCount)) {
1129 msg->setInt32("haptic-channel-count", hapticChannelCount);
1130 }
1131 }
1132
1133 int32_t maxInputSize;
1134 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
1135 msg->setInt32("max-input-size", maxInputSize);
1136 }
1137
1138 int32_t maxWidth;
1139 if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
1140 msg->setInt32("max-width", maxWidth);
1141 }
1142
1143 int32_t maxHeight;
1144 if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
1145 msg->setInt32("max-height", maxHeight);
1146 }
1147
1148 int32_t rotationDegrees;
1149 if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
1150 msg->setInt32("rotation-degrees", rotationDegrees);
1151 }
1152
1153 int32_t fps;
1154 if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
1155 msg->setInt32("frame-rate", fps);
1156 }
1157
1158 if (meta->findData(kKeyAVCC, &type, &data, &size)) {
1159 // Parse the AVCDecoderConfigurationRecord
1160
1161 const uint8_t *ptr = (const uint8_t *)data;
1162
1163 if (size < 7 || ptr[0] != 1) { // configurationVersion == 1
1164 ALOGE("b/23680780");
1165 return BAD_VALUE;
1166 }
1167
1168 parseAvcProfileLevelFromAvcc(ptr, size, msg);
1169
1170 // There is decodable content out there that fails the following
1171 // assertion, let's be lenient for now...
1172 // CHECK((ptr[4] >> 2) == 0x3f); // reserved
1173
1174 // we can get lengthSize value from 1 + (ptr[4] & 3)
1175
1176 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
1177 // violates it...
1178 // CHECK((ptr[5] >> 5) == 7); // reserved
1179
1180 size_t numSeqParameterSets = ptr[5] & 31;
1181
1182 ptr += 6;
1183 size -= 6;
1184
1185 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
1186 if (buffer.get() == NULL || buffer->base() == NULL) {
1187 return NO_MEMORY;
1188 }
1189 buffer->setRange(0, 0);
1190
1191 for (size_t i = 0; i < numSeqParameterSets; ++i) {
1192 if (size < 2) {
1193 ALOGE("b/23680780");
1194 return BAD_VALUE;
1195 }
1196 size_t length = U16_AT(ptr);
1197
1198 ptr += 2;
1199 size -= 2;
1200
1201 if (size < length) {
1202 return BAD_VALUE;
1203 }
1204 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1205 if (err != OK) {
1206 return err;
1207 }
1208
1209 ptr += length;
1210 size -= length;
1211 }
1212
1213 buffer->meta()->setInt32("csd", true);
1214 buffer->meta()->setInt64("timeUs", 0);
1215
1216 msg->setBuffer("csd-0", buffer);
1217
1218 buffer = new (std::nothrow) ABuffer(1024);
1219 if (buffer.get() == NULL || buffer->base() == NULL) {
1220 return NO_MEMORY;
1221 }
1222 buffer->setRange(0, 0);
1223
1224 if (size < 1) {
1225 ALOGE("b/23680780");
1226 return BAD_VALUE;
1227 }
1228 size_t numPictureParameterSets = *ptr;
1229 ++ptr;
1230 --size;
1231
1232 for (size_t i = 0; i < numPictureParameterSets; ++i) {
1233 if (size < 2) {
1234 ALOGE("b/23680780");
1235 return BAD_VALUE;
1236 }
1237 size_t length = U16_AT(ptr);
1238
1239 ptr += 2;
1240 size -= 2;
1241
1242 if (size < length) {
1243 return BAD_VALUE;
1244 }
1245 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1246 if (err != OK) {
1247 return err;
1248 }
1249
1250 ptr += length;
1251 size -= length;
1252 }
1253
1254 buffer->meta()->setInt32("csd", true);
1255 buffer->meta()->setInt64("timeUs", 0);
1256 msg->setBuffer("csd-1", buffer);
1257 } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
1258 const uint8_t *ptr = (const uint8_t *)data;
1259
1260 if (size < 23 || (ptr[0] != 1 && ptr[0] != 0)) {
1261 // configurationVersion == 1 or 0
1262 // 1 is what the standard dictates, but some old muxers may have used 0.
1263 ALOGE("b/23680780");
1264 return BAD_VALUE;
1265 }
1266
1267 const size_t dataSize = size; // save for later
1268 ptr += 22;
1269 size -= 22;
1270
1271 size_t numofArrays = (char)ptr[0];
1272 ptr += 1;
1273 size -= 1;
1274 size_t j = 0, i = 0;
1275
1276 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
1277 if (buffer.get() == NULL || buffer->base() == NULL) {
1278 return NO_MEMORY;
1279 }
1280 buffer->setRange(0, 0);
1281
1282 HevcParameterSets hvcc;
1283
1284 for (i = 0; i < numofArrays; i++) {
1285 if (size < 3) {
1286 ALOGE("b/23680780");
1287 return BAD_VALUE;
1288 }
1289 ptr += 1;
1290 size -= 1;
1291
1292 //Num of nals
1293 size_t numofNals = U16_AT(ptr);
1294
1295 ptr += 2;
1296 size -= 2;
1297
1298 for (j = 0; j < numofNals; j++) {
1299 if (size < 2) {
1300 ALOGE("b/23680780");
1301 return BAD_VALUE;
1302 }
1303 size_t length = U16_AT(ptr);
1304
1305 ptr += 2;
1306 size -= 2;
1307
1308 if (size < length) {
1309 return BAD_VALUE;
1310 }
1311 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1312 if (err != OK) {
1313 return err;
1314 }
1315 (void)hvcc.addNalUnit(ptr, length);
1316
1317 ptr += length;
1318 size -= length;
1319 }
1320 }
1321 buffer->meta()->setInt32("csd", true);
1322 buffer->meta()->setInt64("timeUs", 0);
1323 msg->setBuffer("csd-0", buffer);
1324
1325 // if we saw VUI color information we know whether this is HDR because VUI trumps other
1326 // format parameters for HEVC.
1327 HevcParameterSets::Info info = hvcc.getInfo();
1328 if (info & hvcc.kInfoHasColorDescription) {
1329 msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
1330 }
1331
1332 uint32_t isoPrimaries, isoTransfer, isoMatrix, isoRange;
1333 if (hvcc.findParam32(kColourPrimaries, &isoPrimaries)
1334 && hvcc.findParam32(kTransferCharacteristics, &isoTransfer)
1335 && hvcc.findParam32(kMatrixCoeffs, &isoMatrix)
1336 && hvcc.findParam32(kVideoFullRangeFlag, &isoRange)) {
1337 ALOGV("found iso color aspects : primaris=%d, transfer=%d, matrix=%d, range=%d",
1338 isoPrimaries, isoTransfer, isoMatrix, isoRange);
1339
1340 ColorAspects aspects;
1341 ColorUtils::convertIsoColorAspectsToCodecAspects(
1342 isoPrimaries, isoTransfer, isoMatrix, isoRange, aspects);
1343
1344 if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
1345 int32_t primaries;
1346 if (meta->findInt32(kKeyColorPrimaries, &primaries)) {
1347 ALOGV("unspecified primaries found, replaced to %d", primaries);
1348 aspects.mPrimaries = static_cast<ColorAspects::Primaries>(primaries);
1349 }
1350 }
1351 if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
1352 int32_t transferFunction;
1353 if (meta->findInt32(kKeyTransferFunction, &transferFunction)) {
1354 ALOGV("unspecified transfer found, replaced to %d", transferFunction);
1355 aspects.mTransfer = static_cast<ColorAspects::Transfer>(transferFunction);
1356 }
1357 }
1358 if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
1359 int32_t colorMatrix;
1360 if (meta->findInt32(kKeyColorMatrix, &colorMatrix)) {
1361 ALOGV("unspecified matrix found, replaced to %d", colorMatrix);
1362 aspects.mMatrixCoeffs = static_cast<ColorAspects::MatrixCoeffs>(colorMatrix);
1363 }
1364 }
1365 if (aspects.mRange == ColorAspects::RangeUnspecified) {
1366 int32_t range;
1367 if (meta->findInt32(kKeyColorRange, &range)) {
1368 ALOGV("unspecified range found, replaced to %d", range);
1369 aspects.mRange = static_cast<ColorAspects::Range>(range);
1370 }
1371 }
1372
1373 int32_t standard, transfer, range;
1374 if (ColorUtils::convertCodecColorAspectsToPlatformAspects(
1375 aspects, &range, &standard, &transfer) == OK) {
1376 msg->setInt32("color-standard", standard);
1377 msg->setInt32("color-transfer", transfer);
1378 msg->setInt32("color-range", range);
1379 }
1380 }
1381
1382 parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
1383 } else if (meta->findData(kKeyAV1C, &type, &data, &size)) {
1384 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1385 if (buffer.get() == NULL || buffer->base() == NULL) {
1386 return NO_MEMORY;
1387 }
1388 memcpy(buffer->data(), data, size);
1389
1390 buffer->meta()->setInt32("csd", true);
1391 buffer->meta()->setInt64("timeUs", 0);
1392 msg->setBuffer("csd-0", buffer);
1393 parseAV1ProfileLevelFromCsd(buffer, msg);
1394 } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
1395 ESDS esds((const char *)data, size);
1396 if (esds.InitCheck() != (status_t)OK) {
1397 return BAD_VALUE;
1398 }
1399
1400 const void *codec_specific_data;
1401 size_t codec_specific_data_size;
1402 esds.getCodecSpecificInfo(
1403 &codec_specific_data, &codec_specific_data_size);
1404
1405 sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
1406 if (buffer.get() == NULL || buffer->base() == NULL) {
1407 return NO_MEMORY;
1408 }
1409
1410 memcpy(buffer->data(), codec_specific_data,
1411 codec_specific_data_size);
1412
1413 buffer->meta()->setInt32("csd", true);
1414 buffer->meta()->setInt64("timeUs", 0);
1415 msg->setBuffer("csd-0", buffer);
1416
1417 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
1418 parseMpeg4ProfileLevelFromCsd(buffer, msg);
1419 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
1420 parseMpeg2ProfileLevelFromEsds(esds, msg);
1421 if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
1422 parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
1423 }
1424 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1425 parseAacProfileFromCsd(buffer, msg);
1426 }
1427
1428 uint32_t maxBitrate, avgBitrate;
1429 if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
1430 if (!meta->hasData(kKeyBitRate)
1431 && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
1432 msg->setInt32("bitrate", (int32_t)avgBitrate);
1433 } else {
1434 (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
1435 }
1436 if (!meta->hasData(kKeyMaxBitRate)
1437 && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
1438 msg->setInt32("max-bitrate", (int32_t)maxBitrate);
1439 }
1440 }
1441 } else if (meta->findData(kKeyD263, &type, &data, &size)) {
1442 const uint8_t *ptr = (const uint8_t *)data;
1443 parseH263ProfileLevelFromD263(ptr, size, msg);
1444 } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
1445 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1446 if (buffer.get() == NULL || buffer->base() == NULL) {
1447 return NO_MEMORY;
1448 }
1449 memcpy(buffer->data(), data, size);
1450
1451 buffer->meta()->setInt32("csd", true);
1452 buffer->meta()->setInt64("timeUs", 0);
1453 msg->setBuffer("csd-0", buffer);
1454
1455 if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
1456 return -EINVAL;
1457 }
1458
1459 buffer = new (std::nothrow) ABuffer(size);
1460 if (buffer.get() == NULL || buffer->base() == NULL) {
1461 return NO_MEMORY;
1462 }
1463 memcpy(buffer->data(), data, size);
1464
1465 buffer->meta()->setInt32("csd", true);
1466 buffer->meta()->setInt64("timeUs", 0);
1467 msg->setBuffer("csd-1", buffer);
1468
1469 if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
1470 return -EINVAL;
1471 }
1472
1473 buffer = new (std::nothrow) ABuffer(size);
1474 if (buffer.get() == NULL || buffer->base() == NULL) {
1475 return NO_MEMORY;
1476 }
1477 memcpy(buffer->data(), data, size);
1478
1479 buffer->meta()->setInt32("csd", true);
1480 buffer->meta()->setInt64("timeUs", 0);
1481 msg->setBuffer("csd-2", buffer);
1482 } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
1483 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1484 if (buffer.get() == NULL || buffer->base() == NULL) {
1485 return NO_MEMORY;
1486 }
1487 memcpy(buffer->data(), data, size);
1488
1489 buffer->meta()->setInt32("csd", true);
1490 buffer->meta()->setInt64("timeUs", 0);
1491 msg->setBuffer("csd-0", buffer);
1492
1493 parseVp9ProfileLevelFromCsd(buffer, msg);
1494 } else if (meta->findData(kKeyAlacMagicCookie, &type, &data, &size)) {
1495 ALOGV("convertMetaDataToMessage found kKeyAlacMagicCookie of size %zu\n", size);
1496 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1497 if (buffer.get() == NULL || buffer->base() == NULL) {
1498 return NO_MEMORY;
1499 }
1500 memcpy(buffer->data(), data, size);
1501
1502 buffer->meta()->setInt32("csd", true);
1503 buffer->meta()->setInt64("timeUs", 0);
1504 msg->setBuffer("csd-0", buffer);
1505 }
1506
1507 if (meta->findData(kKeyDVCC, &type, &data, &size)) {
1508 const uint8_t *ptr = (const uint8_t *)data;
1509 ALOGV("DV: calling parseDolbyVisionProfileLevelFromDvcc with data size %zu", size);
1510 parseDolbyVisionProfileLevelFromDvcc(ptr, size, msg);
1511 }
1512
1513 *format = msg;
1514
1515 return OK;
1516 }
1517
findNextNalStartCode(const uint8_t * data,size_t length)1518 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
1519 uint8_t *res = NULL;
1520 if (length > 4) {
1521 // minus 1 as to not match NAL start code at end
1522 res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
1523 }
1524 return res != NULL && res < data + length - 4 ? res : &data[length];
1525 }
1526
reassembleAVCC(const sp<ABuffer> & csd0,const sp<ABuffer> & csd1,char * avcc)1527 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> &csd1, char *avcc) {
1528 avcc[0] = 1; // version
1529 avcc[1] = 0x64; // profile (default to high)
1530 avcc[2] = 0; // constraints (default to none)
1531 avcc[3] = 0xd; // level (default to 1.3)
1532 avcc[4] = 0xff; // reserved+size
1533
1534 size_t i = 0;
1535 int numparams = 0;
1536 int lastparamoffset = 0;
1537 int avccidx = 6;
1538 do {
1539 i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
1540 ALOGV("block at %zu, last was %d", i, lastparamoffset);
1541 if (lastparamoffset > 0) {
1542 const uint8_t *lastparam = csd0->data() + lastparamoffset;
1543 int size = i - lastparamoffset;
1544 if (size > 3) {
1545 if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
1546 ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
1547 avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
1548 } else if (!numparams) {
1549 // fill in profile, constraints and level
1550 memcpy(avcc + 1, lastparam + 1, 3);
1551 }
1552 }
1553 avcc[avccidx++] = size >> 8;
1554 avcc[avccidx++] = size & 0xff;
1555 memcpy(avcc+avccidx, lastparam, size);
1556 avccidx += size;
1557 numparams++;
1558 }
1559 i += 4;
1560 lastparamoffset = i;
1561 } while(i < csd0->size());
1562 ALOGV("csd0 contains %d params", numparams);
1563
1564 avcc[5] = 0xe0 | numparams;
1565 //and now csd-1
1566 i = 0;
1567 numparams = 0;
1568 lastparamoffset = 0;
1569 int numpicparamsoffset = avccidx;
1570 avccidx++;
1571 do {
1572 i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
1573 ALOGV("block at %zu, last was %d", i, lastparamoffset);
1574 if (lastparamoffset > 0) {
1575 int size = i - lastparamoffset;
1576 avcc[avccidx++] = size >> 8;
1577 avcc[avccidx++] = size & 0xff;
1578 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
1579 avccidx += size;
1580 numparams++;
1581 }
1582 i += 4;
1583 lastparamoffset = i;
1584 } while(i < csd1->size());
1585 avcc[numpicparamsoffset] = numparams;
1586 return avccidx;
1587 }
1588
reassembleESDS(const sp<ABuffer> & csd0,char * esds)1589 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
1590 int csd0size = csd0->size();
1591 esds[0] = 3; // kTag_ESDescriptor;
1592 int esdescriptorsize = 26 + csd0size;
1593 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
1594 esds[1] = 0x80 | (esdescriptorsize >> 21);
1595 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
1596 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
1597 esds[4] = (esdescriptorsize & 0x7f);
1598 esds[5] = esds[6] = 0; // es id
1599 esds[7] = 0; // flags
1600 esds[8] = 4; // kTag_DecoderConfigDescriptor
1601 int configdescriptorsize = 18 + csd0size;
1602 esds[9] = 0x80 | (configdescriptorsize >> 21);
1603 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
1604 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
1605 esds[12] = (configdescriptorsize & 0x7f);
1606 esds[13] = 0x40; // objectTypeIndication
1607 // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
1608 esds[14] = 0x15; // streamType(5), upStream(0),
1609 esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
1610 esds[16] = 0x18;
1611 esds[17] = 0x00;
1612 esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
1613 esds[19] = 0x00;
1614 esds[20] = 0xfa;
1615 esds[21] = 0x00;
1616 esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
1617 esds[23] = 0x00;
1618 esds[24] = 0xfa;
1619 esds[25] = 0x00;
1620 esds[26] = 5; // kTag_DecoderSpecificInfo;
1621 esds[27] = 0x80 | (csd0size >> 21);
1622 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
1623 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
1624 esds[30] = (csd0size & 0x7f);
1625 memcpy((void*)&esds[31], csd0->data(), csd0size);
1626 // data following this is ignored, so don't bother appending it
1627 }
1628
reassembleHVCC(const sp<ABuffer> & csd0,uint8_t * hvcc,size_t hvccSize,size_t nalSizeLength)1629 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
1630 HevcParameterSets paramSets;
1631 uint8_t* data = csd0->data();
1632 if (csd0->size() < 4) {
1633 ALOGE("csd0 too small");
1634 return 0;
1635 }
1636 if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
1637 ALOGE("csd0 doesn't start with a start code");
1638 return 0;
1639 }
1640 size_t prevNalOffset = 4;
1641 status_t err = OK;
1642 for (size_t i = 1; i < csd0->size() - 4; ++i) {
1643 if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
1644 continue;
1645 }
1646 err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
1647 if (err != OK) {
1648 return 0;
1649 }
1650 prevNalOffset = i + 4;
1651 }
1652 err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
1653 if (err != OK) {
1654 return 0;
1655 }
1656 size_t size = hvccSize;
1657 err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
1658 if (err != OK) {
1659 return 0;
1660 }
1661 return size;
1662 }
1663
1664 #if 0
1665 static void convertMessageToMetaDataInt32(
1666 const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
1667 int32_t value;
1668 if (msg->findInt32(name, &value)) {
1669 meta->setInt32(key, value);
1670 }
1671 }
1672 #endif
1673
convertMessageToMetaDataColorAspects(const sp<AMessage> & msg,sp<MetaData> & meta)1674 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
1675 // 0 values are unspecified
1676 int32_t range = 0, standard = 0, transfer = 0;
1677 (void)msg->findInt32("color-range", &range);
1678 (void)msg->findInt32("color-standard", &standard);
1679 (void)msg->findInt32("color-transfer", &transfer);
1680
1681 ColorAspects colorAspects;
1682 memset(&colorAspects, 0, sizeof(colorAspects));
1683 if (CodecBase::convertPlatformColorAspectsToCodecAspects(
1684 range, standard, transfer, colorAspects) != OK) {
1685 return;
1686 }
1687
1688 // save specified values to meta
1689 if (colorAspects.mRange != 0) {
1690 meta->setInt32(kKeyColorRange, colorAspects.mRange);
1691 }
1692 if (colorAspects.mPrimaries != 0) {
1693 meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
1694 }
1695 if (colorAspects.mTransfer != 0) {
1696 meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
1697 }
1698 if (colorAspects.mMatrixCoeffs != 0) {
1699 meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
1700 }
1701 }
1702 /* Converts key and value pairs in AMessage format to MetaData format.
1703 * Also checks for the presence of required keys.
1704 */
convertMessageToMetaData(const sp<AMessage> & msg,sp<MetaData> & meta)1705 status_t convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
1706 AString mime;
1707 if (msg->findString("mime", &mime)) {
1708 meta->setCString(kKeyMIMEType, mime.c_str());
1709 } else {
1710 ALOGV("did not find mime type");
1711 return BAD_VALUE;
1712 }
1713
1714 convertMessageToMetaDataFromMappings(msg, meta);
1715
1716 int32_t systemId;
1717 if (msg->findInt32("ca-system-id", &systemId)) {
1718 meta->setInt32(kKeyCASystemID, systemId);
1719
1720 sp<ABuffer> caSessionId, caPvtData;
1721 if (msg->findBuffer("ca-session-id", &caSessionId)) {
1722 meta->setData(kKeyCASessionID, 0, caSessionId->data(), caSessionId->size());
1723 }
1724 if (msg->findBuffer("ca-private-data", &caPvtData)) {
1725 meta->setData(kKeyCAPrivateData, 0, caPvtData->data(), caPvtData->size());
1726 }
1727 }
1728
1729 int64_t durationUs;
1730 if (msg->findInt64("durationUs", &durationUs)) {
1731 meta->setInt64(kKeyDuration, durationUs);
1732 }
1733
1734 int32_t isSync;
1735 if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
1736 meta->setInt32(kKeyIsSyncFrame, 1);
1737 }
1738
1739 // Mode for media transcoding.
1740 int32_t isBackgroundMode;
1741 if (msg->findInt32("android._background-mode", &isBackgroundMode) && isBackgroundMode != 0) {
1742 meta->setInt32(isBackgroundMode, 1);
1743 }
1744
1745 int32_t avgBitrate = 0;
1746 int32_t maxBitrate;
1747 if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
1748 meta->setInt32(kKeyBitRate, avgBitrate);
1749 }
1750 if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
1751 meta->setInt32(kKeyMaxBitRate, maxBitrate);
1752 }
1753
1754 AString lang;
1755 if (msg->findString("language", &lang)) {
1756 meta->setCString(kKeyMediaLanguage, lang.c_str());
1757 }
1758
1759 if (mime.startsWith("video/") || mime.startsWith("image/")) {
1760 int32_t width;
1761 int32_t height;
1762 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
1763 meta->setInt32(kKeyWidth, width);
1764 meta->setInt32(kKeyHeight, height);
1765 } else {
1766 ALOGV("did not find width and/or height");
1767 return BAD_VALUE;
1768 }
1769
1770 int32_t sarWidth, sarHeight;
1771 if (msg->findInt32("sar-width", &sarWidth)
1772 && msg->findInt32("sar-height", &sarHeight)) {
1773 meta->setInt32(kKeySARWidth, sarWidth);
1774 meta->setInt32(kKeySARHeight, sarHeight);
1775 }
1776
1777 int32_t displayWidth, displayHeight;
1778 if (msg->findInt32("display-width", &displayWidth)
1779 && msg->findInt32("display-height", &displayHeight)) {
1780 meta->setInt32(kKeyDisplayWidth, displayWidth);
1781 meta->setInt32(kKeyDisplayHeight, displayHeight);
1782 }
1783
1784 if (mime.startsWith("image/")){
1785 int32_t isPrimary;
1786 if (msg->findInt32("is-default", &isPrimary) && isPrimary) {
1787 meta->setInt32(kKeyTrackIsDefault, 1);
1788 }
1789 int32_t tileWidth, tileHeight, gridRows, gridCols;
1790 if (msg->findInt32("tile-width", &tileWidth)) {
1791 meta->setInt32(kKeyTileWidth, tileWidth);
1792 }
1793 if (msg->findInt32("tile-height", &tileHeight)) {
1794 meta->setInt32(kKeyTileHeight, tileHeight);
1795 }
1796 if (msg->findInt32("grid-rows", &gridRows)) {
1797 meta->setInt32(kKeyGridRows, gridRows);
1798 }
1799 if (msg->findInt32("grid-cols", &gridCols)) {
1800 meta->setInt32(kKeyGridCols, gridCols);
1801 }
1802 }
1803
1804 int32_t colorFormat;
1805 if (msg->findInt32("color-format", &colorFormat)) {
1806 meta->setInt32(kKeyColorFormat, colorFormat);
1807 }
1808
1809 int32_t cropLeft, cropTop, cropRight, cropBottom;
1810 if (msg->findRect("crop",
1811 &cropLeft,
1812 &cropTop,
1813 &cropRight,
1814 &cropBottom)) {
1815 meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
1816 }
1817
1818 int32_t rotationDegrees;
1819 if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1820 meta->setInt32(kKeyRotation, rotationDegrees);
1821 }
1822
1823 if (msg->contains("hdr-static-info")) {
1824 HDRStaticInfo info;
1825 if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
1826 meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
1827 }
1828 }
1829
1830 sp<ABuffer> hdr10PlusInfo;
1831 if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
1832 meta->setData(kKeyHdr10PlusInfo, 0,
1833 hdr10PlusInfo->data(), hdr10PlusInfo->size());
1834 }
1835
1836 convertMessageToMetaDataColorAspects(msg, meta);
1837
1838 AString tsSchema;
1839 if (msg->findString("ts-schema", &tsSchema)) {
1840 unsigned int numLayers = 0;
1841 unsigned int numBLayers = 0;
1842 char dummy;
1843 int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
1844 &numLayers, &dummy, &numBLayers, &dummy);
1845 if ((tags == 1 || (tags == 3 && dummy == '+'))
1846 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers
1847 && numLayers + numBLayers <= INT32_MAX) {
1848 meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
1849 }
1850 }
1851 } else if (mime.startsWith("audio/")) {
1852 int32_t numChannels, sampleRate;
1853 if (!msg->findInt32("channel-count", &numChannels) ||
1854 !msg->findInt32("sample-rate", &sampleRate)) {
1855 ALOGV("did not find channel-count and/or sample-rate");
1856 return BAD_VALUE;
1857 }
1858 meta->setInt32(kKeyChannelCount, numChannels);
1859 meta->setInt32(kKeySampleRate, sampleRate);
1860 int32_t bitsPerSample;
1861 if (msg->findInt32("bits-per-sample", &bitsPerSample)) {
1862 meta->setInt32(kKeyBitsPerSample, bitsPerSample);
1863 }
1864 int32_t channelMask;
1865 if (msg->findInt32("channel-mask", &channelMask)) {
1866 meta->setInt32(kKeyChannelMask, channelMask);
1867 }
1868 int32_t delay = 0;
1869 if (msg->findInt32("encoder-delay", &delay)) {
1870 meta->setInt32(kKeyEncoderDelay, delay);
1871 }
1872 int32_t padding = 0;
1873 if (msg->findInt32("encoder-padding", &padding)) {
1874 meta->setInt32(kKeyEncoderPadding, padding);
1875 }
1876
1877 int32_t isADTS;
1878 if (msg->findInt32("is-adts", &isADTS)) {
1879 meta->setInt32(kKeyIsADTS, isADTS);
1880 }
1881
1882 int32_t mpeghProfileLevelIndication = -1;
1883 if (msg->findInt32(AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
1884 &mpeghProfileLevelIndication)) {
1885 meta->setInt32(kKeyMpeghProfileLevelIndication, mpeghProfileLevelIndication);
1886 }
1887 int32_t mpeghReferenceChannelLayout = -1;
1888 if (msg->findInt32(AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
1889 &mpeghReferenceChannelLayout)) {
1890 meta->setInt32(kKeyMpeghReferenceChannelLayout, mpeghReferenceChannelLayout);
1891 }
1892 sp<ABuffer> mpeghCompatibleSets;
1893 if (msg->findBuffer(AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
1894 &mpeghCompatibleSets)) {
1895 meta->setData(kKeyMpeghCompatibleSets, kTypeHCOS,
1896 mpeghCompatibleSets->data(), mpeghCompatibleSets->size());
1897 }
1898
1899 int32_t aacProfile = -1;
1900 if (msg->findInt32("aac-profile", &aacProfile)) {
1901 meta->setInt32(kKeyAACAOT, aacProfile);
1902 }
1903
1904 int32_t pcmEncoding;
1905 if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
1906 meta->setInt32(kKeyPcmEncoding, pcmEncoding);
1907 }
1908
1909 int32_t hapticChannelCount;
1910 if (msg->findInt32("haptic-channel-count", &hapticChannelCount)) {
1911 meta->setInt32(kKeyHapticChannelCount, hapticChannelCount);
1912 }
1913 }
1914
1915 int32_t maxInputSize;
1916 if (msg->findInt32("max-input-size", &maxInputSize)) {
1917 meta->setInt32(kKeyMaxInputSize, maxInputSize);
1918 }
1919
1920 int32_t maxWidth;
1921 if (msg->findInt32("max-width", &maxWidth)) {
1922 meta->setInt32(kKeyMaxWidth, maxWidth);
1923 }
1924
1925 int32_t maxHeight;
1926 if (msg->findInt32("max-height", &maxHeight)) {
1927 meta->setInt32(kKeyMaxHeight, maxHeight);
1928 }
1929
1930 int32_t fps;
1931 float fpsFloat;
1932 if (msg->findInt32("frame-rate", &fps) && fps > 0) {
1933 meta->setInt32(kKeyFrameRate, fps);
1934 } else if (msg->findFloat("frame-rate", &fpsFloat)
1935 && fpsFloat >= 1 && fpsFloat <= (float)INT32_MAX) {
1936 // truncate values to distinguish between e.g. 24 vs 23.976 fps
1937 meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
1938 }
1939
1940 // reassemble the csd data into its original form
1941 sp<ABuffer> csd0, csd1, csd2;
1942 if (msg->findBuffer("csd-0", &csd0)) {
1943 int csd0size = csd0->size();
1944 if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
1945 sp<ABuffer> csd1;
1946 if (msg->findBuffer("csd-1", &csd1)) {
1947 std::vector<char> avcc(csd0size + csd1->size() + 1024);
1948 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
1949 meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
1950 }
1951 } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC ||
1952 mime == MEDIA_MIMETYPE_VIDEO_MPEG4 ||
1953 mime == MEDIA_MIMETYPE_AUDIO_WMA ||
1954 mime == MEDIA_MIMETYPE_AUDIO_MS_ADPCM ||
1955 mime == MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) {
1956 std::vector<char> esds(csd0size + 31);
1957 // The written ESDS is actually for an audio stream, but it's enough
1958 // for transporting the CSD to muxers.
1959 reassembleESDS(csd0, esds.data());
1960 meta->setData(kKeyESDS, kTypeESDS, esds.data(), esds.size());
1961 } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC ||
1962 mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) {
1963 std::vector<uint8_t> hvcc(csd0size + 1024);
1964 size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
1965 meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize);
1966 } else if (mime == MEDIA_MIMETYPE_VIDEO_AV1 ||
1967 mime == MEDIA_MIMETYPE_IMAGE_AVIF) {
1968 meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
1969 } else if (mime == MEDIA_MIMETYPE_VIDEO_DOLBY_VISION) {
1970 if (msg->findBuffer("csd-2", &csd2)) {
1971 //dvcc should be 24
1972 if (csd2->size() == 24) {
1973 meta->setData(kKeyDVCC, kTypeDVCC, csd2->data(), csd2->size());
1974 uint8_t *dvcc = csd2->data();
1975 const uint8_t profile = dvcc[2] >> 1;
1976 if (profile > 1 && profile < 9) {
1977 std::vector<uint8_t> hvcc(csd0size + 1024);
1978 size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
1979 meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize);
1980 } else if (DolbyVisionProfileDvav110 == profile) {
1981 meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
1982 } else {
1983 sp<ABuffer> csd1;
1984 if (msg->findBuffer("csd-1", &csd1)) {
1985 std::vector<char> avcc(csd0size + csd1->size() + 1024);
1986 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
1987 meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
1988 }
1989 }
1990 }
1991 } else {
1992 ALOGE("We need csd-2!!. %s", msg->debugString().c_str());
1993 return BAD_VALUE;
1994 }
1995 } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
1996 meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
1997 } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
1998 size_t opusHeadSize = csd0->size();
1999 size_t codecDelayBufSize = 0;
2000 size_t seekPreRollBufSize = 0;
2001 void *opusHeadBuf = csd0->data();
2002 void *codecDelayBuf = NULL;
2003 void *seekPreRollBuf = NULL;
2004 if (msg->findBuffer("csd-1", &csd1)) {
2005 codecDelayBufSize = csd1->size();
2006 codecDelayBuf = csd1->data();
2007 }
2008 if (msg->findBuffer("csd-2", &csd2)) {
2009 seekPreRollBufSize = csd2->size();
2010 seekPreRollBuf = csd2->data();
2011 }
2012 /* Extract codec delay and seek pre roll from csd-0,
2013 * if csd-1 and csd-2 are not present */
2014 if (!codecDelayBuf && !seekPreRollBuf) {
2015 GetOpusHeaderBuffers(csd0->data(), csd0->size(), &opusHeadBuf,
2016 &opusHeadSize, &codecDelayBuf,
2017 &codecDelayBufSize, &seekPreRollBuf,
2018 &seekPreRollBufSize);
2019 }
2020 meta->setData(kKeyOpusHeader, 0, opusHeadBuf, opusHeadSize);
2021 if (codecDelayBuf) {
2022 meta->setData(kKeyOpusCodecDelay, 0, codecDelayBuf, codecDelayBufSize);
2023 }
2024 if (seekPreRollBuf) {
2025 meta->setData(kKeyOpusSeekPreRoll, 0, seekPreRollBuf, seekPreRollBufSize);
2026 }
2027 } else if (mime == MEDIA_MIMETYPE_AUDIO_ALAC) {
2028 meta->setData(kKeyAlacMagicCookie, 0, csd0->data(), csd0->size());
2029 }
2030 } else if (mime == MEDIA_MIMETYPE_VIDEO_AVC && msg->findBuffer("csd-avc", &csd0)) {
2031 meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size());
2032 } else if ((mime == MEDIA_MIMETYPE_VIDEO_HEVC || mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)
2033 && msg->findBuffer("csd-hevc", &csd0)) {
2034 meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size());
2035 } else if (msg->findBuffer("esds", &csd0)) {
2036 meta->setData(kKeyESDS, kTypeESDS, csd0->data(), csd0->size());
2037 } else if (msg->findBuffer("mpeg2-stream-header", &csd0)) {
2038 meta->setData(kKeyStreamHeader, 'mdat', csd0->data(), csd0->size());
2039 } else if (msg->findBuffer("d263", &csd0)) {
2040 meta->setData(kKeyD263, kTypeD263, csd0->data(), csd0->size());
2041 } else if (mime == MEDIA_MIMETYPE_VIDEO_DOLBY_VISION && msg->findBuffer("csd-2", &csd2)) {
2042 meta->setData(kKeyDVCC, kTypeDVCC, csd2->data(), csd2->size());
2043
2044 // Remove CSD-2 from the data here to avoid duplicate data in meta
2045 meta->remove(kKeyOpaqueCSD2);
2046
2047 if (msg->findBuffer("csd-avc", &csd0)) {
2048 meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size());
2049 } else if (msg->findBuffer("csd-hevc", &csd0)) {
2050 meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size());
2051 }
2052 }
2053 // XXX TODO add whatever other keys there are
2054
2055 #if 0
2056 ALOGI("converted %s to:", msg->debugString(0).c_str());
2057 meta->dumpToLog();
2058 #endif
2059 return OK;
2060 }
2061
sendMetaDataToHal(sp<MediaPlayerBase::AudioSink> & sink,const sp<MetaData> & meta)2062 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
2063 const sp<MetaData>& meta)
2064 {
2065 int32_t sampleRate = 0;
2066 int32_t bitRate = 0;
2067 int32_t channelMask = 0;
2068 int32_t delaySamples = 0;
2069 int32_t paddingSamples = 0;
2070
2071 AudioParameter param = AudioParameter();
2072
2073 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
2074 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
2075 }
2076 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
2077 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
2078 }
2079 if (meta->findInt32(kKeyBitRate, &bitRate)) {
2080 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
2081 }
2082 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
2083 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
2084 }
2085 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
2086 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
2087 }
2088
2089 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
2090 "delaySample %d, paddingSample %d", bitRate, sampleRate,
2091 channelMask, delaySamples, paddingSamples);
2092
2093 sink->setParameters(param.toString());
2094 return OK;
2095 }
2096
2097 struct mime_conv_t {
2098 const char* mime;
2099 audio_format_t format;
2100 };
2101
2102 static const struct mime_conv_t mimeLookup[] = {
2103 { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 },
2104 { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT },
2105 { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB },
2106 { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB },
2107 { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC },
2108 { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS },
2109 { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS},
2110 { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3},
2111 { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3},
2112 { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, AUDIO_FORMAT_E_AC3_JOC},
2113 { MEDIA_MIMETYPE_AUDIO_AC4, AUDIO_FORMAT_AC4},
2114 { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC},
2115 { MEDIA_MIMETYPE_AUDIO_ALAC, AUDIO_FORMAT_ALAC },
2116 { 0, AUDIO_FORMAT_INVALID }
2117 };
2118
mapMimeToAudioFormat(audio_format_t & format,const char * mime)2119 status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
2120 {
2121 const struct mime_conv_t* p = &mimeLookup[0];
2122 while (p->mime != NULL) {
2123 if (0 == strcasecmp(mime, p->mime)) {
2124 format = p->format;
2125 return OK;
2126 }
2127 ++p;
2128 }
2129
2130 return BAD_VALUE;
2131 }
2132
2133 struct aac_format_conv_t {
2134 OMX_AUDIO_AACPROFILETYPE eAacProfileType;
2135 audio_format_t format;
2136 };
2137
2138 static const struct aac_format_conv_t profileLookup[] = {
2139 { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN},
2140 { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC},
2141 { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR},
2142 { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP},
2143 { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1},
2144 { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE},
2145 { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC},
2146 { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD},
2147 { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2},
2148 { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD},
2149 { OMX_AUDIO_AACObjectXHE, AUDIO_FORMAT_AAC_XHE},
2150 { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC},
2151 };
2152
mapAACProfileToAudioFormat(audio_format_t & format,uint64_t eAacProfile)2153 void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
2154 {
2155 const struct aac_format_conv_t* p = &profileLookup[0];
2156 while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
2157 if (eAacProfile == p->eAacProfileType) {
2158 format = p->format;
2159 return;
2160 }
2161 ++p;
2162 }
2163 format = AUDIO_FORMAT_AAC;
2164 return;
2165 }
2166
getAudioOffloadInfo(const sp<MetaData> & meta,bool hasVideo,bool isStreaming,audio_stream_type_t streamType,audio_offload_info_t * info)2167 status_t getAudioOffloadInfo(const sp<MetaData>& meta, bool hasVideo,
2168 bool isStreaming, audio_stream_type_t streamType, audio_offload_info_t *info)
2169 {
2170 const char *mime;
2171 if (meta == NULL) {
2172 return BAD_VALUE;
2173 }
2174 CHECK(meta->findCString(kKeyMIMEType, &mime));
2175
2176 (*info) = AUDIO_INFO_INITIALIZER;
2177
2178 info->format = AUDIO_FORMAT_INVALID;
2179 if (mapMimeToAudioFormat(info->format, mime) != OK) {
2180 ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
2181 return BAD_VALUE;
2182 } else {
2183 ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info->format);
2184 }
2185
2186 if (AUDIO_FORMAT_INVALID == info->format) {
2187 // can't offload if we don't know what the source format is
2188 ALOGE("mime type \"%s\" not a known audio format", mime);
2189 return BAD_VALUE;
2190 }
2191
2192 // Redefine aac format according to its profile
2193 // Offloading depends on audio DSP capabilities.
2194 int32_t aacaot = -1;
2195 if (meta->findInt32(kKeyAACAOT, &aacaot)) {
2196 mapAACProfileToAudioFormat(info->format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
2197 }
2198
2199 int32_t srate = -1;
2200 if (!meta->findInt32(kKeySampleRate, &srate)) {
2201 ALOGV("track of type '%s' does not publish sample rate", mime);
2202 }
2203 info->sample_rate = srate;
2204
2205 int32_t rawChannelMask;
2206 audio_channel_mask_t cmask = meta->findInt32(kKeyChannelMask, &rawChannelMask) ?
2207 static_cast<audio_channel_mask_t>(rawChannelMask) : CHANNEL_MASK_USE_CHANNEL_ORDER;
2208 if (cmask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
2209 ALOGV("track of type '%s' does not publish channel mask", mime);
2210
2211 // Try a channel count instead
2212 int32_t channelCount;
2213 if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
2214 ALOGV("track of type '%s' does not publish channel count", mime);
2215 } else {
2216 cmask = audio_channel_out_mask_from_count(channelCount);
2217 }
2218 }
2219 info->channel_mask = cmask;
2220
2221 int64_t duration = 0;
2222 if (!meta->findInt64(kKeyDuration, &duration)) {
2223 ALOGV("track of type '%s' does not publish duration", mime);
2224 }
2225 info->duration_us = duration;
2226
2227 int32_t brate = 0;
2228 if (!meta->findInt32(kKeyBitRate, &brate)) {
2229 ALOGV("track of type '%s' does not publish bitrate", mime);
2230 }
2231 info->bit_rate = brate;
2232
2233
2234 info->stream_type = streamType;
2235 info->has_video = hasVideo;
2236 info->is_streaming = isStreaming;
2237 return OK;
2238 }
2239
canOffloadStream(const sp<MetaData> & meta,bool hasVideo,bool isStreaming,audio_stream_type_t streamType)2240 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
2241 bool isStreaming, audio_stream_type_t streamType)
2242 {
2243 audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
2244 if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
2245 return false;
2246 }
2247 // Check if offload is possible for given format, stream type, sample rate,
2248 // bit rate, duration, video and streaming
2249 #ifdef DISABLE_AUDIO_SYSTEM_OFFLOAD
2250 return false;
2251 #else
2252 return AudioSystem::getOffloadSupport(info) != AUDIO_OFFLOAD_NOT_SUPPORTED;
2253 #endif
2254 }
2255
HLSTime(const sp<AMessage> & meta)2256 HLSTime::HLSTime(const sp<AMessage>& meta) :
2257 mSeq(-1),
2258 mTimeUs(-1LL),
2259 mMeta(meta) {
2260 if (meta != NULL) {
2261 CHECK(meta->findInt32("discontinuitySeq", &mSeq));
2262 CHECK(meta->findInt64("timeUs", &mTimeUs));
2263 }
2264 }
2265
getSegmentTimeUs() const2266 int64_t HLSTime::getSegmentTimeUs() const {
2267 int64_t segmentStartTimeUs = -1LL;
2268 if (mMeta != NULL) {
2269 CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
2270
2271 int64_t segmentFirstTimeUs;
2272 if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
2273 segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
2274 }
2275
2276 // adjust segment time by playlist age (for live streaming)
2277 int64_t playlistTimeUs;
2278 if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
2279 int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
2280
2281 int64_t durationUs;
2282 CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
2283
2284 // round to nearest whole segment
2285 playlistAgeUs = (playlistAgeUs + durationUs / 2)
2286 / durationUs * durationUs;
2287
2288 segmentStartTimeUs -= playlistAgeUs;
2289 if (segmentStartTimeUs < 0) {
2290 segmentStartTimeUs = 0;
2291 }
2292 }
2293 }
2294 return segmentStartTimeUs;
2295 }
2296
operator <(const HLSTime & t0,const HLSTime & t1)2297 bool operator <(const HLSTime &t0, const HLSTime &t1) {
2298 // we can only compare discontinuity sequence and timestamp.
2299 // (mSegmentTimeUs is not reliable in live streaming case, it's the
2300 // time starting from beginning of playlist but playlist could change.)
2301 return t0.mSeq < t1.mSeq
2302 || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
2303 }
2304
writeToAMessage(const sp<AMessage> & msg,const AudioPlaybackRate & rate)2305 void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate) {
2306 msg->setFloat("speed", rate.mSpeed);
2307 msg->setFloat("pitch", rate.mPitch);
2308 msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
2309 msg->setInt32("audio-stretch-mode", rate.mStretchMode);
2310 }
2311
readFromAMessage(const sp<AMessage> & msg,AudioPlaybackRate * rate)2312 void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
2313 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
2314 CHECK(msg->findFloat("speed", &rate->mSpeed));
2315 CHECK(msg->findFloat("pitch", &rate->mPitch));
2316 CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
2317 CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
2318 }
2319
writeToAMessage(const sp<AMessage> & msg,const AVSyncSettings & sync,float videoFpsHint)2320 void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint) {
2321 msg->setInt32("sync-source", sync.mSource);
2322 msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
2323 msg->setFloat("tolerance", sync.mTolerance);
2324 msg->setFloat("video-fps", videoFpsHint);
2325 }
2326
readFromAMessage(const sp<AMessage> & msg,AVSyncSettings * sync,float * videoFps)2327 void readFromAMessage(
2328 const sp<AMessage> &msg,
2329 AVSyncSettings *sync /* nonnull */,
2330 float *videoFps /* nonnull */) {
2331 AVSyncSettings settings;
2332 CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
2333 CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
2334 CHECK(msg->findFloat("tolerance", &settings.mTolerance));
2335 CHECK(msg->findFloat("video-fps", videoFps));
2336 *sync = settings;
2337 }
2338
writeToAMessage(const sp<AMessage> & msg,const BufferingSettings & buffering)2339 void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering) {
2340 msg->setInt32("init-ms", buffering.mInitialMarkMs);
2341 msg->setInt32("resume-playback-ms", buffering.mResumePlaybackMarkMs);
2342 }
2343
readFromAMessage(const sp<AMessage> & msg,BufferingSettings * buffering)2344 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */) {
2345 int32_t value;
2346 if (msg->findInt32("init-ms", &value)) {
2347 buffering->mInitialMarkMs = value;
2348 }
2349 if (msg->findInt32("resume-playback-ms", &value)) {
2350 buffering->mResumePlaybackMarkMs = value;
2351 }
2352 }
2353
2354 } // namespace android
2355