ARTPSource.cpp revision 57648e4eec7dd2593af467877bc7cce4aa654759
17a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber/*
27a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * Copyright (C) 2010 The Android Open Source Project
37a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber *
47a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
57a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * you may not use this file except in compliance with the License.
67a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * You may obtain a copy of the License at
77a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber *
87a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
97a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber *
107a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * Unless required by applicable law or agreed to in writing, software
117a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
127a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * See the License for the specific language governing permissions and
147a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber * limitations under the License.
157a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber */
167a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
177a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "ARTPSource.h"
187a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "AAMRAssembler.h"
207a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "AAVCAssembler.h"
2157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "AH263Assembler.h"
227a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "AMPEG4AudioAssembler.h"
237a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "ASessionDescription.h"
247a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
257a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
267a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/ADebug.h>
277a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/AMessage.h>
287a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#define BE_VERBOSE      0
307a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
317a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubernamespace android {
327a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
3357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic const uint32_t kSourceID = 0xdeadbeef;
3457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
357a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas HuberARTPSource::ARTPSource(
367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        uint32_t id,
377a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index,
387a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        const sp<AMessage> &notify)
397a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    : mID(id),
407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber      mHighestSeqNumber(0),
417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber      mNumBuffersReceived(0),
4257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mNumTimes(0),
4357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastNTPTime(0),
4457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastNTPTimeUpdateUs(0),
4557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mIssueFIRRequests(false),
4657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastFIRRequestUs(-1),
4757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mNextFIRSeqNo((rand() * 256.0) / RAND_MAX) {
487a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    unsigned long PT;
497a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    AString desc;
507a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    AString params;
517a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
537a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
547a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mAssembler = new AAVCAssembler(notify);
5557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mIssueFIRRequests = true;
5657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
577a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mAssembler = new AMPEG4AudioAssembler(notify);
5857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
5957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            || !strncmp(desc.c_str(), "H263-2000/", 10)) {
6057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AH263Assembler(notify);
6157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
6257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
6357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
6457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
657a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else {
667a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        TRESPASS();
677a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
687a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
697a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
707a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huberstatic uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
717a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
727a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
737a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
747a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubervoid ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
7557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (queuePacket(buffer)
7657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            && mNumTimes == 2
7757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            && mAssembler != NULL) {
787a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mAssembler->onPacketReceived(this);
797a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
807a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
817a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    dump();
827a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
837a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
847a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubervoid ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
8557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if BE_VERBOSE
867a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    LOG(VERBOSE) << "timeUpdate";
877a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#endif
887a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
8957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastNTPTime = ntpTime;
9057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastNTPTimeUpdateUs = ALooper::GetNowUs();
9157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
927a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mNumTimes == 2) {
937a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mNTPTime[0] = mNTPTime[1];
947a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mRTPTime[0] = mRTPTime[1];
957a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mNumTimes = 1;
967a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
977a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    mNTPTime[mNumTimes] = ntpTime;
987a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    mRTPTime[mNumTimes++] = rtpTime;
997a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1007a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mNumTimes == 2) {
1017a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        for (List<sp<ABuffer> >::iterator it = mQueue.begin();
1027a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber             it != mQueue.end(); ++it) {
1037a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            sp<AMessage> meta = (*it)->meta();
1047a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1057a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            uint32_t rtpTime;
1067a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
1077a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1087a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            meta->setInt64("ntp-time", RTP2NTP(rtpTime));
1097a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
1107a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1117a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
1127a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1137a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huberbool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
11457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 1
11557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (mNumTimes != 2) {
11657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        // Drop incoming packets until we've established a time base.
11757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return false;
11857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
11957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif
12057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
1217a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seqNum = (uint32_t)buffer->int32Data();
1227a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1237a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mNumTimes == 2) {
1247a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        sp<AMessage> meta = buffer->meta();
1257a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1267a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        uint32_t rtpTime;
1277a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
1287a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1297a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        meta->setInt64("ntp-time", RTP2NTP(rtpTime));
1307a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1317a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1327a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mNumBuffersReceived++ == 0) {
1337a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mHighestSeqNumber = seqNum;
1347a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mQueue.push_back(buffer);
1357a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        return true;
1367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1377a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1387a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // Only the lower 16-bit of the sequence numbers are transmitted,
1397a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // derive the high-order bits by choosing the candidate closest
1407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // to the highest sequence number (extended to 32 bits) received so far.
1417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1427a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
1437a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
1447a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
1457a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
1467a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
1477a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
1487a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1497a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (diff1 < diff2) {
1507a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (diff1 < diff3) {
1517a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            // diff1 < diff2 ^ diff1 < diff3
1527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            seqNum = seq1;
1537a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        } else {
1547a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            // diff3 <= diff1 < diff2
1557a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            seqNum = seq3;
1567a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
1577a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else if (diff2 < diff3) {
1587a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        // diff2 <= diff1 ^ diff2 < diff3
1597a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        seqNum = seq2;
1607a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else {
1617a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        // diff3 <= diff2 <= diff1
1627a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        seqNum = seq3;
1637a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1647a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1657a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (seqNum > mHighestSeqNumber) {
1667a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mHighestSeqNumber = seqNum;
1677a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1687a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1697a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    buffer->setInt32Data(seqNum);
1707a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1717a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    List<sp<ABuffer> >::iterator it = mQueue.begin();
1727a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
1737a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        ++it;
1747a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1757a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1767a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
1777a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        LOG(WARNING) << "Discarding duplicate buffer";
1787a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        return false;
1797a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1807a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1817a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    mQueue.insert(it, buffer);
1827a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1837a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    return true;
1847a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
1857a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1867a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubervoid ARTPSource::dump() const {
1877a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if ((mNumBuffersReceived % 128) != 0) {
1887a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        return;
1897a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1907a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1917a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#if 0
1927a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mAssembler == NULL) {
1937a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        char tmp[20];
1947a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        sprintf(tmp, "0x%08x", mID);
1957a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1967a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        int32_t numMissing = 0;
1977a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1987a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (!mQueue.empty()) {
1997a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            List<sp<ABuffer> >::const_iterator it = mQueue.begin();
2007a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data();
2017a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            ++expectedSeqNum;
2027a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            ++it;
2037a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2047a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            for (; it != mQueue.end(); ++it) {
2057a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                uint32_t seqNum = (uint32_t)(*it)->int32Data();
2067a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                CHECK_GE(seqNum, expectedSeqNum);
2077a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2087a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                if (seqNum != expectedSeqNum) {
2097a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                    numMissing += seqNum - expectedSeqNum;
2107a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                    expectedSeqNum = seqNum;
2117a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                }
2127a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2137a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                ++expectedSeqNum;
2147a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            }
2157a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
2167a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2177a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing
2187a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber             << " / " << (mNumBuffersReceived + numMissing) << " packets. ("
2197a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber             << (100.0 * numMissing / (mNumBuffersReceived + numMissing))
2207a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber             << " %%)";
2217a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
2227a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#endif
2237a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2247a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#if 0
2257a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    AString out;
22657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
2277a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    out.append(tmp);
2287a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    out.append(" [");
2297a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2307a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    List<sp<ABuffer> >::const_iterator it = mQueue.begin();
2317a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    while (it != mQueue.end()) {
2327a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        uint32_t start = (uint32_t)(*it)->int32Data();
2337a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2347a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        out.append(start);
2357a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        ++it;
2377a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        uint32_t expected = start + 1;
2387a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2397a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        while (it != mQueue.end()) {
2407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            uint32_t seqNum = (uint32_t)(*it)->int32Data();
2417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2427a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            if (seqNum != expected) {
2437a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                if (expected > start + 1) {
2447a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                    out.append("-");
2457a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                    out.append(expected - 1);
2467a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                }
2477a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                out.append(", ");
2487a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                break;
2497a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            }
2507a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2517a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            ++it;
2527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            ++expected;
2537a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
2547a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2557a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (it == mQueue.end()) {
2567a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            if (expected > start + 1) {
2577a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                out.append("-");
2587a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber                out.append(expected - 1);
2597a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            }
2607a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
2617a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
2627a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2637a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    out.append("]");
2647a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2657a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    LOG(VERBOSE) << out;
2667a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#endif
2677a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
2687a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2697a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huberuint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const {
2707a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    CHECK_EQ(mNumTimes, 2u);
2717a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2727a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0])
2737a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            * ((double)rtpTime - (double)mRTPTime[0])
2747a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            / (double)(mRTPTime[1] - mRTPTime[0]);
2757a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
2767a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
27757648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::byeReceived() {
27857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mAssembler->onByeReceived();
27957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
28057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
28157648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::addFIR(const sp<ABuffer> &buffer) {
28257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (!mIssueFIRRequests) {
28357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
28457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
28557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
28657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
28757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
28857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        // Send FIR requests at most every 5 secs.
28957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
29057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
29157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
29257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastFIRRequestUs = nowUs;
29357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
29457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (buffer->size() + 20 > buffer->capacity()) {
29557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        LOG(WARNING) << "RTCP buffer too small to accomodate FIR.";
29657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
29757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
29857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
29957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
30057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
30157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[0] = 0x80 | 4;
30257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[1] = 206;  // PSFB
30357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[2] = 0;
30457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[3] = 4;
30557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[4] = kSourceID >> 24;
30657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
30757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
30857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[7] = kSourceID & 0xff;
30957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
31057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[8] = 0x00;  // SSRC of media source (unused)
31157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[9] = 0x00;
31257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[10] = 0x00;
31357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[11] = 0x00;
31457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
31557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[12] = mID >> 24;
31657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[13] = (mID >> 16) & 0xff;
31757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[14] = (mID >> 8) & 0xff;
31857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[15] = mID & 0xff;
31957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
32057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[16] = mNextFIRSeqNo++;  // Seq Nr.
32157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
32257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[17] = 0x00;  // Reserved
32357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[18] = 0x00;
32457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[19] = 0x00;
32557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
32657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 20);
32757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
32857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    LOG(VERBOSE) << "Added FIR request.";
32957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
33057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
33157648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
33257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (buffer->size() + 32 > buffer->capacity()) {
33357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        LOG(WARNING) << "RTCP buffer too small to accomodate RR.";
33457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
33557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
33657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
33757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
33857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
33957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[0] = 0x80 | 1;
34057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[1] = 201;  // RR
34157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[2] = 0;
34257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[3] = 7;
34357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[4] = kSourceID >> 24;
34457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
34557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
34657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[7] = kSourceID & 0xff;
34757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
34857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[8] = mID >> 24;
34957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[9] = (mID >> 16) & 0xff;
35057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[10] = (mID >> 8) & 0xff;
35157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[11] = mID & 0xff;
35257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
35357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[12] = 0x00;  // fraction lost
35457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
35557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[13] = 0x00;  // cumulative lost
35657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[14] = 0x00;
35757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[15] = 0x00;
35857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
35957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[16] = mHighestSeqNumber >> 24;
36057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[17] = (mHighestSeqNumber >> 16) & 0xff;
36157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[18] = (mHighestSeqNumber >> 8) & 0xff;
36257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[19] = mHighestSeqNumber & 0xff;
36357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
36457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[20] = 0x00;  // Interarrival jitter
36557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[21] = 0x00;
36657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[22] = 0x00;
36757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[23] = 0x00;
36857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
36957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint32_t LSR = 0;
37057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint32_t DLSR = 0;
37157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (mLastNTPTime != 0) {
37257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        LSR = (mLastNTPTime >> 16) & 0xffffffff;
37357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
37457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        DLSR = (uint32_t)
37557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
37657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
37757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
37857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[24] = LSR >> 24;
37957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[25] = (LSR >> 16) & 0xff;
38057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[26] = (LSR >> 8) & 0xff;
38157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[27] = LSR & 0xff;
38257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
38357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[28] = DLSR >> 24;
38457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[29] = (DLSR >> 16) & 0xff;
38557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[30] = (DLSR >> 8) & 0xff;
38657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[31] = DLSR & 0xff;
38757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
38857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 32);
38957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
39057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
3917a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}  // namespace android
3927a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
3937a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
394