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 "AMPEG2TSAssembler.h" 27 #include "AMPEG4AudioAssembler.h" 28 #include "AMPEG4ElementaryAssembler.h" 29 #include "ARawAudioAssembler.h" 30 #include "ASessionDescription.h" 31 32 #include <media/stagefright/foundation/ABuffer.h> 33 #include <media/stagefright/foundation/ADebug.h> 34 #include <media/stagefright/foundation/AMessage.h> 35 36 namespace android { 37 38 static const uint32_t kSourceID = 0xdeadbeef; 39 40 ARTPSource::ARTPSource( 41 uint32_t id, 42 const sp<ASessionDescription> &sessionDesc, size_t index, 43 const sp<AMessage> ¬ify) 44 : mID(id), 45 mHighestSeqNumber(0), 46 mNumBuffersReceived(0), 47 mLastNTPTime(0), 48 mLastNTPTimeUpdateUs(0), 49 mIssueFIRRequests(false), 50 mLastFIRRequestUs(-1), 51 mNextFIRSeqNo((rand() * 256.0) / RAND_MAX), 52 mNotify(notify) { 53 unsigned long PT; 54 AString desc; 55 AString params; 56 sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 57 58 if (!strncmp(desc.c_str(), "H264/", 5)) { 59 mAssembler = new AAVCAssembler(notify); 60 mIssueFIRRequests = true; 61 } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) { 62 mAssembler = new AMPEG4AudioAssembler(notify, params); 63 } else if (!strncmp(desc.c_str(), "H263-1998/", 10) 64 || !strncmp(desc.c_str(), "H263-2000/", 10)) { 65 mAssembler = new AH263Assembler(notify); 66 mIssueFIRRequests = true; 67 } else if (!strncmp(desc.c_str(), "AMR/", 4)) { 68 mAssembler = new AAMRAssembler(notify, false /* isWide */, params); 69 } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) { 70 mAssembler = new AAMRAssembler(notify, true /* isWide */, params); 71 } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8) 72 || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) { 73 mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params); 74 mIssueFIRRequests = true; 75 } else if (ARawAudioAssembler::Supports(desc.c_str())) { 76 mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params); 77 } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) { 78 mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params); 79 } else { 80 TRESPASS(); 81 } 82 } 83 84 static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) { 85 return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1; 86 } 87 88 void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) { 89 if (queuePacket(buffer) && mAssembler != NULL) { 90 mAssembler->onPacketReceived(this); 91 } 92 } 93 94 void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) { 95 mLastNTPTime = ntpTime; 96 mLastNTPTimeUpdateUs = ALooper::GetNowUs(); 97 98 sp<AMessage> notify = mNotify->dup(); 99 notify->setInt32("time-update", true); 100 notify->setInt32("rtp-time", rtpTime); 101 notify->setInt64("ntp-time", ntpTime); 102 notify->post(); 103 } 104 105 bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) { 106 uint32_t seqNum = (uint32_t)buffer->int32Data(); 107 108 if (mNumBuffersReceived++ == 0) { 109 mHighestSeqNumber = seqNum; 110 mQueue.push_back(buffer); 111 return true; 112 } 113 114 // Only the lower 16-bit of the sequence numbers are transmitted, 115 // derive the high-order bits by choosing the candidate closest 116 // to the highest sequence number (extended to 32 bits) received so far. 117 118 uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000); 119 120 // non-overflowing version of: 121 // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 122 uint32_t seq2 = seqNum | (((mHighestSeqNumber >> 16) + 1) << 16); 123 124 // non-underflowing version of: 125 // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 126 uint32_t seq3 = seqNum | ((((mHighestSeqNumber >> 16) | 0x10000) - 1) << 16); 127 128 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 129 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 130 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 131 132 if (diff1 < diff2) { 133 if (diff1 < diff3) { 134 // diff1 < diff2 ^ diff1 < diff3 135 seqNum = seq1; 136 } else { 137 // diff3 <= diff1 < diff2 138 seqNum = seq3; 139 } 140 } else if (diff2 < diff3) { 141 // diff2 <= diff1 ^ diff2 < diff3 142 seqNum = seq2; 143 } else { 144 // diff3 <= diff2 <= diff1 145 seqNum = seq3; 146 } 147 148 if (seqNum > mHighestSeqNumber) { 149 mHighestSeqNumber = seqNum; 150 } 151 152 buffer->setInt32Data(seqNum); 153 154 List<sp<ABuffer> >::iterator it = mQueue.begin(); 155 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 156 ++it; 157 } 158 159 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 160 ALOGW("Discarding duplicate buffer"); 161 return false; 162 } 163 164 mQueue.insert(it, buffer); 165 166 return true; 167 } 168 169 void ARTPSource::byeReceived() { 170 mAssembler->onByeReceived(); 171 } 172 173 void ARTPSource::addFIR(const sp<ABuffer> &buffer) { 174 if (!mIssueFIRRequests) { 175 return; 176 } 177 178 int64_t nowUs = ALooper::GetNowUs(); 179 if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) { 180 // Send FIR requests at most every 5 secs. 181 return; 182 } 183 184 mLastFIRRequestUs = nowUs; 185 186 if (buffer->size() + 20 > buffer->capacity()) { 187 ALOGW("RTCP buffer too small to accomodate FIR."); 188 return; 189 } 190 191 uint8_t *data = buffer->data() + buffer->size(); 192 193 data[0] = 0x80 | 4; 194 data[1] = 206; // PSFB 195 data[2] = 0; 196 data[3] = 4; 197 data[4] = kSourceID >> 24; 198 data[5] = (kSourceID >> 16) & 0xff; 199 data[6] = (kSourceID >> 8) & 0xff; 200 data[7] = kSourceID & 0xff; 201 202 data[8] = 0x00; // SSRC of media source (unused) 203 data[9] = 0x00; 204 data[10] = 0x00; 205 data[11] = 0x00; 206 207 data[12] = mID >> 24; 208 data[13] = (mID >> 16) & 0xff; 209 data[14] = (mID >> 8) & 0xff; 210 data[15] = mID & 0xff; 211 212 data[16] = mNextFIRSeqNo++; // Seq Nr. 213 214 data[17] = 0x00; // Reserved 215 data[18] = 0x00; 216 data[19] = 0x00; 217 218 buffer->setRange(buffer->offset(), buffer->size() + 20); 219 220 ALOGV("Added FIR request."); 221 } 222 223 void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) { 224 if (buffer->size() + 32 > buffer->capacity()) { 225 ALOGW("RTCP buffer too small to accomodate RR."); 226 return; 227 } 228 229 uint8_t *data = buffer->data() + buffer->size(); 230 231 data[0] = 0x80 | 1; 232 data[1] = 201; // RR 233 data[2] = 0; 234 data[3] = 7; 235 data[4] = kSourceID >> 24; 236 data[5] = (kSourceID >> 16) & 0xff; 237 data[6] = (kSourceID >> 8) & 0xff; 238 data[7] = kSourceID & 0xff; 239 240 data[8] = mID >> 24; 241 data[9] = (mID >> 16) & 0xff; 242 data[10] = (mID >> 8) & 0xff; 243 data[11] = mID & 0xff; 244 245 data[12] = 0x00; // fraction lost 246 247 data[13] = 0x00; // cumulative lost 248 data[14] = 0x00; 249 data[15] = 0x00; 250 251 data[16] = mHighestSeqNumber >> 24; 252 data[17] = (mHighestSeqNumber >> 16) & 0xff; 253 data[18] = (mHighestSeqNumber >> 8) & 0xff; 254 data[19] = mHighestSeqNumber & 0xff; 255 256 data[20] = 0x00; // Interarrival jitter 257 data[21] = 0x00; 258 data[22] = 0x00; 259 data[23] = 0x00; 260 261 uint32_t LSR = 0; 262 uint32_t DLSR = 0; 263 if (mLastNTPTime != 0) { 264 LSR = (mLastNTPTime >> 16) & 0xffffffff; 265 266 DLSR = (uint32_t) 267 ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6); 268 } 269 270 data[24] = LSR >> 24; 271 data[25] = (LSR >> 16) & 0xff; 272 data[26] = (LSR >> 8) & 0xff; 273 data[27] = LSR & 0xff; 274 275 data[28] = DLSR >> 24; 276 data[29] = (DLSR >> 16) & 0xff; 277 data[30] = (DLSR >> 8) & 0xff; 278 data[31] = DLSR & 0xff; 279 280 buffer->setRange(buffer->offset(), buffer->size() + 32); 281 } 282 283 } // namespace android 284 285 286