ARTPSource.cpp revision fc9ac988e08a8b4c42e58999300265989f26f24c
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ARTPSource" 19#include <utils/Log.h> 20 21#include "ARTPSource.h" 22 23#include "AAMRAssembler.h" 24#include "AAVCAssembler.h" 25#include "AH263Assembler.h" 26#include "AMPEG4AudioAssembler.h" 27#include "AMPEG4ElementaryAssembler.h" 28#include "ASessionDescription.h" 29 30#include <media/stagefright/foundation/ABuffer.h> 31#include <media/stagefright/foundation/ADebug.h> 32#include <media/stagefright/foundation/AMessage.h> 33 34namespace android { 35 36static const uint32_t kSourceID = 0xdeadbeef; 37 38ARTPSource::ARTPSource( 39 uint32_t id, 40 const sp<ASessionDescription> &sessionDesc, size_t index, 41 const sp<AMessage> ¬ify) 42 : mID(id), 43 mHighestSeqNumber(0), 44 mNumBuffersReceived(0), 45 mNumTimes(0), 46 mLastNTPTime(0), 47 mLastNTPTimeUpdateUs(0), 48 mIssueFIRRequests(false), 49 mLastFIRRequestUs(-1), 50 mNextFIRSeqNo((rand() * 256.0) / RAND_MAX) { 51 unsigned long PT; 52 AString desc; 53 AString params; 54 sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 55 56 if (!strncmp(desc.c_str(), "H264/", 5)) { 57 mAssembler = new AAVCAssembler(notify); 58 mIssueFIRRequests = true; 59 } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 60 mAssembler = new AMPEG4AudioAssembler(notify, params); 61 } else if (!strncmp(desc.c_str(), "H263-1998/", 10) 62 || !strncmp(desc.c_str(), "H263-2000/", 10)) { 63 mAssembler = new AH263Assembler(notify); 64 mIssueFIRRequests = true; 65 } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 66 mAssembler = new AAMRAssembler(notify, false /* isWide */, params); 67 } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 68 mAssembler = new AAMRAssembler(notify, true /* isWide */, params); 69 } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8) 70 || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) { 71 mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params); 72 mIssueFIRRequests = true; 73 } else { 74 TRESPASS(); 75 } 76} 77 78static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) { 79 return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1; 80} 81 82void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) { 83 if (queuePacket(buffer) 84 && mNumTimes == 2 85 && mAssembler != NULL) { 86 mAssembler->onPacketReceived(this); 87 } 88} 89 90void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) { 91 LOGV("timeUpdate"); 92 93 mLastNTPTime = ntpTime; 94 mLastNTPTimeUpdateUs = ALooper::GetNowUs(); 95 96 if (mNumTimes == 2) { 97 mNTPTime[0] = mNTPTime[1]; 98 mRTPTime[0] = mRTPTime[1]; 99 mNumTimes = 1; 100 } 101 mNTPTime[mNumTimes] = ntpTime; 102 mRTPTime[mNumTimes++] = rtpTime; 103 104 if (timeEstablished()) { 105 for (List<sp<ABuffer> >::iterator it = mQueue.begin(); 106 it != mQueue.end(); ++it) { 107 sp<AMessage> meta = (*it)->meta(); 108 109 uint32_t rtpTime; 110 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 111 112 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 113 } 114 } 115} 116 117bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) { 118 uint32_t seqNum = (uint32_t)buffer->int32Data(); 119 120 if (mNumTimes == 2) { 121 sp<AMessage> meta = buffer->meta(); 122 123 uint32_t rtpTime; 124 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 125 126 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 127 } 128 129 if (mNumBuffersReceived++ == 0) { 130 mHighestSeqNumber = seqNum; 131 mQueue.push_back(buffer); 132 return true; 133 } 134 135 // Only the lower 16-bit of the sequence numbers are transmitted, 136 // derive the high-order bits by choosing the candidate closest 137 // to the highest sequence number (extended to 32 bits) received so far. 138 139 uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000); 140 uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 141 uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 142 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 143 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 144 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 145 146 if (diff1 < diff2) { 147 if (diff1 < diff3) { 148 // diff1 < diff2 ^ diff1 < diff3 149 seqNum = seq1; 150 } else { 151 // diff3 <= diff1 < diff2 152 seqNum = seq3; 153 } 154 } else if (diff2 < diff3) { 155 // diff2 <= diff1 ^ diff2 < diff3 156 seqNum = seq2; 157 } else { 158 // diff3 <= diff2 <= diff1 159 seqNum = seq3; 160 } 161 162 if (seqNum > mHighestSeqNumber) { 163 mHighestSeqNumber = seqNum; 164 } 165 166 buffer->setInt32Data(seqNum); 167 168 List<sp<ABuffer> >::iterator it = mQueue.begin(); 169 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 170 ++it; 171 } 172 173 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 174 LOGW("Discarding duplicate buffer"); 175 return false; 176 } 177 178 mQueue.insert(it, buffer); 179 180 return true; 181} 182 183uint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const { 184 CHECK_EQ(mNumTimes, 2u); 185 186 return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0]) 187 * ((double)rtpTime - (double)mRTPTime[0]) 188 / (double)(mRTPTime[1] - mRTPTime[0]); 189} 190 191void ARTPSource::byeReceived() { 192 mAssembler->onByeReceived(); 193} 194 195void ARTPSource::addFIR(const sp<ABuffer> &buffer) { 196 if (!mIssueFIRRequests) { 197 return; 198 } 199 200 int64_t nowUs = ALooper::GetNowUs(); 201 if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) { 202 // Send FIR requests at most every 5 secs. 203 return; 204 } 205 206 mLastFIRRequestUs = nowUs; 207 208 if (buffer->size() + 20 > buffer->capacity()) { 209 LOGW("RTCP buffer too small to accomodate FIR."); 210 return; 211 } 212 213 uint8_t *data = buffer->data() + buffer->size(); 214 215 data[0] = 0x80 | 4; 216 data[1] = 206; // PSFB 217 data[2] = 0; 218 data[3] = 4; 219 data[4] = kSourceID >> 24; 220 data[5] = (kSourceID >> 16) & 0xff; 221 data[6] = (kSourceID >> 8) & 0xff; 222 data[7] = kSourceID & 0xff; 223 224 data[8] = 0x00; // SSRC of media source (unused) 225 data[9] = 0x00; 226 data[10] = 0x00; 227 data[11] = 0x00; 228 229 data[12] = mID >> 24; 230 data[13] = (mID >> 16) & 0xff; 231 data[14] = (mID >> 8) & 0xff; 232 data[15] = mID & 0xff; 233 234 data[16] = mNextFIRSeqNo++; // Seq Nr. 235 236 data[17] = 0x00; // Reserved 237 data[18] = 0x00; 238 data[19] = 0x00; 239 240 buffer->setRange(buffer->offset(), buffer->size() + 20); 241 242 LOGV("Added FIR request."); 243} 244 245void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) { 246 if (buffer->size() + 32 > buffer->capacity()) { 247 LOGW("RTCP buffer too small to accomodate RR."); 248 return; 249 } 250 251 uint8_t *data = buffer->data() + buffer->size(); 252 253 data[0] = 0x80 | 1; 254 data[1] = 201; // RR 255 data[2] = 0; 256 data[3] = 7; 257 data[4] = kSourceID >> 24; 258 data[5] = (kSourceID >> 16) & 0xff; 259 data[6] = (kSourceID >> 8) & 0xff; 260 data[7] = kSourceID & 0xff; 261 262 data[8] = mID >> 24; 263 data[9] = (mID >> 16) & 0xff; 264 data[10] = (mID >> 8) & 0xff; 265 data[11] = mID & 0xff; 266 267 data[12] = 0x00; // fraction lost 268 269 data[13] = 0x00; // cumulative lost 270 data[14] = 0x00; 271 data[15] = 0x00; 272 273 data[16] = mHighestSeqNumber >> 24; 274 data[17] = (mHighestSeqNumber >> 16) & 0xff; 275 data[18] = (mHighestSeqNumber >> 8) & 0xff; 276 data[19] = mHighestSeqNumber & 0xff; 277 278 data[20] = 0x00; // Interarrival jitter 279 data[21] = 0x00; 280 data[22] = 0x00; 281 data[23] = 0x00; 282 283 uint32_t LSR = 0; 284 uint32_t DLSR = 0; 285 if (mLastNTPTime != 0) { 286 LSR = (mLastNTPTime >> 16) & 0xffffffff; 287 288 DLSR = (uint32_t) 289 ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6); 290 } 291 292 data[24] = LSR >> 24; 293 data[25] = (LSR >> 16) & 0xff; 294 data[26] = (LSR >> 8) & 0xff; 295 data[27] = LSR & 0xff; 296 297 data[28] = DLSR >> 24; 298 data[29] = (DLSR >> 16) & 0xff; 299 data[30] = (DLSR >> 8) & 0xff; 300 data[31] = DLSR & 0xff; 301 302 buffer->setRange(buffer->offset(), buffer->size() + 32); 303} 304 305} // namespace android 306 307 308