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> ¬ify) 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber : mID(id), 45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mHighestSeqNumber(0), 465451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mPrevExpected(0), 475451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mBaseSeqNumber(0), 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mNumBuffersReceived(0), 495451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mPrevNumBuffersReceived(0), 5039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime(0), 5139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTimeUpdateUs(0), 5239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mIssueFIRRequests(false), 5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastFIRRequestUs(-1), 54100a4408968b90e314526185d572c72ea4cc784aAndreas Huber mNextFIRSeqNo((rand() * 256.0) / RAND_MAX), 55100a4408968b90e314526185d572c72ea4cc784aAndreas Huber mNotify(notify) { 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned long PT; 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString desc; 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber AString params; 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!strncmp(desc.c_str(), "H264/", 5)) { 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mAssembler = new AAVCAssembler(notify); 6339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mIssueFIRRequests = true; 6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 65fc9ac988e08a8b4c42e58999300265989f26f24cAndreas Huber mAssembler = new AMPEG4AudioAssembler(notify, params); 6639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "H263-1998/", 10) 6739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || !strncmp(desc.c_str(), "H263-2000/", 10)) { 6839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mAssembler = new AH263Assembler(notify); 69ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber mIssueFIRRequests = true; 7039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 7139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mAssembler = new AAMRAssembler(notify, false /* isWide */, params); 7239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 7339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mAssembler = new AAMRAssembler(notify, true /* isWide */, params); 744dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8) 75dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) { 764dba3e90f211eb5f5af19b10c5d3fc8c967b0086Andreas Huber mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params); 7762cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber mIssueFIRRequests = true; 78fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber } else if (ARawAudioAssembler::Supports(desc.c_str())) { 79fcea8f7a7d178e5426aa06586cff54726e18d1f6Andreas Huber mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params); 80cfaeeec0900014d97e15829e0fa52f865ee4c786Andreas Huber } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) { 81cfaeeec0900014d97e15829e0fa52f865ee4c786Andreas Huber mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params); 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) { 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1; 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) { 92100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (queuePacket(buffer) && mAssembler != NULL) { 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mAssembler->onPacketReceived(this); 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) { 9839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTime = ntpTime; 9939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastNTPTimeUpdateUs = ALooper::GetNowUs(); 10039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 101100a4408968b90e314526185d572c72ea4cc784aAndreas Huber sp<AMessage> notify = mNotify->dup(); 102100a4408968b90e314526185d572c72ea4cc784aAndreas Huber notify->setInt32("time-update", true); 103100a4408968b90e314526185d572c72ea4cc784aAndreas Huber notify->setInt32("rtp-time", rtpTime); 104100a4408968b90e314526185d572c72ea4cc784aAndreas Huber notify->setInt64("ntp-time", ntpTime); 105100a4408968b90e314526185d572c72ea4cc784aAndreas Huber notify->post(); 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ARTPSource::queuePacket(const sp<ABuffer> &buffer) { 109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t seqNum = (uint32_t)buffer->int32Data(); 110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mNumBuffersReceived++ == 0) { 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mHighestSeqNumber = seqNum; 1135451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mBaseSeqNumber = seqNum; 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mQueue.push_back(buffer); 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return true; 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Only the lower 16-bit of the sequence numbers are transmitted, 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // derive the high-order bits by choosing the candidate closest 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // to the highest sequence number (extended to 32 bits) received so far. 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000); 123df9e6aaf716279baf0e27b99acf10005924245edRobert Shih 124df9e6aaf716279baf0e27b99acf10005924245edRobert Shih // non-overflowing version of: 125df9e6aaf716279baf0e27b99acf10005924245edRobert Shih // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 126df9e6aaf716279baf0e27b99acf10005924245edRobert Shih uint32_t seq2 = seqNum | (((mHighestSeqNumber >> 16) + 1) << 16); 127df9e6aaf716279baf0e27b99acf10005924245edRobert Shih 128df9e6aaf716279baf0e27b99acf10005924245edRobert Shih // non-underflowing version of: 129df9e6aaf716279baf0e27b99acf10005924245edRobert Shih // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 130df9e6aaf716279baf0e27b99acf10005924245edRobert Shih uint32_t seq3 = seqNum | ((((mHighestSeqNumber >> 16) | 0x10000) - 1) << 16); 131df9e6aaf716279baf0e27b99acf10005924245edRobert Shih 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (diff1 < diff2) { 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (diff1 < diff3) { 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // diff1 < diff2 ^ diff1 < diff3 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber seqNum = seq1; 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // diff3 <= diff1 < diff2 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber seqNum = seq3; 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (diff2 < diff3) { 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // diff2 <= diff1 ^ diff2 < diff3 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber seqNum = seq2; 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // diff3 <= diff2 <= diff1 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber seqNum = seq3; 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (seqNum > mHighestSeqNumber) { 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mHighestSeqNumber = seqNum; 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setInt32Data(seqNum); 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber List<sp<ABuffer> >::iterator it = mQueue.begin(); 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++it; 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 1645ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Discarding duplicate buffer"); 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mQueue.insert(it, buffer); 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return true; 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 17339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::byeReceived() { 17439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mAssembler->onByeReceived(); 17539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 17639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 17739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::addFIR(const sp<ABuffer> &buffer) { 17839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!mIssueFIRRequests) { 17939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 18039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 18139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 18239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) { 18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Send FIR requests at most every 5 secs. 18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 18639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 18739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 18839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastFIRRequestUs = nowUs; 18939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 19039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (buffer->size() + 20 > buffer->capacity()) { 1915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("RTCP buffer too small to accomodate FIR."); 19239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 19339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 19439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 19539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 19639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 19739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80 | 4; 19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = 206; // PSFB 19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = 0; 20039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = 4; 20139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = kSourceID >> 24; 20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (kSourceID >> 16) & 0xff; 20339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (kSourceID >> 8) & 0xff; 20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = kSourceID & 0xff; 20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 20639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = 0x00; // SSRC of media source (unused) 20739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = 0x00; 20839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = 0x00; 20939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = 0x00; 21039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 21139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[12] = mID >> 24; 21239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[13] = (mID >> 16) & 0xff; 21339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[14] = (mID >> 8) & 0xff; 21439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[15] = mID & 0xff; 21539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 21639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[16] = mNextFIRSeqNo++; // Seq Nr. 21739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 21839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[17] = 0x00; // Reserved 21939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[18] = 0x00; 22039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[19] = 0x00; 22139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 22239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + 20); 22339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Added FIR request."); 22539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 22639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 22739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) { 22839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (buffer->size() + 32 > buffer->capacity()) { 2295ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("RTCP buffer too small to accomodate RR."); 23039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return; 23139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 23239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2335451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson uint8_t fraction = 0; 2345451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson 2355451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson // According to appendix A.3 in RFC 3550 2365451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1; 2375451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson int64_t intervalExpected = expected - mPrevExpected; 2385451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived; 2395451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson int64_t intervalPacketLost = intervalExpected - intervalReceived; 2405451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson 2415451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson if (intervalExpected > 0 && intervalPacketLost > 0) { 2425451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson fraction = (intervalPacketLost << 8) / intervalExpected; 2435451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson } 2445451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson 2455451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mPrevExpected = expected; 2465451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson mPrevNumBuffersReceived = mNumBuffersReceived; 2475451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson int32_t cumulativePacketLost = (int32_t)expected - mNumBuffersReceived; 2485451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson 24939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 25039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 25139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[0] = 0x80 | 1; 25239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[1] = 201; // RR 25339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[2] = 0; 25439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[3] = 7; 25539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[4] = kSourceID >> 24; 25639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[5] = (kSourceID >> 16) & 0xff; 25739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[6] = (kSourceID >> 8) & 0xff; 25839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[7] = kSourceID & 0xff; 25939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 26039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[8] = mID >> 24; 26139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[9] = (mID >> 16) & 0xff; 26239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[10] = (mID >> 8) & 0xff; 26339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[11] = mID & 0xff; 26439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2655451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson data[12] = fraction; // fraction lost 26639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2675451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson data[13] = cumulativePacketLost >> 16; // cumulative lost 2685451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson data[14] = (cumulativePacketLost >> 8) & 0xff; 2695451d9ce9e4216e54e02c6aef11022dcfb833c05joakim johansson data[15] = cumulativePacketLost & 0xff; 27039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[16] = mHighestSeqNumber >> 24; 27239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[17] = (mHighestSeqNumber >> 16) & 0xff; 27339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[18] = (mHighestSeqNumber >> 8) & 0xff; 27439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[19] = mHighestSeqNumber & 0xff; 27539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[20] = 0x00; // Interarrival jitter 27739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[21] = 0x00; 27839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[22] = 0x00; 27939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[23] = 0x00; 28039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t LSR = 0; 28239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t DLSR = 0; 28339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mLastNTPTime != 0) { 28439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber LSR = (mLastNTPTime >> 16) & 0xffffffff; 28539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber DLSR = (uint32_t) 28739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6); 28839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 28939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[24] = LSR >> 24; 29139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[25] = (LSR >> 16) & 0xff; 29239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[26] = (LSR >> 8) & 0xff; 29339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[27] = LSR & 0xff; 29439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[28] = DLSR >> 24; 29639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[29] = (DLSR >> 16) & 0xff; 29739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[30] = (DLSR >> 8) & 0xff; 29839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber data[31] = DLSR & 0xff; 29939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 30039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + 32); 30139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 30239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 304cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 305cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 306