• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "MetaDataUtils"
19 #include <utils/Log.h>
20 
21 #include <media/stagefright/foundation/avc_utils.h>
22 #include <media/stagefright/foundation/base64.h>
23 #include <media/stagefright/foundation/ABitReader.h>
24 #include <media/stagefright/foundation/ABuffer.h>
25 #include <media/stagefright/foundation/ByteUtils.h>
26 #include <media/stagefright/MediaDefs.h>
27 #include <media/stagefright/MetaDataUtils.h>
28 #include <media/NdkMediaFormat.h>
29 
30 namespace android {
31 
MakeAVCCodecSpecificData(MetaDataBase & meta,const uint8_t * data,size_t size)32 bool MakeAVCCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
33     if (data == nullptr || size == 0) {
34         return false;
35     }
36 
37     int32_t width;
38     int32_t height;
39     int32_t sarWidth;
40     int32_t sarHeight;
41     sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
42     sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
43     if (csd == nullptr) {
44         return false;
45     }
46     meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
47 
48     meta.setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
49     meta.setInt32(kKeyWidth, width);
50     meta.setInt32(kKeyHeight, height);
51     if (sarWidth > 0 && sarHeight > 0) {
52         meta.setInt32(kKeySARWidth, sarWidth);
53         meta.setInt32(kKeySARHeight, sarHeight);
54     }
55     return true;
56 }
57 
MakeAVCCodecSpecificData(AMediaFormat * meta,const uint8_t * data,size_t size)58 bool MakeAVCCodecSpecificData(AMediaFormat *meta, const uint8_t *data, size_t size) {
59     if (meta == nullptr || data == nullptr || size == 0) {
60         return false;
61     }
62 
63     int32_t width;
64     int32_t height;
65     int32_t sarWidth;
66     int32_t sarHeight;
67     sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
68     sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
69     if (csd == nullptr) {
70         return false;
71     }
72     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
73 
74     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_AVC, csd->data(), csd->size());
75     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, width);
76     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, height);
77     if (sarWidth > 0 && sarHeight > 0) {
78         AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_WIDTH, sarWidth);
79         AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_HEIGHT, sarHeight);
80     }
81     return true;
82 }
83 
84 // Check if the next 24 bits are VP9 SYNC_CODE
isVp9SyncCode(ABitReader & bits)85 static bool isVp9SyncCode(ABitReader &bits) {
86     if (bits.numBitsLeft() < 24) {
87         return false;
88     }
89     return bits.getBits(24) == 0x498342;
90 }
91 
92 // This parses bitdepth and subsampling in a VP9 uncompressed header
93 // (refer section bitdepth_colorspace_sampling in 6.2 of the VP9 bitstream spec)
getVp9BitdepthChromaSubSampling(ABitReader & bits,int32_t profile,int32_t * bitDepth,int32_t * chromaSubsampling)94 static bool getVp9BitdepthChromaSubSampling(ABitReader &bits,
95         int32_t profile,
96         int32_t *bitDepth,
97         int32_t *chromaSubsampling) {
98     if (profile >= 2) {
99         if (bits.numBitsLeft() < 1) {
100             return false;
101         }
102         *bitDepth = bits.getBits(1) ? 12 : 10;
103     } else {
104         *bitDepth = 8;
105     }
106 
107     uint32_t colorspace;
108     if (!bits.getBitsGraceful(3, &colorspace)) {
109         return false;
110     }
111 
112     *chromaSubsampling = -1;
113     if (colorspace != 7 /*SRGB*/) {
114         // Skip yuv_range_flag
115         if (!bits.skipBits(1)) {
116             return false;
117         }
118         // Check for subsampling only for profiles 1 and 3.
119         if (profile == 1 || profile == 3) {
120             uint32_t ss_x;
121             uint32_t ss_y;
122             if (bits.getBitsGraceful(1, &ss_x) && bits.getBitsGraceful(1, &ss_y)) {
123                 *chromaSubsampling = ss_x << 1 & ss_y;
124             } else {
125                 return false;
126             }
127         } else {
128             *chromaSubsampling = 3;
129         }
130     } else {
131         if (profile == 1 || profile == 3) {
132             *chromaSubsampling = 0;
133         }
134     }
135     return true;
136 }
137 // The param data contains the first frame data, starting with the uncompressed frame
138 // header. This uncompressed header (refer section 6.2 of the VP9 bitstream spec) is
139 // used to parse profile, bitdepth and subsampling.
MakeVP9CodecSpecificData(AMediaFormat * meta,const uint8_t * data,size_t size)140 bool MakeVP9CodecSpecificData(AMediaFormat* meta, const uint8_t* data, size_t size) {
141     if (meta == nullptr || data == nullptr || size == 0) {
142         return false;
143     }
144 
145     ABitReader bits(data, size);
146 
147     // First 2 bits of the uncompressed header should be the frame_marker.
148     if (bits.getBits(2) != 0b10) {
149         return false;
150     }
151 
152     int32_t profileLowBit = bits.getBits(1);
153     int32_t profileHighBit = bits.getBits(1);
154     int32_t profile = profileHighBit * 2 + profileLowBit;
155 
156     // One reserved '0' bit if profile is 3.
157     if (profile == 3 && bits.getBits(1) != 0) {
158         return false;
159     }
160 
161     // If show_existing_frame is set, we get no more data. Since this is
162     // expected to be the first frame, we can return false which will cascade
163     // into ERROR_MALFORMED.
164     if (bits.getBits(1)) {
165         return false;
166     }
167 
168     int32_t frame_type = bits.getBits(1);
169 
170     // Upto 7 bits could be read till now, which were guaranteed to be available
171     // since size > 0. Check for bits available before reading them from now on.
172     if (bits.numBitsLeft() < 2) {
173         return false;
174     }
175 
176     int32_t show_frame = bits.getBits(1);
177     int32_t error_resilient_mode = bits.getBits(1);
178     int32_t bitDepth = 8;
179     int32_t chromaSubsampling = -1;
180 
181     if (frame_type == 0 /* KEY_FRAME */) {
182         // Check for sync code.
183         if (!isVp9SyncCode(bits)) {
184             return false;
185         }
186 
187         if (!getVp9BitdepthChromaSubSampling(bits, profile, &bitDepth, &chromaSubsampling)) {
188             return false;
189         }
190     } else {
191         int32_t intra_only = 0;
192         if (!show_frame) {
193             if (bits.numBitsLeft() < 1) {
194                 return false;
195             }
196             intra_only = bits.getBits(1);
197         }
198 
199         if (!error_resilient_mode) {
200             if (bits.numBitsLeft() < 2) {
201                 return false;
202             }
203             // ignore reset_frame_context
204             bits.skipBits(2);
205         }
206 
207         if (!intra_only) {
208             // Require first frame to be either KEY_FRAME or INTER_FRAME with intra_only set to true
209             return false;
210         }
211 
212         // Check for sync code.
213         if (!isVp9SyncCode(bits)) {
214             return false;
215         }
216 
217         if (profile > 0) {
218             if (!getVp9BitdepthChromaSubSampling(bits, profile, &bitDepth, &chromaSubsampling)) {
219                 return false;
220             }
221         } else {
222             bitDepth = 8;
223             chromaSubsampling = 3;
224         }
225     }
226     int32_t csdSize = 6;
227     if (chromaSubsampling != -1) {
228         csdSize += 3;
229     }
230 
231     // Create VP9 Codec Feature Metadata (CodecPrivate) that can be parsed
232     // https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate
233     sp<ABuffer> csd = sp<ABuffer>::make(csdSize);
234     uint8_t* csdData = csd->data();
235 
236     *csdData++ = 0x01 /* FEATURE PROFILE */;
237     *csdData++ = 0x01 /* length */;
238     *csdData++ = profile;
239 
240     *csdData++ = 0x03 /* FEATURE BITDEPTH */;
241     *csdData++ = 0x01 /* length */;
242     *csdData++ = bitDepth;
243 
244     // csdSize more than 6 means chroma subsampling data was found.
245     if (csdSize > 6) {
246         *csdData++ = 0x04 /* FEATURE SUBSAMPLING */;
247         *csdData++ = 0x01 /* length */;
248         *csdData++ = chromaSubsampling;
249     }
250 
251     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, csd->data(), csd->size());
252     return true;
253 }
254 
MakeAACCodecSpecificData(MetaDataBase & meta,const uint8_t * data,size_t size)255 bool MakeAACCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
256     if (data == nullptr || size < 7) {
257         return false;
258     }
259 
260     ABitReader bits(data, size);
261 
262     // adts_fixed_header
263 
264     if (bits.getBits(12) != 0xfffu) {
265         ALOGE("Wrong atds_fixed_header");
266         return false;
267     }
268 
269     bits.skipBits(4);  // ID, layer, protection_absent
270 
271     unsigned profile = bits.getBits(2);
272     if (profile == 3u) {
273         ALOGE("profile should not be 3");
274         return false;
275     }
276     unsigned sampling_freq_index = bits.getBits(4);
277     bits.getBits(1);  // private_bit
278     unsigned channel_configuration = bits.getBits(3);
279     if (channel_configuration == 0u) {
280         ALOGE("channel_config should not be 0");
281         return false;
282     }
283 
284     if (!MakeAACCodecSpecificData(
285             meta, profile, sampling_freq_index, channel_configuration)) {
286         return false;
287     }
288 
289     meta.setInt32(kKeyIsADTS, true);
290     return true;
291 }
292 
MakeAACCodecSpecificData(uint8_t * csd,size_t * esds_size,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration,int32_t * sampling_rate)293 bool MakeAACCodecSpecificData(
294         uint8_t *csd, /* out */
295         size_t *esds_size, /* in/out */
296         unsigned profile, /* in */
297         unsigned sampling_freq_index, /* in */
298         unsigned channel_configuration, /* in */
299         int32_t *sampling_rate /* out */
300 ) {
301     if(sampling_freq_index > 11u) {
302         return false;
303     }
304     static const int32_t kSamplingFreq[] = {
305         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
306         16000, 12000, 11025, 8000
307     };
308     *sampling_rate = kSamplingFreq[sampling_freq_index];
309 
310     static const uint8_t kStaticESDS[] = {
311         0x03, 22,
312         0x00, 0x00,     // ES_ID
313         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
314 
315         0x04, 17,
316         0x40,                       // Audio ISO/IEC 14496-3
317         0x00, 0x00, 0x00, 0x00,
318         0x00, 0x00, 0x00, 0x00,
319         0x00, 0x00, 0x00, 0x00,
320 
321         0x05, 2,
322         // AudioSpecificInfo follows
323 
324         // oooo offf fccc c000
325         // o - audioObjectType
326         // f - samplingFreqIndex
327         // c - channelConfig
328     };
329 
330     size_t csdSize = sizeof(kStaticESDS) + 2;
331     if (csdSize > *esds_size) {
332         return false;
333     }
334     memcpy(csd, kStaticESDS, sizeof(kStaticESDS));
335 
336     csd[sizeof(kStaticESDS)] =
337         ((profile + 1) << 3) | (sampling_freq_index >> 1);
338 
339     csd[sizeof(kStaticESDS) + 1] =
340         ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
341 
342     *esds_size = csdSize;
343     return true;
344 }
345 
MakeAACCodecSpecificData(AMediaFormat * meta,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration)346 bool MakeAACCodecSpecificData(AMediaFormat *meta, unsigned profile, unsigned sampling_freq_index,
347         unsigned channel_configuration) {
348 
349     if(sampling_freq_index > 11u) {
350         return false;
351     }
352 
353     uint8_t csd[2];
354     csd[0] = ((profile + 1) << 3) | (sampling_freq_index >> 1);
355     csd[1] = ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
356 
357     static const int32_t kSamplingFreq[] = {
358         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
359         16000, 12000, 11025, 8000
360     };
361     int32_t sampleRate = kSamplingFreq[sampling_freq_index];
362 
363     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, csd, sizeof(csd));
364     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
365     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
366     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channel_configuration);
367 
368     return true;
369 }
370 
MakeAACCodecSpecificData(MetaDataBase & meta,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration)371 bool MakeAACCodecSpecificData(
372         MetaDataBase &meta,
373         unsigned profile, unsigned sampling_freq_index,
374         unsigned channel_configuration) {
375 
376     uint8_t csd[24];
377     size_t csdSize = sizeof(csd);
378     int32_t sampleRate;
379 
380     if (!MakeAACCodecSpecificData(csd, &csdSize, profile, sampling_freq_index,
381             channel_configuration, &sampleRate)) {
382         return false;
383     }
384 
385     meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
386 
387     meta.setInt32(kKeySampleRate, sampleRate);
388     meta.setInt32(kKeyChannelCount, channel_configuration);
389     meta.setData(kKeyESDS, 0, csd, csdSize);
390     return true;
391 }
392 
393 
extractAlbumArt(AMediaFormat * fileMeta,const void * data,size_t size)394 static void extractAlbumArt(
395         AMediaFormat *fileMeta, const void *data, size_t size) {
396     ALOGV("extractAlbumArt from '%s'", (const char *)data);
397 
398     size_t inLen = strnlen((const char *)data, size);
399     size_t flacSize = inLen / 4 * 3;
400     uint8_t *flac = new uint8_t[flacSize];
401     if (!decodeBase64(flac, &flacSize, (const char*)data)) {
402         ALOGE("malformed base64 encoded data.");
403         delete[] flac;
404         return;
405     }
406 
407     ALOGV("got flac of size %zu", flacSize);
408 
409     uint32_t picType;
410     uint32_t typeLen;
411     uint32_t descLen;
412     uint32_t dataLen;
413     char type[128];
414 
415     if (flacSize < 8) {
416         delete[] flac;
417         return;
418     }
419 
420     picType = U32_AT(flac);
421 
422     if (picType != 3) {
423         // This is not a front cover.
424         delete[] flac;
425         return;
426     }
427 
428     typeLen = U32_AT(&flac[4]);
429     if (typeLen > sizeof(type) - 1) {
430         delete[] flac;
431         return;
432     }
433 
434     // we've already checked above that flacSize >= 8
435     if (flacSize - 8 < typeLen) {
436         delete[] flac;
437         return;
438     }
439 
440     memcpy(type, &flac[8], typeLen);
441     type[typeLen] = '\0';
442 
443     ALOGV("picType = %d, type = '%s'", picType, type);
444 
445     if (!strcmp(type, "-->")) {
446         // This is not inline cover art, but an external url instead.
447         delete[] flac;
448         return;
449     }
450 
451     if (flacSize < 32 || flacSize - 32 < typeLen) {
452         delete[] flac;
453         return;
454     }
455 
456     descLen = U32_AT(&flac[8 + typeLen]);
457     if (flacSize - 32 - typeLen < descLen) {
458         delete[] flac;
459         return;
460     }
461 
462     dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
463 
464     // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
465     if (flacSize - 32 - typeLen - descLen < dataLen) {
466         delete[] flac;
467         return;
468     }
469 
470     ALOGV("got image data, %zu trailing bytes",
471          flacSize - 32 - typeLen - descLen - dataLen);
472 
473     AMediaFormat_setBuffer(fileMeta, AMEDIAFORMAT_KEY_ALBUMART,
474             &flac[8 + typeLen + 4 + descLen + 20], dataLen);
475 
476     delete[] flac;
477 }
478 
parseVorbisComment(AMediaFormat * fileMeta,const char * comment,size_t commentLength)479 void parseVorbisComment(
480         AMediaFormat *fileMeta, const char *comment, size_t commentLength) {
481     // Haptic tag is only kept here as it will only be used in extractor to generate channel mask.
482     struct {
483         const char *const mTag;
484         const char *mKey;
485     } kMap[] = {
486         { "TITLE", AMEDIAFORMAT_KEY_TITLE },
487         { "ARTIST", AMEDIAFORMAT_KEY_ARTIST },
488         { "ALBUMARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
489         { "ALBUM ARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
490         { "COMPILATION", AMEDIAFORMAT_KEY_COMPILATION },
491         { "ALBUM", AMEDIAFORMAT_KEY_ALBUM },
492         { "COMPOSER", AMEDIAFORMAT_KEY_COMPOSER },
493         { "GENRE", AMEDIAFORMAT_KEY_GENRE },
494         { "AUTHOR", AMEDIAFORMAT_KEY_AUTHOR },
495         { "TRACKNUMBER", AMEDIAFORMAT_KEY_CDTRACKNUMBER },
496         { "DISCNUMBER", AMEDIAFORMAT_KEY_DISCNUMBER },
497         { "DATE", AMEDIAFORMAT_KEY_DATE },
498         { "YEAR", AMEDIAFORMAT_KEY_YEAR },
499         { "LYRICIST", AMEDIAFORMAT_KEY_LYRICIST },
500         { "METADATA_BLOCK_PICTURE", AMEDIAFORMAT_KEY_ALBUMART },
501         { "ANDROID_LOOP", AMEDIAFORMAT_KEY_LOOP },
502         { "ANDROID_HAPTIC", AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT },
503     };
504 
505         for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
506             size_t tagLen = strlen(kMap[j].mTag);
507             if (!strncasecmp(kMap[j].mTag, comment, tagLen)
508                     && comment[tagLen] == '=') {
509                 if (kMap[j].mKey == AMEDIAFORMAT_KEY_ALBUMART) {
510                     extractAlbumArt(
511                             fileMeta,
512                             &comment[tagLen + 1],
513                             commentLength - tagLen - 1);
514                 } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_LOOP) {
515                     if (!strcasecmp(&comment[tagLen + 1], "true")) {
516                         AMediaFormat_setInt32(fileMeta, AMEDIAFORMAT_KEY_LOOP, 1);
517                     }
518                 } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT) {
519                     char *end;
520                     errno = 0;
521                     const int hapticChannelCount = strtol(&comment[tagLen + 1], &end, 10);
522                     if (errno == 0) {
523                         AMediaFormat_setInt32(fileMeta, kMap[j].mKey, hapticChannelCount);
524                     } else {
525                         ALOGE("Error(%d) when parsing haptic channel count", errno);
526                     }
527                 } else {
528                     AMediaFormat_setString(fileMeta, kMap[j].mKey, &comment[tagLen + 1]);
529                 }
530             }
531         }
532 
533 }
534 
535 }  // namespace android
536