Home | History | Annotate | Download | only in rtsp
      1 /*
      2  * Copyright (C) 2010 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 "APacketSource"
     19 #include <utils/Log.h>
     20 
     21 #include "APacketSource.h"
     22 
     23 #include "ARawAudioAssembler.h"
     24 #include "ASessionDescription.h"
     25 
     26 #include "avc_utils.h"
     27 
     28 #include <ctype.h>
     29 
     30 #include <media/stagefright/foundation/ABitReader.h>
     31 #include <media/stagefright/foundation/ABuffer.h>
     32 #include <media/stagefright/foundation/ADebug.h>
     33 #include <media/stagefright/foundation/AMessage.h>
     34 #include <media/stagefright/foundation/AString.h>
     35 #include <media/stagefright/foundation/base64.h>
     36 #include <media/stagefright/foundation/hexdump.h>
     37 #include <media/stagefright/MediaDefs.h>
     38 #include <media/stagefright/MediaErrors.h>
     39 #include <media/stagefright/MetaData.h>
     40 #include <utils/Vector.h>
     41 
     42 namespace android {
     43 
     44 static bool GetAttribute(const char *s, const char *key, AString *value) {
     45     value->clear();
     46 
     47     size_t keyLen = strlen(key);
     48 
     49     for (;;) {
     50         while (isspace(*s)) {
     51             ++s;
     52         }
     53 
     54         const char *colonPos = strchr(s, ';');
     55 
     56         size_t len =
     57             (colonPos == NULL) ? strlen(s) : colonPos - s;
     58 
     59         if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
     60             value->setTo(&s[keyLen + 1], len - keyLen - 1);
     61             return true;
     62         }
     63 
     64         if (colonPos == NULL) {
     65             return false;
     66         }
     67 
     68         s = colonPos + 1;
     69     }
     70 }
     71 
     72 static sp<ABuffer> decodeHex(const AString &s) {
     73     if ((s.size() % 2) != 0) {
     74         return NULL;
     75     }
     76 
     77     size_t outLen = s.size() / 2;
     78     sp<ABuffer> buffer = new ABuffer(outLen);
     79     uint8_t *out = buffer->data();
     80 
     81     uint8_t accum = 0;
     82     for (size_t i = 0; i < s.size(); ++i) {
     83         char c = s.c_str()[i];
     84         unsigned value;
     85         if (c >= '0' && c <= '9') {
     86             value = c - '0';
     87         } else if (c >= 'a' && c <= 'f') {
     88             value = c - 'a' + 10;
     89         } else if (c >= 'A' && c <= 'F') {
     90             value = c - 'A' + 10;
     91         } else {
     92             return NULL;
     93         }
     94 
     95         accum = (accum << 4) | value;
     96 
     97         if (i & 1) {
     98             *out++ = accum;
     99 
    100             accum = 0;
    101         }
    102     }
    103 
    104     return buffer;
    105 }
    106 
    107 static sp<ABuffer> MakeAVCCodecSpecificData(
    108         const char *params, int32_t *width, int32_t *height) {
    109     *width = 0;
    110     *height = 0;
    111 
    112     AString val;
    113     sp<ABuffer> profileLevelID = NULL;
    114     if (GetAttribute(params, "profile-level-id", &val)) {
    115         profileLevelID = decodeHex(val);
    116         CHECK_EQ(profileLevelID->size(), 3u);
    117     }
    118 
    119     Vector<sp<ABuffer> > paramSets;
    120 
    121     size_t numSeqParameterSets = 0;
    122     size_t totalSeqParameterSetSize = 0;
    123     size_t numPicParameterSets = 0;
    124     size_t totalPicParameterSetSize = 0;
    125 
    126     if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
    127         return NULL;
    128     }
    129 
    130     size_t start = 0;
    131     for (;;) {
    132         ssize_t commaPos = val.find(",", start);
    133         size_t end = (commaPos < 0) ? val.size() : commaPos;
    134 
    135         AString nalString(val, start, end - start);
    136         sp<ABuffer> nal = decodeBase64(nalString);
    137         CHECK(nal != NULL);
    138         CHECK_GT(nal->size(), 0u);
    139         CHECK_LE(nal->size(), 65535u);
    140 
    141         uint8_t nalType = nal->data()[0] & 0x1f;
    142         if (numSeqParameterSets == 0) {
    143             CHECK_EQ((unsigned)nalType, 7u);
    144         } else if (numPicParameterSets > 0) {
    145             CHECK_EQ((unsigned)nalType, 8u);
    146         }
    147         if (nalType == 7) {
    148             ++numSeqParameterSets;
    149             totalSeqParameterSetSize += nal->size();
    150         } else  {
    151             CHECK_EQ((unsigned)nalType, 8u);
    152             ++numPicParameterSets;
    153             totalPicParameterSetSize += nal->size();
    154         }
    155 
    156         paramSets.push(nal);
    157 
    158         if (commaPos < 0) {
    159             break;
    160         }
    161 
    162         start = commaPos + 1;
    163     }
    164 
    165     CHECK_LT(numSeqParameterSets, 32u);
    166     CHECK_LE(numPicParameterSets, 255u);
    167 
    168     size_t csdSize =
    169         1 + 3 + 1 + 1
    170         + 2 * numSeqParameterSets + totalSeqParameterSetSize
    171         + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
    172 
    173     sp<ABuffer> csd = new ABuffer(csdSize);
    174     uint8_t *out = csd->data();
    175 
    176     *out++ = 0x01;  // configurationVersion
    177     if (profileLevelID != NULL) {
    178         memcpy(out, profileLevelID->data(), 3);
    179         out += 3;
    180     } else {
    181         *out++ = 0x42; // Baseline profile
    182         *out++ = 0xE0; // Common subset for all profiles
    183         *out++ = 0x0A; // Level 1
    184     }
    185 
    186     *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
    187     *out++ = 0xe0 | numSeqParameterSets;
    188 
    189     for (size_t i = 0; i < numSeqParameterSets; ++i) {
    190         sp<ABuffer> nal = paramSets.editItemAt(i);
    191 
    192         *out++ = nal->size() >> 8;
    193         *out++ = nal->size() & 0xff;
    194 
    195         memcpy(out, nal->data(), nal->size());
    196 
    197         out += nal->size();
    198 
    199         if (i == 0) {
    200             FindAVCDimensions(nal, width, height);
    201             ALOGI("dimensions %dx%d", *width, *height);
    202         }
    203     }
    204 
    205     *out++ = numPicParameterSets;
    206 
    207     for (size_t i = 0; i < numPicParameterSets; ++i) {
    208         sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
    209 
    210         *out++ = nal->size() >> 8;
    211         *out++ = nal->size() & 0xff;
    212 
    213         memcpy(out, nal->data(), nal->size());
    214 
    215         out += nal->size();
    216     }
    217 
    218     // hexdump(csd->data(), csd->size());
    219 
    220     return csd;
    221 }
    222 
    223 sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
    224     AString val;
    225     CHECK(GetAttribute(params, "config", &val));
    226 
    227     sp<ABuffer> config = decodeHex(val);
    228     CHECK(config != NULL);
    229     CHECK_GE(config->size(), 4u);
    230 
    231     const uint8_t *data = config->data();
    232     uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    233     x = (x >> 1) & 0xffff;
    234 
    235     static const uint8_t kStaticESDS[] = {
    236         0x03, 22,
    237         0x00, 0x00,     // ES_ID
    238         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
    239 
    240         0x04, 17,
    241         0x40,                       // Audio ISO/IEC 14496-3
    242         0x00, 0x00, 0x00, 0x00,
    243         0x00, 0x00, 0x00, 0x00,
    244         0x00, 0x00, 0x00, 0x00,
    245 
    246         0x05, 2,
    247         // AudioSpecificInfo follows
    248     };
    249 
    250     sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
    251     memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
    252     csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
    253     csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
    254 
    255     // hexdump(csd->data(), csd->size());
    256 
    257     return csd;
    258 }
    259 
    260 // From mpeg4-generic configuration data.
    261 sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
    262     AString val;
    263     unsigned long objectType;
    264     if (GetAttribute(params, "objectType", &val)) {
    265         const char *s = val.c_str();
    266         char *end;
    267         objectType = strtoul(s, &end, 10);
    268         CHECK(end > s && *end == '\0');
    269     } else {
    270         objectType = 0x40;  // Audio ISO/IEC 14496-3
    271     }
    272 
    273     CHECK(GetAttribute(params, "config", &val));
    274 
    275     sp<ABuffer> config = decodeHex(val);
    276     CHECK(config != NULL);
    277 
    278     // Make sure size fits into a single byte and doesn't have to
    279     // be encoded.
    280     CHECK_LT(20 + config->size(), 128u);
    281 
    282     const uint8_t *data = config->data();
    283 
    284     static const uint8_t kStaticESDS[] = {
    285         0x03, 22,
    286         0x00, 0x00,     // ES_ID
    287         0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
    288 
    289         0x04, 17,
    290         0x40,                       // Audio ISO/IEC 14496-3
    291         0x00, 0x00, 0x00, 0x00,
    292         0x00, 0x00, 0x00, 0x00,
    293         0x00, 0x00, 0x00, 0x00,
    294 
    295         0x05, 2,
    296         // AudioSpecificInfo follows
    297     };
    298 
    299     sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
    300     uint8_t *dst = csd->data();
    301     *dst++ = 0x03;
    302     *dst++ = 20 + config->size();
    303     *dst++ = 0x00;  // ES_ID
    304     *dst++ = 0x00;
    305     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
    306     *dst++ = 0x04;
    307     *dst++ = 15 + config->size();
    308     *dst++ = objectType;
    309     for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
    310     *dst++ = 0x05;
    311     *dst++ = config->size();
    312     memcpy(dst, config->data(), config->size());
    313 
    314     // hexdump(csd->data(), csd->size());
    315 
    316     return csd;
    317 }
    318 
    319 static size_t GetSizeWidth(size_t x) {
    320     size_t n = 1;
    321     while (x > 127) {
    322         ++n;
    323         x >>= 7;
    324     }
    325     return n;
    326 }
    327 
    328 static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
    329     while (x > 127) {
    330         *dst++ = (x & 0x7f) | 0x80;
    331         x >>= 7;
    332     }
    333     *dst++ = x;
    334     return dst;
    335 }
    336 
    337 static bool ExtractDimensionsMPEG4Config(
    338         const sp<ABuffer> &config, int32_t *width, int32_t *height) {
    339     *width = 0;
    340     *height = 0;
    341 
    342     const uint8_t *ptr = config->data();
    343     size_t offset = 0;
    344     bool foundVOL = false;
    345     while (offset + 3 < config->size()) {
    346         if (memcmp("\x00\x00\x01", &ptr[offset], 3)
    347                 || (ptr[offset + 3] & 0xf0) != 0x20) {
    348             ++offset;
    349             continue;
    350         }
    351 
    352         foundVOL = true;
    353         break;
    354     }
    355 
    356     if (!foundVOL) {
    357         return false;
    358     }
    359 
    360     return ExtractDimensionsFromVOLHeader(
    361             &ptr[offset], config->size() - offset, width, height);
    362 }
    363 
    364 static sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
    365         const char *params, int32_t *width, int32_t *height) {
    366     *width = 0;
    367     *height = 0;
    368 
    369     AString val;
    370     CHECK(GetAttribute(params, "config", &val));
    371 
    372     sp<ABuffer> config = decodeHex(val);
    373     CHECK(config != NULL);
    374 
    375     if (!ExtractDimensionsMPEG4Config(config, width, height)) {
    376         return NULL;
    377     }
    378 
    379     ALOGI("VOL dimensions = %dx%d", *width, *height);
    380 
    381     size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
    382     size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
    383     size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
    384 
    385     sp<ABuffer> csd = new ABuffer(len3);
    386     uint8_t *dst = csd->data();
    387     *dst++ = 0x03;
    388     dst = EncodeSize(dst, len2 + 3);
    389     *dst++ = 0x00;  // ES_ID
    390     *dst++ = 0x00;
    391     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
    392 
    393     *dst++ = 0x04;
    394     dst = EncodeSize(dst, len1 + 13);
    395     *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
    396     for (size_t i = 0; i < 12; ++i) {
    397         *dst++ = 0x00;
    398     }
    399 
    400     *dst++ = 0x05;
    401     dst = EncodeSize(dst, config->size());
    402     memcpy(dst, config->data(), config->size());
    403     dst += config->size();
    404 
    405     // hexdump(csd->data(), csd->size());
    406 
    407     return csd;
    408 }
    409 
    410 APacketSource::APacketSource(
    411         const sp<ASessionDescription> &sessionDesc, size_t index)
    412     : mInitCheck(NO_INIT),
    413       mFormat(new MetaData) {
    414     unsigned long PT;
    415     AString desc;
    416     AString params;
    417     sessionDesc->getFormatType(index, &PT, &desc, &params);
    418 
    419     int64_t durationUs;
    420     if (sessionDesc->getDurationUs(&durationUs)) {
    421         mFormat->setInt64(kKeyDuration, durationUs);
    422     } else {
    423         mFormat->setInt64(kKeyDuration, 60 * 60 * 1000000ll);
    424     }
    425 
    426     mInitCheck = OK;
    427     if (!strncmp(desc.c_str(), "H264/", 5)) {
    428         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
    429 
    430         int32_t width, height;
    431         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
    432             width = -1;
    433             height = -1;
    434         }
    435 
    436         int32_t encWidth, encHeight;
    437         sp<ABuffer> codecSpecificData =
    438             MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
    439 
    440         if (codecSpecificData != NULL) {
    441             if (width < 0) {
    442                 // If no explicit width/height given in the sdp, use the dimensions
    443                 // extracted from the first sequence parameter set.
    444                 width = encWidth;
    445                 height = encHeight;
    446             }
    447 
    448             mFormat->setData(
    449                     kKeyAVCC, 0,
    450                     codecSpecificData->data(), codecSpecificData->size());
    451         } else if (width < 0) {
    452             mInitCheck = ERROR_UNSUPPORTED;
    453             return;
    454         }
    455 
    456         mFormat->setInt32(kKeyWidth, width);
    457         mFormat->setInt32(kKeyHeight, height);
    458     } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
    459             || !strncmp(desc.c_str(), "H263-1998/", 10)) {
    460         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
    461 
    462         int32_t width, height;
    463         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
    464             mInitCheck = ERROR_UNSUPPORTED;
    465             return;
    466         }
    467 
    468         mFormat->setInt32(kKeyWidth, width);
    469         mFormat->setInt32(kKeyHeight, height);
    470     } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
    471         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
    472 
    473         int32_t sampleRate, numChannels;
    474         ASessionDescription::ParseFormatDesc(
    475                 desc.c_str(), &sampleRate, &numChannels);
    476 
    477         mFormat->setInt32(kKeySampleRate, sampleRate);
    478         mFormat->setInt32(kKeyChannelCount, numChannels);
    479 
    480         sp<ABuffer> codecSpecificData =
    481             MakeAACCodecSpecificData(params.c_str());
    482 
    483         mFormat->setData(
    484                 kKeyESDS, 0,
    485                 codecSpecificData->data(), codecSpecificData->size());
    486     } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
    487         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
    488 
    489         int32_t sampleRate, numChannels;
    490         ASessionDescription::ParseFormatDesc(
    491                 desc.c_str(), &sampleRate, &numChannels);
    492 
    493         mFormat->setInt32(kKeySampleRate, sampleRate);
    494         mFormat->setInt32(kKeyChannelCount, numChannels);
    495 
    496         if (sampleRate != 8000 || numChannels != 1) {
    497             mInitCheck = ERROR_UNSUPPORTED;
    498         }
    499     } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
    500         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
    501 
    502         int32_t sampleRate, numChannels;
    503         ASessionDescription::ParseFormatDesc(
    504                 desc.c_str(), &sampleRate, &numChannels);
    505 
    506         mFormat->setInt32(kKeySampleRate, sampleRate);
    507         mFormat->setInt32(kKeyChannelCount, numChannels);
    508 
    509         if (sampleRate != 16000 || numChannels != 1) {
    510             mInitCheck = ERROR_UNSUPPORTED;
    511         }
    512     } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
    513         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
    514 
    515         int32_t width, height;
    516         if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
    517             width = -1;
    518             height = -1;
    519         }
    520 
    521         int32_t encWidth, encHeight;
    522         sp<ABuffer> codecSpecificData =
    523             MakeMPEG4VideoCodecSpecificData(
    524                     params.c_str(), &encWidth, &encHeight);
    525 
    526         if (codecSpecificData != NULL) {
    527             mFormat->setData(
    528                     kKeyESDS, 0,
    529                     codecSpecificData->data(), codecSpecificData->size());
    530 
    531             if (width < 0) {
    532                 width = encWidth;
    533                 height = encHeight;
    534             }
    535         } else if (width < 0) {
    536             mInitCheck = ERROR_UNSUPPORTED;
    537             return;
    538         }
    539 
    540         mFormat->setInt32(kKeyWidth, width);
    541         mFormat->setInt32(kKeyHeight, height);
    542     } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
    543         AString val;
    544         if (!GetAttribute(params.c_str(), "mode", &val)
    545                 || (strcasecmp(val.c_str(), "AAC-lbr")
    546                     && strcasecmp(val.c_str(), "AAC-hbr"))) {
    547             mInitCheck = ERROR_UNSUPPORTED;
    548             return;
    549         }
    550 
    551         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
    552 
    553         int32_t sampleRate, numChannels;
    554         ASessionDescription::ParseFormatDesc(
    555                 desc.c_str(), &sampleRate, &numChannels);
    556 
    557         mFormat->setInt32(kKeySampleRate, sampleRate);
    558         mFormat->setInt32(kKeyChannelCount, numChannels);
    559         mFormat->setInt32(kKeyIsADTS, true);
    560 
    561         sp<ABuffer> codecSpecificData =
    562             MakeAACCodecSpecificData2(params.c_str());
    563 
    564         mFormat->setData(
    565                 kKeyESDS, 0,
    566                 codecSpecificData->data(), codecSpecificData->size());
    567     } else if (ARawAudioAssembler::Supports(desc.c_str())) {
    568         ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat);
    569     } else if (!strncasecmp("MP2T/", desc.c_str(), 5)) {
    570         mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
    571     } else {
    572         mInitCheck = ERROR_UNSUPPORTED;
    573     }
    574 }
    575 
    576 APacketSource::~APacketSource() {
    577 }
    578 
    579 status_t APacketSource::initCheck() const {
    580     return mInitCheck;
    581 }
    582 
    583 sp<MetaData> APacketSource::getFormat() {
    584     return mFormat;
    585 }
    586 
    587 }  // namespace android
    588