|
1 /* |
|
2 * Copyright (c) 2002-2004 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: RTP Datasink |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include "mccrtpsender.h" |
|
23 #include "mccrtpdefs.h" |
|
24 #include "mcctimermanager.h" |
|
25 |
|
26 // CONSTANTS |
|
27 const TInt KMccMaxSendQueueSize = 30; |
|
28 const TUint32 KMccRtpSendTimeoutLongMillisecs = 600; |
|
29 |
|
30 |
|
31 // ----------------------------------------------------------------------------- |
|
32 // CMccRtpSender::NewL |
|
33 // ----------------------------------------------------------------------------- |
|
34 // |
|
35 CMccRtpSender* CMccRtpSender::NewL( |
|
36 MMccRtpSenderObserver& aObserver, |
|
37 CRtpAPI& aRtpApi, |
|
38 TRtpId aSessionId, |
|
39 TBool aDoMarkerBasedCleanup ) |
|
40 { |
|
41 TRACE_RTP_SINK_PRINT( "CMccRtpSender::NewL, entry" ) |
|
42 |
|
43 CMccRtpSender* self = |
|
44 new ( ELeave ) CMccRtpSender( |
|
45 aObserver, aRtpApi, aSessionId, aDoMarkerBasedCleanup ); |
|
46 CleanupStack::PushL( self ); |
|
47 self->ConstructL(); |
|
48 CleanupStack::Pop( self ); |
|
49 |
|
50 TRACE_RTP_SINK_PRINT( "CMccRtpSender::NewL, exit" ) |
|
51 |
|
52 return self; |
|
53 } |
|
54 |
|
55 // ----------------------------------------------------------------------------- |
|
56 // CMccRtpSender::~CMccRtpSender |
|
57 // ----------------------------------------------------------------------------- |
|
58 // |
|
59 CMccRtpSender::~CMccRtpSender() |
|
60 { |
|
61 TRACE_RTP_SINK_PRINT( "CMccRtpSender::~CMccRtpSender, entry" ) |
|
62 |
|
63 Cancel(); |
|
64 delete iTimeoutTimer; |
|
65 |
|
66 iSendQueue.ResetAndDestroy(); |
|
67 |
|
68 TRACE_RTP_SINK_PRINT( "CMccRtpSender::~CMccRtpSender, exit" ) |
|
69 } |
|
70 |
|
71 // ----------------------------------------------------------------------------- |
|
72 // CMccRtpSender::SendRtpPacketL |
|
73 // ----------------------------------------------------------------------------- |
|
74 // |
|
75 void CMccRtpSender::SendRtpPacketL( |
|
76 TRtpId aRtpStreamId, |
|
77 const TRtpSendHeader& aRtpHeader, |
|
78 const TDesC8& aData ) |
|
79 { |
|
80 TInt count( iSendQueue.Count() ); |
|
81 |
|
82 if ( CheckDiscarding( aRtpHeader ) ) |
|
83 { |
|
84 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::SendRtpPacketL [%d], packet dropped 1", |
|
85 reinterpret_cast<TUint32>( this ) ) |
|
86 return; |
|
87 } |
|
88 |
|
89 if ( count >= KMccMaxSendQueueSize ) |
|
90 { |
|
91 // Full, frame must be dropped. Check also if there's already in queue |
|
92 // rtp packets which contain parts of the same frame. In that case, |
|
93 // those can be also dropped as the frame is useless if something is |
|
94 // missing from it. |
|
95 DoQueueCleanup( count - 1, aRtpHeader ); |
|
96 |
|
97 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::SendRtpPacketL [%d], packet dropped 2", |
|
98 reinterpret_cast<TUint32>( this ) ) |
|
99 return; |
|
100 } |
|
101 |
|
102 TRACE_RTP_SINK_PRINT3( "CMccRtpSender::SendRtpPacketL [%d], items in queue:%d", |
|
103 reinterpret_cast<TUint32>( this ), count ) |
|
104 |
|
105 CMccRtpSendItem* sendItem = |
|
106 CMccRtpSendItem::NewLC( aRtpStreamId, aRtpHeader, aData ); |
|
107 iSendQueue.AppendL( sendItem ); |
|
108 CleanupStack::Pop( sendItem ); |
|
109 |
|
110 if ( !IsActive() ) |
|
111 { |
|
112 SendPacketL(); |
|
113 } |
|
114 } |
|
115 |
|
116 // ----------------------------------------------------------------------------- |
|
117 // CMccRtpSender::SendDataL |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 void CMccRtpSender::SendDataL( TRtpId aSessionId, TBool aUseRtpSocket, |
|
121 const TDesC8& aData ) |
|
122 { |
|
123 if ( KMccMaxSendQueueSize <= iSendQueue.Count() ) |
|
124 { |
|
125 TRACE_RTP_SINK_PRINT2( |
|
126 "CMccRtpSender::SendDataL [%d], queue full, leaving", |
|
127 reinterpret_cast<TUint32>( this ) ) |
|
128 User::Leave( KErrOverflow ); |
|
129 } |
|
130 else |
|
131 { |
|
132 TRACE_RTP_SINK_PRINT3( |
|
133 "CMccRtpSender::SendDataL [%d], items in queue: %d", |
|
134 reinterpret_cast<TUint32>( this ), iSendQueue.Count() ) |
|
135 |
|
136 CMccRtpSendItem* sendItem = |
|
137 CMccRtpSendItem::NewLC( aSessionId, aUseRtpSocket, aData ); |
|
138 iSendQueue.AppendL( sendItem ); |
|
139 CleanupStack::Pop( sendItem ); |
|
140 |
|
141 if ( !IsActive() ) |
|
142 { |
|
143 SendPacketL(); |
|
144 } |
|
145 } |
|
146 } |
|
147 |
|
148 // ----------------------------------------------------------------------------- |
|
149 // CMccRtpSender::Clear |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 void CMccRtpSender::Clear() |
|
153 { |
|
154 TRACE_RTP_SINK_PRINT( "CMccRtpSender::Clear, entry" ) |
|
155 |
|
156 Cancel(); |
|
157 iSendQueue.ResetAndDestroy(); |
|
158 |
|
159 iDiscarding = EFalse; |
|
160 |
|
161 TRACE_RTP_SINK_PRINT( "CMccRtpSender::Clear, exit" ) |
|
162 } |
|
163 |
|
164 // ----------------------------------------------------------------------------- |
|
165 // CMccRtpSender::RunL |
|
166 // ----------------------------------------------------------------------------- |
|
167 // |
|
168 void CMccRtpSender::RunL() |
|
169 { |
|
170 TInt status = iStatus.Int(); |
|
171 |
|
172 TRACE_RTP_SINK_PRINT3( "CMccRtpSender::RunL [%d], status:%d", |
|
173 reinterpret_cast<TUint32>( this ), status ) |
|
174 |
|
175 RemovePacket(); |
|
176 |
|
177 if ( !ErrorReport( status ) ) |
|
178 { |
|
179 SendPacketL(); |
|
180 } |
|
181 |
|
182 TRACE_RTP_SINK_PRINT( "CMccRtpSender::RunL, exit" ) |
|
183 } |
|
184 |
|
185 // ----------------------------------------------------------------------------- |
|
186 // CMccRtpSender::DoCancel |
|
187 // ----------------------------------------------------------------------------- |
|
188 // |
|
189 void CMccRtpSender::DoCancel() |
|
190 { |
|
191 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoCancel, entry" ) |
|
192 |
|
193 iRtpApi.CancelSend( iSessionId ); |
|
194 iTimeoutTimer->Stop( iTimerId ); |
|
195 |
|
196 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoCancel, exit" ) |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CMccRtpSender::RunError |
|
201 // ----------------------------------------------------------------------------- |
|
202 // |
|
203 TInt CMccRtpSender::RunError( TInt aError ) |
|
204 { |
|
205 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::RunError, err:%d", aError ) |
|
206 |
|
207 ErrorReport( aError ); |
|
208 |
|
209 if ( aError != KErrNoMemory ) |
|
210 { |
|
211 aError = KErrNone; |
|
212 } |
|
213 |
|
214 return aError; |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CMccRtpSender::InactivityTimeout |
|
219 // ----------------------------------------------------------------------------- |
|
220 // |
|
221 void CMccRtpSender::TimerExpiredL( |
|
222 TMccTimerId /*aTimerId*/, TAny* /*aTimerParam*/ ) |
|
223 { |
|
224 TRACE_RTP_SINK_PRINT( "CMccRtpSender::TimerExpiredL, entry" ) |
|
225 |
|
226 if ( iTimeoutTimeMilliseconds > KMccRtpSendTimeoutLongMillisecs ) |
|
227 { |
|
228 // Timeout value is so long that if sending of one rtp packet really |
|
229 // took so long, receiver will have big problems and it's better |
|
230 // to drop all frames queued in order to avoid delay increase |
|
231 // at receiver side. |
|
232 Clear(); |
|
233 } |
|
234 else |
|
235 { |
|
236 // Sending timeout, cancel send and discard that packet |
|
237 Cancel(); |
|
238 |
|
239 // Do also cleanup of related packets as those are useless as this |
|
240 // packet is removed because of timeout |
|
241 RemovePacket( ETrue ); |
|
242 |
|
243 // Send next packet anyway |
|
244 TRAPD( err, SendPacketL() ) |
|
245 if ( err ) |
|
246 { |
|
247 ErrorReport( err ); |
|
248 } |
|
249 } |
|
250 |
|
251 TRACE_RTP_SINK_PRINT( "CMccRtpSender::TimerExpiredL, exit" ) |
|
252 } |
|
253 |
|
254 // ----------------------------------------------------------------------------- |
|
255 // CMccRtpSender::ConstructL |
|
256 // ----------------------------------------------------------------------------- |
|
257 // |
|
258 void CMccRtpSender::ConstructL() |
|
259 { |
|
260 iTimeoutTimer = CMccTimerManager::NewL(); |
|
261 } |
|
262 |
|
263 // ----------------------------------------------------------------------------- |
|
264 // CMccRtpSender::CMccRtpSender |
|
265 // ----------------------------------------------------------------------------- |
|
266 // |
|
267 CMccRtpSender::CMccRtpSender( |
|
268 MMccRtpSenderObserver& aObserver, |
|
269 CRtpAPI& aRtpApi, |
|
270 TRtpId aSessionId, |
|
271 TBool aDoMarkerBasedCleanup ) : |
|
272 CActive( EPriorityStandard ), |
|
273 iObserver( aObserver ), |
|
274 iRtpApi( aRtpApi ), |
|
275 iSessionId( aSessionId ), |
|
276 iDoMarkerBasedCleanup( aDoMarkerBasedCleanup ), |
|
277 iTimeoutTimeMilliseconds( KMccRtpSendTimeoutLongMillisecs ) |
|
278 { |
|
279 CActiveScheduler::Add( this ); |
|
280 |
|
281 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::CMccRtpSender, marker based cleanup:%d", |
|
282 iDoMarkerBasedCleanup ) |
|
283 } |
|
284 |
|
285 // ----------------------------------------------------------------------------- |
|
286 // CMccRtpSender::SendPacketL |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 void CMccRtpSender::SendPacketL() |
|
290 { |
|
291 if ( iSendQueue.Count() > 0 ) |
|
292 { |
|
293 CMccRtpSendItem* item = iSendQueue[ 0 ]; |
|
294 if ( KNullId == item->SessionId( ) ) |
|
295 { |
|
296 User::LeaveIfError( |
|
297 iRtpApi.SendRtpPacket( |
|
298 item->RtpStreamId(), |
|
299 item->RtpHeader(), |
|
300 item->DataPtr(), |
|
301 iStatus ) ); |
|
302 } |
|
303 else |
|
304 { |
|
305 iRtpApi.SendDataL( item->SessionId(), item->UseRtpSocket(), |
|
306 item->DataPtr(), iStatus ); |
|
307 } |
|
308 |
|
309 SetActive(); |
|
310 |
|
311 iTimeoutTimer->Stop( iTimerId ); |
|
312 iTimerId = iTimeoutTimer->StartL( this, iTimeoutTimeMilliseconds ); |
|
313 } |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CMccRtpSender::RemovePacket |
|
318 // ----------------------------------------------------------------------------- |
|
319 // |
|
320 void CMccRtpSender::RemovePacket( TBool aDoQueueCleanup ) |
|
321 { |
|
322 if ( iSendQueue.Count() > 0 ) |
|
323 { |
|
324 TBool removed( EFalse ); |
|
325 |
|
326 if ( aDoQueueCleanup ) |
|
327 { |
|
328 removed = DoQueueCleanup( 0, iSendQueue[ 0 ]->RtpHeader() ); |
|
329 } |
|
330 else |
|
331 { |
|
332 #ifdef TRACE_RTP_SINK |
|
333 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::RemovePacket, sent packet size: %d", |
|
334 iSendQueue[ 0 ]->DataPtr().Length() ) |
|
335 #endif |
|
336 } |
|
337 |
|
338 if ( !removed ) |
|
339 { |
|
340 delete iSendQueue[ 0 ]; |
|
341 iSendQueue.Remove( 0 ); |
|
342 } |
|
343 |
|
344 iTimeoutTimer->Stop( iTimerId ); |
|
345 } |
|
346 } |
|
347 |
|
348 // ----------------------------------------------------------------------------- |
|
349 // CMccRtpSender::ErrorReport |
|
350 // ----------------------------------------------------------------------------- |
|
351 // |
|
352 TBool CMccRtpSender::ErrorReport( TInt aError ) |
|
353 { |
|
354 TBool errorReported( EFalse ); |
|
355 |
|
356 if ( aError != KErrNone && aError != KErrCancel && aError != KErrTooBig ) |
|
357 { |
|
358 iObserver.SendErrorOccured( aError ); |
|
359 errorReported = ETrue; |
|
360 } |
|
361 |
|
362 return errorReported; |
|
363 } |
|
364 |
|
365 // ----------------------------------------------------------------------------- |
|
366 // CMccRtpSender::CheckDiscarding |
|
367 // ----------------------------------------------------------------------------- |
|
368 // |
|
369 TBool CMccRtpSender::CheckDiscarding( const TRtpSendHeader& aRtpHeader ) |
|
370 { |
|
371 TBool discard( EFalse ); |
|
372 if ( iDiscarding ) |
|
373 { |
|
374 if ( aRtpHeader.iMarker ) |
|
375 { |
|
376 TRACE_RTP_SINK_PRINT( "CMccRtpSender::CheckDiscarding, stop discarding" ) |
|
377 iDiscarding = EFalse; |
|
378 } |
|
379 discard = ETrue; |
|
380 } |
|
381 return discard; |
|
382 } |
|
383 |
|
384 // ----------------------------------------------------------------------------- |
|
385 // CMccRtpSender::DoQueueCleanup |
|
386 // ----------------------------------------------------------------------------- |
|
387 // |
|
388 TBool CMccRtpSender::DoQueueCleanup( TInt aItemIndex, |
|
389 const TRtpSendHeader& aRtpHeader ) |
|
390 { |
|
391 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoQueueCleanup, entry" ) |
|
392 |
|
393 TInt queueCount = iSendQueue.Count(); |
|
394 TInt itemIndex = aItemIndex; |
|
395 TBool itemRemoved = EFalse; |
|
396 TBool markerEnabled( aRtpHeader.iMarker ); |
|
397 |
|
398 if ( !iDoMarkerBasedCleanup || itemIndex >= queueCount ) |
|
399 { |
|
400 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoQueueCleanup (disabled), exit" ) |
|
401 return itemRemoved; |
|
402 } |
|
403 |
|
404 // Check if this item is zero marker packet or if there's items with zero |
|
405 // marker before this one in the queue. All of those can be removed as they |
|
406 // belong to the same frame. |
|
407 // |
|
408 TBool removingCompleted( EFalse ); |
|
409 for ( TInt i = itemIndex; i >= 0 && !removingCompleted; i-- ) |
|
410 { |
|
411 if ( !iSendQueue[ i ]->RtpHeader().iMarker ) |
|
412 { |
|
413 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoQueueCleanup, clean earlier packet" ) |
|
414 |
|
415 delete iSendQueue[ i ]; |
|
416 iSendQueue.Remove( i ); |
|
417 itemIndex--; |
|
418 |
|
419 itemRemoved = ( itemRemoved || ( i == aItemIndex ) ); |
|
420 |
|
421 if ( i == 0 ) |
|
422 { |
|
423 // Deleted first item which is always the one which is sent currently, |
|
424 // must cancel sending |
|
425 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoQueueCleanup, deleted active item" ) |
|
426 Cancel(); |
|
427 } |
|
428 } |
|
429 else |
|
430 { |
|
431 removingCompleted = ETrue; |
|
432 } |
|
433 } |
|
434 |
|
435 if ( !markerEnabled ) |
|
436 { |
|
437 // If zero marker frame was removed, all upcoming frames until |
|
438 // next marker frame can be removed (also that marker frame can be removed) |
|
439 // |
|
440 removingCompleted = EFalse; |
|
441 |
|
442 TInt beginIndex( itemIndex + 1 ); |
|
443 for ( TInt j = beginIndex; j < iSendQueue.Count() && !removingCompleted; j++ ) |
|
444 { |
|
445 TRACE_RTP_SINK_PRINT( "CMccRtpSender::DoQueueCleanup, clean next packet" ) |
|
446 |
|
447 TUint8 marker = iSendQueue[ j ]->RtpHeader().iMarker; |
|
448 |
|
449 delete iSendQueue[ j ]; |
|
450 iSendQueue.Remove( j ); |
|
451 |
|
452 if ( marker ) |
|
453 { |
|
454 removingCompleted = ETrue; |
|
455 } |
|
456 |
|
457 // Start again from beginning as packet was removed from queue |
|
458 j = beginIndex - 1; |
|
459 } |
|
460 |
|
461 if ( !removingCompleted ) |
|
462 { |
|
463 // Following packets of the same frame can be discarded when |
|
464 // those are tried to be sent. |
|
465 iDiscarding = ETrue; |
|
466 } |
|
467 else |
|
468 { |
|
469 iDiscarding = EFalse; |
|
470 } |
|
471 } |
|
472 |
|
473 |
|
474 TRACE_RTP_SINK_PRINT2( "CMccRtpSender::DoQueueCleanup, exit with discarding:%d", |
|
475 iDiscarding ) |
|
476 return itemRemoved; |
|
477 } |
|
478 |
|
479 // ========================== HELPER CLASS ==================================== |
|
480 |
|
481 // ----------------------------------------------------------------------------- |
|
482 // CMccRtpSendItem::NewLC |
|
483 // ----------------------------------------------------------------------------- |
|
484 // |
|
485 CMccRtpSendItem* CMccRtpSendItem::NewLC( |
|
486 TRtpId aRtpStreamId, |
|
487 const TRtpSendHeader& aRtpHeader, |
|
488 const TDesC8& aData ) |
|
489 { |
|
490 CMccRtpSendItem* self = |
|
491 new ( ELeave ) CMccRtpSendItem( aRtpStreamId, aRtpHeader ); |
|
492 CleanupStack::PushL( self ); |
|
493 self->ConstructL( aData ); |
|
494 return self; |
|
495 } |
|
496 |
|
497 // ----------------------------------------------------------------------------- |
|
498 // CMccRtpSendItem::NewLC |
|
499 // ----------------------------------------------------------------------------- |
|
500 // |
|
501 CMccRtpSendItem* CMccRtpSendItem::NewLC( TRtpId aSessionId, |
|
502 TBool aUseRtpSocket, const TDesC8& aData ) |
|
503 { |
|
504 CMccRtpSendItem* self = |
|
505 new ( ELeave ) CMccRtpSendItem( aSessionId, aUseRtpSocket ); |
|
506 CleanupStack::PushL( self ); |
|
507 self->ConstructL( aData ); |
|
508 return self; |
|
509 } |
|
510 |
|
511 // ----------------------------------------------------------------------------- |
|
512 // CMccRtpSendItem::~CMccRtpSendItem |
|
513 // ----------------------------------------------------------------------------- |
|
514 // |
|
515 CMccRtpSendItem::~CMccRtpSendItem() |
|
516 { |
|
517 delete iData; |
|
518 } |
|
519 |
|
520 // ----------------------------------------------------------------------------- |
|
521 // CMccRtpSendItem::DataPtr |
|
522 // ----------------------------------------------------------------------------- |
|
523 // |
|
524 const TDesC8& CMccRtpSendItem::DataPtr() const |
|
525 { |
|
526 return iDataPtr; |
|
527 } |
|
528 |
|
529 // ----------------------------------------------------------------------------- |
|
530 // CMccRtpSendItem::RtpStreamId |
|
531 // ----------------------------------------------------------------------------- |
|
532 // |
|
533 TRtpId CMccRtpSendItem::RtpStreamId() const |
|
534 { |
|
535 return iRtpStreamId; |
|
536 } |
|
537 |
|
538 // ----------------------------------------------------------------------------- |
|
539 // CMccRtpSendItem::RtpHeader |
|
540 // ----------------------------------------------------------------------------- |
|
541 // |
|
542 const TRtpSendHeader& CMccRtpSendItem::RtpHeader() const |
|
543 { |
|
544 return iRtpHeader; |
|
545 } |
|
546 |
|
547 // ----------------------------------------------------------------------------- |
|
548 // CMccRtpSendItem::SessionId |
|
549 // ----------------------------------------------------------------------------- |
|
550 // |
|
551 TRtpId CMccRtpSendItem::SessionId() const |
|
552 { |
|
553 return iSessionId; |
|
554 } |
|
555 |
|
556 |
|
557 // ----------------------------------------------------------------------------- |
|
558 // CMccRtpSendItem::UseRtpSocket |
|
559 // ----------------------------------------------------------------------------- |
|
560 // |
|
561 TBool CMccRtpSendItem::UseRtpSocket() const |
|
562 { |
|
563 return iUseRtpSocket; |
|
564 } |
|
565 |
|
566 |
|
567 // ----------------------------------------------------------------------------- |
|
568 // CMccRtpSendItem::ConstructL |
|
569 // ----------------------------------------------------------------------------- |
|
570 // |
|
571 void CMccRtpSendItem::ConstructL( const TDesC8& aData ) |
|
572 { |
|
573 iData = aData.AllocL(); |
|
574 iDataPtr.Set( *iData ); |
|
575 } |
|
576 |
|
577 // ----------------------------------------------------------------------------- |
|
578 // CMccRtpSendItem::CMccRtpSendItem |
|
579 // ----------------------------------------------------------------------------- |
|
580 // |
|
581 CMccRtpSendItem::CMccRtpSendItem( |
|
582 TRtpId aRtpStreamId, |
|
583 const TRtpSendHeader& aRtpHeader ) : |
|
584 iRtpStreamId( aRtpStreamId ), |
|
585 iRtpHeader( aRtpHeader ), |
|
586 iDataPtr( NULL, 0 ), |
|
587 iSessionId( KNullId ) |
|
588 { |
|
589 } |
|
590 |
|
591 |
|
592 // ----------------------------------------------------------------------------- |
|
593 // CMccRtpSendItem::CMccRtpSendItem |
|
594 // ----------------------------------------------------------------------------- |
|
595 // |
|
596 CMccRtpSendItem::CMccRtpSendItem( |
|
597 TRtpId aSessionId, |
|
598 TBool aUseRtpSocket ) |
|
599 : |
|
600 iRtpStreamId( KNullId ), |
|
601 iDataPtr( NULL, 0 ), |
|
602 iSessionId( aSessionId ), |
|
603 iUseRtpSocket( aUseRtpSocket ) |
|
604 { |
|
605 } |
|
606 |
|
607 // End of File |
|
608 |