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