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
21#include "include/ESDS.h"
22
23#include <arpa/inet.h>
24#include <cutils/properties.h>
25#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>
29#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
45uint16_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
57// 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
66status_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
81    int32_t isSync;
82    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
83        msg->setInt32("is-sync-frame", 1);
84    }
85
86    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);
93
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        }
100    } 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
256static 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
378    int32_t isSync;
379    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
380        meta->setInt32(kKeyIsSyncFrame, 1);
381    }
382
383    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        }
392
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        }
399    } 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
458AString 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}
473
474}  // namespace android
475
476