Home | History | Annotate | Download | only in libstagefright
      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 
     31 namespace android {
     32 
     33 uint16_t U16_AT(const uint8_t *ptr) {
     34     return ptr[0] << 8 | ptr[1];
     35 }
     36 
     37 uint32_t U32_AT(const uint8_t *ptr) {
     38     return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
     39 }
     40 
     41 uint64_t U64_AT(const uint8_t *ptr) {
     42     return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
     43 }
     44 
     45 uint16_t U16LE_AT(const uint8_t *ptr) {
     46     return ptr[0] | (ptr[1] << 8);
     47 }
     48 
     49 uint32_t U32LE_AT(const uint8_t *ptr) {
     50     return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
     51 }
     52 
     53 uint64_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.
     58 uint64_t ntoh64(uint64_t x) {
     59     return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
     60 }
     61 
     62 uint64_t hton64(uint64_t x) {
     63     return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
     64 }
     65 
     66 status_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 
    256 static 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 
    325 static 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 
    365 void 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 
    458 AString 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