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 //#define LOG_NDEBUG 0
     17 #define LOG_TAG "AH263Assembler"
     18 #include <utils/Log.h>
     19 
     20 #include "AH263Assembler.h"
     21 
     22 #include "ARTPSource.h"
     23 
     24 #include <media/stagefright/foundation/ABuffer.h>
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/foundation/AMessage.h>
     27 #include <media/stagefright/foundation/hexdump.h>
     28 #include <media/stagefright/foundation/ByteUtils.h>
     29 
     30 namespace android {
     31 
     32 AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
     33     : mNotifyMsg(notify),
     34       mAccessUnitRTPTime(0),
     35       mNextExpectedSeqNoValid(false),
     36       mNextExpectedSeqNo(0),
     37       mAccessUnitDamaged(false) {
     38 }
     39 
     40 AH263Assembler::~AH263Assembler() {
     41 }
     42 
     43 ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
     44         const sp<ARTPSource> &source) {
     45     AssemblyStatus status = addPacket(source);
     46     if (status == MALFORMED_PACKET) {
     47         mAccessUnitDamaged = true;
     48     }
     49     return status;
     50 }
     51 
     52 ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
     53         const sp<ARTPSource> &source) {
     54     List<sp<ABuffer> > *queue = source->queue();
     55 
     56     if (queue->empty()) {
     57         return NOT_ENOUGH_DATA;
     58     }
     59 
     60     if (mNextExpectedSeqNoValid) {
     61         List<sp<ABuffer> >::iterator it = queue->begin();
     62         while (it != queue->end()) {
     63             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
     64                 break;
     65             }
     66 
     67             it = queue->erase(it);
     68         }
     69 
     70         if (queue->empty()) {
     71             return NOT_ENOUGH_DATA;
     72         }
     73     }
     74 
     75     sp<ABuffer> buffer = *queue->begin();
     76 
     77     if (!mNextExpectedSeqNoValid) {
     78         mNextExpectedSeqNoValid = true;
     79         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
     80     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
     81 #if VERBOSE
     82         LOG(VERBOSE) << "Not the sequence number I expected";
     83 #endif
     84 
     85         return WRONG_SEQUENCE_NUMBER;
     86     }
     87 
     88     uint32_t rtpTime;
     89     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
     90 
     91     if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
     92         submitAccessUnit();
     93     }
     94     mAccessUnitRTPTime = rtpTime;
     95 
     96     // hexdump(buffer->data(), buffer->size());
     97 
     98     if (buffer->size() < 2) {
     99         queue->erase(queue->begin());
    100         ++mNextExpectedSeqNo;
    101 
    102         return MALFORMED_PACKET;
    103     }
    104 
    105     unsigned payloadHeader = U16_AT(buffer->data());
    106     unsigned P = (payloadHeader >> 10) & 1;
    107     unsigned V = (payloadHeader >> 9) & 1;
    108     unsigned PLEN = (payloadHeader >> 3) & 0x3f;
    109     unsigned PEBIT = payloadHeader & 7;
    110 
    111     // V=0
    112     if (V != 0u) {
    113         queue->erase(queue->begin());
    114         ++mNextExpectedSeqNo;
    115         ALOGW("Packet discarded due to VRC (V != 0)");
    116         return MALFORMED_PACKET;
    117     }
    118 
    119     // PLEN=0
    120     if (PLEN != 0u) {
    121         queue->erase(queue->begin());
    122         ++mNextExpectedSeqNo;
    123         ALOGW("Packet discarded (PLEN != 0)");
    124         return MALFORMED_PACKET;
    125     }
    126 
    127     // PEBIT=0
    128     if (PEBIT != 0u) {
    129         queue->erase(queue->begin());
    130         ++mNextExpectedSeqNo;
    131         ALOGW("Packet discarded (PEBIT != 0)");
    132         return MALFORMED_PACKET;
    133     }
    134 
    135     size_t skip = V + PLEN + (P ? 0 : 2);
    136 
    137     buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
    138 
    139     if (P) {
    140         buffer->data()[0] = 0x00;
    141         buffer->data()[1] = 0x00;
    142     }
    143 
    144     mPackets.push_back(buffer);
    145 
    146     queue->erase(queue->begin());
    147     ++mNextExpectedSeqNo;
    148 
    149     return OK;
    150 }
    151 
    152 void AH263Assembler::submitAccessUnit() {
    153     CHECK(!mPackets.empty());
    154 
    155 #if VERBOSE
    156     LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
    157 #endif
    158 
    159     size_t totalSize = 0;
    160     List<sp<ABuffer> >::iterator it = mPackets.begin();
    161     while (it != mPackets.end()) {
    162         const sp<ABuffer> &unit = *it;
    163 
    164         totalSize += unit->size();
    165         ++it;
    166     }
    167 
    168     sp<ABuffer> accessUnit = new ABuffer(totalSize);
    169     size_t offset = 0;
    170     it = mPackets.begin();
    171     while (it != mPackets.end()) {
    172         const sp<ABuffer> &unit = *it;
    173 
    174         memcpy((uint8_t *)accessUnit->data() + offset,
    175                unit->data(), unit->size());
    176 
    177         offset += unit->size();
    178 
    179         ++it;
    180     }
    181 
    182     CopyTimes(accessUnit, *mPackets.begin());
    183 
    184 #if 0
    185     printf(mAccessUnitDamaged ? "X" : ".");
    186     fflush(stdout);
    187 #endif
    188 
    189     if (mAccessUnitDamaged) {
    190         accessUnit->meta()->setInt32("damaged", true);
    191     }
    192 
    193     mPackets.clear();
    194     mAccessUnitDamaged = false;
    195 
    196     sp<AMessage> msg = mNotifyMsg->dup();
    197     msg->setBuffer("access-unit", accessUnit);
    198     msg->post();
    199 }
    200 
    201 void AH263Assembler::packetLost() {
    202     CHECK(mNextExpectedSeqNoValid);
    203     ++mNextExpectedSeqNo;
    204 
    205     mAccessUnitDamaged = true;
    206 }
    207 
    208 void AH263Assembler::onByeReceived() {
    209     sp<AMessage> msg = mNotifyMsg->dup();
    210     msg->setInt32("eos", true);
    211     msg->post();
    212 }
    213 
    214 }  // namespace android
    215 
    216