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