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 "AMPEG4ElementaryAssembler"
     19 #include <utils/Log.h>
     20 
     21 #include "AMPEG4ElementaryAssembler.h"
     22 
     23 #include "ARTPSource.h"
     24 #include "ASessionDescription.h"
     25 
     26 #include <media/stagefright/foundation/ABitReader.h>
     27 #include <media/stagefright/foundation/ABuffer.h>
     28 #include <media/stagefright/foundation/ADebug.h>
     29 #include <media/stagefright/foundation/AMessage.h>
     30 #include <media/stagefright/foundation/hexdump.h>
     31 #include <media/stagefright/Utils.h>
     32 
     33 #include <ctype.h>
     34 #include <stdint.h>
     35 
     36 namespace android {
     37 
     38 static bool GetAttribute(const char *s, const char *key, AString *value) {
     39     value->clear();
     40 
     41     size_t keyLen = strlen(key);
     42 
     43     for (;;) {
     44         while (isspace(*s)) {
     45             ++s;
     46         }
     47 
     48         const char *colonPos = strchr(s, ';');
     49 
     50         size_t len =
     51             (colonPos == NULL) ? strlen(s) : colonPos - s;
     52 
     53         if (len >= keyLen + 1 && s[keyLen] == '='
     54                 && !strncasecmp(s, key, keyLen)) {
     55             value->setTo(&s[keyLen + 1], len - keyLen - 1);
     56             return true;
     57         }
     58 
     59         if (colonPos == NULL) {
     60             return false;
     61         }
     62 
     63         s = colonPos + 1;
     64     }
     65 }
     66 
     67 static bool GetIntegerAttribute(
     68         const char *s, const char *key, unsigned *x) {
     69     *x = 0;
     70 
     71     AString val;
     72     if (!GetAttribute(s, key, &val)) {
     73         return false;
     74     }
     75 
     76     s = val.c_str();
     77     char *end;
     78     unsigned y = strtoul(s, &end, 10);
     79 
     80     if (end == s || *end != '\0') {
     81         return false;
     82     }
     83 
     84     *x = y;
     85 
     86     return true;
     87 }
     88 
     89 static bool GetSampleRateIndex(int32_t sampleRate, size_t *tableIndex) {
     90     static const int32_t kSampleRateTable[] = {
     91         96000, 88200, 64000, 48000, 44100, 32000,
     92         24000, 22050, 16000, 12000, 11025, 8000
     93     };
     94     const size_t kNumSampleRates =
     95         sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
     96 
     97     *tableIndex = 0;
     98     for (size_t index = 0; index < kNumSampleRates; ++index) {
     99         if (sampleRate == kSampleRateTable[index]) {
    100             *tableIndex = index;
    101             return true;
    102         }
    103     }
    104 
    105     return false;
    106 }
    107 
    108 // static
    109 AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
    110         const sp<AMessage> &notify, const AString &desc, const AString &params)
    111     : mNotifyMsg(notify),
    112       mIsGeneric(false),
    113       mParams(params),
    114       mSizeLength(0),
    115       mIndexLength(0),
    116       mIndexDeltaLength(0),
    117       mCTSDeltaLength(0),
    118       mDTSDeltaLength(0),
    119       mRandomAccessIndication(false),
    120       mStreamStateIndication(0),
    121       mAuxiliaryDataSizeLength(0),
    122       mHasAUHeader(false),
    123       mChannelConfig(0),
    124       mSampleRateIndex(0),
    125       mAccessUnitRTPTime(0),
    126       mNextExpectedSeqNoValid(false),
    127       mNextExpectedSeqNo(0),
    128       mAccessUnitDamaged(false) {
    129     mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
    130 
    131     if (mIsGeneric) {
    132         AString value;
    133         CHECK(GetAttribute(params.c_str(), "mode", &value));
    134 
    135         if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
    136             mSizeLength = 0;
    137         }
    138 
    139         if (!GetIntegerAttribute(
    140                     params.c_str(), "indexLength", &mIndexLength)) {
    141             mIndexLength = 0;
    142         }
    143 
    144         if (!GetIntegerAttribute(
    145                     params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
    146             mIndexDeltaLength = 0;
    147         }
    148 
    149         if (!GetIntegerAttribute(
    150                     params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
    151             mCTSDeltaLength = 0;
    152         }
    153 
    154         if (!GetIntegerAttribute(
    155                     params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
    156             mDTSDeltaLength = 0;
    157         }
    158 
    159         unsigned x;
    160         if (!GetIntegerAttribute(
    161                     params.c_str(), "randomAccessIndication", &x)) {
    162             mRandomAccessIndication = false;
    163         } else {
    164             CHECK(x == 0 || x == 1);
    165             mRandomAccessIndication = (x != 0);
    166         }
    167 
    168         if (!GetIntegerAttribute(
    169                     params.c_str(), "streamStateIndication",
    170                     &mStreamStateIndication)) {
    171             mStreamStateIndication = 0;
    172         }
    173 
    174         if (!GetIntegerAttribute(
    175                     params.c_str(), "auxiliaryDataSizeLength",
    176                     &mAuxiliaryDataSizeLength)) {
    177             mAuxiliaryDataSizeLength = 0;
    178         }
    179 
    180         mHasAUHeader =
    181             mSizeLength > 0
    182             || mIndexLength > 0
    183             || mIndexDeltaLength > 0
    184             || mCTSDeltaLength > 0
    185             || mDTSDeltaLength > 0
    186             || mRandomAccessIndication
    187             || mStreamStateIndication > 0;
    188 
    189         int32_t sampleRate, numChannels;
    190         ASessionDescription::ParseFormatDesc(
    191                 desc.c_str(), &sampleRate, &numChannels);
    192 
    193         mChannelConfig = numChannels;
    194         CHECK(GetSampleRateIndex(sampleRate, &mSampleRateIndex));
    195     }
    196 }
    197 
    198 AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
    199 }
    200 
    201 struct AUHeader {
    202     unsigned mSize;
    203     unsigned mSerial;
    204 };
    205 
    206 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
    207         const sp<ARTPSource> &source) {
    208     List<sp<ABuffer> > *queue = source->queue();
    209 
    210     if (queue->empty()) {
    211         return NOT_ENOUGH_DATA;
    212     }
    213 
    214     if (mNextExpectedSeqNoValid) {
    215         List<sp<ABuffer> >::iterator it = queue->begin();
    216         while (it != queue->end()) {
    217             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
    218                 break;
    219             }
    220 
    221             it = queue->erase(it);
    222         }
    223 
    224         if (queue->empty()) {
    225             return NOT_ENOUGH_DATA;
    226         }
    227     }
    228 
    229     sp<ABuffer> buffer = *queue->begin();
    230 
    231     if (!mNextExpectedSeqNoValid) {
    232         mNextExpectedSeqNoValid = true;
    233         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
    234     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
    235         ALOGV("Not the sequence number I expected");
    236 
    237         return WRONG_SEQUENCE_NUMBER;
    238     }
    239 
    240     uint32_t rtpTime;
    241     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
    242 
    243     if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
    244         submitAccessUnit();
    245     }
    246     mAccessUnitRTPTime = rtpTime;
    247 
    248     if (!mIsGeneric) {
    249         mPackets.push_back(buffer);
    250     } else {
    251         // hexdump(buffer->data(), buffer->size());
    252         if (buffer->size() < 2) {
    253             return MALFORMED_PACKET;
    254         }
    255 
    256         unsigned AU_headers_length = U16_AT(buffer->data());  // in bits
    257 
    258         if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
    259             return MALFORMED_PACKET;
    260         }
    261 
    262         List<AUHeader> headers;
    263 
    264         ABitReader bits(buffer->data() + 2, buffer->size() - 2);
    265         unsigned numBitsLeft = AU_headers_length;
    266 
    267         unsigned AU_serial = 0;
    268         for (;;) {
    269             if (numBitsLeft < mSizeLength) { break; }
    270 
    271             unsigned AU_size = bits.getBits(mSizeLength);
    272             numBitsLeft -= mSizeLength;
    273 
    274             size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
    275             if (numBitsLeft < n) { break; }
    276 
    277             unsigned AU_index = bits.getBits(n);
    278             numBitsLeft -= n;
    279 
    280             if (headers.empty()) {
    281                 AU_serial = AU_index;
    282             } else {
    283                 AU_serial += 1 + AU_index;
    284             }
    285 
    286             if (mCTSDeltaLength > 0) {
    287                 if (numBitsLeft < 1) {
    288                     break;
    289                 }
    290                 --numBitsLeft;
    291                 if (bits.getBits(1)) {
    292                     if (numBitsLeft < mCTSDeltaLength) {
    293                         break;
    294                     }
    295                     bits.skipBits(mCTSDeltaLength);
    296                     numBitsLeft -= mCTSDeltaLength;
    297                 }
    298             }
    299 
    300             if (mDTSDeltaLength > 0) {
    301                 if (numBitsLeft < 1) {
    302                     break;
    303                 }
    304                 --numBitsLeft;
    305                 if (bits.getBits(1)) {
    306                     if (numBitsLeft < mDTSDeltaLength) {
    307                         break;
    308                     }
    309                     bits.skipBits(mDTSDeltaLength);
    310                     numBitsLeft -= mDTSDeltaLength;
    311                 }
    312             }
    313 
    314             if (mRandomAccessIndication) {
    315                 if (numBitsLeft < 1) {
    316                     break;
    317                 }
    318                 bits.skipBits(1);
    319                 --numBitsLeft;
    320             }
    321 
    322             if (mStreamStateIndication > 0) {
    323                 if (numBitsLeft < mStreamStateIndication) {
    324                     break;
    325                 }
    326                 bits.skipBits(mStreamStateIndication);
    327             }
    328 
    329             AUHeader header;
    330             header.mSize = AU_size;
    331             header.mSerial = AU_serial;
    332             headers.push_back(header);
    333         }
    334 
    335         size_t offset = 2 + (AU_headers_length + 7) / 8;
    336 
    337         if (mAuxiliaryDataSizeLength > 0) {
    338             ABitReader bits(buffer->data() + offset, buffer->size() - offset);
    339 
    340             unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
    341 
    342             offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
    343         }
    344 
    345         for (List<AUHeader>::iterator it = headers.begin();
    346              it != headers.end(); ++it) {
    347             const AUHeader &header = *it;
    348 
    349             if (buffer->size() < offset + header.mSize) {
    350                 return MALFORMED_PACKET;
    351             }
    352 
    353             sp<ABuffer> accessUnit = new ABuffer(header.mSize);
    354             memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
    355 
    356             offset += header.mSize;
    357 
    358             CopyTimes(accessUnit, buffer);
    359             mPackets.push_back(accessUnit);
    360         }
    361 
    362         if (offset != buffer->size()) {
    363             ALOGW("potentially malformed packet (offset %d, size %d)",
    364                     offset, buffer->size());
    365         }
    366     }
    367 
    368     queue->erase(queue->begin());
    369     ++mNextExpectedSeqNo;
    370 
    371     return OK;
    372 }
    373 
    374 void AMPEG4ElementaryAssembler::submitAccessUnit() {
    375     CHECK(!mPackets.empty());
    376 
    377     ALOGV("Access unit complete (%zu nal units)", mPackets.size());
    378 
    379     sp<ABuffer> accessUnit;
    380 
    381     if (mIsGeneric) {
    382         accessUnit = MakeADTSCompoundFromAACFrames(
    383                 OMX_AUDIO_AACObjectLC - 1,
    384                 mSampleRateIndex,
    385                 mChannelConfig,
    386                 mPackets);
    387     } else {
    388         accessUnit = MakeCompoundFromPackets(mPackets);
    389     }
    390 
    391 #if 0
    392     printf(mAccessUnitDamaged ? "X" : ".");
    393     fflush(stdout);
    394 #endif
    395 
    396     if (mAccessUnitDamaged) {
    397         accessUnit->meta()->setInt32("damaged", true);
    398     }
    399 
    400     mPackets.clear();
    401     mAccessUnitDamaged = false;
    402 
    403     sp<AMessage> msg = mNotifyMsg->dup();
    404     msg->setBuffer("access-unit", accessUnit);
    405     msg->post();
    406 }
    407 
    408 ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::assembleMore(
    409         const sp<ARTPSource> &source) {
    410     AssemblyStatus status = addPacket(source);
    411     if (status == MALFORMED_PACKET) {
    412         ALOGI("access unit is damaged");
    413         mAccessUnitDamaged = true;
    414     }
    415     return status;
    416 }
    417 
    418 void AMPEG4ElementaryAssembler::packetLost() {
    419     CHECK(mNextExpectedSeqNoValid);
    420     ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
    421 
    422     ++mNextExpectedSeqNo;
    423 
    424     mAccessUnitDamaged = true;
    425 }
    426 
    427 void AMPEG4ElementaryAssembler::onByeReceived() {
    428     sp<AMessage> msg = mNotifyMsg->dup();
    429     msg->setInt32("eos", true);
    430     msg->post();
    431 }
    432 
    433 }  // namespace android
    434