• Home
  • 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       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, &params);
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 
AbsDiff(uint32_t seq1,uint32_t seq2)84 static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
85     return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
86 }
87 
processRTPPacket(const sp<ABuffer> & buffer)88 void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
89     if (queuePacket(buffer) && mAssembler != NULL) {
90         mAssembler->onPacketReceived(this);
91     }
92 }
93 
timeUpdate(uint32_t rtpTime,uint64_t ntpTime)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 
queuePacket(const sp<ABuffer> & buffer)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 
byeReceived()162 void ARTPSource::byeReceived() {
163     mAssembler->onByeReceived();
164 }
165 
addFIR(const sp<ABuffer> & buffer)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 
addReceiverReport(const sp<ABuffer> & buffer)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