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