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 uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 120 uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 121 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 122 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 123 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 124 125 if (diff1 < diff2) { 126 if (diff1 < diff3) { 127 // diff1 < diff2 ^ diff1 < diff3 128 seqNum = seq1; 129 } else { 130 // diff3 <= diff1 < diff2 131 seqNum = seq3; 132 } 133 } else if (diff2 < diff3) { 134 // diff2 <= diff1 ^ diff2 < diff3 135 seqNum = seq2; 136 } else { 137 // diff3 <= diff2 <= diff1 138 seqNum = seq3; 139 } 140 141 if (seqNum > mHighestSeqNumber) { 142 mHighestSeqNumber = seqNum; 143 } 144 145 buffer->setInt32Data(seqNum); 146 147 List<sp<ABuffer> >::iterator it = mQueue.begin(); 148 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 149 ++it; 150 } 151 152 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 153 ALOGW("Discarding duplicate buffer"); 154 return false; 155 } 156 157 mQueue.insert(it, buffer); 158 159 return true; 160 } 161 162 void ARTPSource::byeReceived() { 163 mAssembler->onByeReceived(); 164 } 165 166 void ARTPSource::addFIR(const sp<ABuffer> &buffer) { 167 if (!mIssueFIRRequests) { 168 return; 169 } 170 171 int64_t nowUs = ALooper::GetNowUs(); 172 if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) { 173 // Send FIR requests at most every 5 secs. 174 return; 175 } 176 177 mLastFIRRequestUs = nowUs; 178 179 if (buffer->size() + 20 > buffer->capacity()) { 180 ALOGW("RTCP buffer too small to accomodate FIR."); 181 return; 182 } 183 184 uint8_t *data = buffer->data() + buffer->size(); 185 186 data[0] = 0x80 | 4; 187 data[1] = 206; // PSFB 188 data[2] = 0; 189 data[3] = 4; 190 data[4] = kSourceID >> 24; 191 data[5] = (kSourceID >> 16) & 0xff; 192 data[6] = (kSourceID >> 8) & 0xff; 193 data[7] = kSourceID & 0xff; 194 195 data[8] = 0x00; // SSRC of media source (unused) 196 data[9] = 0x00; 197 data[10] = 0x00; 198 data[11] = 0x00; 199 200 data[12] = mID >> 24; 201 data[13] = (mID >> 16) & 0xff; 202 data[14] = (mID >> 8) & 0xff; 203 data[15] = mID & 0xff; 204 205 data[16] = mNextFIRSeqNo++; // Seq Nr. 206 207 data[17] = 0x00; // Reserved 208 data[18] = 0x00; 209 data[19] = 0x00; 210 211 buffer->setRange(buffer->offset(), buffer->size() + 20); 212 213 ALOGV("Added FIR request."); 214 } 215 216 void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) { 217 if (buffer->size() + 32 > buffer->capacity()) { 218 ALOGW("RTCP buffer too small to accomodate RR."); 219 return; 220 } 221 222 uint8_t *data = buffer->data() + buffer->size(); 223 224 data[0] = 0x80 | 1; 225 data[1] = 201; // RR 226 data[2] = 0; 227 data[3] = 7; 228 data[4] = kSourceID >> 24; 229 data[5] = (kSourceID >> 16) & 0xff; 230 data[6] = (kSourceID >> 8) & 0xff; 231 data[7] = kSourceID & 0xff; 232 233 data[8] = mID >> 24; 234 data[9] = (mID >> 16) & 0xff; 235 data[10] = (mID >> 8) & 0xff; 236 data[11] = mID & 0xff; 237 238 data[12] = 0x00; // fraction lost 239 240 data[13] = 0x00; // cumulative lost 241 data[14] = 0x00; 242 data[15] = 0x00; 243 244 data[16] = mHighestSeqNumber >> 24; 245 data[17] = (mHighestSeqNumber >> 16) & 0xff; 246 data[18] = (mHighestSeqNumber >> 8) & 0xff; 247 data[19] = mHighestSeqNumber & 0xff; 248 249 data[20] = 0x00; // Interarrival jitter 250 data[21] = 0x00; 251 data[22] = 0x00; 252 data[23] = 0x00; 253 254 uint32_t LSR = 0; 255 uint32_t DLSR = 0; 256 if (mLastNTPTime != 0) { 257 LSR = (mLastNTPTime >> 16) & 0xffffffff; 258 259 DLSR = (uint32_t) 260 ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6); 261 } 262 263 data[24] = LSR >> 24; 264 data[25] = (LSR >> 16) & 0xff; 265 data[26] = (LSR >> 8) & 0xff; 266 data[27] = LSR & 0xff; 267 268 data[28] = DLSR >> 24; 269 data[29] = (DLSR >> 16) & 0xff; 270 data[30] = (DLSR >> 8) & 0xff; 271 data[31] = DLSR & 0xff; 272 273 buffer->setRange(buffer->offset(), buffer->size() + 32); 274 } 275 276 } // namespace android 277 278 279