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