|
1 /* |
|
2 * Copyright (c) 2002-2003 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #include "rtprecvstream.h" |
|
22 |
|
23 |
|
24 |
|
25 // --------------------------------------------------------------------------- |
|
26 // C++ default constructor can NOT contain any code, that |
|
27 // might leave. |
|
28 // --------------------------------------------------------------------------- |
|
29 // |
|
30 CRtpRecvStream::CRtpRecvStream( MSsrcCheckCallback* aCallback, |
|
31 const TRtpPayloadType aPayloadType, |
|
32 const TRtpId aSessionId, |
|
33 const TRtpId aReceiveStreamId, |
|
34 MRtpObserver** aRtpObserver, |
|
35 MRtcpObserver* aRtcpObserver, |
|
36 const TUint32* aProfileRTPTimeRates ) |
|
37 : |
|
38 CRtpStream( aReceiveStreamId, |
|
39 aSessionId, |
|
40 aProfileRTPTimeRates, |
|
41 aRtcpObserver, |
|
42 aPayloadType ), |
|
43 iNumWrapAround( 0 ), |
|
44 iRtpObserver( aRtpObserver ), |
|
45 iCallback( aCallback ) |
|
46 { |
|
47 // set syncInfo values to zero |
|
48 RtpStreamJitterInit(); |
|
49 RtpStreamSyncInfoInit(); |
|
50 } |
|
51 |
|
52 // --------------------------------------------------------------------------- |
|
53 // Symbian 2nd phase constructor can leave. |
|
54 // --------------------------------------------------------------------------- |
|
55 // |
|
56 void CRtpRecvStream::ConstructL() |
|
57 { |
|
58 iRemoteSDES = CRtpSDES::NewL(); |
|
59 } |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // Two-phased constructor. |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 CRtpRecvStream* CRtpRecvStream::NewL( const TRtpPayloadType aPayloadType, |
|
66 const TRtpId aSessionId, |
|
67 const TRtpId aReceiveStreamId, |
|
68 MRtpObserver** aRtpObserver, |
|
69 MRtcpObserver* aRtcpObserver, |
|
70 const TUint32* aProfileRTPTimeRates, |
|
71 MSsrcCheckCallback* aCallback ) |
|
72 { |
|
73 CRtpRecvStream* self = |
|
74 new ( ELeave ) CRtpRecvStream( aCallback, |
|
75 aPayloadType, |
|
76 aSessionId, |
|
77 aReceiveStreamId, |
|
78 aRtpObserver, |
|
79 aRtcpObserver, |
|
80 aProfileRTPTimeRates ); |
|
81 CleanupStack::PushL( self ); |
|
82 self->ConstructL(); |
|
83 CleanupStack::Pop(); // self |
|
84 return self; |
|
85 } |
|
86 |
|
87 // --------------------------------------------------------------------------- |
|
88 // Destructor |
|
89 // --------------------------------------------------------------------------- |
|
90 // |
|
91 CRtpRecvStream::~CRtpRecvStream() |
|
92 { |
|
93 delete iRemoteSDES; |
|
94 } |
|
95 |
|
96 |
|
97 // --------------------------------------------------------------------------- |
|
98 // RegisterRtpObserver |
|
99 // --------------------------------------------------------------------------- |
|
100 // |
|
101 void CRtpRecvStream::RegisterRtpObserver(MRtpObserver* aRtpObserver) |
|
102 { |
|
103 *iRtpObserver = aRtpObserver; |
|
104 } |
|
105 |
|
106 |
|
107 // --------------------------------------------------------------------------- |
|
108 // UnRegisterRtpObserver |
|
109 // --------------------------------------------------------------------------- |
|
110 // |
|
111 void CRtpRecvStream::UnRegisterRtpObserver() |
|
112 { |
|
113 *iRtpObserver = NULL; |
|
114 } |
|
115 |
|
116 // --------------------------------------------------------------------------- |
|
117 // TInt CRtpRecvStream::ResetStreamStat() |
|
118 // --------------------------------------------------------------------------- |
|
119 // |
|
120 TInt CRtpRecvStream::ResetStreamStat() |
|
121 { |
|
122 TRtcpStats rtcpStat; |
|
123 |
|
124 RtcpStats( rtcpStat ); |
|
125 |
|
126 rtcpStat.iRtcpReceiverStats.iFractionLost = 0; |
|
127 rtcpStat.iRtcpReceiverStats.iCumNumPacketsLost = 0; |
|
128 rtcpStat.iRtcpReceiverStats.iSeqNumReceived = 0; |
|
129 rtcpStat.iRtcpReceiverStats.iArrivalJitter = 0; |
|
130 rtcpStat.iRtcpReceiverStats.iRoundTripDelay = 0; |
|
131 rtcpStat.iRtcpReceiverStats.iChannelBufferSize = 0; |
|
132 |
|
133 // The sender stats are updated when receiving SR packets, so reset |
|
134 rtcpStat.iRtcpSenderStats.iSSRC = 0; |
|
135 rtcpStat.iRtcpSenderStats.iCumNumOctetsSent = 0; |
|
136 rtcpStat.iRtcpSenderStats.iNumPacketsSent = 0; |
|
137 rtcpStat.iRtcpSenderStats.iNTPTimeStampSec = 0; |
|
138 rtcpStat.iRtcpSenderStats.iNTPTimeStampFrac = 0; |
|
139 rtcpStat.iRtcpSenderStats.iTimeStamp = 0; |
|
140 |
|
141 iRtcpStats = rtcpStat; |
|
142 |
|
143 iNumReceivedPackets = 0; |
|
144 iNumWrapAround = 0; |
|
145 |
|
146 // set syncInfo values to zero |
|
147 RtpStreamJitterInit(); |
|
148 RtpStreamSyncInfoInit(); |
|
149 |
|
150 return KErrNone; |
|
151 } |
|
152 |
|
153 // --------------------------------------------------------------------------- |
|
154 // TInt CRtpTranStream::GetStreamStat() |
|
155 // |
|
156 // --------------------------------------------------------------------------- |
|
157 // |
|
158 TInt CRtpRecvStream::GetStreamStat( TRtpPeerStat& aStat ) |
|
159 { |
|
160 TRtcpStats rtcpStat; |
|
161 |
|
162 RtcpStats( rtcpStat ); |
|
163 |
|
164 aStat.iCumNumOctetsSent = rtcpStat.iRtcpSenderStats.iCumNumOctetsSent; |
|
165 aStat.iNumPacketsSent = rtcpStat.iRtcpSenderStats.iNumPacketsSent; |
|
166 |
|
167 aStat.iTxBandwidth = rtcpStat.iRtcpReceiverStats.iTxBandwidth; |
|
168 aStat.iArrivalJitter = rtcpStat.iRtcpReceiverStats.iArrivalJitter; |
|
169 aStat.iCumNumPacketsLost = rtcpStat.iRtcpReceiverStats.iCumNumPacketsLost; |
|
170 aStat.iFractionLost = rtcpStat.iRtcpReceiverStats.iFractionLost; |
|
171 aStat.iRoundTripDelay = rtcpStat.iRtcpReceiverStats.iRoundTripDelay; |
|
172 aStat.iRxBandwidth = rtcpStat.iRtcpReceiverStats.iBandwidth; |
|
173 aStat.iChannelBufferSize = rtcpStat.iRtcpReceiverStats.iChannelBufferSize; |
|
174 aStat.iNTPTimeStampSec = 0; |
|
175 aStat.iNTPTimeStampFrac = 0; |
|
176 aStat.iTimeStamp = 0; |
|
177 |
|
178 return KErrNone; |
|
179 } |
|
180 |
|
181 // --------------------------------------------------------------------------- |
|
182 // TInt CRtpRecvStream::RtpStreamProcessRtpPacketL() |
|
183 // |
|
184 // --------------------------------------------------------------------------- |
|
185 // |
|
186 TInt CRtpRecvStream::RtpStreamProcessRtpPacketL( CRtpPacket* aPktRcv, TBool aAssignStream ) |
|
187 { |
|
188 RTP_DEBUG_DETAIL( "CRtpRecvStream::RtpStreamProcessRtpPacketL Entry" ); |
|
189 aPktRcv->RtpPacketResetPtr(); |
|
190 |
|
191 // Check if this packet belongs to this stream by looking at the source SSRC |
|
192 if ( !aAssignStream ) |
|
193 { |
|
194 TRtpSSRC aRemoteSSRC( NULL ); |
|
195 aPktRcv->SetType( ERTP ); |
|
196 aRemoteSSRC = aPktRcv->RtpPacketGetSSRC(); |
|
197 if ( iRemoteSSRC != aRemoteSSRC ) |
|
198 { |
|
199 RTP_DEBUG_DETAIL( "RtpRecvStream: Wrong SSRC" ); |
|
200 return KErrNotFound; |
|
201 } |
|
202 } |
|
203 else |
|
204 { |
|
205 //assigned RTP packet SSRC if this stream's remote SSRC is NULL |
|
206 // if it is not null then return KErrNotFound |
|
207 if ( iRemoteSSRC ) |
|
208 { |
|
209 RTP_DEBUG_DETAIL( "RtpRecvStream: Did not expect own SSRC" ); |
|
210 return KErrNotFound; |
|
211 } |
|
212 } |
|
213 |
|
214 TRtpPacketStreamParam streamParam; |
|
215 TRtpPacketIOParam extractParam; |
|
216 |
|
217 // process RTP packet |
|
218 aPktRcv->SetType( ERTP ); |
|
219 |
|
220 extractParam.TRTP.extension.data = NULL; |
|
221 |
|
222 if ( aPktRcv->RtpPacketProcessL( &streamParam, &extractParam ) < 0 ) |
|
223 { |
|
224 RTP_DEBUG_DETAIL( "Invalid Rtp packet is received" ); |
|
225 return KErrCorrupt; |
|
226 } |
|
227 if (!iCallback->CheckRemoteAddr()) |
|
228 { |
|
229 RTP_DEBUG_DETAIL( "Packet comes from wrong remote address" ); |
|
230 return KErrNotFound; |
|
231 } |
|
232 // update and check stream parameters |
|
233 if ( RtpStreamUpdateParamL( aPktRcv->Type(), &streamParam ) < 0 ) |
|
234 { |
|
235 |
|
236 RTP_DEBUG_PACKET("RtpRecvStream: Could not update params" ); |
|
237 |
|
238 return KErrNotFound; |
|
239 } |
|
240 |
|
241 iHdr.iPadding = extractParam.TRTP.padding; |
|
242 iHdr.iExtension = extractParam.TRTP.fHeaderExtension; |
|
243 iHdr.iCsrcCount = extractParam.TRTP.numCSRC; |
|
244 |
|
245 iHdr.iMarker = extractParam.TRTP.marker; |
|
246 iHdr.iTimestamp = streamParam.TRTP.timeStamp; |
|
247 iHdr.iPayloadType = streamParam.TRTP.payload; // iPayload; pass payload type to app,even if it changed |
|
248 |
|
249 if ( iHdr.iExtension ) |
|
250 { |
|
251 iHdr.iHeaderExtension = &iHeaderExtension; |
|
252 iHdr.iHeaderExtension->iType = extractParam.TRTP.extension.type; |
|
253 iHdr.iHeaderExtension->iLength = extractParam.TRTP.extension.length; |
|
254 iHdr.iHeaderExtension->iData = extractParam.TRTP.extension.data; |
|
255 } |
|
256 |
|
257 iFlagReceivedRTPPackets = ETrue; |
|
258 |
|
259 // calculate jitter, maybe it eats a big portion of CPU time? |
|
260 RtpStreamUpdateJitter( iHdr.iTimestamp ); |
|
261 |
|
262 iHdr.iSeqNum = streamParam.TRTP.seqNum; |
|
263 |
|
264 RTP_DEBUG_DETAIL_DVALUE( "The received RTP packet size = ", extractParam.TRTP.payloadDataLen ); |
|
265 RTP_DEBUG_DETAIL_DVALUE( "The received RTP packet Seq Num = ", streamParam.TRTP.seqNum ); |
|
266 |
|
267 TPtrC8 payloadData( extractParam.TRTP.payloadData, extractParam.TRTP.payloadDataLen ); |
|
268 |
|
269 if ( *iRtpObserver ) |
|
270 { |
|
271 RTP_DEBUG_PACKET("RTP packet received and pass to upper application" ); |
|
272 |
|
273 (*iRtpObserver)->RtpPacketReceived( iStreamId, iHdr, payloadData ); |
|
274 } |
|
275 else |
|
276 { |
|
277 RTP_DEBUG_PACKET( "RtpRecvStream: No observer registered" ); |
|
278 } |
|
279 if(aPktRcv->iExdataAlloc ) |
|
280 { |
|
281 User::Free( extractParam.TRTP.extension.data ); |
|
282 } |
|
283 if (aPktRcv->iCsrcAlloc) |
|
284 { |
|
285 User::Free( extractParam.TRTP.CSRCarray); |
|
286 } |
|
287 RTP_DEBUG_DETAIL( "CRtpRecvStream::RtpStreamProcessRtpPacketL Exit" ); |
|
288 |
|
289 return KErrNone; |
|
290 } |
|
291 |
|
292 |
|
293 |
|
294 // --------------------------------------------------------------------------- |
|
295 // CRtpRecvStream::RtpStreamSyncInfoInit() |
|
296 // For receiving stream, iSyncInfo is initialized to zero |
|
297 // and will be updated by SR received for the future RR creating |
|
298 // iSyncInfo.timeStamp & iSyncInfo.lastUpdateLocalTime are |
|
299 // not useful actually. |
|
300 // --------------------------------------------------------------------------- |
|
301 // |
|
302 void CRtpRecvStream::RtpStreamSyncInfoInit() |
|
303 { |
|
304 iSyncInfo.iNTPTimeStampFrac = 0; |
|
305 iSyncInfo.iNTPTimeStampSec = 0; |
|
306 iSyncInfo.iTimeStamp = 0; |
|
307 iSyncInfo.iLastUpdateLocalTime = 0; |
|
308 } |
|
309 |
|
310 // --------------------------------------------------------------------------- |
|
311 // CRtpRecvStream::RtpStreamJitterInit() |
|
312 // |
|
313 // --------------------------------------------------------------------------- |
|
314 // |
|
315 void CRtpRecvStream::RtpStreamJitterInit() |
|
316 { |
|
317 iSyncJitter.iLastPacketS = 0; |
|
318 iSyncJitter.iLastPacketR = 0; |
|
319 iSyncJitter.iJitterTime = 0; |
|
320 |
|
321 iSyncJitter.iWaitTime = 0; |
|
322 } |
|
323 |
|
324 // --------------------------------------------------------------------------- |
|
325 // CRtpRecvStream::RtpStreamUpdateJitter() |
|
326 // |
|
327 // --------------------------------------------------------------------------- |
|
328 // |
|
329 void CRtpRecvStream::RtpStreamUpdateJitter( TRtpTimeStamp aCurrentTimeStamp ) |
|
330 { |
|
331 TUint32 gtTime = TRtpUtil::GtGetTime(); |
|
332 TRtpTimeStamp packetRTP( aCurrentTimeStamp ); |
|
333 TInt jitterTime = 0; |
|
334 |
|
335 if ( packetRTP == iSyncJitter.iLastPacketS ) |
|
336 { |
|
337 return; |
|
338 } |
|
339 |
|
340 jitterTime = ( ( ( gtTime - iSyncJitter.iLastPacketR ) * iSyncJitter.iTimeStampResolution ) |
|
341 / KTenthOfmsPerSecond ) - ( packetRTP - iSyncJitter.iLastPacketS ); |
|
342 |
|
343 iSyncJitter.iJitterTime = iSyncJitter.iJitterTime + |
|
344 ( ( ( TReal64 ) Abs( jitterTime ) - iSyncJitter.iJitterTime ) / 16.0 ); |
|
345 |
|
346 // if jitter > 100 seconds, reset it. |
|
347 if ( iSyncJitter.iJitterTime > 1000000 ) // 100 * KTenthOfmsPerSecond |
|
348 { |
|
349 iSyncJitter.iJitterTime = 0; |
|
350 } |
|
351 iSyncJitter.iLastPacketR = gtTime; |
|
352 iSyncJitter.iLastPacketS = packetRTP; |
|
353 } |
|
354 |
|
355 // --------------------------------------------------------------------------- |
|
356 // TInt CRtpRecvStream::RtpStreamUpdateParamL() |
|
357 // |
|
358 // --------------------------------------------------------------------------- |
|
359 // |
|
360 TInt CRtpRecvStream::RtpStreamUpdateParamL( TRtpPacketType aPType, |
|
361 TRtpPacketStreamParam* aStreamParam ) |
|
362 { |
|
363 TUint32 timerate; |
|
364 TInt error( KErrNone ); |
|
365 |
|
366 if ( aPType == ERTP ) |
|
367 { |
|
368 // Check if there is an SSRC collision |
|
369 if ( iCallback ) |
|
370 { |
|
371 error = iCallback->CheckRemoteSsrcL( aStreamParam->TRTP.SSRC ); |
|
372 } |
|
373 if ( error < KErrNone ) |
|
374 { |
|
375 return KErrCorrupt; |
|
376 } |
|
377 if ( error > KErrNone ) |
|
378 { |
|
379 // There was an SSRC collision, and TRTP.SSRC now contains the |
|
380 // updated SSRC value. |
|
381 iRemoteSSRC = aStreamParam->TRTP.SSRC; |
|
382 } |
|
383 |
|
384 if ( iFlagFirstPkg ) |
|
385 { |
|
386 iRemoteSSRC = aStreamParam->TRTP.SSRC; |
|
387 iPayload = aStreamParam->TRTP.payload; |
|
388 iBaseSeqNum = aStreamParam->TRTP.seqNum; |
|
389 |
|
390 timerate = *( iProfileRTPTimeRates + iPayload ); |
|
391 if ( timerate != 0 ) |
|
392 { |
|
393 iSyncJitter.iTimeStampResolution = KMicrosecondPerSecond / timerate; |
|
394 } |
|
395 else |
|
396 { |
|
397 iSyncJitter.iTimeStampResolution = 0; |
|
398 } |
|
399 } |
|
400 else if ( iRemoteSSRC != aStreamParam->TRTP.SSRC ) |
|
401 { |
|
402 // SSRC and seqNum change. start monitoring if this change is intentional, |
|
403 // if several packets received sequentionally, and then re-initialize the stream |
|
404 |
|
405 RTP_DEBUG_DETAIL( "SSRC changed" ); |
|
406 |
|
407 |
|
408 return KErrNotFound; |
|
409 } |
|
410 else |
|
411 { |
|
412 if ( iPayload != aStreamParam->TRTP.payload ) |
|
413 { |
|
414 // payload type changed, inform application somehow |
|
415 RTP_DEBUG_DETAIL( "payload type changed" ); |
|
416 |
|
417 } |
|
418 } |
|
419 |
|
420 if ( aStreamParam->TRTP.seqNum == TRtpUtil::Min16( aStreamParam->TRTP.seqNum, iSeqNum ) && !iFlagFirstPkg ) |
|
421 { |
|
422 // if there is no buffering, out of order and duplicate packets |
|
423 // have to be discarded |
|
424 return KErrNone; // give this packet to the application as there is no buffer in RTP |
|
425 } |
|
426 else |
|
427 { |
|
428 //update the highest received SN and TS |
|
429 if ( TRtpUtil::Wrap16( iSeqNum, aStreamParam->TRTP.seqNum ) && !iFlagFirstPkg ) |
|
430 { |
|
431 iSeqNumCycles++; |
|
432 } |
|
433 iSeqNum = aStreamParam->TRTP.seqNum; |
|
434 iTimeStamp = aStreamParam->TRTP.timeStamp; |
|
435 iFlagFirstPkg = 0; |
|
436 iNumReceivedPackets++; |
|
437 } |
|
438 } |
|
439 else |
|
440 { |
|
441 return KErrNotFound; |
|
442 } |
|
443 |
|
444 return KErrNone; |
|
445 } |
|
446 |
|
447 |
|
448 // --------------------------------------------------------------------------- |
|
449 // CRtpRecvStream::RtpStreamCreateRtcpReportSection() |
|
450 // For receiving stream, it only creates RR packet |
|
451 // --------------------------------------------------------------------------- |
|
452 // |
|
453 void CRtpRecvStream::RtpStreamCreateRtcpReportSection( CRtpPacket* aPkt ) |
|
454 { |
|
455 TRtpPacketStreamParam streamParam; |
|
456 TRtpPacketIOParam inParam; |
|
457 |
|
458 TUint32 numPacketsExpected; |
|
459 TUint32 numPacketsIntervalLost; |
|
460 TUint32 numPacketsIntervalExpected; |
|
461 |
|
462 streamParam.TRTCP_RR.SSRC = iRemoteSSRC; |
|
463 |
|
464 // iSeqNum is 16 bit, but streamParam.TRTCP_RR.seqNumReceived is 32 bits. |
|
465 // Check RFC1889 for RTCP part |
|
466 |
|
467 streamParam.TRTCP_RR.seqNumReceived = iSeqNum + ( iSeqNumCycles << 16 ); |
|
468 numPacketsExpected = streamParam.TRTCP_RR.seqNumReceived - iBaseSeqNum + 1; |
|
469 |
|
470 if ( numPacketsExpected < iNumReceivedPackets ) |
|
471 { |
|
472 streamParam.TRTCP_RR.cumNumPacketsLost = 0; |
|
473 } |
|
474 else |
|
475 { |
|
476 if ( ( numPacketsExpected + ( 1 << 16 ) * iNumWrapAround ) < iLastRR_numExpectedPackets ) |
|
477 { |
|
478 iNumWrapAround++; |
|
479 numPacketsExpected += ( 1 << 16 ) * iNumWrapAround; |
|
480 } |
|
481 else |
|
482 { |
|
483 numPacketsExpected += ( 1 << 16 ) * iNumWrapAround; |
|
484 } |
|
485 streamParam.TRTCP_RR.cumNumPacketsLost = numPacketsExpected - iNumReceivedPackets; |
|
486 } |
|
487 |
|
488 numPacketsIntervalExpected = numPacketsExpected - iLastRR_numExpectedPackets; |
|
489 numPacketsIntervalLost = numPacketsIntervalExpected - ( iNumReceivedPackets - iLastRR_numReceivedPackets ); |
|
490 |
|
491 // |
|
492 // From RFC 1889 |
|
493 // fraction lost: 8 bits |
|
494 // The fraction of RTP data packets from source SSRC_n lost since the previous SR or RR packet was sent, |
|
495 // expressed as a fixed point number with the binary point at the left edge of the field. (That is |
|
496 // equivalent to taking the integer part after multiplying the loss fraction by 256.) This fraction is |
|
497 // defined to be the number of packets lost divided by the number of packets expected. |
|
498 // |
|
499 |
|
500 if ( ( numPacketsIntervalExpected == 0 ) || ( numPacketsIntervalLost == 0 ) ) |
|
501 { |
|
502 streamParam.TRTCP_RR.fractionLost = 0; |
|
503 } |
|
504 else |
|
505 { |
|
506 streamParam.TRTCP_RR.fractionLost = static_cast<TUint8>( |
|
507 ( numPacketsIntervalLost << 8 ) / numPacketsIntervalExpected ); |
|
508 } |
|
509 |
|
510 iLastRR_numReceivedPackets = iNumReceivedPackets; |
|
511 iLastRR_numExpectedPackets = numPacketsExpected; |
|
512 |
|
513 streamParam.TRTCP_RR.arrivalJitter = static_cast<TUint32>( iSyncJitter.iJitterTime ); |
|
514 |
|
515 // add receiver statistics to sender of SR packet |
|
516 iRtcpStats.iRtcpReceiverStats.iRoundTripDelay = 0; |
|
517 iRtcpStats.iRtcpReceiverStats.iFractionLost = streamParam.TRTCP_RR.fractionLost; |
|
518 iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost = streamParam.TRTCP_RR.cumNumPacketsLost; |
|
519 iRtcpStats.iRtcpReceiverStats.iSeqNumReceived = streamParam.TRTCP_RR.seqNumReceived; |
|
520 iRtcpStats.iRtcpReceiverStats.iBandwidth = 0; |
|
521 iRtcpStats.iRtcpReceiverStats.iChannelBufferSize = 0; |
|
522 |
|
523 if ( iSyncJitter.iTimeStampResolution > 0 ) |
|
524 { |
|
525 iRtcpStats.iRtcpReceiverStats.iArrivalJitter = ( streamParam.TRTCP_RR.arrivalJitter * KTenthOfmsPerSecond ) / |
|
526 iSyncJitter.iTimeStampResolution; |
|
527 } |
|
528 else |
|
529 { |
|
530 iRtcpStats.iRtcpReceiverStats.iArrivalJitter = 0; |
|
531 } |
|
532 |
|
533 iRtcpStats.iRtcpReceiverStats.iSSRC = streamParam.TRTCP_RR.SSRC; // SSRC sender (coming source) |
|
534 |
|
535 |
|
536 RTP_DEBUG_STAT( "----- RX: Create RTCP Report Statistics -----" ); |
|
537 RTP_DEBUG_STAT_DVALUE( "RX: roundTripDelay = ", iRtcpStats.iRtcpReceiverStats.iRoundTripDelay ); |
|
538 RTP_DEBUG_STAT_DVALUE( "RX: fractionLost = ", (TInt)iRtcpStats.iRtcpReceiverStats.iFractionLost ); |
|
539 RTP_DEBUG_STAT_DVALUE( "RX: cumNumPacketsLost = ", iRtcpStats.iRtcpReceiverStats.iCumNumPacketsLost ); |
|
540 RTP_DEBUG_STAT_DVALUE( "RX: seqNumReceived = ", iRtcpStats.iRtcpReceiverStats.iSeqNumReceived ); |
|
541 RTP_DEBUG_STAT_DVALUE( "RX: bandwidth = ", iRtcpStats.iRtcpReceiverStats.iBandwidth ); |
|
542 RTP_DEBUG_STAT_DVALUE( "RX: channelBufferSize = ", iRtcpStats.iRtcpReceiverStats.iChannelBufferSize ); |
|
543 RTP_DEBUG_STAT_DVALUE( "RX: arrivalJitter = ", iRtcpStats.iRtcpReceiverStats.iArrivalJitter ); |
|
544 RTP_DEBUG_STAT_DVALUE( "RX: SSRC (Tx) = ", iRtcpStats.iRtcpReceiverStats.iSSRC ); |
|
545 |
|
546 TUint32 gtTime = TRtpUtil::GtGetTime(); |
|
547 // lastSRTimeStamp: use the middle 32 bits of the 64-bit NTP timestamp |
|
548 // This results in value where the 16-MSB is the amount of seconds, and |
|
549 // the 16-LSB is the fraction of seconds (in tenths of milliseconds). |
|
550 // See RFC3550 page 34 for details. |
|
551 inParam.TRTCP_RR.lastSRTimeStamp = ( iSyncInfo.iNTPTimeStampSec << 16 ) + ( iSyncInfo.iNTPTimeStampFrac >> 16 ); |
|
552 inParam.TRTCP_RR.delaySinceLSR = |
|
553 ( static_cast<TUint32>( ( gtTime - iSyncInfo.iLastUpdateLocalTime ) / KTenthOfmsPerSecond ) << 16 ); |
|
554 inParam.TRTCP_RR.delaySinceLSR += |
|
555 ( ( ( ( TUint32 ) ( ( gtTime - iSyncInfo.iLastUpdateLocalTime ) % KTenthOfmsPerSecond ) ) << 16 ) / KTenthOfmsPerSecond ); |
|
556 |
|
557 // For receiving stream, it only generates RR packet. |
|
558 aPkt->SetType( ERTCP_RR ); |
|
559 aPkt->RtpPacketBuild( &streamParam, &inParam ); |
|
560 } |
|
561 |
|
562 |
|
563 // --------------------------------------------------------------------------- |
|
564 // TRtpRtcpEnum CRtpRecvStream::RtpStreamProcessRtcpReportSectionL() |
|
565 // For receiving stream, it only process SR packet |
|
566 // --------------------------------------------------------------------------- |
|
567 // |
|
568 TRtpRtcpEnum CRtpRecvStream::RtpStreamProcessRtcpReportSectionL( CRtpPacket* aPkt ) |
|
569 { |
|
570 TRtpPacketStreamParam streamParam; |
|
571 TRtpPacketIOParam extractParam; |
|
572 TRtpRtcpEnum parseResult = ERTCP_NO_ERROR; |
|
573 TUint32 gtTime = TRtpUtil::GtGetTime(); |
|
574 |
|
575 parseResult = aPkt->RtpPacketProcessL( &streamParam, &extractParam ); |
|
576 if ( parseResult < 0 ) |
|
577 { |
|
578 return ERTCP_PACKET_ERROR; |
|
579 } |
|
580 |
|
581 // For receiving stream, it only processes SR packet. |
|
582 if ( aPkt->Type() == ERTCP_SR ) |
|
583 { |
|
584 // give this information to receiver on RTCP callback |
|
585 iSyncInfo.iLastUpdateLocalTime = gtTime; |
|
586 iSyncInfo.iNTPTimeStampSec = extractParam.TRTCP_SR.NTPTimeStampSec; |
|
587 iSyncInfo.iNTPTimeStampFrac = extractParam.TRTCP_SR.NTPTimeStampFrac; |
|
588 iSyncInfo.iTimeStamp = extractParam.TRTCP_SR.timeStamp; |
|
589 |
|
590 // do something with numPacketsSent and cumNumOctetsSent |
|
591 iRtcpStats.iRtcpSenderStats.iSSRC = streamParam.TRTCP_SR.SSRC; |
|
592 iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent = streamParam.TRTCP_SR.cumNumOctetsSent; |
|
593 iRtcpStats.iRtcpSenderStats.iNumPacketsSent = streamParam.TRTCP_SR.numPacketsSent; |
|
594 iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec = iSyncInfo.iNTPTimeStampSec; |
|
595 iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac = iSyncInfo.iNTPTimeStampFrac; |
|
596 iRtcpStats.iRtcpSenderStats.iTimeStamp = iSyncInfo.iTimeStamp; |
|
597 |
|
598 |
|
599 RTP_DEBUG_STAT( "----- RX: Process RTCP Report Statistics -----" ); |
|
600 RTP_DEBUG_STAT_DVALUE( "RX: cumNumOctetsSent = ", iRtcpStats.iRtcpSenderStats.iCumNumOctetsSent ); |
|
601 RTP_DEBUG_STAT_DVALUE( "RX: numPacketsSent = ", iRtcpStats.iRtcpSenderStats.iNumPacketsSent ); |
|
602 RTP_DEBUG_STAT_DVALUE( "RX: SSRC (Tx) = ", iRtcpStats.iRtcpSenderStats.iSSRC ); |
|
603 RTP_DEBUG_STAT_DVALUE( "RX: NTPTimeStampSec = ", iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec ); |
|
604 RTP_DEBUG_STAT_DVALUE( "RX: NTPTimeStampFrac = ", iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac ); |
|
605 RTP_DEBUG_STAT_DVALUE( "RX: timeStamp = ", iRtcpStats.iRtcpSenderStats.iTimeStamp ); |
|
606 |
|
607 |
|
608 TTimeStamps timeStamps; |
|
609 timeStamps.iNTPTimeStampFrac = iRtcpStats.iRtcpSenderStats.iNTPTimeStampFrac; |
|
610 timeStamps.iNTPTimeStampSec = iRtcpStats.iRtcpSenderStats.iNTPTimeStampSec; |
|
611 timeStamps.iTimeStamp = iRtcpStats.iRtcpSenderStats.iTimeStamp; |
|
612 |
|
613 if ( iRtcpObserver ) |
|
614 { |
|
615 iRtcpObserver->SrReceived( iStreamId, iRtcpStats.iRtcpSenderStats.iSSRC, timeStamps ); |
|
616 } |
|
617 } |
|
618 else |
|
619 { |
|
620 // the received report can not be associated with the stream |
|
621 return ERTCP_PACKET_ERROR; |
|
622 } |
|
623 |
|
624 return parseResult; |
|
625 } |
|
626 |
|
627 // --------------------------------------------------------------------------- |
|
628 // TInt CRtpRecvStream::GetRemoteStreamInfo() |
|
629 // |
|
630 // --------------------------------------------------------------------------- |
|
631 // |
|
632 TInt CRtpRecvStream::GetRemoteStreamInfo( TRtpSdesParams& aSdes ) |
|
633 { |
|
634 iRemoteSDES->GetSDES( aSdes ); |
|
635 return KErrNone; |
|
636 } |
|
637 |
|
638 // --------------------------------------------------------------------------- |
|
639 // TInt CRtpRecvStream::SetReceivedRTPPackets() |
|
640 // |
|
641 // --------------------------------------------------------------------------- |
|
642 // |
|
643 void CRtpRecvStream::SetReceivedRTPPackets( TBool aFlag ) |
|
644 { |
|
645 iFlagReceivedRTPPackets = aFlag; |
|
646 }; |
|
647 |
|
648 |
|
649 // --------------------------------------------------------------------------- |
|
650 // TInt CRtpRecvStream::ReceivedRTPPackets() |
|
651 // |
|
652 // --------------------------------------------------------------------------- |
|
653 // |
|
654 TBool CRtpRecvStream::ReceivedRTPPackets() const |
|
655 { |
|
656 return iFlagReceivedRTPPackets; |
|
657 }; |
|
658 |
|
659 // --------------------------------------------------------------------------- |
|
660 // TInt CRtpRecvStream::GetRemoteSSRC() |
|
661 // |
|
662 // --------------------------------------------------------------------------- |
|
663 // |
|
664 TRtpSSRC CRtpRecvStream::GetRemoteSSRC() |
|
665 { |
|
666 return iRemoteSSRC; |
|
667 } |
|
668 |
|
669 |