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/stagefright/Utils.h>
29 #include <media/NdkMediaFormat.h>
30 
31 namespace android {
32 
MakeAVCCodecSpecificData(MetaDataBase & meta,const uint8_t * data,size_t size)33 bool MakeAVCCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
34     if (data == nullptr || size == 0) {
35         return false;
36     }
37 
38     int32_t width;
39     int32_t height;
40     int32_t sarWidth;
41     int32_t sarHeight;
42     sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
43     sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
44     if (csd == nullptr) {
45         return false;
46     }
47     meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
48 
49     meta.setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
50     meta.setInt32(kKeyWidth, width);
51     meta.setInt32(kKeyHeight, height);
52     if (sarWidth > 0 && sarHeight > 0) {
53         meta.setInt32(kKeySARWidth, sarWidth);
54         meta.setInt32(kKeySARHeight, sarHeight);
55     }
56     return true;
57 }
58 
MakeAVCCodecSpecificData(AMediaFormat * meta,const uint8_t * data,size_t size)59 bool MakeAVCCodecSpecificData(AMediaFormat *meta, const uint8_t *data, size_t size) {
60     if (meta == nullptr || data == nullptr || size == 0) {
61         return false;
62     }
63 
64     int32_t width;
65     int32_t height;
66     int32_t sarWidth;
67     int32_t sarHeight;
68     sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
69     sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
70     if (csd == nullptr) {
71         return false;
72     }
73     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
74 
75     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_AVC, csd->data(), csd->size());
76     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, width);
77     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, height);
78     if (sarWidth > 0 && sarHeight > 0) {
79         AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_WIDTH, sarWidth);
80         AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAR_HEIGHT, sarHeight);
81     }
82     return true;
83 }
84 
MakeAACCodecSpecificData(MetaDataBase & meta,const uint8_t * data,size_t size)85 bool MakeAACCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
86     if (data == nullptr || size < 7) {
87         return false;
88     }
89 
90     ABitReader bits(data, size);
91 
92     // adts_fixed_header
93 
94     if (bits.getBits(12) != 0xfffu) {
95         ALOGE("Wrong atds_fixed_header");
96         return false;
97     }
98 
99     bits.skipBits(4);  // ID, layer, protection_absent
100 
101     unsigned profile = bits.getBits(2);
102     if (profile == 3u) {
103         ALOGE("profile should not be 3");
104         return false;
105     }
106     unsigned sampling_freq_index = bits.getBits(4);
107     bits.getBits(1);  // private_bit
108     unsigned channel_configuration = bits.getBits(3);
109     if (channel_configuration == 0u) {
110         ALOGE("channel_config should not be 0");
111         return false;
112     }
113 
114     if (!MakeAACCodecSpecificData(
115             meta, profile, sampling_freq_index, channel_configuration)) {
116         return false;
117     }
118 
119     meta.setInt32(kKeyIsADTS, true);
120     return true;
121 }
122 
MakeAACCodecSpecificData(uint8_t * csd,size_t * esds_size,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration,int32_t * sampling_rate)123 bool MakeAACCodecSpecificData(
124         uint8_t *csd, /* out */
125         size_t *esds_size, /* in/out */
126         unsigned profile, /* in */
127         unsigned sampling_freq_index, /* in */
128         unsigned channel_configuration, /* in */
129         int32_t *sampling_rate /* out */
130 ) {
131     if(sampling_freq_index > 11u) {
132         return false;
133     }
134     static const int32_t kSamplingFreq[] = {
135         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
136         16000, 12000, 11025, 8000
137     };
138     *sampling_rate = kSamplingFreq[sampling_freq_index];
139 
140     static const uint8_t kStaticESDS[] = {
141         0x03, 22,
142         0x00, 0x00,     // ES_ID
143         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
144 
145         0x04, 17,
146         0x40,                       // Audio ISO/IEC 14496-3
147         0x00, 0x00, 0x00, 0x00,
148         0x00, 0x00, 0x00, 0x00,
149         0x00, 0x00, 0x00, 0x00,
150 
151         0x05, 2,
152         // AudioSpecificInfo follows
153 
154         // oooo offf fccc c000
155         // o - audioObjectType
156         // f - samplingFreqIndex
157         // c - channelConfig
158     };
159 
160     size_t csdSize = sizeof(kStaticESDS) + 2;
161     if (csdSize > *esds_size) {
162         return false;
163     }
164     memcpy(csd, kStaticESDS, sizeof(kStaticESDS));
165 
166     csd[sizeof(kStaticESDS)] =
167         ((profile + 1) << 3) | (sampling_freq_index >> 1);
168 
169     csd[sizeof(kStaticESDS) + 1] =
170         ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
171 
172     *esds_size = csdSize;
173     return true;
174 }
175 
MakeAACCodecSpecificData(AMediaFormat * meta,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration)176 bool MakeAACCodecSpecificData(AMediaFormat *meta, unsigned profile, unsigned sampling_freq_index,
177         unsigned channel_configuration) {
178 
179     if(sampling_freq_index > 11u) {
180         return false;
181     }
182 
183     uint8_t csd[2];
184     csd[0] = ((profile + 1) << 3) | (sampling_freq_index >> 1);
185     csd[1] = ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
186 
187     static const int32_t kSamplingFreq[] = {
188         96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
189         16000, 12000, 11025, 8000
190     };
191     int32_t sampleRate = kSamplingFreq[sampling_freq_index];
192 
193     AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, csd, sizeof(csd));
194     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
195     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
196     AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channel_configuration);
197 
198     return true;
199 }
200 
MakeAACCodecSpecificData(MetaDataBase & meta,unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration)201 bool MakeAACCodecSpecificData(
202         MetaDataBase &meta,
203         unsigned profile, unsigned sampling_freq_index,
204         unsigned channel_configuration) {
205 
206     uint8_t csd[24];
207     size_t csdSize = sizeof(csd);
208     int32_t sampleRate;
209 
210     if (!MakeAACCodecSpecificData(csd, &csdSize, profile, sampling_freq_index,
211             channel_configuration, &sampleRate)) {
212         return false;
213     }
214 
215     meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
216 
217     meta.setInt32(kKeySampleRate, sampleRate);
218     meta.setInt32(kKeyChannelCount, channel_configuration);
219     meta.setData(kKeyESDS, 0, csd, csdSize);
220     return true;
221 }
222 
223 
extractAlbumArt(AMediaFormat * fileMeta,const void * data,size_t size)224 static void extractAlbumArt(
225         AMediaFormat *fileMeta, const void *data, size_t size) {
226     ALOGV("extractAlbumArt from '%s'", (const char *)data);
227 
228     size_t inLen = strnlen((const char *)data, size);
229     size_t flacSize = inLen / 4 * 3;
230     uint8_t *flac = new uint8_t[flacSize];
231     if (!decodeBase64(flac, &flacSize, (const char*)data)) {
232         ALOGE("malformed base64 encoded data.");
233         delete[] flac;
234         return;
235     }
236 
237     ALOGV("got flac of size %zu", flacSize);
238 
239     uint32_t picType;
240     uint32_t typeLen;
241     uint32_t descLen;
242     uint32_t dataLen;
243     char type[128];
244 
245     if (flacSize < 8) {
246         delete[] flac;
247         return;
248     }
249 
250     picType = U32_AT(flac);
251 
252     if (picType != 3) {
253         // This is not a front cover.
254         delete[] flac;
255         return;
256     }
257 
258     typeLen = U32_AT(&flac[4]);
259     if (typeLen > sizeof(type) - 1) {
260         delete[] flac;
261         return;
262     }
263 
264     // we've already checked above that flacSize >= 8
265     if (flacSize - 8 < typeLen) {
266         delete[] flac;
267         return;
268     }
269 
270     memcpy(type, &flac[8], typeLen);
271     type[typeLen] = '\0';
272 
273     ALOGV("picType = %d, type = '%s'", picType, type);
274 
275     if (!strcmp(type, "-->")) {
276         // This is not inline cover art, but an external url instead.
277         delete[] flac;
278         return;
279     }
280 
281     if (flacSize < 32 || flacSize - 32 < typeLen) {
282         delete[] flac;
283         return;
284     }
285 
286     descLen = U32_AT(&flac[8 + typeLen]);
287     if (flacSize - 32 - typeLen < descLen) {
288         delete[] flac;
289         return;
290     }
291 
292     dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
293 
294     // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
295     if (flacSize - 32 - typeLen - descLen < dataLen) {
296         delete[] flac;
297         return;
298     }
299 
300     ALOGV("got image data, %zu trailing bytes",
301          flacSize - 32 - typeLen - descLen - dataLen);
302 
303     AMediaFormat_setBuffer(fileMeta, AMEDIAFORMAT_KEY_ALBUMART,
304             &flac[8 + typeLen + 4 + descLen + 20], dataLen);
305 
306     delete[] flac;
307 }
308 
parseVorbisComment(AMediaFormat * fileMeta,const char * comment,size_t commentLength)309 void parseVorbisComment(
310         AMediaFormat *fileMeta, const char *comment, size_t commentLength) {
311     // Haptic tag is only kept here as it will only be used in extractor to generate channel mask.
312     struct {
313         const char *const mTag;
314         const char *mKey;
315     } kMap[] = {
316         { "TITLE", AMEDIAFORMAT_KEY_TITLE },
317         { "ARTIST", AMEDIAFORMAT_KEY_ARTIST },
318         { "ALBUMARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
319         { "ALBUM ARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
320         { "COMPILATION", AMEDIAFORMAT_KEY_COMPILATION },
321         { "ALBUM", AMEDIAFORMAT_KEY_ALBUM },
322         { "COMPOSER", AMEDIAFORMAT_KEY_COMPOSER },
323         { "GENRE", AMEDIAFORMAT_KEY_GENRE },
324         { "AUTHOR", AMEDIAFORMAT_KEY_AUTHOR },
325         { "TRACKNUMBER", AMEDIAFORMAT_KEY_CDTRACKNUMBER },
326         { "DISCNUMBER", AMEDIAFORMAT_KEY_DISCNUMBER },
327         { "DATE", AMEDIAFORMAT_KEY_DATE },
328         { "YEAR", AMEDIAFORMAT_KEY_YEAR },
329         { "LYRICIST", AMEDIAFORMAT_KEY_LYRICIST },
330         { "METADATA_BLOCK_PICTURE", AMEDIAFORMAT_KEY_ALBUMART },
331         { "ANDROID_LOOP", AMEDIAFORMAT_KEY_LOOP },
332         { "ANDROID_HAPTIC", AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT },
333     };
334 
335         for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
336             size_t tagLen = strlen(kMap[j].mTag);
337             if (!strncasecmp(kMap[j].mTag, comment, tagLen)
338                     && comment[tagLen] == '=') {
339                 if (kMap[j].mKey == AMEDIAFORMAT_KEY_ALBUMART) {
340                     extractAlbumArt(
341                             fileMeta,
342                             &comment[tagLen + 1],
343                             commentLength - tagLen - 1);
344                 } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_LOOP) {
345                     if (!strcasecmp(&comment[tagLen + 1], "true")) {
346                         AMediaFormat_setInt32(fileMeta, AMEDIAFORMAT_KEY_LOOP, 1);
347                     }
348                 } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT) {
349                     char *end;
350                     errno = 0;
351                     const int hapticChannelCount = strtol(&comment[tagLen + 1], &end, 10);
352                     if (errno == 0) {
353                         AMediaFormat_setInt32(fileMeta, kMap[j].mKey, hapticChannelCount);
354                     } else {
355                         ALOGE("Error(%d) when parsing haptic channel count", errno);
356                     }
357                 } else {
358                     AMediaFormat_setString(fileMeta, kMap[j].mKey, &comment[tagLen + 1]);
359                 }
360             }
361         }
362 
363 }
364 
365 }  // namespace android
366