ARTPSource.cpp revision a979ad6739d573b3823b0fe7321f554ef5544753
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#include "ARTPSource.h" 18 19#include "AAMRAssembler.h" 20#include "AAVCAssembler.h" 21#include "AH263Assembler.h" 22#include "AMPEG4AudioAssembler.h" 23#include "AMPEG4ElementaryAssembler.h" 24#include "ASessionDescription.h" 25 26#include <media/stagefright/foundation/ABuffer.h> 27#include <media/stagefright/foundation/ADebug.h> 28#include <media/stagefright/foundation/AMessage.h> 29 30#define BE_VERBOSE 0 31 32namespace android { 33 34static const uint32_t kSourceID = 0xdeadbeef; 35 36ARTPSource::ARTPSource( 37 uint32_t id, 38 const sp<ASessionDescription> &sessionDesc, size_t index, 39 const sp<AMessage> ¬ify) 40 : mID(id), 41 mHighestSeqNumber(0), 42 mNumBuffersReceived(0), 43 mNumTimes(0), 44 mLastNTPTime(0), 45 mLastNTPTimeUpdateUs(0), 46 mIssueFIRRequests(false), 47 mLastFIRRequestUs(-1), 48 mNextFIRSeqNo((rand() * 256.0) / RAND_MAX) { 49 unsigned long PT; 50 AString desc; 51 AString params; 52 sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 53 54 if (!strncmp(desc.c_str(), "H264/", 5)) { 55 mAssembler = new AAVCAssembler(notify); 56 mIssueFIRRequests = true; 57 } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 58 mAssembler = new AMPEG4AudioAssembler(notify); 59 } else if (!strncmp(desc.c_str(), "H263-1998/", 10) 60 || !strncmp(desc.c_str(), "H263-2000/", 10)) { 61 mAssembler = new AH263Assembler(notify); 62 mIssueFIRRequests = true; 63 } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 64 mAssembler = new AAMRAssembler(notify, false /* isWide */, params); 65 } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 66 mAssembler = new AAMRAssembler(notify, true /* isWide */, params); 67 } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) { 68 mAssembler = new AMPEG4ElementaryAssembler(notify); 69 mIssueFIRRequests = true; 70 } else { 71 TRESPASS(); 72 } 73} 74 75static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) { 76 return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1; 77} 78 79void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) { 80 if (queuePacket(buffer) 81 && mNumTimes == 2 82 && mAssembler != NULL) { 83 mAssembler->onPacketReceived(this); 84 } 85 86 dump(); 87} 88 89void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) { 90#if BE_VERBOSE 91 LOG(VERBOSE) << "timeUpdate"; 92#endif 93 94 mLastNTPTime = ntpTime; 95 mLastNTPTimeUpdateUs = ALooper::GetNowUs(); 96 97 if (mNumTimes == 2) { 98 mNTPTime[0] = mNTPTime[1]; 99 mRTPTime[0] = mRTPTime[1]; 100 mNumTimes = 1; 101 } 102 mNTPTime[mNumTimes] = ntpTime; 103 mRTPTime[mNumTimes++] = rtpTime; 104 105 if (timeEstablished()) { 106 for (List<sp<ABuffer> >::iterator it = mQueue.begin(); 107 it != mQueue.end(); ++it) { 108 sp<AMessage> meta = (*it)->meta(); 109 110 uint32_t rtpTime; 111 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 112 113 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 114 } 115 } 116} 117 118bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) { 119 uint32_t seqNum = (uint32_t)buffer->int32Data(); 120 121 if (mNumTimes == 2) { 122 sp<AMessage> meta = buffer->meta(); 123 124 uint32_t rtpTime; 125 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 126 127 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 128 } 129 130 if (mNumBuffersReceived++ == 0) { 131 mHighestSeqNumber = seqNum; 132 mQueue.push_back(buffer); 133 return true; 134 } 135 136 // Only the lower 16-bit of the sequence numbers are transmitted, 137 // derive the high-order bits by choosing the candidate closest 138 // to the highest sequence number (extended to 32 bits) received so far. 139 140 uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000); 141 uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 142 uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 143 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 144 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 145 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 146 147 if (diff1 < diff2) { 148 if (diff1 < diff3) { 149 // diff1 < diff2 ^ diff1 < diff3 150 seqNum = seq1; 151 } else { 152 // diff3 <= diff1 < diff2 153 seqNum = seq3; 154 } 155 } else if (diff2 < diff3) { 156 // diff2 <= diff1 ^ diff2 < diff3 157 seqNum = seq2; 158 } else { 159 // diff3 <= diff2 <= diff1 160 seqNum = seq3; 161 } 162 163 if (seqNum > mHighestSeqNumber) { 164 mHighestSeqNumber = seqNum; 165 } 166 167 buffer->setInt32Data(seqNum); 168 169 List<sp<ABuffer> >::iterator it = mQueue.begin(); 170 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 171 ++it; 172 } 173 174 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 175 LOG(WARNING) << "Discarding duplicate buffer"; 176 return false; 177 } 178 179 mQueue.insert(it, buffer); 180 181 return true; 182} 183 184void ARTPSource::dump() const { 185 if ((mNumBuffersReceived % 128) != 0) { 186 return; 187 } 188 189#if 0 190 if (mAssembler == NULL) { 191 char tmp[20]; 192 sprintf(tmp, "0x%08x", mID); 193 194 int32_t numMissing = 0; 195 196 if (!mQueue.empty()) { 197 List<sp<ABuffer> >::const_iterator it = mQueue.begin(); 198 uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data(); 199 ++expectedSeqNum; 200 ++it; 201 202 for (; it != mQueue.end(); ++it) { 203 uint32_t seqNum = (uint32_t)(*it)->int32Data(); 204 CHECK_GE(seqNum, expectedSeqNum); 205 206 if (seqNum != expectedSeqNum) { 207 numMissing += seqNum - expectedSeqNum; 208 expectedSeqNum = seqNum; 209 } 210 211 ++expectedSeqNum; 212 } 213 } 214 215 LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing 216 << " / " << (mNumBuffersReceived + numMissing) << " packets. (" 217 << (100.0 * numMissing / (mNumBuffersReceived + numMissing)) 218 << " %%)"; 219 } 220#endif 221 222#if 0 223 AString out; 224 225 out.append(tmp); 226 out.append(" ["); 227 228 List<sp<ABuffer> >::const_iterator it = mQueue.begin(); 229 while (it != mQueue.end()) { 230 uint32_t start = (uint32_t)(*it)->int32Data(); 231 232 out.append(start); 233 234 ++it; 235 uint32_t expected = start + 1; 236 237 while (it != mQueue.end()) { 238 uint32_t seqNum = (uint32_t)(*it)->int32Data(); 239 240 if (seqNum != expected) { 241 if (expected > start + 1) { 242 out.append("-"); 243 out.append(expected - 1); 244 } 245 out.append(", "); 246 break; 247 } 248 249 ++it; 250 ++expected; 251 } 252 253 if (it == mQueue.end()) { 254 if (expected > start + 1) { 255 out.append("-"); 256 out.append(expected - 1); 257 } 258 } 259 } 260 261 out.append("]"); 262 263 LOG(VERBOSE) << out; 264#endif 265} 266 267uint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const { 268 CHECK_EQ(mNumTimes, 2u); 269 270 return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0]) 271 * ((double)rtpTime - (double)mRTPTime[0]) 272 / (double)(mRTPTime[1] - mRTPTime[0]); 273} 274 275void ARTPSource::byeReceived() { 276 mAssembler->onByeReceived(); 277} 278 279void ARTPSource::addFIR(const sp<ABuffer> &buffer) { 280 if (!mIssueFIRRequests) { 281 return; 282 } 283 284 int64_t nowUs = ALooper::GetNowUs(); 285 if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) { 286 // Send FIR requests at most every 5 secs. 287 return; 288 } 289 290 mLastFIRRequestUs = nowUs; 291 292 if (buffer->size() + 20 > buffer->capacity()) { 293 LOG(WARNING) << "RTCP buffer too small to accomodate FIR."; 294 return; 295 } 296 297 uint8_t *data = buffer->data() + buffer->size(); 298 299 data[0] = 0x80 | 4; 300 data[1] = 206; // PSFB 301 data[2] = 0; 302 data[3] = 4; 303 data[4] = kSourceID >> 24; 304 data[5] = (kSourceID >> 16) & 0xff; 305 data[6] = (kSourceID >> 8) & 0xff; 306 data[7] = kSourceID & 0xff; 307 308 data[8] = 0x00; // SSRC of media source (unused) 309 data[9] = 0x00; 310 data[10] = 0x00; 311 data[11] = 0x00; 312 313 data[12] = mID >> 24; 314 data[13] = (mID >> 16) & 0xff; 315 data[14] = (mID >> 8) & 0xff; 316 data[15] = mID & 0xff; 317 318 data[16] = mNextFIRSeqNo++; // Seq Nr. 319 320 data[17] = 0x00; // Reserved 321 data[18] = 0x00; 322 data[19] = 0x00; 323 324 buffer->setRange(buffer->offset(), buffer->size() + 20); 325 326 LOG(VERBOSE) << "Added FIR request."; 327} 328 329void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) { 330 if (buffer->size() + 32 > buffer->capacity()) { 331 LOG(WARNING) << "RTCP buffer too small to accomodate RR."; 332 return; 333 } 334 335 uint8_t *data = buffer->data() + buffer->size(); 336 337 data[0] = 0x80 | 1; 338 data[1] = 201; // RR 339 data[2] = 0; 340 data[3] = 7; 341 data[4] = kSourceID >> 24; 342 data[5] = (kSourceID >> 16) & 0xff; 343 data[6] = (kSourceID >> 8) & 0xff; 344 data[7] = kSourceID & 0xff; 345 346 data[8] = mID >> 24; 347 data[9] = (mID >> 16) & 0xff; 348 data[10] = (mID >> 8) & 0xff; 349 data[11] = mID & 0xff; 350 351 data[12] = 0x00; // fraction lost 352 353 data[13] = 0x00; // cumulative lost 354 data[14] = 0x00; 355 data[15] = 0x00; 356 357 data[16] = mHighestSeqNumber >> 24; 358 data[17] = (mHighestSeqNumber >> 16) & 0xff; 359 data[18] = (mHighestSeqNumber >> 8) & 0xff; 360 data[19] = mHighestSeqNumber & 0xff; 361 362 data[20] = 0x00; // Interarrival jitter 363 data[21] = 0x00; 364 data[22] = 0x00; 365 data[23] = 0x00; 366 367 uint32_t LSR = 0; 368 uint32_t DLSR = 0; 369 if (mLastNTPTime != 0) { 370 LSR = (mLastNTPTime >> 16) & 0xffffffff; 371 372 DLSR = (uint32_t) 373 ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6); 374 } 375 376 data[24] = LSR >> 24; 377 data[25] = (LSR >> 16) & 0xff; 378 data[26] = (LSR >> 8) & 0xff; 379 data[27] = LSR & 0xff; 380 381 data[28] = DLSR >> 24; 382 data[29] = (DLSR >> 16) & 0xff; 383 data[30] = (DLSR >> 8) & 0xff; 384 data[31] = DLSR & 0xff; 385 386 buffer->setRange(buffer->offset(), buffer->size() + 32); 387} 388 389} // namespace android 390 391 392