ARTPSource.cpp revision cf7b9c7aae758ac0b99833915053c63c2ac46e09
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 "AAVCAssembler.h" 20#include "AMPEG4AudioAssembler.h" 21#include "ASessionDescription.h" 22 23#include <media/stagefright/foundation/ABuffer.h> 24#include <media/stagefright/foundation/ADebug.h> 25#include <media/stagefright/foundation/AMessage.h> 26 27#define VERBOSE 0 28 29namespace android { 30 31ARTPSource::ARTPSource( 32 uint32_t id, 33 const sp<ASessionDescription> &sessionDesc, size_t index, 34 const sp<AMessage> ¬ify) 35 : mID(id), 36 mHighestSeqNumber(0), 37 mNumBuffersReceived(0), 38 mNumTimes(0) { 39 unsigned long PT; 40 AString desc; 41 AString params; 42 sessionDesc->getFormatType(index, &PT, &desc, ¶ms); 43 44 if (!strncmp(desc.c_str(), "H264/", 5)) { 45 mAssembler = new AAVCAssembler(notify); 46 } else if (!strncmp(desc.c_str(), "MP4A-LATM", 9)) { 47 mAssembler = new AMPEG4AudioAssembler(notify); 48 } else { 49 TRESPASS(); 50 } 51} 52 53static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) { 54 return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1; 55} 56 57void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) { 58 if (queuePacket(buffer) && mNumTimes == 2 && mAssembler != NULL) { 59 mAssembler->onPacketReceived(this); 60 } 61 62 dump(); 63} 64 65void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) { 66#if VERBOSE 67 LOG(VERBOSE) << "timeUpdate"; 68#endif 69 70 if (mNumTimes == 2) { 71 mNTPTime[0] = mNTPTime[1]; 72 mRTPTime[0] = mRTPTime[1]; 73 mNumTimes = 1; 74 } 75 mNTPTime[mNumTimes] = ntpTime; 76 mRTPTime[mNumTimes++] = rtpTime; 77 78 if (mNumTimes == 2) { 79 for (List<sp<ABuffer> >::iterator it = mQueue.begin(); 80 it != mQueue.end(); ++it) { 81 sp<AMessage> meta = (*it)->meta(); 82 83 uint32_t rtpTime; 84 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 85 86 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 87 } 88 } 89} 90 91bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) { 92 uint32_t seqNum = (uint32_t)buffer->int32Data(); 93 94 if (mNumTimes == 2) { 95 sp<AMessage> meta = buffer->meta(); 96 97 uint32_t rtpTime; 98 CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime)); 99 100 meta->setInt64("ntp-time", RTP2NTP(rtpTime)); 101 } 102 103 if (mNumBuffersReceived++ == 0) { 104 mHighestSeqNumber = seqNum; 105 mQueue.push_back(buffer); 106 return true; 107 } 108 109 // Only the lower 16-bit of the sequence numbers are transmitted, 110 // derive the high-order bits by choosing the candidate closest 111 // to the highest sequence number (extended to 32 bits) received so far. 112 113 uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000); 114 uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000); 115 uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000); 116 uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber); 117 uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber); 118 uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber); 119 120 if (diff1 < diff2) { 121 if (diff1 < diff3) { 122 // diff1 < diff2 ^ diff1 < diff3 123 seqNum = seq1; 124 } else { 125 // diff3 <= diff1 < diff2 126 seqNum = seq3; 127 } 128 } else if (diff2 < diff3) { 129 // diff2 <= diff1 ^ diff2 < diff3 130 seqNum = seq2; 131 } else { 132 // diff3 <= diff2 <= diff1 133 seqNum = seq3; 134 } 135 136 if (seqNum > mHighestSeqNumber) { 137 mHighestSeqNumber = seqNum; 138 } 139 140 buffer->setInt32Data(seqNum); 141 142 List<sp<ABuffer> >::iterator it = mQueue.begin(); 143 while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) { 144 ++it; 145 } 146 147 if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) { 148 LOG(WARNING) << "Discarding duplicate buffer"; 149 return false; 150 } 151 152 mQueue.insert(it, buffer); 153 154 return true; 155} 156 157void ARTPSource::dump() const { 158 if ((mNumBuffersReceived % 128) != 0) { 159 return; 160 } 161 162#if 0 163 if (mAssembler == NULL) { 164 char tmp[20]; 165 sprintf(tmp, "0x%08x", mID); 166 167 int32_t numMissing = 0; 168 169 if (!mQueue.empty()) { 170 List<sp<ABuffer> >::const_iterator it = mQueue.begin(); 171 uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data(); 172 ++expectedSeqNum; 173 ++it; 174 175 for (; it != mQueue.end(); ++it) { 176 uint32_t seqNum = (uint32_t)(*it)->int32Data(); 177 CHECK_GE(seqNum, expectedSeqNum); 178 179 if (seqNum != expectedSeqNum) { 180 numMissing += seqNum - expectedSeqNum; 181 expectedSeqNum = seqNum; 182 } 183 184 ++expectedSeqNum; 185 } 186 } 187 188 LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing 189 << " / " << (mNumBuffersReceived + numMissing) << " packets. (" 190 << (100.0 * numMissing / (mNumBuffersReceived + numMissing)) 191 << " %%)"; 192 } 193#endif 194 195#if 0 196 AString out; 197 198 out.append(tmp); 199 out.append(" ["); 200 201 List<sp<ABuffer> >::const_iterator it = mQueue.begin(); 202 while (it != mQueue.end()) { 203 uint32_t start = (uint32_t)(*it)->int32Data(); 204 205 out.append(start); 206 207 ++it; 208 uint32_t expected = start + 1; 209 210 while (it != mQueue.end()) { 211 uint32_t seqNum = (uint32_t)(*it)->int32Data(); 212 213 if (seqNum != expected) { 214 if (expected > start + 1) { 215 out.append("-"); 216 out.append(expected - 1); 217 } 218 out.append(", "); 219 break; 220 } 221 222 ++it; 223 ++expected; 224 } 225 226 if (it == mQueue.end()) { 227 if (expected > start + 1) { 228 out.append("-"); 229 out.append(expected - 1); 230 } 231 } 232 } 233 234 out.append("]"); 235 236 LOG(VERBOSE) << out; 237#endif 238} 239 240uint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const { 241 CHECK_EQ(mNumTimes, 2u); 242 243 return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0]) 244 * ((double)rtpTime - (double)mRTPTime[0]) 245 / (double)(mRTPTime[1] - mRTPTime[0]); 246} 247 248} // namespace android 249 250 251