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 #include "AMPEG4AudioAssembler.h"
     18 
     19 #include "ARTPSource.h"
     20 
     21 #include <media/stagefright/foundation/ABuffer.h>
     22 #include <media/stagefright/foundation/ADebug.h>
     23 #include <media/stagefright/foundation/AMessage.h>
     24 
     25 namespace android {
     26 
     27 AMPEG4AudioAssembler::AMPEG4AudioAssembler(const sp<AMessage> &notify)
     28     : mNotifyMsg(notify),
     29       mAccessUnitRTPTime(0),
     30       mNextExpectedSeqNoValid(false),
     31       mNextExpectedSeqNo(0),
     32       mAccessUnitDamaged(false) {
     33 }
     34 
     35 AMPEG4AudioAssembler::~AMPEG4AudioAssembler() {
     36 }
     37 
     38 ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore(
     39         const sp<ARTPSource> &source) {
     40     AssemblyStatus status = addPacket(source);
     41     if (status == MALFORMED_PACKET) {
     42         mAccessUnitDamaged = true;
     43     }
     44     return status;
     45 }
     46 
     47 ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket(
     48         const sp<ARTPSource> &source) {
     49     List<sp<ABuffer> > *queue = source->queue();
     50 
     51     if (queue->empty()) {
     52         return NOT_ENOUGH_DATA;
     53     }
     54 
     55     if (mNextExpectedSeqNoValid) {
     56         List<sp<ABuffer> >::iterator it = queue->begin();
     57         while (it != queue->end()) {
     58             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
     59                 break;
     60             }
     61 
     62             it = queue->erase(it);
     63         }
     64 
     65         if (queue->empty()) {
     66             return NOT_ENOUGH_DATA;
     67         }
     68     }
     69 
     70     sp<ABuffer> buffer = *queue->begin();
     71 
     72     if (!mNextExpectedSeqNoValid) {
     73         mNextExpectedSeqNoValid = true;
     74         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
     75     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
     76 #if VERBOSE
     77         LOG(VERBOSE) << "Not the sequence number I expected";
     78 #endif
     79 
     80         return WRONG_SEQUENCE_NUMBER;
     81     }
     82 
     83     uint32_t rtpTime;
     84     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
     85 
     86     if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
     87         submitAccessUnit();
     88     }
     89     mAccessUnitRTPTime = rtpTime;
     90 
     91     mPackets.push_back(buffer);
     92 
     93     queue->erase(queue->begin());
     94     ++mNextExpectedSeqNo;
     95 
     96     return OK;
     97 }
     98 
     99 void AMPEG4AudioAssembler::submitAccessUnit() {
    100     CHECK(!mPackets.empty());
    101 
    102 #if VERBOSE
    103     LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
    104 #endif
    105 
    106     size_t totalSize = 0;
    107     List<sp<ABuffer> >::iterator it = mPackets.begin();
    108     while (it != mPackets.end()) {
    109         const sp<ABuffer> &unit = *it;
    110 
    111         size_t n = 0;
    112         while (unit->data()[n] == 0xff) {
    113             ++n;
    114         }
    115         ++n;
    116 
    117         totalSize += unit->size() - n;
    118         ++it;
    119     }
    120 
    121     sp<ABuffer> accessUnit = new ABuffer(totalSize);
    122     size_t offset = 0;
    123     it = mPackets.begin();
    124     while (it != mPackets.end()) {
    125         const sp<ABuffer> &unit = *it;
    126 
    127         size_t n = 0;
    128         while (unit->data()[n] == 0xff) {
    129             ++n;
    130         }
    131         ++n;
    132 
    133         memcpy((uint8_t *)accessUnit->data() + offset,
    134                unit->data() + n, unit->size() - n);
    135 
    136         offset += unit->size() - n;
    137 
    138         ++it;
    139     }
    140 
    141     CopyTimes(accessUnit, *mPackets.begin());
    142 
    143 #if 0
    144     printf(mAccessUnitDamaged ? "X" : ".");
    145     fflush(stdout);
    146 #endif
    147 
    148     if (mAccessUnitDamaged) {
    149         accessUnit->meta()->setInt32("damaged", true);
    150     }
    151 
    152     mPackets.clear();
    153     mAccessUnitDamaged = false;
    154 
    155     sp<AMessage> msg = mNotifyMsg->dup();
    156     msg->setObject("access-unit", accessUnit);
    157     msg->post();
    158 }
    159 
    160 void AMPEG4AudioAssembler::packetLost() {
    161     CHECK(mNextExpectedSeqNoValid);
    162     ++mNextExpectedSeqNo;
    163 
    164     mAccessUnitDamaged = true;
    165 }
    166 
    167 void AMPEG4AudioAssembler::onByeReceived() {
    168     sp<AMessage> msg = mNotifyMsg->dup();
    169     msg->setInt32("eos", true);
    170     msg->post();
    171 }
    172 
    173 }  // namespace android
    174