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