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> ¬ify) 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, ¶ms); 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