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 "ARTPSource"
     19 #include <utils/Log.h>
     20 
     21 #include "ARTPSource.h"
     22 
     23 #include "AAMRAssembler.h"
     24 #include "AAVCAssembler.h"
     25 #include "AH263Assembler.h"
     26 #include "AMPEG2TSAssembler.h"
     27 #include "AMPEG4AudioAssembler.h"
     28 #include "AMPEG4ElementaryAssembler.h"
     29 #include "ARawAudioAssembler.h"
     30 #include "ASessionDescription.h"
     31 
     32 #include <media/stagefright/foundation/ABuffer.h>
     33 #include <media/stagefright/foundation/ADebug.h>
     34 #include <media/stagefright/foundation/AMessage.h>
     35 
     36 namespace android {
     37 
     38 static const uint32_t kSourceID = 0xdeadbeef;
     39 
     40 ARTPSource::ARTPSource(
     41         uint32_t id,
     42         const sp<ASessionDescription> &sessionDesc, size_t index,
     43         const sp<AMessage> &notify)
     44     : mID(id),
     45       mHighestSeqNumber(0),
     46       mPrevExpected(0),
     47       mBaseSeqNumber(0),
     48       mNumBuffersReceived(0),
     49       mPrevNumBuffersReceived(0),
     50       mLastNTPTime(0),
     51       mLastNTPTimeUpdateUs(0),
     52       mIssueFIRRequests(false),
     53       mLastFIRRequestUs(-1),
     54       mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
     55       mNotify(notify) {
     56     unsigned long PT;
     57     AString desc;
     58     AString params;
     59     sessionDesc->getFormatType(index, &PT, &desc, &params);
     60 
     61     if (!strncmp(desc.c_str(), "H264/", 5)) {
     62         mAssembler = new AAVCAssembler(notify);
     63         mIssueFIRRequests = true;
     64     } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
     65         mAssembler = new AMPEG4AudioAssembler(notify, params);
     66     } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
     67             || !strncmp(desc.c_str(), "H263-2000/", 10)) {
     68         mAssembler = new AH263Assembler(notify);
     69         mIssueFIRRequests = true;
     70     } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
     71         mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
     72     } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
     73         mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
     74     } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
     75             || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
     76         mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
     77         mIssueFIRRequests = true;
     78     } else if (ARawAudioAssembler::Supports(desc.c_str())) {
     79         mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
     80     } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) {
     81         mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params);
     82     } else {
     83         TRESPASS();
     84     }
     85 }
     86 
     87 static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
     88     return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
     89 }
     90 
     91 void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
     92     if (queuePacket(buffer) && mAssembler != NULL) {
     93         mAssembler->onPacketReceived(this);
     94     }
     95 }
     96 
     97 void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
     98     mLastNTPTime = ntpTime;
     99     mLastNTPTimeUpdateUs = ALooper::GetNowUs();
    100 
    101     sp<AMessage> notify = mNotify->dup();
    102     notify->setInt32("time-update", true);
    103     notify->setInt32("rtp-time", rtpTime);
    104     notify->setInt64("ntp-time", ntpTime);
    105     notify->post();
    106 }
    107 
    108 bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
    109     uint32_t seqNum = (uint32_t)buffer->int32Data();
    110 
    111     if (mNumBuffersReceived++ == 0) {
    112         mHighestSeqNumber = seqNum;
    113         mBaseSeqNumber = seqNum;
    114         mQueue.push_back(buffer);
    115         return true;
    116     }
    117 
    118     // Only the lower 16-bit of the sequence numbers are transmitted,
    119     // derive the high-order bits by choosing the candidate closest
    120     // to the highest sequence number (extended to 32 bits) received so far.
    121 
    122     uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
    123 
    124     // non-overflowing version of:
    125     // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
    126     uint32_t seq2 = seqNum | (((mHighestSeqNumber >> 16) + 1) << 16);
    127 
    128     // non-underflowing version of:
    129     // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
    130     uint32_t seq3 = seqNum | ((((mHighestSeqNumber >> 16) | 0x10000) - 1) << 16);
    131 
    132     uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
    133     uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
    134     uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
    135 
    136     if (diff1 < diff2) {
    137         if (diff1 < diff3) {
    138             // diff1 < diff2 ^ diff1 < diff3
    139             seqNum = seq1;
    140         } else {
    141             // diff3 <= diff1 < diff2
    142             seqNum = seq3;
    143         }
    144     } else if (diff2 < diff3) {
    145         // diff2 <= diff1 ^ diff2 < diff3
    146         seqNum = seq2;
    147     } else {
    148         // diff3 <= diff2 <= diff1
    149         seqNum = seq3;
    150     }
    151 
    152     if (seqNum > mHighestSeqNumber) {
    153         mHighestSeqNumber = seqNum;
    154     }
    155 
    156     buffer->setInt32Data(seqNum);
    157 
    158     List<sp<ABuffer> >::iterator it = mQueue.begin();
    159     while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
    160         ++it;
    161     }
    162 
    163     if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
    164         ALOGW("Discarding duplicate buffer");
    165         return false;
    166     }
    167 
    168     mQueue.insert(it, buffer);
    169 
    170     return true;
    171 }
    172 
    173 void ARTPSource::byeReceived() {
    174     mAssembler->onByeReceived();
    175 }
    176 
    177 void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
    178     if (!mIssueFIRRequests) {
    179         return;
    180     }
    181 
    182     int64_t nowUs = ALooper::GetNowUs();
    183     if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
    184         // Send FIR requests at most every 5 secs.
    185         return;
    186     }
    187 
    188     mLastFIRRequestUs = nowUs;
    189 
    190     if (buffer->size() + 20 > buffer->capacity()) {
    191         ALOGW("RTCP buffer too small to accomodate FIR.");
    192         return;
    193     }
    194 
    195     uint8_t *data = buffer->data() + buffer->size();
    196 
    197     data[0] = 0x80 | 4;
    198     data[1] = 206;  // PSFB
    199     data[2] = 0;
    200     data[3] = 4;
    201     data[4] = kSourceID >> 24;
    202     data[5] = (kSourceID >> 16) & 0xff;
    203     data[6] = (kSourceID >> 8) & 0xff;
    204     data[7] = kSourceID & 0xff;
    205 
    206     data[8] = 0x00;  // SSRC of media source (unused)
    207     data[9] = 0x00;
    208     data[10] = 0x00;
    209     data[11] = 0x00;
    210 
    211     data[12] = mID >> 24;
    212     data[13] = (mID >> 16) & 0xff;
    213     data[14] = (mID >> 8) & 0xff;
    214     data[15] = mID & 0xff;
    215 
    216     data[16] = mNextFIRSeqNo++;  // Seq Nr.
    217 
    218     data[17] = 0x00;  // Reserved
    219     data[18] = 0x00;
    220     data[19] = 0x00;
    221 
    222     buffer->setRange(buffer->offset(), buffer->size() + 20);
    223 
    224     ALOGV("Added FIR request.");
    225 }
    226 
    227 void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
    228     if (buffer->size() + 32 > buffer->capacity()) {
    229         ALOGW("RTCP buffer too small to accomodate RR.");
    230         return;
    231     }
    232 
    233     uint8_t fraction = 0;
    234 
    235     // According to appendix A.3 in RFC 3550
    236     uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
    237     int64_t intervalExpected = expected - mPrevExpected;
    238     int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived;
    239     int64_t intervalPacketLost = intervalExpected - intervalReceived;
    240 
    241     if (intervalExpected > 0 && intervalPacketLost > 0) {
    242         fraction = (intervalPacketLost << 8) / intervalExpected;
    243     }
    244 
    245     mPrevExpected = expected;
    246     mPrevNumBuffersReceived = mNumBuffersReceived;
    247     int32_t cumulativePacketLost = (int32_t)expected - mNumBuffersReceived;
    248 
    249     uint8_t *data = buffer->data() + buffer->size();
    250 
    251     data[0] = 0x80 | 1;
    252     data[1] = 201;  // RR
    253     data[2] = 0;
    254     data[3] = 7;
    255     data[4] = kSourceID >> 24;
    256     data[5] = (kSourceID >> 16) & 0xff;
    257     data[6] = (kSourceID >> 8) & 0xff;
    258     data[7] = kSourceID & 0xff;
    259 
    260     data[8] = mID >> 24;
    261     data[9] = (mID >> 16) & 0xff;
    262     data[10] = (mID >> 8) & 0xff;
    263     data[11] = mID & 0xff;
    264 
    265     data[12] = fraction;  // fraction lost
    266 
    267     data[13] = cumulativePacketLost >> 16;  // cumulative lost
    268     data[14] = (cumulativePacketLost >> 8) & 0xff;
    269     data[15] = cumulativePacketLost & 0xff;
    270 
    271     data[16] = mHighestSeqNumber >> 24;
    272     data[17] = (mHighestSeqNumber >> 16) & 0xff;
    273     data[18] = (mHighestSeqNumber >> 8) & 0xff;
    274     data[19] = mHighestSeqNumber & 0xff;
    275 
    276     data[20] = 0x00;  // Interarrival jitter
    277     data[21] = 0x00;
    278     data[22] = 0x00;
    279     data[23] = 0x00;
    280 
    281     uint32_t LSR = 0;
    282     uint32_t DLSR = 0;
    283     if (mLastNTPTime != 0) {
    284         LSR = (mLastNTPTime >> 16) & 0xffffffff;
    285 
    286         DLSR = (uint32_t)
    287             ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
    288     }
    289 
    290     data[24] = LSR >> 24;
    291     data[25] = (LSR >> 16) & 0xff;
    292     data[26] = (LSR >> 8) & 0xff;
    293     data[27] = LSR & 0xff;
    294 
    295     data[28] = DLSR >> 24;
    296     data[29] = (DLSR >> 16) & 0xff;
    297     data[30] = (DLSR >> 8) & 0xff;
    298     data[31] = DLSR & 0xff;
    299 
    300     buffer->setRange(buffer->offset(), buffer->size() + 32);
    301 }
    302 
    303 }  // namespace android
    304 
    305 
    306