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 { "valid-samples", kKeyValidSamples },
693 }
694 };
695
696 static std::vector<std::pair<const char *, uint32_t>> bufferMappings {
697 {
698 { "albumart", kKeyAlbumArt },
699 { "audio-presentation-info", kKeyAudioPresentationInfo },
700 { "pssh", kKeyPssh },
701 { "crypto-iv", kKeyCryptoIV },
702 { "crypto-key", kKeyCryptoKey },
703 { "crypto-encrypted-sizes", kKeyEncryptedSizes },
704 { "crypto-plain-sizes", kKeyPlainSizes },
705 { "icc-profile", kKeyIccProfile },
706 { "sei", kKeySEI },
707 { "text-format-data", kKeyTextFormatData },
708 { "thumbnail-csd-hevc", kKeyThumbnailHVCC },
709 }
710 };
711
712 static std::vector<std::pair<const char *, uint32_t>> CSDMappings {
713 {
714 { "csd-0", kKeyOpaqueCSD0 },
715 { "csd-1", kKeyOpaqueCSD1 },
716 { "csd-2", kKeyOpaqueCSD2 },
717 }
718 };
719
convertMessageToMetaDataFromMappings(const sp<AMessage> & msg,sp<MetaData> & meta)720 void convertMessageToMetaDataFromMappings(const sp<AMessage> &msg, sp<MetaData> &meta) {
721 for (auto elem : stringMappings) {
722 AString value;
723 if (msg->findString(elem.first, &value)) {
724 meta->setCString(elem.second, value.c_str());
725 }
726 }
727
728 for (auto elem : floatMappings) {
729 float value;
730 if (msg->findFloat(elem.first, &value)) {
731 meta->setFloat(elem.second, value);
732 }
733 }
734
735 for (auto elem : int64Mappings) {
736 int64_t value;
737 if (msg->findInt64(elem.first, &value)) {
738 meta->setInt64(elem.second, value);
739 }
740 }
741
742 for (auto elem : int32Mappings) {
743 int32_t value;
744 if (msg->findInt32(elem.first, &value)) {
745 meta->setInt32(elem.second, value);
746 }
747 }
748
749 for (auto elem : bufferMappings) {
750 sp<ABuffer> value;
751 if (msg->findBuffer(elem.first, &value)) {
752 meta->setData(elem.second,
753 MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
754 }
755 }
756
757 for (auto elem : CSDMappings) {
758 sp<ABuffer> value;
759 if (msg->findBuffer(elem.first, &value)) {
760 meta->setData(elem.second,
761 MetaDataBase::Type::TYPE_NONE, value->data(), value->size());
762 }
763 }
764 }
765
convertMetaDataToMessageFromMappings(const MetaDataBase * meta,sp<AMessage> format)766 void convertMetaDataToMessageFromMappings(const MetaDataBase *meta, sp<AMessage> format) {
767 for (auto elem : stringMappings) {
768 const char *value;
769 if (meta->findCString(elem.second, &value)) {
770 format->setString(elem.first, value, strlen(value));
771 }
772 }
773
774 for (auto elem : floatMappings) {
775 float value;
776 if (meta->findFloat(elem.second, &value)) {
777 format->setFloat(elem.first, value);
778 }
779 }
780
781 for (auto elem : int64Mappings) {
782 int64_t value;
783 if (meta->findInt64(elem.second, &value)) {
784 format->setInt64(elem.first, value);
785 }
786 }
787
788 for (auto elem : int32Mappings) {
789 int32_t value;
790 if (meta->findInt32(elem.second, &value)) {
791 format->setInt32(elem.first, value);
792 }
793 }
794
795 for (auto elem : bufferMappings) {
796 uint32_t type;
797 const void* data;
798 size_t size;
799 if (meta->findData(elem.second, &type, &data, &size)) {
800 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
801 format->setBuffer(elem.first, buf);
802 }
803 }
804
805 for (auto elem : CSDMappings) {
806 uint32_t type;
807 const void* data;
808 size_t size;
809 if (meta->findData(elem.second, &type, &data, &size)) {
810 sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
811 buf->meta()->setInt32("csd", true);
812 buf->meta()->setInt64("timeUs", 0);
813 format->setBuffer(elem.first, buf);
814 }
815 }
816 }
817
convertMetaDataToMessage(const sp<MetaData> & meta,sp<AMessage> * format)818 status_t convertMetaDataToMessage(
819 const sp<MetaData> &meta, sp<AMessage> *format) {
820 return convertMetaDataToMessage(meta.get(), format);
821 }
822
convertMetaDataToMessage(const MetaDataBase * meta,sp<AMessage> * format)823 status_t convertMetaDataToMessage(
824 const MetaDataBase *meta, sp<AMessage> *format) {
825
826 format->clear();
827
828 if (meta == NULL) {
829 ALOGE("convertMetaDataToMessage: NULL input");
830 return BAD_VALUE;
831 }
832
833 const char *mime;
834 if (!meta->findCString(kKeyMIMEType, &mime)) {
835 return BAD_VALUE;
836 }
837
838 sp<AMessage> msg = new AMessage;
839 msg->setString("mime", mime);
840
841 convertMetaDataToMessageFromMappings(meta, msg);
842
843 uint32_t type;
844 const void *data;
845 size_t size;
846 if (meta->findData(kKeyCASessionID, &type, &data, &size)) {
847 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
848 if (buffer.get() == NULL || buffer->base() == NULL) {
849 return NO_MEMORY;
850 }
851
852 msg->setBuffer("ca-session-id", buffer);
853 memcpy(buffer->data(), data, size);
854 }
855
856 if (meta->findData(kKeyCAPrivateData, &type, &data, &size)) {
857 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
858 if (buffer.get() == NULL || buffer->base() == NULL) {
859 return NO_MEMORY;
860 }
861
862 msg->setBuffer("ca-private-data", buffer);
863 memcpy(buffer->data(), data, size);
864 }
865
866 int32_t systemId;
867 if (meta->findInt32(kKeyCASystemID, &systemId)) {
868 msg->setInt32("ca-system-id", systemId);
869 }
870
871 if (!strncasecmp("video/scrambled", mime, 15)
872 || !strncasecmp("audio/scrambled", mime, 15)) {
873
874 *format = msg;
875 return OK;
876 }
877
878 int64_t durationUs;
879 if (meta->findInt64(kKeyDuration, &durationUs)) {
880 msg->setInt64("durationUs", durationUs);
881 }
882
883 int32_t avgBitRate = 0;
884 if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
885 msg->setInt32("bitrate", avgBitRate);
886 }
887
888 int32_t maxBitRate;
889 if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
890 && maxBitRate > 0 && maxBitRate >= avgBitRate) {
891 msg->setInt32("max-bitrate", maxBitRate);
892 }
893
894 int32_t isSync;
895 if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
896 msg->setInt32("is-sync-frame", 1);
897 }
898
899 // this only needs to be translated from meta to message as it is an extractor key
900 int32_t trackID;
901 if (meta->findInt32(kKeyTrackID, &trackID)) {
902 msg->setInt32("track-id", trackID);
903 }
904
905 const char *lang;
906 if (meta->findCString(kKeyMediaLanguage, &lang)) {
907 msg->setString("language", lang);
908 }
909
910 if (!strncasecmp("video/", mime, 6) ||
911 !strncasecmp("image/", mime, 6)) {
912 int32_t width, height;
913 if (!meta->findInt32(kKeyWidth, &width)
914 || !meta->findInt32(kKeyHeight, &height)) {
915 return BAD_VALUE;
916 }
917
918 msg->setInt32("width", width);
919 msg->setInt32("height", height);
920
921 int32_t displayWidth, displayHeight;
922 if (meta->findInt32(kKeyDisplayWidth, &displayWidth)
923 && meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
924 msg->setInt32("display-width", displayWidth);
925 msg->setInt32("display-height", displayHeight);
926 }
927
928 int32_t sarWidth, sarHeight;
929 if (meta->findInt32(kKeySARWidth, &sarWidth)
930 && meta->findInt32(kKeySARHeight, &sarHeight)) {
931 msg->setInt32("sar-width", sarWidth);
932 msg->setInt32("sar-height", sarHeight);
933 }
934
935 if (!strncasecmp("image/", mime, 6)) {
936 int32_t tileWidth, tileHeight, gridRows, gridCols;
937 if (meta->findInt32(kKeyTileWidth, &tileWidth)
938 && meta->findInt32(kKeyTileHeight, &tileHeight)
939 && meta->findInt32(kKeyGridRows, &gridRows)
940 && meta->findInt32(kKeyGridCols, &gridCols)) {
941 msg->setInt32("tile-width", tileWidth);
942 msg->setInt32("tile-height", tileHeight);
943 msg->setInt32("grid-rows", gridRows);
944 msg->setInt32("grid-cols", gridCols);
945 }
946 int32_t isPrimary;
947 if (meta->findInt32(kKeyTrackIsDefault, &isPrimary) && isPrimary) {
948 msg->setInt32("is-default", 1);
949 }
950 }
951
952 int32_t colorFormat;
953 if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
954 msg->setInt32("color-format", colorFormat);
955 }
956
957 int32_t cropLeft, cropTop, cropRight, cropBottom;
958 if (meta->findRect(kKeyCropRect,
959 &cropLeft,
960 &cropTop,
961 &cropRight,
962 &cropBottom)) {
963 msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
964 }
965
966 int32_t rotationDegrees;
967 if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
968 msg->setInt32("rotation-degrees", rotationDegrees);
969 }
970
971 uint32_t type;
972 const void *data;
973 size_t size;
974 if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
975 && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
976 ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
977 }
978
979 if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size)
980 && size > 0) {
981 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
982 if (buffer.get() == NULL || buffer->base() == NULL) {
983 return NO_MEMORY;
984 }
985 memcpy(buffer->data(), data, size);
986 msg->setBuffer("hdr10-plus-info", buffer);
987 }
988
989 convertMetaDataToMessageColorAspects(meta, msg);
990 } else if (!strncasecmp("audio/", mime, 6)) {
991 int32_t numChannels, sampleRate;
992 if (!meta->findInt32(kKeyChannelCount, &numChannels)
993 || !meta->findInt32(kKeySampleRate, &sampleRate)) {
994 return BAD_VALUE;
995 }
996
997 msg->setInt32("channel-count", numChannels);
998 msg->setInt32("sample-rate", sampleRate);
999
1000 int32_t bitsPerSample;
1001 if (meta->findInt32(kKeyBitsPerSample, &bitsPerSample)) {
1002 msg->setInt32("bits-per-sample", bitsPerSample);
1003 }
1004
1005 int32_t channelMask;
1006 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
1007 msg->setInt32("channel-mask", channelMask);
1008 }
1009
1010 int32_t delay = 0;
1011 if (meta->findInt32(kKeyEncoderDelay, &delay)) {
1012 msg->setInt32("encoder-delay", delay);
1013 }
1014 int32_t padding = 0;
1015 if (meta->findInt32(kKeyEncoderPadding, &padding)) {
1016 msg->setInt32("encoder-padding", padding);
1017 }
1018
1019 int32_t isADTS;
1020 if (meta->findInt32(kKeyIsADTS, &isADTS)) {
1021 msg->setInt32("is-adts", isADTS);
1022 }
1023
1024 int32_t aacProfile = -1;
1025 if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
1026 msg->setInt32("aac-profile", aacProfile);
1027 }
1028
1029 int32_t pcmEncoding;
1030 if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
1031 msg->setInt32("pcm-encoding", pcmEncoding);
1032 }
1033
1034 int32_t hapticChannelCount;
1035 if (meta->findInt32(kKeyHapticChannelCount, &hapticChannelCount)) {
1036 msg->setInt32("haptic-channel-count", hapticChannelCount);
1037 }
1038 }
1039
1040 int32_t maxInputSize;
1041 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
1042 msg->setInt32("max-input-size", maxInputSize);
1043 }
1044
1045 int32_t maxWidth;
1046 if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
1047 msg->setInt32("max-width", maxWidth);
1048 }
1049
1050 int32_t maxHeight;
1051 if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
1052 msg->setInt32("max-height", maxHeight);
1053 }
1054
1055 int32_t rotationDegrees;
1056 if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
1057 msg->setInt32("rotation-degrees", rotationDegrees);
1058 }
1059
1060 int32_t fps;
1061 if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
1062 msg->setInt32("frame-rate", fps);
1063 }
1064
1065 if (meta->findData(kKeyAVCC, &type, &data, &size)) {
1066 // Parse the AVCDecoderConfigurationRecord
1067
1068 const uint8_t *ptr = (const uint8_t *)data;
1069
1070 if (size < 7 || ptr[0] != 1) { // configurationVersion == 1
1071 ALOGE("b/23680780");
1072 return BAD_VALUE;
1073 }
1074
1075 parseAvcProfileLevelFromAvcc(ptr, size, msg);
1076
1077 // There is decodable content out there that fails the following
1078 // assertion, let's be lenient for now...
1079 // CHECK((ptr[4] >> 2) == 0x3f); // reserved
1080
1081 size_t lengthSize __unused = 1 + (ptr[4] & 3);
1082
1083 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
1084 // violates it...
1085 // CHECK((ptr[5] >> 5) == 7); // reserved
1086
1087 size_t numSeqParameterSets = ptr[5] & 31;
1088
1089 ptr += 6;
1090 size -= 6;
1091
1092 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
1093 if (buffer.get() == NULL || buffer->base() == NULL) {
1094 return NO_MEMORY;
1095 }
1096 buffer->setRange(0, 0);
1097
1098 for (size_t i = 0; i < numSeqParameterSets; ++i) {
1099 if (size < 2) {
1100 ALOGE("b/23680780");
1101 return BAD_VALUE;
1102 }
1103 size_t length = U16_AT(ptr);
1104
1105 ptr += 2;
1106 size -= 2;
1107
1108 if (size < length) {
1109 return BAD_VALUE;
1110 }
1111 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1112 if (err != OK) {
1113 return err;
1114 }
1115
1116 ptr += length;
1117 size -= length;
1118 }
1119
1120 buffer->meta()->setInt32("csd", true);
1121 buffer->meta()->setInt64("timeUs", 0);
1122
1123 msg->setBuffer("csd-0", buffer);
1124
1125 buffer = new (std::nothrow) ABuffer(1024);
1126 if (buffer.get() == NULL || buffer->base() == NULL) {
1127 return NO_MEMORY;
1128 }
1129 buffer->setRange(0, 0);
1130
1131 if (size < 1) {
1132 ALOGE("b/23680780");
1133 return BAD_VALUE;
1134 }
1135 size_t numPictureParameterSets = *ptr;
1136 ++ptr;
1137 --size;
1138
1139 for (size_t i = 0; i < numPictureParameterSets; ++i) {
1140 if (size < 2) {
1141 ALOGE("b/23680780");
1142 return BAD_VALUE;
1143 }
1144 size_t length = U16_AT(ptr);
1145
1146 ptr += 2;
1147 size -= 2;
1148
1149 if (size < length) {
1150 return BAD_VALUE;
1151 }
1152 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1153 if (err != OK) {
1154 return err;
1155 }
1156
1157 ptr += length;
1158 size -= length;
1159 }
1160
1161 buffer->meta()->setInt32("csd", true);
1162 buffer->meta()->setInt64("timeUs", 0);
1163 msg->setBuffer("csd-1", buffer);
1164 } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
1165 const uint8_t *ptr = (const uint8_t *)data;
1166
1167 if (size < 23 || (ptr[0] != 1 && ptr[0] != 0)) {
1168 // configurationVersion == 1 or 0
1169 // 1 is what the standard dictates, but some old muxers may have used 0.
1170 ALOGE("b/23680780");
1171 return BAD_VALUE;
1172 }
1173
1174 const size_t dataSize = size; // save for later
1175 ptr += 22;
1176 size -= 22;
1177
1178 size_t numofArrays = (char)ptr[0];
1179 ptr += 1;
1180 size -= 1;
1181 size_t j = 0, i = 0;
1182
1183 sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
1184 if (buffer.get() == NULL || buffer->base() == NULL) {
1185 return NO_MEMORY;
1186 }
1187 buffer->setRange(0, 0);
1188
1189 HevcParameterSets hvcc;
1190
1191 for (i = 0; i < numofArrays; i++) {
1192 if (size < 3) {
1193 ALOGE("b/23680780");
1194 return BAD_VALUE;
1195 }
1196 ptr += 1;
1197 size -= 1;
1198
1199 //Num of nals
1200 size_t numofNals = U16_AT(ptr);
1201
1202 ptr += 2;
1203 size -= 2;
1204
1205 for (j = 0; j < numofNals; j++) {
1206 if (size < 2) {
1207 ALOGE("b/23680780");
1208 return BAD_VALUE;
1209 }
1210 size_t length = U16_AT(ptr);
1211
1212 ptr += 2;
1213 size -= 2;
1214
1215 if (size < length) {
1216 return BAD_VALUE;
1217 }
1218 status_t err = copyNALUToABuffer(&buffer, ptr, length);
1219 if (err != OK) {
1220 return err;
1221 }
1222 (void)hvcc.addNalUnit(ptr, length);
1223
1224 ptr += length;
1225 size -= length;
1226 }
1227 }
1228 buffer->meta()->setInt32("csd", true);
1229 buffer->meta()->setInt64("timeUs", 0);
1230 msg->setBuffer("csd-0", buffer);
1231
1232 // if we saw VUI color information we know whether this is HDR because VUI trumps other
1233 // format parameters for HEVC.
1234 HevcParameterSets::Info info = hvcc.getInfo();
1235 if (info & hvcc.kInfoHasColorDescription) {
1236 msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
1237 }
1238
1239 uint32_t isoPrimaries, isoTransfer, isoMatrix, isoRange;
1240 if (hvcc.findParam32(kColourPrimaries, &isoPrimaries)
1241 && hvcc.findParam32(kTransferCharacteristics, &isoTransfer)
1242 && hvcc.findParam32(kMatrixCoeffs, &isoMatrix)
1243 && hvcc.findParam32(kVideoFullRangeFlag, &isoRange)) {
1244 ALOGV("found iso color aspects : primaris=%d, transfer=%d, matrix=%d, range=%d",
1245 isoPrimaries, isoTransfer, isoMatrix, isoRange);
1246
1247 ColorAspects aspects;
1248 ColorUtils::convertIsoColorAspectsToCodecAspects(
1249 isoPrimaries, isoTransfer, isoMatrix, isoRange, aspects);
1250
1251 if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
1252 int32_t primaries;
1253 if (meta->findInt32(kKeyColorPrimaries, &primaries)) {
1254 ALOGV("unspecified primaries found, replaced to %d", primaries);
1255 aspects.mPrimaries = static_cast<ColorAspects::Primaries>(primaries);
1256 }
1257 }
1258 if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
1259 int32_t transferFunction;
1260 if (meta->findInt32(kKeyTransferFunction, &transferFunction)) {
1261 ALOGV("unspecified transfer found, replaced to %d", transferFunction);
1262 aspects.mTransfer = static_cast<ColorAspects::Transfer>(transferFunction);
1263 }
1264 }
1265 if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
1266 int32_t colorMatrix;
1267 if (meta->findInt32(kKeyColorMatrix, &colorMatrix)) {
1268 ALOGV("unspecified matrix found, replaced to %d", colorMatrix);
1269 aspects.mMatrixCoeffs = static_cast<ColorAspects::MatrixCoeffs>(colorMatrix);
1270 }
1271 }
1272 if (aspects.mRange == ColorAspects::RangeUnspecified) {
1273 int32_t range;
1274 if (meta->findInt32(kKeyColorRange, &range)) {
1275 ALOGV("unspecified range found, replaced to %d", range);
1276 aspects.mRange = static_cast<ColorAspects::Range>(range);
1277 }
1278 }
1279
1280 int32_t standard, transfer, range;
1281 if (ColorUtils::convertCodecColorAspectsToPlatformAspects(
1282 aspects, &range, &standard, &transfer) == OK) {
1283 msg->setInt32("color-standard", standard);
1284 msg->setInt32("color-transfer", transfer);
1285 msg->setInt32("color-range", range);
1286 }
1287 }
1288
1289 parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
1290 } else if (meta->findData(kKeyAV1C, &type, &data, &size)) {
1291 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1292 if (buffer.get() == NULL || buffer->base() == NULL) {
1293 return NO_MEMORY;
1294 }
1295 memcpy(buffer->data(), data, size);
1296
1297 buffer->meta()->setInt32("csd", true);
1298 buffer->meta()->setInt64("timeUs", 0);
1299 msg->setBuffer("csd-0", buffer);
1300 parseAV1ProfileLevelFromCsd(buffer, msg);
1301 } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
1302 ESDS esds((const char *)data, size);
1303 if (esds.InitCheck() != (status_t)OK) {
1304 return BAD_VALUE;
1305 }
1306
1307 const void *codec_specific_data;
1308 size_t codec_specific_data_size;
1309 esds.getCodecSpecificInfo(
1310 &codec_specific_data, &codec_specific_data_size);
1311
1312 sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
1313 if (buffer.get() == NULL || buffer->base() == NULL) {
1314 return NO_MEMORY;
1315 }
1316
1317 memcpy(buffer->data(), codec_specific_data,
1318 codec_specific_data_size);
1319
1320 buffer->meta()->setInt32("csd", true);
1321 buffer->meta()->setInt64("timeUs", 0);
1322 msg->setBuffer("csd-0", buffer);
1323
1324 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
1325 parseMpeg4ProfileLevelFromCsd(buffer, msg);
1326 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
1327 parseMpeg2ProfileLevelFromEsds(esds, msg);
1328 if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
1329 parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
1330 }
1331 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1332 parseAacProfileFromCsd(buffer, msg);
1333 }
1334
1335 uint32_t maxBitrate, avgBitrate;
1336 if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
1337 if (!meta->hasData(kKeyBitRate)
1338 && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
1339 msg->setInt32("bitrate", (int32_t)avgBitrate);
1340 } else {
1341 (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
1342 }
1343 if (!meta->hasData(kKeyMaxBitRate)
1344 && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
1345 msg->setInt32("max-bitrate", (int32_t)maxBitrate);
1346 }
1347 }
1348 } else if (meta->findData(kKeyD263, &type, &data, &size)) {
1349 const uint8_t *ptr = (const uint8_t *)data;
1350 parseH263ProfileLevelFromD263(ptr, size, msg);
1351 } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
1352 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1353 if (buffer.get() == NULL || buffer->base() == NULL) {
1354 return NO_MEMORY;
1355 }
1356 memcpy(buffer->data(), data, size);
1357
1358 buffer->meta()->setInt32("csd", true);
1359 buffer->meta()->setInt64("timeUs", 0);
1360 msg->setBuffer("csd-0", buffer);
1361
1362 if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
1363 return -EINVAL;
1364 }
1365
1366 buffer = new (std::nothrow) ABuffer(size);
1367 if (buffer.get() == NULL || buffer->base() == NULL) {
1368 return NO_MEMORY;
1369 }
1370 memcpy(buffer->data(), data, size);
1371
1372 buffer->meta()->setInt32("csd", true);
1373 buffer->meta()->setInt64("timeUs", 0);
1374 msg->setBuffer("csd-1", buffer);
1375
1376 if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
1377 return -EINVAL;
1378 }
1379
1380 buffer = new (std::nothrow) ABuffer(size);
1381 if (buffer.get() == NULL || buffer->base() == NULL) {
1382 return NO_MEMORY;
1383 }
1384 memcpy(buffer->data(), data, size);
1385
1386 buffer->meta()->setInt32("csd", true);
1387 buffer->meta()->setInt64("timeUs", 0);
1388 msg->setBuffer("csd-2", buffer);
1389 } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
1390 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1391 if (buffer.get() == NULL || buffer->base() == NULL) {
1392 return NO_MEMORY;
1393 }
1394 memcpy(buffer->data(), data, size);
1395
1396 buffer->meta()->setInt32("csd", true);
1397 buffer->meta()->setInt64("timeUs", 0);
1398 msg->setBuffer("csd-0", buffer);
1399
1400 parseVp9ProfileLevelFromCsd(buffer, msg);
1401 } else if (meta->findData(kKeyAlacMagicCookie, &type, &data, &size)) {
1402 ALOGV("convertMetaDataToMessage found kKeyAlacMagicCookie of size %zu\n", size);
1403 sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1404 if (buffer.get() == NULL || buffer->base() == NULL) {
1405 return NO_MEMORY;
1406 }
1407 memcpy(buffer->data(), data, size);
1408
1409 buffer->meta()->setInt32("csd", true);
1410 buffer->meta()->setInt64("timeUs", 0);
1411 msg->setBuffer("csd-0", buffer);
1412 }
1413
1414 *format = msg;
1415
1416 return OK;
1417 }
1418
findNextNalStartCode(const uint8_t * data,size_t length)1419 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
1420 uint8_t *res = NULL;
1421 if (length > 4) {
1422 // minus 1 as to not match NAL start code at end
1423 res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
1424 }
1425 return res != NULL && res < data + length - 4 ? res : &data[length];
1426 }
1427
reassembleAVCC(const sp<ABuffer> & csd0,const sp<ABuffer> & csd1,char * avcc)1428 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> &csd1, char *avcc) {
1429 avcc[0] = 1; // version
1430 avcc[1] = 0x64; // profile (default to high)
1431 avcc[2] = 0; // constraints (default to none)
1432 avcc[3] = 0xd; // level (default to 1.3)
1433 avcc[4] = 0xff; // reserved+size
1434
1435 size_t i = 0;
1436 int numparams = 0;
1437 int lastparamoffset = 0;
1438 int avccidx = 6;
1439 do {
1440 i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
1441 ALOGV("block at %zu, last was %d", i, lastparamoffset);
1442 if (lastparamoffset > 0) {
1443 const uint8_t *lastparam = csd0->data() + lastparamoffset;
1444 int size = i - lastparamoffset;
1445 if (size > 3) {
1446 if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
1447 ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
1448 avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
1449 } else if (!numparams) {
1450 // fill in profile, constraints and level
1451 memcpy(avcc + 1, lastparam + 1, 3);
1452 }
1453 }
1454 avcc[avccidx++] = size >> 8;
1455 avcc[avccidx++] = size & 0xff;
1456 memcpy(avcc+avccidx, lastparam, size);
1457 avccidx += size;
1458 numparams++;
1459 }
1460 i += 4;
1461 lastparamoffset = i;
1462 } while(i < csd0->size());
1463 ALOGV("csd0 contains %d params", numparams);
1464
1465 avcc[5] = 0xe0 | numparams;
1466 //and now csd-1
1467 i = 0;
1468 numparams = 0;
1469 lastparamoffset = 0;
1470 int numpicparamsoffset = avccidx;
1471 avccidx++;
1472 do {
1473 i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
1474 ALOGV("block at %zu, last was %d", i, lastparamoffset);
1475 if (lastparamoffset > 0) {
1476 int size = i - lastparamoffset;
1477 avcc[avccidx++] = size >> 8;
1478 avcc[avccidx++] = size & 0xff;
1479 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
1480 avccidx += size;
1481 numparams++;
1482 }
1483 i += 4;
1484 lastparamoffset = i;
1485 } while(i < csd1->size());
1486 avcc[numpicparamsoffset] = numparams;
1487 return avccidx;
1488 }
1489
reassembleESDS(const sp<ABuffer> & csd0,char * esds)1490 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
1491 int csd0size = csd0->size();
1492 esds[0] = 3; // kTag_ESDescriptor;
1493 int esdescriptorsize = 26 + csd0size;
1494 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
1495 esds[1] = 0x80 | (esdescriptorsize >> 21);
1496 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
1497 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
1498 esds[4] = (esdescriptorsize & 0x7f);
1499 esds[5] = esds[6] = 0; // es id
1500 esds[7] = 0; // flags
1501 esds[8] = 4; // kTag_DecoderConfigDescriptor
1502 int configdescriptorsize = 18 + csd0size;
1503 esds[9] = 0x80 | (configdescriptorsize >> 21);
1504 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
1505 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
1506 esds[12] = (configdescriptorsize & 0x7f);
1507 esds[13] = 0x40; // objectTypeIndication
1508 // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
1509 esds[14] = 0x15; // streamType(5), upStream(0),
1510 esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
1511 esds[16] = 0x18;
1512 esds[17] = 0x00;
1513 esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
1514 esds[19] = 0x00;
1515 esds[20] = 0xfa;
1516 esds[21] = 0x00;
1517 esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
1518 esds[23] = 0x00;
1519 esds[24] = 0xfa;
1520 esds[25] = 0x00;
1521 esds[26] = 5; // kTag_DecoderSpecificInfo;
1522 esds[27] = 0x80 | (csd0size >> 21);
1523 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
1524 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
1525 esds[30] = (csd0size & 0x7f);
1526 memcpy((void*)&esds[31], csd0->data(), csd0size);
1527 // data following this is ignored, so don't bother appending it
1528 }
1529
reassembleHVCC(const sp<ABuffer> & csd0,uint8_t * hvcc,size_t hvccSize,size_t nalSizeLength)1530 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
1531 HevcParameterSets paramSets;
1532 uint8_t* data = csd0->data();
1533 if (csd0->size() < 4) {
1534 ALOGE("csd0 too small");
1535 return 0;
1536 }
1537 if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
1538 ALOGE("csd0 doesn't start with a start code");
1539 return 0;
1540 }
1541 size_t prevNalOffset = 4;
1542 status_t err = OK;
1543 for (size_t i = 1; i < csd0->size() - 4; ++i) {
1544 if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
1545 continue;
1546 }
1547 err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
1548 if (err != OK) {
1549 return 0;
1550 }
1551 prevNalOffset = i + 4;
1552 }
1553 err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
1554 if (err != OK) {
1555 return 0;
1556 }
1557 size_t size = hvccSize;
1558 err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
1559 if (err != OK) {
1560 return 0;
1561 }
1562 return size;
1563 }
1564
1565 #if 0
1566 static void convertMessageToMetaDataInt32(
1567 const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
1568 int32_t value;
1569 if (msg->findInt32(name, &value)) {
1570 meta->setInt32(key, value);
1571 }
1572 }
1573 #endif
1574
convertMessageToMetaDataColorAspects(const sp<AMessage> & msg,sp<MetaData> & meta)1575 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
1576 // 0 values are unspecified
1577 int32_t range = 0, standard = 0, transfer = 0;
1578 (void)msg->findInt32("color-range", &range);
1579 (void)msg->findInt32("color-standard", &standard);
1580 (void)msg->findInt32("color-transfer", &transfer);
1581
1582 ColorAspects colorAspects;
1583 memset(&colorAspects, 0, sizeof(colorAspects));
1584 if (CodecBase::convertPlatformColorAspectsToCodecAspects(
1585 range, standard, transfer, colorAspects) != OK) {
1586 return;
1587 }
1588
1589 // save specified values to meta
1590 if (colorAspects.mRange != 0) {
1591 meta->setInt32(kKeyColorRange, colorAspects.mRange);
1592 }
1593 if (colorAspects.mPrimaries != 0) {
1594 meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
1595 }
1596 if (colorAspects.mTransfer != 0) {
1597 meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
1598 }
1599 if (colorAspects.mMatrixCoeffs != 0) {
1600 meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
1601 }
1602 }
1603
convertMessageToMetaData(const sp<AMessage> & msg,sp<MetaData> & meta)1604 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
1605 AString mime;
1606 if (msg->findString("mime", &mime)) {
1607 meta->setCString(kKeyMIMEType, mime.c_str());
1608 } else {
1609 ALOGW("did not find mime type");
1610 }
1611
1612 convertMessageToMetaDataFromMappings(msg, meta);
1613
1614 int32_t systemId;
1615 if (msg->findInt32("ca-system-id", &systemId)) {
1616 meta->setInt32(kKeyCASystemID, systemId);
1617
1618 sp<ABuffer> caSessionId, caPvtData;
1619 if (msg->findBuffer("ca-session-id", &caSessionId)) {
1620 meta->setData(kKeyCASessionID, 0, caSessionId->data(), caSessionId->size());
1621 }
1622 if (msg->findBuffer("ca-private-data", &caPvtData)) {
1623 meta->setData(kKeyCAPrivateData, 0, caPvtData->data(), caPvtData->size());
1624 }
1625 }
1626
1627 int64_t durationUs;
1628 if (msg->findInt64("durationUs", &durationUs)) {
1629 meta->setInt64(kKeyDuration, durationUs);
1630 }
1631
1632 int32_t isSync;
1633 if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
1634 meta->setInt32(kKeyIsSyncFrame, 1);
1635 }
1636
1637 int32_t avgBitrate = 0;
1638 int32_t maxBitrate;
1639 if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
1640 meta->setInt32(kKeyBitRate, avgBitrate);
1641 }
1642 if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
1643 meta->setInt32(kKeyMaxBitRate, maxBitrate);
1644 }
1645
1646 AString lang;
1647 if (msg->findString("language", &lang)) {
1648 meta->setCString(kKeyMediaLanguage, lang.c_str());
1649 }
1650
1651 if (mime.startsWith("video/") || mime.startsWith("image/")) {
1652 int32_t width;
1653 int32_t height;
1654 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
1655 meta->setInt32(kKeyWidth, width);
1656 meta->setInt32(kKeyHeight, height);
1657 } else {
1658 ALOGV("did not find width and/or height");
1659 }
1660
1661 int32_t sarWidth, sarHeight;
1662 if (msg->findInt32("sar-width", &sarWidth)
1663 && msg->findInt32("sar-height", &sarHeight)) {
1664 meta->setInt32(kKeySARWidth, sarWidth);
1665 meta->setInt32(kKeySARHeight, sarHeight);
1666 }
1667
1668 int32_t displayWidth, displayHeight;
1669 if (msg->findInt32("display-width", &displayWidth)
1670 && msg->findInt32("display-height", &displayHeight)) {
1671 meta->setInt32(kKeyDisplayWidth, displayWidth);
1672 meta->setInt32(kKeyDisplayHeight, displayHeight);
1673 }
1674
1675 if (mime.startsWith("image/")){
1676 int32_t isPrimary;
1677 if (msg->findInt32("is-default", &isPrimary) && isPrimary) {
1678 meta->setInt32(kKeyTrackIsDefault, 1);
1679 }
1680 int32_t tileWidth, tileHeight, gridRows, gridCols;
1681 if (msg->findInt32("tile-width", &tileWidth)) {
1682 meta->setInt32(kKeyTileWidth, tileWidth);
1683 }
1684 if (msg->findInt32("tile-height", &tileHeight)) {
1685 meta->setInt32(kKeyTileHeight, tileHeight);
1686 }
1687 if (msg->findInt32("grid-rows", &gridRows)) {
1688 meta->setInt32(kKeyGridRows, gridRows);
1689 }
1690 if (msg->findInt32("grid-cols", &gridCols)) {
1691 meta->setInt32(kKeyGridCols, gridCols);
1692 }
1693 }
1694
1695 int32_t colorFormat;
1696 if (msg->findInt32("color-format", &colorFormat)) {
1697 meta->setInt32(kKeyColorFormat, colorFormat);
1698 }
1699
1700 int32_t cropLeft, cropTop, cropRight, cropBottom;
1701 if (msg->findRect("crop",
1702 &cropLeft,
1703 &cropTop,
1704 &cropRight,
1705 &cropBottom)) {
1706 meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
1707 }
1708
1709 int32_t rotationDegrees;
1710 if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1711 meta->setInt32(kKeyRotation, rotationDegrees);
1712 }
1713
1714 if (msg->contains("hdr-static-info")) {
1715 HDRStaticInfo info;
1716 if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
1717 meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
1718 }
1719 }
1720
1721 sp<ABuffer> hdr10PlusInfo;
1722 if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
1723 meta->setData(kKeyHdr10PlusInfo, 0,
1724 hdr10PlusInfo->data(), hdr10PlusInfo->size());
1725 }
1726
1727 convertMessageToMetaDataColorAspects(msg, meta);
1728
1729 AString tsSchema;
1730 if (msg->findString("ts-schema", &tsSchema)) {
1731 unsigned int numLayers = 0;
1732 unsigned int numBLayers = 0;
1733 char dummy;
1734 int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
1735 &numLayers, &dummy, &numBLayers, &dummy);
1736 if ((tags == 1 || (tags == 3 && dummy == '+'))
1737 && numLayers > 0 && numLayers < UINT32_MAX - numBLayers
1738 && numLayers + numBLayers <= INT32_MAX) {
1739 meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
1740 }
1741 }
1742 } else if (mime.startsWith("audio/")) {
1743 int32_t numChannels;
1744 if (msg->findInt32("channel-count", &numChannels)) {
1745 meta->setInt32(kKeyChannelCount, numChannels);
1746 }
1747 int32_t sampleRate;
1748 if (msg->findInt32("sample-rate", &sampleRate)) {
1749 meta->setInt32(kKeySampleRate, sampleRate);
1750 }
1751 int32_t bitsPerSample;
1752 if (msg->findInt32("bits-per-sample", &bitsPerSample)) {
1753 meta->setInt32(kKeyBitsPerSample, bitsPerSample);
1754 }
1755 int32_t channelMask;
1756 if (msg->findInt32("channel-mask", &channelMask)) {
1757 meta->setInt32(kKeyChannelMask, channelMask);
1758 }
1759 int32_t delay = 0;
1760 if (msg->findInt32("encoder-delay", &delay)) {
1761 meta->setInt32(kKeyEncoderDelay, delay);
1762 }
1763 int32_t padding = 0;
1764 if (msg->findInt32("encoder-padding", &padding)) {
1765 meta->setInt32(kKeyEncoderPadding, padding);
1766 }
1767
1768 int32_t isADTS;
1769 if (msg->findInt32("is-adts", &isADTS)) {
1770 meta->setInt32(kKeyIsADTS, isADTS);
1771 }
1772
1773 int32_t aacProfile = -1;
1774 if (msg->findInt32("aac-profile", &aacProfile)) {
1775 meta->setInt32(kKeyAACAOT, aacProfile);
1776 }
1777
1778 int32_t pcmEncoding;
1779 if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
1780 meta->setInt32(kKeyPcmEncoding, pcmEncoding);
1781 }
1782
1783 int32_t hapticChannelCount;
1784 if (msg->findInt32("haptic-channel-count", &hapticChannelCount)) {
1785 meta->setInt32(kKeyHapticChannelCount, hapticChannelCount);
1786 }
1787 }
1788
1789 int32_t maxInputSize;
1790 if (msg->findInt32("max-input-size", &maxInputSize)) {
1791 meta->setInt32(kKeyMaxInputSize, maxInputSize);
1792 }
1793
1794 int32_t maxWidth;
1795 if (msg->findInt32("max-width", &maxWidth)) {
1796 meta->setInt32(kKeyMaxWidth, maxWidth);
1797 }
1798
1799 int32_t maxHeight;
1800 if (msg->findInt32("max-height", &maxHeight)) {
1801 meta->setInt32(kKeyMaxHeight, maxHeight);
1802 }
1803
1804 int32_t fps;
1805 float fpsFloat;
1806 if (msg->findInt32("frame-rate", &fps) && fps > 0) {
1807 meta->setInt32(kKeyFrameRate, fps);
1808 } else if (msg->findFloat("frame-rate", &fpsFloat)
1809 && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
1810 // truncate values to distinguish between e.g. 24 vs 23.976 fps
1811 meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
1812 }
1813
1814 // reassemble the csd data into its original form
1815 sp<ABuffer> csd0, csd1, csd2;
1816 if (msg->findBuffer("csd-0", &csd0)) {
1817 int csd0size = csd0->size();
1818 if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
1819 sp<ABuffer> csd1;
1820 if (msg->findBuffer("csd-1", &csd1)) {
1821 std::vector<char> avcc(csd0size + csd1->size() + 1024);
1822 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
1823 meta->setData(kKeyAVCC, kTypeAVCC, avcc.data(), outsize);
1824 }
1825 } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC ||
1826 mime == MEDIA_MIMETYPE_VIDEO_MPEG4 ||
1827 mime == MEDIA_MIMETYPE_AUDIO_WMA ||
1828 mime == MEDIA_MIMETYPE_AUDIO_MS_ADPCM ||
1829 mime == MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) {
1830 std::vector<char> esds(csd0size + 31);
1831 // The written ESDS is actually for an audio stream, but it's enough
1832 // for transporting the CSD to muxers.
1833 reassembleESDS(csd0, esds.data());
1834 meta->setData(kKeyESDS, kTypeESDS, esds.data(), esds.size());
1835 } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC ||
1836 mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) {
1837 std::vector<uint8_t> hvcc(csd0size + 1024);
1838 size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
1839 meta->setData(kKeyHVCC, kTypeHVCC, hvcc.data(), outsize);
1840 } else if (mime == MEDIA_MIMETYPE_VIDEO_AV1) {
1841 meta->setData(kKeyAV1C, 0, csd0->data(), csd0->size());
1842 } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
1843 meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
1844 } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
1845 size_t opusHeadSize = csd0->size();
1846 size_t codecDelayBufSize = 0;
1847 size_t seekPreRollBufSize = 0;
1848 void *opusHeadBuf = csd0->data();
1849 void *codecDelayBuf = NULL;
1850 void *seekPreRollBuf = NULL;
1851 if (msg->findBuffer("csd-1", &csd1)) {
1852 codecDelayBufSize = csd1->size();
1853 codecDelayBuf = csd1->data();
1854 }
1855 if (msg->findBuffer("csd-2", &csd2)) {
1856 seekPreRollBufSize = csd2->size();
1857 seekPreRollBuf = csd2->data();
1858 }
1859 /* Extract codec delay and seek pre roll from csd-0,
1860 * if csd-1 and csd-2 are not present */
1861 if (!codecDelayBuf && !seekPreRollBuf) {
1862 GetOpusHeaderBuffers(csd0->data(), csd0->size(), &opusHeadBuf,
1863 &opusHeadSize, &codecDelayBuf,
1864 &codecDelayBufSize, &seekPreRollBuf,
1865 &seekPreRollBufSize);
1866 }
1867 meta->setData(kKeyOpusHeader, 0, opusHeadBuf, opusHeadSize);
1868 if (codecDelayBuf) {
1869 meta->setData(kKeyOpusCodecDelay, 0, codecDelayBuf, codecDelayBufSize);
1870 }
1871 if (seekPreRollBuf) {
1872 meta->setData(kKeyOpusSeekPreRoll, 0, seekPreRollBuf, seekPreRollBufSize);
1873 }
1874 } else if (mime == MEDIA_MIMETYPE_AUDIO_ALAC) {
1875 meta->setData(kKeyAlacMagicCookie, 0, csd0->data(), csd0->size());
1876 }
1877 } else if (mime == MEDIA_MIMETYPE_VIDEO_AVC && msg->findBuffer("csd-avc", &csd0)) {
1878 meta->setData(kKeyAVCC, kTypeAVCC, csd0->data(), csd0->size());
1879 } else if ((mime == MEDIA_MIMETYPE_VIDEO_HEVC || mime == MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)
1880 && msg->findBuffer("csd-hevc", &csd0)) {
1881 meta->setData(kKeyHVCC, kTypeHVCC, csd0->data(), csd0->size());
1882 } else if (msg->findBuffer("esds", &csd0)) {
1883 meta->setData(kKeyESDS, kTypeESDS, csd0->data(), csd0->size());
1884 } else if (msg->findBuffer("mpeg2-stream-header", &csd0)) {
1885 meta->setData(kKeyStreamHeader, 'mdat', csd0->data(), csd0->size());
1886 } else if (msg->findBuffer("d263", &csd0)) {
1887 meta->setData(kKeyD263, kTypeD263, csd0->data(), csd0->size());
1888 }
1889
1890 // XXX TODO add whatever other keys there are
1891
1892 #if 0
1893 ALOGI("converted %s to:", msg->debugString(0).c_str());
1894 meta->dumpToLog();
1895 #endif
1896 }
1897
MakeUserAgent()1898 AString MakeUserAgent() {
1899 AString ua;
1900 ua.append("stagefright/1.2 (Linux;Android ");
1901
1902 #if (PROPERTY_VALUE_MAX < 8)
1903 #error "PROPERTY_VALUE_MAX must be at least 8"
1904 #endif
1905
1906 char value[PROPERTY_VALUE_MAX];
1907 property_get("ro.build.version.release", value, "Unknown");
1908 ua.append(value);
1909 ua.append(")");
1910
1911 return ua;
1912 }
1913
sendMetaDataToHal(sp<MediaPlayerBase::AudioSink> & sink,const sp<MetaData> & meta)1914 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
1915 const sp<MetaData>& meta)
1916 {
1917 int32_t sampleRate = 0;
1918 int32_t bitRate = 0;
1919 int32_t channelMask = 0;
1920 int32_t delaySamples = 0;
1921 int32_t paddingSamples = 0;
1922
1923 AudioParameter param = AudioParameter();
1924
1925 if (meta->findInt32(kKeySampleRate, &sampleRate)) {
1926 param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
1927 }
1928 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
1929 param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
1930 }
1931 if (meta->findInt32(kKeyBitRate, &bitRate)) {
1932 param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
1933 }
1934 if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
1935 param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
1936 }
1937 if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
1938 param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
1939 }
1940
1941 ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
1942 "delaySample %d, paddingSample %d", bitRate, sampleRate,
1943 channelMask, delaySamples, paddingSamples);
1944
1945 sink->setParameters(param.toString());
1946 return OK;
1947 }
1948
1949 struct mime_conv_t {
1950 const char* mime;
1951 audio_format_t format;
1952 };
1953
1954 static const struct mime_conv_t mimeLookup[] = {
1955 { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 },
1956 { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT },
1957 { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB },
1958 { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB },
1959 { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC },
1960 { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS },
1961 { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS},
1962 { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3},
1963 { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3},
1964 { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, AUDIO_FORMAT_E_AC3_JOC},
1965 { MEDIA_MIMETYPE_AUDIO_AC4, AUDIO_FORMAT_AC4},
1966 { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC},
1967 { MEDIA_MIMETYPE_AUDIO_ALAC, AUDIO_FORMAT_ALAC },
1968 { 0, AUDIO_FORMAT_INVALID }
1969 };
1970
mapMimeToAudioFormat(audio_format_t & format,const char * mime)1971 status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
1972 {
1973 const struct mime_conv_t* p = &mimeLookup[0];
1974 while (p->mime != NULL) {
1975 if (0 == strcasecmp(mime, p->mime)) {
1976 format = p->format;
1977 return OK;
1978 }
1979 ++p;
1980 }
1981
1982 return BAD_VALUE;
1983 }
1984
1985 struct aac_format_conv_t {
1986 OMX_AUDIO_AACPROFILETYPE eAacProfileType;
1987 audio_format_t format;
1988 };
1989
1990 static const struct aac_format_conv_t profileLookup[] = {
1991 { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN},
1992 { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC},
1993 { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR},
1994 { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP},
1995 { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1},
1996 { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE},
1997 { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC},
1998 { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD},
1999 { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2},
2000 { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD},
2001 { OMX_AUDIO_AACObjectXHE, AUDIO_FORMAT_AAC_XHE},
2002 { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC},
2003 };
2004
mapAACProfileToAudioFormat(audio_format_t & format,uint64_t eAacProfile)2005 void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
2006 {
2007 const struct aac_format_conv_t* p = &profileLookup[0];
2008 while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
2009 if (eAacProfile == p->eAacProfileType) {
2010 format = p->format;
2011 return;
2012 }
2013 ++p;
2014 }
2015 format = AUDIO_FORMAT_AAC;
2016 return;
2017 }
2018
getAudioOffloadInfo(const sp<MetaData> & meta,bool hasVideo,bool isStreaming,audio_stream_type_t streamType,audio_offload_info_t * info)2019 status_t getAudioOffloadInfo(const sp<MetaData>& meta, bool hasVideo,
2020 bool isStreaming, audio_stream_type_t streamType, audio_offload_info_t *info)
2021 {
2022 const char *mime;
2023 if (meta == NULL) {
2024 return BAD_VALUE;
2025 }
2026 CHECK(meta->findCString(kKeyMIMEType, &mime));
2027
2028 (*info) = AUDIO_INFO_INITIALIZER;
2029
2030 info->format = AUDIO_FORMAT_INVALID;
2031 if (mapMimeToAudioFormat(info->format, mime) != OK) {
2032 ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
2033 return BAD_VALUE;
2034 } else {
2035 ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info->format);
2036 }
2037
2038 if (AUDIO_FORMAT_INVALID == info->format) {
2039 // can't offload if we don't know what the source format is
2040 ALOGE("mime type \"%s\" not a known audio format", mime);
2041 return BAD_VALUE;
2042 }
2043
2044 // Redefine aac format according to its profile
2045 // Offloading depends on audio DSP capabilities.
2046 int32_t aacaot = -1;
2047 if (meta->findInt32(kKeyAACAOT, &aacaot)) {
2048 mapAACProfileToAudioFormat(info->format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
2049 }
2050
2051 int32_t srate = -1;
2052 if (!meta->findInt32(kKeySampleRate, &srate)) {
2053 ALOGV("track of type '%s' does not publish sample rate", mime);
2054 }
2055 info->sample_rate = srate;
2056
2057 int32_t cmask = 0;
2058 if (!meta->findInt32(kKeyChannelMask, &cmask) || cmask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
2059 ALOGV("track of type '%s' does not publish channel mask", mime);
2060
2061 // Try a channel count instead
2062 int32_t channelCount;
2063 if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
2064 ALOGV("track of type '%s' does not publish channel count", mime);
2065 } else {
2066 cmask = audio_channel_out_mask_from_count(channelCount);
2067 }
2068 }
2069 info->channel_mask = cmask;
2070
2071 int64_t duration = 0;
2072 if (!meta->findInt64(kKeyDuration, &duration)) {
2073 ALOGV("track of type '%s' does not publish duration", mime);
2074 }
2075 info->duration_us = duration;
2076
2077 int32_t brate = -1;
2078 if (!meta->findInt32(kKeyBitRate, &brate)) {
2079 ALOGV("track of type '%s' does not publish bitrate", mime);
2080 }
2081 info->bit_rate = brate;
2082
2083
2084 info->stream_type = streamType;
2085 info->has_video = hasVideo;
2086 info->is_streaming = isStreaming;
2087 return OK;
2088 }
2089
canOffloadStream(const sp<MetaData> & meta,bool hasVideo,bool isStreaming,audio_stream_type_t streamType)2090 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
2091 bool isStreaming, audio_stream_type_t streamType)
2092 {
2093 audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
2094 if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
2095 return false;
2096 }
2097 // Check if offload is possible for given format, stream type, sample rate,
2098 // bit rate, duration, video and streaming
2099 return AudioSystem::isOffloadSupported(info);
2100 }
2101
uriDebugString(const AString & uri,bool incognito)2102 AString uriDebugString(const AString &uri, bool incognito) {
2103 if (incognito) {
2104 return AString("<URI suppressed>");
2105 }
2106
2107 if (property_get_bool("media.stagefright.log-uri", false)) {
2108 return uri;
2109 }
2110
2111 // find scheme
2112 AString scheme;
2113 const char *chars = uri.c_str();
2114 for (size_t i = 0; i < uri.size(); i++) {
2115 const char c = chars[i];
2116 if (!isascii(c)) {
2117 break;
2118 } else if (isalpha(c)) {
2119 continue;
2120 } else if (i == 0) {
2121 // first character must be a letter
2122 break;
2123 } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
2124 continue;
2125 } else if (c != ':') {
2126 break;
2127 }
2128 scheme = AString(uri, 0, i);
2129 scheme.append("://<suppressed>");
2130 return scheme;
2131 }
2132 return AString("<no-scheme URI suppressed>");
2133 }
2134
HLSTime(const sp<AMessage> & meta)2135 HLSTime::HLSTime(const sp<AMessage>& meta) :
2136 mSeq(-1),
2137 mTimeUs(-1LL),
2138 mMeta(meta) {
2139 if (meta != NULL) {
2140 CHECK(meta->findInt32("discontinuitySeq", &mSeq));
2141 CHECK(meta->findInt64("timeUs", &mTimeUs));
2142 }
2143 }
2144
getSegmentTimeUs() const2145 int64_t HLSTime::getSegmentTimeUs() const {
2146 int64_t segmentStartTimeUs = -1LL;
2147 if (mMeta != NULL) {
2148 CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
2149
2150 int64_t segmentFirstTimeUs;
2151 if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
2152 segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
2153 }
2154
2155 // adjust segment time by playlist age (for live streaming)
2156 int64_t playlistTimeUs;
2157 if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
2158 int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
2159
2160 int64_t durationUs;
2161 CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
2162
2163 // round to nearest whole segment
2164 playlistAgeUs = (playlistAgeUs + durationUs / 2)
2165 / durationUs * durationUs;
2166
2167 segmentStartTimeUs -= playlistAgeUs;
2168 if (segmentStartTimeUs < 0) {
2169 segmentStartTimeUs = 0;
2170 }
2171 }
2172 }
2173 return segmentStartTimeUs;
2174 }
2175
operator <(const HLSTime & t0,const HLSTime & t1)2176 bool operator <(const HLSTime &t0, const HLSTime &t1) {
2177 // we can only compare discontinuity sequence and timestamp.
2178 // (mSegmentTimeUs is not reliable in live streaming case, it's the
2179 // time starting from beginning of playlist but playlist could change.)
2180 return t0.mSeq < t1.mSeq
2181 || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
2182 }
2183
writeToAMessage(const sp<AMessage> & msg,const AudioPlaybackRate & rate)2184 void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate) {
2185 msg->setFloat("speed", rate.mSpeed);
2186 msg->setFloat("pitch", rate.mPitch);
2187 msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
2188 msg->setInt32("audio-stretch-mode", rate.mStretchMode);
2189 }
2190
readFromAMessage(const sp<AMessage> & msg,AudioPlaybackRate * rate)2191 void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
2192 *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
2193 CHECK(msg->findFloat("speed", &rate->mSpeed));
2194 CHECK(msg->findFloat("pitch", &rate->mPitch));
2195 CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
2196 CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
2197 }
2198
writeToAMessage(const sp<AMessage> & msg,const AVSyncSettings & sync,float videoFpsHint)2199 void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint) {
2200 msg->setInt32("sync-source", sync.mSource);
2201 msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
2202 msg->setFloat("tolerance", sync.mTolerance);
2203 msg->setFloat("video-fps", videoFpsHint);
2204 }
2205
readFromAMessage(const sp<AMessage> & msg,AVSyncSettings * sync,float * videoFps)2206 void readFromAMessage(
2207 const sp<AMessage> &msg,
2208 AVSyncSettings *sync /* nonnull */,
2209 float *videoFps /* nonnull */) {
2210 AVSyncSettings settings;
2211 CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
2212 CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
2213 CHECK(msg->findFloat("tolerance", &settings.mTolerance));
2214 CHECK(msg->findFloat("video-fps", videoFps));
2215 *sync = settings;
2216 }
2217
writeToAMessage(const sp<AMessage> & msg,const BufferingSettings & buffering)2218 void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering) {
2219 msg->setInt32("init-ms", buffering.mInitialMarkMs);
2220 msg->setInt32("resume-playback-ms", buffering.mResumePlaybackMarkMs);
2221 }
2222
readFromAMessage(const sp<AMessage> & msg,BufferingSettings * buffering)2223 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */) {
2224 int32_t value;
2225 if (msg->findInt32("init-ms", &value)) {
2226 buffering->mInitialMarkMs = value;
2227 }
2228 if (msg->findInt32("resume-playback-ms", &value)) {
2229 buffering->mResumePlaybackMarkMs = value;
2230 }
2231 }
2232
nameForFd(int fd)2233 AString nameForFd(int fd) {
2234 const size_t SIZE = 256;
2235 char buffer[SIZE];
2236 AString result;
2237 snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
2238 struct stat s;
2239 if (lstat(buffer, &s) == 0) {
2240 if ((s.st_mode & S_IFMT) == S_IFLNK) {
2241 char linkto[256];
2242 int len = readlink(buffer, linkto, sizeof(linkto));
2243 if(len > 0) {
2244 if(len > 255) {
2245 linkto[252] = '.';
2246 linkto[253] = '.';
2247 linkto[254] = '.';
2248 linkto[255] = 0;
2249 } else {
2250 linkto[len] = 0;
2251 }
2252 result.append(linkto);
2253 }
2254 } else {
2255 result.append("unexpected type for ");
2256 result.append(buffer);
2257 }
2258 } else {
2259 result.append("couldn't open ");
2260 result.append(buffer);
2261 }
2262 return result;
2263 }
2264
2265 } // namespace android
2266