1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ARTPSource"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPSource.h"
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "AAMRAssembler.h"
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "AAVCAssembler.h"
2539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "AH263Assembler.h"
26cfaeeec0900014d97e15829e0fa52f865ee4c786Andreas Huber#include "AMPEG2TSAssembler.h"
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "AMPEG4AudioAssembler.h"
2862cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber#include "AMPEG4ElementaryAssembler.h"
29fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber#include "ARawAudioAssembler.h"
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
3839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic const uint32_t kSourceID = 0xdeadbeef;
3939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPSource::ARTPSource(
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint32_t id,
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index,
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<AMessage> &notify)
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mID(id),
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mHighestSeqNumber(0),
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mNumBuffersReceived(0),
4739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mLastNTPTime(0),
4839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mLastNTPTimeUpdateUs(0),
4939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mIssueFIRRequests(false),
5039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mLastFIRRequestUs(-1),
51100a4408968b90e314526185d572c72ea4cc784aAndreas Huber      mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
52100a4408968b90e314526185d572c72ea4cc784aAndreas Huber      mNotify(notify) {
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long PT;
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc;
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString params;
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAssembler = new AAVCAssembler(notify);
6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mIssueFIRRequests = true;
6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
62fc9ac988e08a8b4c42e58999300265989f26f24cAndreas Huber        mAssembler = new AMPEG4AudioAssembler(notify, params);
6339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            || !strncmp(desc.c_str(), "H263-2000/", 10)) {
6539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mAssembler = new AH263Assembler(notify);
66ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber        mIssueFIRRequests = true;
6739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
6839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
6939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
7039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
714dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
72dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber            || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
734dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber        mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
7462cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber        mIssueFIRRequests = true;
75fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber    } else if (ARawAudioAssembler::Supports(desc.c_str())) {
76fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber        mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
77cfaeeec0900014d97e15829e0fa52f865ee4c786Andreas Huber    } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) {
78cfaeeec0900014d97e15829e0fa52f865ee4c786Andreas Huber        mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params);
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        TRESPASS();
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
89100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    if (queuePacket(buffer) && mAssembler != NULL) {
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAssembler->onPacketReceived(this);
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
9539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mLastNTPTime = ntpTime;
9639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mLastNTPTimeUpdateUs = ALooper::GetNowUs();
9739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
98100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    sp<AMessage> notify = mNotify->dup();
99100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    notify->setInt32("time-update", true);
100100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    notify->setInt32("rtp-time", rtpTime);
101100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    notify->setInt64("ntp-time", ntpTime);
102100a4408968b90e314526185d572c72ea4cc784aAndreas Huber    notify->post();
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seqNum = (uint32_t)buffer->int32Data();
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNumBuffersReceived++ == 0) {
109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mHighestSeqNumber = seqNum;
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mQueue.push_back(buffer);
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return true;
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // Only the lower 16-bit of the sequence numbers are transmitted,
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // derive the high-order bits by choosing the candidate closest
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // to the highest sequence number (extended to 32 bits) received so far.
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
119df9e6aaf716279baf0e27b99acf10005924245edRobert Shih
120df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    // non-overflowing version of:
121df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
122df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    uint32_t seq2 = seqNum | (((mHighestSeqNumber >> 16) + 1) << 16);
123df9e6aaf716279baf0e27b99acf10005924245edRobert Shih
124df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    // non-underflowing version of:
125df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
126df9e6aaf716279baf0e27b99acf10005924245edRobert Shih    uint32_t seq3 = seqNum | ((((mHighestSeqNumber >> 16) | 0x10000) - 1) << 16);
127df9e6aaf716279baf0e27b99acf10005924245edRobert Shih
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (diff1 < diff2) {
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (diff1 < diff3) {
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // diff1 < diff2 ^ diff1 < diff3
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            seqNum = seq1;
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // diff3 <= diff1 < diff2
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            seqNum = seq3;
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (diff2 < diff3) {
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // diff2 <= diff1 ^ diff2 < diff3
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        seqNum = seq2;
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // diff3 <= diff2 <= diff1
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        seqNum = seq3;
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (seqNum > mHighestSeqNumber) {
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mHighestSeqNumber = seqNum;
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    buffer->setInt32Data(seqNum);
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<sp<ABuffer> >::iterator it = mQueue.begin();
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++it;
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
1605ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Discarding duplicate buffer");
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mQueue.insert(it, buffer);
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
16939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::byeReceived() {
17039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mAssembler->onByeReceived();
17139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
17239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::addFIR(const sp<ABuffer> &buffer) {
17439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (!mIssueFIRRequests) {
17539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return;
17639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
17739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
17939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
18039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        // Send FIR requests at most every 5 secs.
18139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return;
18239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mLastFIRRequestUs = nowUs;
18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (buffer->size() + 20 > buffer->capacity()) {
1875ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("RTCP buffer too small to accomodate FIR.");
18839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return;
18939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
19039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
19239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[0] = 0x80 | 4;
19439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[1] = 206;  // PSFB
19539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[2] = 0;
19639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[3] = 4;
19739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[4] = kSourceID >> 24;
19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
20039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[7] = kSourceID & 0xff;
20139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[8] = 0x00;  // SSRC of media source (unused)
20339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[9] = 0x00;
20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[10] = 0x00;
20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[11] = 0x00;
20639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[12] = mID >> 24;
20839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[13] = (mID >> 16) & 0xff;
20939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[14] = (mID >> 8) & 0xff;
21039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[15] = mID & 0xff;
21139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[16] = mNextFIRSeqNo++;  // Seq Nr.
21339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[17] = 0x00;  // Reserved
21539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[18] = 0x00;
21639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[19] = 0x00;
21739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 20);
21939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Added FIR request.");
22139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
22239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
22339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
22439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (buffer->size() + 32 > buffer->capacity()) {
2255ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("RTCP buffer too small to accomodate RR.");
22639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return;
22739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
22839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
22939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint8_t *data = buffer->data() + buffer->size();
23039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
23139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[0] = 0x80 | 1;
23239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[1] = 201;  // RR
23339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[2] = 0;
23439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[3] = 7;
23539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[4] = kSourceID >> 24;
23639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[5] = (kSourceID >> 16) & 0xff;
23739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[6] = (kSourceID >> 8) & 0xff;
23839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[7] = kSourceID & 0xff;
23939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
24039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[8] = mID >> 24;
24139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[9] = (mID >> 16) & 0xff;
24239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[10] = (mID >> 8) & 0xff;
24339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[11] = mID & 0xff;
24439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
24539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[12] = 0x00;  // fraction lost
24639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
24739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[13] = 0x00;  // cumulative lost
24839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[14] = 0x00;
24939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[15] = 0x00;
25039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
25139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[16] = mHighestSeqNumber >> 24;
25239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[17] = (mHighestSeqNumber >> 16) & 0xff;
25339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[18] = (mHighestSeqNumber >> 8) & 0xff;
25439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[19] = mHighestSeqNumber & 0xff;
25539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
25639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[20] = 0x00;  // Interarrival jitter
25739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[21] = 0x00;
25839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[22] = 0x00;
25939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[23] = 0x00;
26039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
26139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint32_t LSR = 0;
26239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint32_t DLSR = 0;
26339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mLastNTPTime != 0) {
26439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        LSR = (mLastNTPTime >> 16) & 0xffffffff;
26539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
26639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        DLSR = (uint32_t)
26739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
26839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
26939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
27039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[24] = LSR >> 24;
27139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[25] = (LSR >> 16) & 0xff;
27239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[26] = (LSR >> 8) & 0xff;
27339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[27] = LSR & 0xff;
27439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
27539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[28] = DLSR >> 24;
27639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[29] = (DLSR >> 16) & 0xff;
27739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[30] = (DLSR >> 8) & 0xff;
27839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    data[31] = DLSR & 0xff;
27939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
28039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 32);
28139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
28239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
286