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
176e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber//#define LOG_NDEBUG 0
186e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber#define LOG_TAG "ARTPSource"
196e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber#include <utils/Log.h>
206e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber
217a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "ARTPSource.h"
227a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "AAMRAssembler.h"
247a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "AAVCAssembler.h"
2557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "AH263Assembler.h"
267a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "AMPEG4AudioAssembler.h"
27a979ad6739d573b3823b0fe7321f554ef5544753Andreas Huber#include "AMPEG4ElementaryAssembler.h"
28b6723735cf1fef04f8af0b4a5a8cb19a96c3c26dAndreas Huber#include "ARawAudioAssembler.h"
297a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "ASessionDescription.h"
307a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
317a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
327a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/ADebug.h>
337a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/AMessage.h>
347a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
357a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubernamespace android {
367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
3757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic const uint32_t kSourceID = 0xdeadbeef;
3857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
397a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas HuberARTPSource::ARTPSource(
407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        uint32_t id,
417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index,
427a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        const sp<AMessage> &notify)
437a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    : mID(id),
447a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber      mHighestSeqNumber(0),
457a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber      mNumBuffersReceived(0),
4657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastNTPTime(0),
4757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastNTPTimeUpdateUs(0),
4857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mIssueFIRRequests(false),
4957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber      mLastFIRRequestUs(-1),
50b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber      mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
51b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber      mNotify(notify) {
527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    unsigned long PT;
537a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    AString desc;
547a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    AString params;
557a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
567a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
577a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
587a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mAssembler = new AAVCAssembler(notify);
5957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mIssueFIRRequests = true;
6057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
61b0d25a00fe28d3153d4c56b24d8e2792230d68beAndreas Huber        mAssembler = new AMPEG4AudioAssembler(notify, params);
6257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
6357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            || !strncmp(desc.c_str(), "H263-2000/", 10)) {
6457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AH263Assembler(notify);
653eaa3006a8230bd607375bedd79b2e328b0fc6b7Andreas Huber        mIssueFIRRequests = true;
6657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
6757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
6857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
6957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
70e536f800c695bcd2ef861b9b9877b2108ed21613Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
710407269ae35e62a6aa2f6e40964970db1bd4b14aAndreas Huber            || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
72e536f800c695bcd2ef861b9b9877b2108ed21613Andreas Huber        mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
73a979ad6739d573b3823b0fe7321f554ef5544753Andreas Huber        mIssueFIRRequests = true;
74b6723735cf1fef04f8af0b4a5a8cb19a96c3c26dAndreas Huber    } else if (ARawAudioAssembler::Supports(desc.c_str())) {
75b6723735cf1fef04f8af0b4a5a8cb19a96c3c26dAndreas Huber        mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
767a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else {
777a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        TRESPASS();
787a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
797a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
807a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
817a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huberstatic uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
827a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
837a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
847a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
857a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubervoid ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
86b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    if (queuePacket(buffer) && mAssembler != NULL) {
877a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mAssembler->onPacketReceived(this);
887a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
897a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
907a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
917a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Hubervoid ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
9257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastNTPTime = ntpTime;
9357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastNTPTimeUpdateUs = ALooper::GetNowUs();
9457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
95b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    sp<AMessage> notify = mNotify->dup();
96b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    notify->setInt32("time-update", true);
97b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    notify->setInt32("rtp-time", rtpTime);
98b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    notify->setInt64("ntp-time", ntpTime);
99b2934b16eac8d8a866c37a7d1d7e03635f475b08Andreas Huber    notify->post();
1007a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
1017a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1027a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huberbool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
1037a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seqNum = (uint32_t)buffer->int32Data();
1047a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1057a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (mNumBuffersReceived++ == 0) {
1067a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mHighestSeqNumber = seqNum;
1077a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mQueue.push_back(buffer);
1087a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        return true;
1097a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1107a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1117a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // Only the lower 16-bit of the sequence numbers are transmitted,
1127a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // derive the high-order bits by choosing the candidate closest
1137a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    // to the highest sequence number (extended to 32 bits) received so far.
1147a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1157a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
1167a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
1177a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
1187a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
1197a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
1207a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
1217a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1227a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (diff1 < diff2) {
1237a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (diff1 < diff3) {
1247a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            // diff1 < diff2 ^ diff1 < diff3
1257a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            seqNum = seq1;
1267a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        } else {
1277a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            // diff3 <= diff1 < diff2
1287a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            seqNum = seq3;
1297a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
1307a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else if (diff2 < diff3) {
1317a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        // diff2 <= diff1 ^ diff2 < diff3
1327a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        seqNum = seq2;
1337a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else {
1347a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        // diff3 <= diff2 <= diff1
1357a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        seqNum = seq3;
1367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1377a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1387a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (seqNum > mHighestSeqNumber) {
1397a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mHighestSeqNumber = seqNum;
1407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1427a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    buffer->setInt32Data(seqNum);
1437a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1447a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    List<sp<ABuffer> >::iterator it = mQueue.begin();
1457a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
1467a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        ++it;
1477a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1487a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1497a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
1506e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber        LOGW("Discarding duplicate buffer");
1517a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        return false;
1527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    }
1537a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1547a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    mQueue.insert(it, buffer);
1557a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
1567a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    return true;
1577a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}
1587a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
15957648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::byeReceived() {
16057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mAssembler->onByeReceived();
16157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
16257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
16357648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::addFIR(const sp<ABuffer> &buffer) {
16457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (!mIssueFIRRequests) {
16557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
16657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
16757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
16857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
16957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
17057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        // Send FIR requests at most every 5 secs.
17157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
17257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
17357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
17457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mLastFIRRequestUs = nowUs;
17557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
17657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (buffer->size() + 20 > buffer->capacity()) {
1776e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber        LOGW("RTCP buffer too small to accomodate FIR.");
17857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
17957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
18057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
18157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
18257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
18357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[0] = 0x80 | 4;
18457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[1] = 206;  // PSFB
18557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[2] = 0;
18657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[3] = 4;
18757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[4] = kSourceID >> 24;
18857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
18957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
19057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[7] = kSourceID & 0xff;
19157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
19257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[8] = 0x00;  // SSRC of media source (unused)
19357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[9] = 0x00;
19457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[10] = 0x00;
19557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[11] = 0x00;
19657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
19757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[12] = mID >> 24;
19857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[13] = (mID >> 16) & 0xff;
19957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[14] = (mID >> 8) & 0xff;
20057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[15] = mID & 0xff;
20157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
20257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[16] = mNextFIRSeqNo++;  // Seq Nr.
20357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
20457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[17] = 0x00;  // Reserved
20557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[18] = 0x00;
20657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[19] = 0x00;
20757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
20857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 20);
20957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
2106e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber    LOGV("Added FIR request.");
21157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
21257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
21357648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
21457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (buffer->size() + 32 > buffer->capacity()) {
2156e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber        LOGW("RTCP buffer too small to accomodate RR.");
21657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return;
21757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
21857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
21957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
22057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
22157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[0] = 0x80 | 1;
22257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[1] = 201;  // RR
22357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[2] = 0;
22457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[3] = 7;
22557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[4] = kSourceID >> 24;
22657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
22757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
22857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[7] = kSourceID & 0xff;
22957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
23057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[8] = mID >> 24;
23157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[9] = (mID >> 16) & 0xff;
23257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[10] = (mID >> 8) & 0xff;
23357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[11] = mID & 0xff;
23457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
23557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[12] = 0x00;  // fraction lost
23657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
23757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[13] = 0x00;  // cumulative lost
23857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[14] = 0x00;
23957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[15] = 0x00;
24057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
24157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[16] = mHighestSeqNumber >> 24;
24257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[17] = (mHighestSeqNumber >> 16) & 0xff;
24357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[18] = (mHighestSeqNumber >> 8) & 0xff;
24457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[19] = mHighestSeqNumber & 0xff;
24557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
24657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[20] = 0x00;  // Interarrival jitter
24757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[21] = 0x00;
24857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[22] = 0x00;
24957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[23] = 0x00;
25057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
25157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint32_t LSR = 0;
25257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    uint32_t DLSR = 0;
25357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    if (mLastNTPTime != 0) {
25457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        LSR = (mLastNTPTime >> 16) & 0xffffffff;
25557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
25657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        DLSR = (uint32_t)
25757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
25857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    }
25957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
26057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[24] = LSR >> 24;
26157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[25] = (LSR >> 16) & 0xff;
26257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[26] = (LSR >> 8) & 0xff;
26357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[27] = LSR & 0xff;
26457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
26557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[28] = DLSR >> 24;
26657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[29] = (DLSR >> 16) & 0xff;
26757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[30] = (DLSR >> 8) & 0xff;
26857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    data[31] = DLSR & 0xff;
26957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
27057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 32);
27157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber}
27257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
2737a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber}  // namespace android
2747a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
2757a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
276