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 "AAVCAssembler"
     19 #include <utils/Log.h>
     20 
     21 #include "AAVCAssembler.h"
     22 
     23 #include "ARTPSource.h"
     24 
     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/foundation/hexdump.h>
     29 
     30 #include <stdint.h>
     31 
     32 namespace android {
     33 
     34 // static
     35 AAVCAssembler::AAVCAssembler(const sp<AMessage> &notify)
     36     : mNotifyMsg(notify),
     37       mAccessUnitRTPTime(0),
     38       mNextExpectedSeqNoValid(false),
     39       mNextExpectedSeqNo(0),
     40       mAccessUnitDamaged(false) {
     41 }
     42 
     43 AAVCAssembler::~AAVCAssembler() {
     44 }
     45 
     46 ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
     47         const sp<ARTPSource> &source) {
     48     List<sp<ABuffer> > *queue = source->queue();
     49 
     50     if (queue->empty()) {
     51         return NOT_ENOUGH_DATA;
     52     }
     53 
     54     if (mNextExpectedSeqNoValid) {
     55         List<sp<ABuffer> >::iterator it = queue->begin();
     56         while (it != queue->end()) {
     57             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
     58                 break;
     59             }
     60 
     61             it = queue->erase(it);
     62         }
     63 
     64         if (queue->empty()) {
     65             return NOT_ENOUGH_DATA;
     66         }
     67     }
     68 
     69     sp<ABuffer> buffer = *queue->begin();
     70 
     71     if (!mNextExpectedSeqNoValid) {
     72         mNextExpectedSeqNoValid = true;
     73         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
     74     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
     75         ALOGV("Not the sequence number I expected");
     76 
     77         return WRONG_SEQUENCE_NUMBER;
     78     }
     79 
     80     const uint8_t *data = buffer->data();
     81     size_t size = buffer->size();
     82 
     83     if (size < 1 || (data[0] & 0x80)) {
     84         // Corrupt.
     85 
     86         ALOGV("Ignoring corrupt buffer.");
     87         queue->erase(queue->begin());
     88 
     89         ++mNextExpectedSeqNo;
     90         return MALFORMED_PACKET;
     91     }
     92 
     93     unsigned nalType = data[0] & 0x1f;
     94     if (nalType >= 1 && nalType <= 23) {
     95         addSingleNALUnit(buffer);
     96         queue->erase(queue->begin());
     97         ++mNextExpectedSeqNo;
     98         return OK;
     99     } else if (nalType == 28) {
    100         // FU-A
    101         return addFragmentedNALUnit(queue);
    102     } else if (nalType == 24) {
    103         // STAP-A
    104         bool success = addSingleTimeAggregationPacket(buffer);
    105         queue->erase(queue->begin());
    106         ++mNextExpectedSeqNo;
    107 
    108         return success ? OK : MALFORMED_PACKET;
    109     } else {
    110         ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
    111 
    112         queue->erase(queue->begin());
    113         ++mNextExpectedSeqNo;
    114 
    115         return MALFORMED_PACKET;
    116     }
    117 }
    118 
    119 void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
    120     ALOGV("addSingleNALUnit of size %d", buffer->size());
    121 #if !LOG_NDEBUG
    122     hexdump(buffer->data(), buffer->size());
    123 #endif
    124 
    125     uint32_t rtpTime;
    126     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
    127 
    128     if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
    129         submitAccessUnit();
    130     }
    131     mAccessUnitRTPTime = rtpTime;
    132 
    133     mNALUnits.push_back(buffer);
    134 }
    135 
    136 bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) {
    137     const uint8_t *data = buffer->data();
    138     size_t size = buffer->size();
    139 
    140     if (size < 3) {
    141         ALOGV("Discarding too small STAP-A packet.");
    142         return false;
    143     }
    144 
    145     ++data;
    146     --size;
    147     while (size >= 2) {
    148         size_t nalSize = (data[0] << 8) | data[1];
    149 
    150         if (size < nalSize + 2) {
    151             ALOGV("Discarding malformed STAP-A packet.");
    152             return false;
    153         }
    154 
    155         sp<ABuffer> unit = new ABuffer(nalSize);
    156         memcpy(unit->data(), &data[2], nalSize);
    157 
    158         CopyTimes(unit, buffer);
    159 
    160         addSingleNALUnit(unit);
    161 
    162         data += 2 + nalSize;
    163         size -= 2 + nalSize;
    164     }
    165 
    166     if (size != 0) {
    167         ALOGV("Unexpected padding at end of STAP-A packet.");
    168     }
    169 
    170     return true;
    171 }
    172 
    173 ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
    174         List<sp<ABuffer> > *queue) {
    175     CHECK(!queue->empty());
    176 
    177     sp<ABuffer> buffer = *queue->begin();
    178     const uint8_t *data = buffer->data();
    179     size_t size = buffer->size();
    180 
    181     CHECK(size > 0);
    182     unsigned indicator = data[0];
    183 
    184     CHECK((indicator & 0x1f) == 28);
    185 
    186     if (size < 2) {
    187         ALOGV("Ignoring malformed FU buffer (size = %d)", size);
    188 
    189         queue->erase(queue->begin());
    190         ++mNextExpectedSeqNo;
    191         return MALFORMED_PACKET;
    192     }
    193 
    194     if (!(data[1] & 0x80)) {
    195         // Start bit not set on the first buffer.
    196 
    197         ALOGV("Start bit not set on first buffer");
    198 
    199         queue->erase(queue->begin());
    200         ++mNextExpectedSeqNo;
    201         return MALFORMED_PACKET;
    202     }
    203 
    204     uint32_t nalType = data[1] & 0x1f;
    205     uint32_t nri = (data[0] >> 5) & 3;
    206 
    207     uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1;
    208     size_t totalSize = size - 2;
    209     size_t totalCount = 1;
    210     bool complete = false;
    211 
    212     if (data[1] & 0x40) {
    213         // Huh? End bit also set on the first buffer.
    214 
    215         ALOGV("Grrr. This isn't fragmented at all.");
    216 
    217         complete = true;
    218     } else {
    219         List<sp<ABuffer> >::iterator it = ++queue->begin();
    220         while (it != queue->end()) {
    221             ALOGV("sequence length %d", totalCount);
    222 
    223             const sp<ABuffer> &buffer = *it;
    224 
    225             const uint8_t *data = buffer->data();
    226             size_t size = buffer->size();
    227 
    228             if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
    229                 ALOGV("sequence not complete, expected seqNo %d, got %d",
    230                      expectedSeqNo, (uint32_t)buffer->int32Data());
    231 
    232                 return WRONG_SEQUENCE_NUMBER;
    233             }
    234 
    235             if (size < 2
    236                     || data[0] != indicator
    237                     || (data[1] & 0x1f) != nalType
    238                     || (data[1] & 0x80)) {
    239                 ALOGV("Ignoring malformed FU buffer.");
    240 
    241                 // Delete the whole start of the FU.
    242 
    243                 it = queue->begin();
    244                 for (size_t i = 0; i <= totalCount; ++i) {
    245                     it = queue->erase(it);
    246                 }
    247 
    248                 mNextExpectedSeqNo = expectedSeqNo + 1;
    249 
    250                 return MALFORMED_PACKET;
    251             }
    252 
    253             totalSize += size - 2;
    254             ++totalCount;
    255 
    256             expectedSeqNo = expectedSeqNo + 1;
    257 
    258             if (data[1] & 0x40) {
    259                 // This is the last fragment.
    260                 complete = true;
    261                 break;
    262             }
    263 
    264             ++it;
    265         }
    266     }
    267 
    268     if (!complete) {
    269         return NOT_ENOUGH_DATA;
    270     }
    271 
    272     mNextExpectedSeqNo = expectedSeqNo;
    273 
    274     // We found all the fragments that make up the complete NAL unit.
    275 
    276     // Leave room for the header. So far totalSize did not include the
    277     // header byte.
    278     ++totalSize;
    279 
    280     sp<ABuffer> unit = new ABuffer(totalSize);
    281     CopyTimes(unit, *queue->begin());
    282 
    283     unit->data()[0] = (nri << 5) | nalType;
    284 
    285     size_t offset = 1;
    286     List<sp<ABuffer> >::iterator it = queue->begin();
    287     for (size_t i = 0; i < totalCount; ++i) {
    288         const sp<ABuffer> &buffer = *it;
    289 
    290         ALOGV("piece #%d/%d", i + 1, totalCount);
    291 #if !LOG_NDEBUG
    292         hexdump(buffer->data(), buffer->size());
    293 #endif
    294 
    295         memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
    296         offset += buffer->size() - 2;
    297 
    298         it = queue->erase(it);
    299     }
    300 
    301     unit->setRange(0, totalSize);
    302 
    303     addSingleNALUnit(unit);
    304 
    305     ALOGV("successfully assembled a NAL unit from fragments.");
    306 
    307     return OK;
    308 }
    309 
    310 void AAVCAssembler::submitAccessUnit() {
    311     CHECK(!mNALUnits.empty());
    312 
    313     ALOGV("Access unit complete (%d nal units)", mNALUnits.size());
    314 
    315     size_t totalSize = 0;
    316     for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
    317          it != mNALUnits.end(); ++it) {
    318         totalSize += 4 + (*it)->size();
    319     }
    320 
    321     sp<ABuffer> accessUnit = new ABuffer(totalSize);
    322     size_t offset = 0;
    323     for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
    324          it != mNALUnits.end(); ++it) {
    325         memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
    326         offset += 4;
    327 
    328         sp<ABuffer> nal = *it;
    329         memcpy(accessUnit->data() + offset, nal->data(), nal->size());
    330         offset += nal->size();
    331     }
    332 
    333     CopyTimes(accessUnit, *mNALUnits.begin());
    334 
    335 #if 0
    336     printf(mAccessUnitDamaged ? "X" : ".");
    337     fflush(stdout);
    338 #endif
    339 
    340     if (mAccessUnitDamaged) {
    341         accessUnit->meta()->setInt32("damaged", true);
    342     }
    343 
    344     mNALUnits.clear();
    345     mAccessUnitDamaged = false;
    346 
    347     sp<AMessage> msg = mNotifyMsg->dup();
    348     msg->setBuffer("access-unit", accessUnit);
    349     msg->post();
    350 }
    351 
    352 ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
    353         const sp<ARTPSource> &source) {
    354     AssemblyStatus status = addNALUnit(source);
    355     if (status == MALFORMED_PACKET) {
    356         mAccessUnitDamaged = true;
    357     }
    358     return status;
    359 }
    360 
    361 void AAVCAssembler::packetLost() {
    362     CHECK(mNextExpectedSeqNoValid);
    363     ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
    364 
    365     ++mNextExpectedSeqNo;
    366 
    367     mAccessUnitDamaged = true;
    368 }
    369 
    370 void AAVCAssembler::onByeReceived() {
    371     sp<AMessage> msg = mNotifyMsg->dup();
    372     msg->setInt32("eos", true);
    373     msg->post();
    374 }
    375 
    376 }  // namespace android
    377