blob: b0df379426e3eb47bf7a9c00c2c767ed902b07c0 [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
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
Andreas Huber98065552012-05-03 11:33:01 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "Utils"
19#include <utils/Log.h>
20
21#include "include/ESDS.h"
22
Andreas Huber20111aa2009-07-14 16:56:47 -070023#include <arpa/inet.h>
Andreas Huber190cdba2013-03-26 10:19:24 -070024#include <cutils/properties.h>
Andreas Huber98065552012-05-03 11:33:01 -070025#include <media/stagefright/foundation/ABuffer.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/AMessage.h>
28#include <media/stagefright/MetaData.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070029#include <media/stagefright/Utils.h>
30
31namespace android {
32
33uint16_t U16_AT(const uint8_t *ptr) {
34 return ptr[0] << 8 | ptr[1];
35}
36
37uint32_t U32_AT(const uint8_t *ptr) {
38 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
39}
40
41uint64_t U64_AT(const uint8_t *ptr) {
42 return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
43}
44
Andreas Huberee7ff202010-05-07 10:35:13 -070045uint16_t U16LE_AT(const uint8_t *ptr) {
46 return ptr[0] | (ptr[1] << 8);
47}
48
49uint32_t U32LE_AT(const uint8_t *ptr) {
50 return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
51}
52
53uint64_t U64LE_AT(const uint8_t *ptr) {
54 return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
55}
56
Andreas Huber20111aa2009-07-14 16:56:47 -070057// XXX warning: these won't work on big-endian host.
58uint64_t ntoh64(uint64_t x) {
59 return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
60}
61
62uint64_t hton64(uint64_t x) {
63 return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
64}
65
Andreas Huber98065552012-05-03 11:33:01 -070066status_t convertMetaDataToMessage(
67 const sp<MetaData> &meta, sp<AMessage> *format) {
68 format->clear();
69
70 const char *mime;
71 CHECK(meta->findCString(kKeyMIMEType, &mime));
72
73 sp<AMessage> msg = new AMessage;
74 msg->setString("mime", mime);
75
76 int64_t durationUs;
77 if (meta->findInt64(kKeyDuration, &durationUs)) {
78 msg->setInt64("durationUs", durationUs);
79 }
80
Marco Nelissen75ce7652012-12-13 11:10:05 -080081 int32_t isSync;
82 if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
83 msg->setInt32("is-sync-frame", 1);
84 }
85
Andreas Huber98065552012-05-03 11:33:01 -070086 if (!strncasecmp("video/", mime, 6)) {
87 int32_t width, height;
88 CHECK(meta->findInt32(kKeyWidth, &width));
89 CHECK(meta->findInt32(kKeyHeight, &height));
90
91 msg->setInt32("width", width);
92 msg->setInt32("height", height);
Andreas Hubere9810fa2012-12-03 15:20:40 -080093
94 int32_t sarWidth, sarHeight;
95 if (meta->findInt32(kKeySARWidth, &sarWidth)
96 && meta->findInt32(kKeySARHeight, &sarHeight)) {
97 msg->setInt32("sar-width", sarWidth);
98 msg->setInt32("sar-height", sarHeight);
99 }
Andreas Huber98065552012-05-03 11:33:01 -0700100 } else if (!strncasecmp("audio/", mime, 6)) {
101 int32_t numChannels, sampleRate;
102 CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
103 CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
104
105 msg->setInt32("channel-count", numChannels);
106 msg->setInt32("sample-rate", sampleRate);
107
108 int32_t channelMask;
109 if (meta->findInt32(kKeyChannelMask, &channelMask)) {
110 msg->setInt32("channel-mask", channelMask);
111 }
112
113 int32_t delay = 0;
114 if (meta->findInt32(kKeyEncoderDelay, &delay)) {
115 msg->setInt32("encoder-delay", delay);
116 }
117 int32_t padding = 0;
118 if (meta->findInt32(kKeyEncoderPadding, &padding)) {
119 msg->setInt32("encoder-padding", padding);
120 }
121
122 int32_t isADTS;
123 if (meta->findInt32(kKeyIsADTS, &isADTS)) {
124 msg->setInt32("is-adts", true);
125 }
126 }
127
128 int32_t maxInputSize;
129 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
130 msg->setInt32("max-input-size", maxInputSize);
131 }
132
133 uint32_t type;
134 const void *data;
135 size_t size;
136 if (meta->findData(kKeyAVCC, &type, &data, &size)) {
137 // Parse the AVCDecoderConfigurationRecord
138
139 const uint8_t *ptr = (const uint8_t *)data;
140
141 CHECK(size >= 7);
142 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
143 uint8_t profile = ptr[1];
144 uint8_t level = ptr[3];
145
146 // There is decodable content out there that fails the following
147 // assertion, let's be lenient for now...
148 // CHECK((ptr[4] >> 2) == 0x3f); // reserved
149
150 size_t lengthSize = 1 + (ptr[4] & 3);
151
152 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
153 // violates it...
154 // CHECK((ptr[5] >> 5) == 7); // reserved
155
156 size_t numSeqParameterSets = ptr[5] & 31;
157
158 ptr += 6;
159 size -= 6;
160
161 sp<ABuffer> buffer = new ABuffer(1024);
162 buffer->setRange(0, 0);
163
164 for (size_t i = 0; i < numSeqParameterSets; ++i) {
165 CHECK(size >= 2);
166 size_t length = U16_AT(ptr);
167
168 ptr += 2;
169 size -= 2;
170
171 CHECK(size >= length);
172
173 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
174 memcpy(buffer->data() + buffer->size() + 4, ptr, length);
175 buffer->setRange(0, buffer->size() + 4 + length);
176
177 ptr += length;
178 size -= length;
179 }
180
181 buffer->meta()->setInt32("csd", true);
182 buffer->meta()->setInt64("timeUs", 0);
183
184 msg->setBuffer("csd-0", buffer);
185
186 buffer = new ABuffer(1024);
187 buffer->setRange(0, 0);
188
189 CHECK(size >= 1);
190 size_t numPictureParameterSets = *ptr;
191 ++ptr;
192 --size;
193
194 for (size_t i = 0; i < numPictureParameterSets; ++i) {
195 CHECK(size >= 2);
196 size_t length = U16_AT(ptr);
197
198 ptr += 2;
199 size -= 2;
200
201 CHECK(size >= length);
202
203 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
204 memcpy(buffer->data() + buffer->size() + 4, ptr, length);
205 buffer->setRange(0, buffer->size() + 4 + length);
206
207 ptr += length;
208 size -= length;
209 }
210
211 buffer->meta()->setInt32("csd", true);
212 buffer->meta()->setInt64("timeUs", 0);
213 msg->setBuffer("csd-1", buffer);
214 } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
215 ESDS esds((const char *)data, size);
216 CHECK_EQ(esds.InitCheck(), (status_t)OK);
217
218 const void *codec_specific_data;
219 size_t codec_specific_data_size;
220 esds.getCodecSpecificInfo(
221 &codec_specific_data, &codec_specific_data_size);
222
223 sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
224
225 memcpy(buffer->data(), codec_specific_data,
226 codec_specific_data_size);
227
228 buffer->meta()->setInt32("csd", true);
229 buffer->meta()->setInt64("timeUs", 0);
230 msg->setBuffer("csd-0", buffer);
231 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
232 sp<ABuffer> buffer = new ABuffer(size);
233 memcpy(buffer->data(), data, size);
234
235 buffer->meta()->setInt32("csd", true);
236 buffer->meta()->setInt64("timeUs", 0);
237 msg->setBuffer("csd-0", buffer);
238
239 if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
240 return -EINVAL;
241 }
242
243 buffer = new ABuffer(size);
244 memcpy(buffer->data(), data, size);
245
246 buffer->meta()->setInt32("csd", true);
247 buffer->meta()->setInt64("timeUs", 0);
248 msg->setBuffer("csd-1", buffer);
249 }
250
251 *format = msg;
252
253 return OK;
254}
255
Marco Nelissen1e9ee012012-08-28 15:09:49 -0700256static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
257
258 avcc[0] = 1; // version
259 avcc[1] = 0x64; // profile
260 avcc[2] = 0; // unused (?)
261 avcc[3] = 0xd; // level
262 avcc[4] = 0xff; // reserved+size
263
264 size_t i = 0;
265 int numparams = 0;
266 int lastparamoffset = 0;
267 int avccidx = 6;
268 do {
269 if (i >= csd0->size() - 4 ||
270 memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
271 if (i >= csd0->size() - 4) {
272 // there can't be another param here, so use all the rest
273 i = csd0->size();
274 }
275 ALOGV("block at %d, last was %d", i, lastparamoffset);
276 if (lastparamoffset > 0) {
277 int size = i - lastparamoffset;
278 avcc[avccidx++] = size >> 8;
279 avcc[avccidx++] = size & 0xff;
280 memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
281 avccidx += size;
282 numparams++;
283 }
284 i += 4;
285 lastparamoffset = i;
286 } else {
287 i++;
288 }
289 } while(i < csd0->size());
290 ALOGV("csd0 contains %d params", numparams);
291
292 avcc[5] = 0xe0 | numparams;
293 //and now csd-1
294 i = 0;
295 numparams = 0;
296 lastparamoffset = 0;
297 int numpicparamsoffset = avccidx;
298 avccidx++;
299 do {
300 if (i >= csd1->size() - 4 ||
301 memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
302 if (i >= csd1->size() - 4) {
303 // there can't be another param here, so use all the rest
304 i = csd1->size();
305 }
306 ALOGV("block at %d, last was %d", i, lastparamoffset);
307 if (lastparamoffset > 0) {
308 int size = i - lastparamoffset;
309 avcc[avccidx++] = size >> 8;
310 avcc[avccidx++] = size & 0xff;
311 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
312 avccidx += size;
313 numparams++;
314 }
315 i += 4;
316 lastparamoffset = i;
317 } else {
318 i++;
319 }
320 } while(i < csd1->size());
321 avcc[numpicparamsoffset] = numparams;
322 return avccidx;
323}
324
325static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
326 int csd0size = csd0->size();
327 esds[0] = 3; // kTag_ESDescriptor;
328 int esdescriptorsize = 26 + csd0size;
329 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
330 esds[1] = 0x80 | (esdescriptorsize >> 21);
331 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
332 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
333 esds[4] = (esdescriptorsize & 0x7f);
334 esds[5] = esds[6] = 0; // es id
335 esds[7] = 0; // flags
336 esds[8] = 4; // kTag_DecoderConfigDescriptor
337 int configdescriptorsize = 18 + csd0size;
338 esds[9] = 0x80 | (configdescriptorsize >> 21);
339 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
340 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
341 esds[12] = (configdescriptorsize & 0x7f);
342 esds[13] = 0x40; // objectTypeIndication
343 esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
344 esds[15] = 0x00; // but the actual values here were taken from a real file.
345 esds[16] = 0x18;
346 esds[17] = 0x00;
347 esds[18] = 0x00;
348 esds[19] = 0x00;
349 esds[20] = 0xfa;
350 esds[21] = 0x00;
351 esds[22] = 0x00;
352 esds[23] = 0x00;
353 esds[24] = 0xfa;
354 esds[25] = 0x00;
355 esds[26] = 5; // kTag_DecoderSpecificInfo;
356 esds[27] = 0x80 | (csd0size >> 21);
357 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
358 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
359 esds[30] = (csd0size & 0x7f);
360 memcpy((void*)&esds[31], csd0->data(), csd0size);
361 // data following this is ignored, so don't bother appending it
362
363}
364
365void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
366 AString mime;
367 if (msg->findString("mime", &mime)) {
368 meta->setCString(kKeyMIMEType, mime.c_str());
369 } else {
370 ALOGW("did not find mime type");
371 }
372
373 int64_t durationUs;
374 if (msg->findInt64("durationUs", &durationUs)) {
375 meta->setInt64(kKeyDuration, durationUs);
376 }
377
Marco Nelissen75ce7652012-12-13 11:10:05 -0800378 int32_t isSync;
379 if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
380 meta->setInt32(kKeyIsSyncFrame, 1);
381 }
382
Marco Nelissen1e9ee012012-08-28 15:09:49 -0700383 if (mime.startsWith("video/")) {
384 int32_t width;
385 int32_t height;
386 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
387 meta->setInt32(kKeyWidth, width);
388 meta->setInt32(kKeyHeight, height);
389 } else {
390 ALOGW("did not find width and/or height");
391 }
Andreas Hubere9810fa2012-12-03 15:20:40 -0800392
393 int32_t sarWidth, sarHeight;
394 if (msg->findInt32("sar-width", &sarWidth)
395 && msg->findInt32("sar-height", &sarHeight)) {
396 meta->setInt32(kKeySARWidth, sarWidth);
397 meta->setInt32(kKeySARHeight, sarHeight);
398 }
Marco Nelissen1e9ee012012-08-28 15:09:49 -0700399 } else if (mime.startsWith("audio/")) {
400 int32_t numChannels;
401 if (msg->findInt32("channel-count", &numChannels)) {
402 meta->setInt32(kKeyChannelCount, numChannels);
403 }
404 int32_t sampleRate;
405 if (msg->findInt32("sample-rate", &sampleRate)) {
406 meta->setInt32(kKeySampleRate, sampleRate);
407 }
408 int32_t channelMask;
409 if (msg->findInt32("channel-mask", &channelMask)) {
410 meta->setInt32(kKeyChannelMask, channelMask);
411 }
412 int32_t delay = 0;
413 if (msg->findInt32("encoder-delay", &delay)) {
414 meta->setInt32(kKeyEncoderDelay, delay);
415 }
416 int32_t padding = 0;
417 if (msg->findInt32("encoder-padding", &padding)) {
418 meta->setInt32(kKeyEncoderPadding, padding);
419 }
420
421 int32_t isADTS;
422 if (msg->findInt32("is-adts", &isADTS)) {
423 meta->setInt32(kKeyIsADTS, isADTS);
424 }
425 }
426
427 int32_t maxInputSize;
428 if (msg->findInt32("max-input-size", &maxInputSize)) {
429 meta->setInt32(kKeyMaxInputSize, maxInputSize);
430 }
431
432 // reassemble the csd data into its original form
433 sp<ABuffer> csd0;
434 if (msg->findBuffer("csd-0", &csd0)) {
435 if (mime.startsWith("video/")) { // do we need to be stricter than this?
436 sp<ABuffer> csd1;
437 if (msg->findBuffer("csd-1", &csd1)) {
438 char avcc[1024]; // that oughta be enough, right?
439 size_t outsize = reassembleAVCC(csd0, csd1, avcc);
440 meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
441 }
442 } else if (mime.startsWith("audio/")) {
443 int csd0size = csd0->size();
444 char esds[csd0size + 31];
445 reassembleESDS(csd0, esds);
446 meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
447 }
448 }
449
450 // XXX TODO add whatever other keys there are
451
452#if 0
453 ALOGI("converted %s to:", msg->debugString(0).c_str());
454 meta->dumpToLog();
455#endif
456}
457
Andreas Huber190cdba2013-03-26 10:19:24 -0700458AString MakeUserAgent() {
459 AString ua;
460 ua.append("stagefright/1.2 (Linux;Android ");
461
462#if (PROPERTY_VALUE_MAX < 8)
463#error "PROPERTY_VALUE_MAX must be at least 8"
464#endif
465
466 char value[PROPERTY_VALUE_MAX];
467 property_get("ro.build.version.release", value, "Unknown");
468 ua.append(value);
469 ua.append(")");
470
471 return ua;
472}
Marco Nelissen1e9ee012012-08-28 15:09:49 -0700473
Andreas Huber20111aa2009-07-14 16:56:47 -0700474} // namespace android
475