|
1 /* |
|
2 * Copyright (c) 2004-2008 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: JitterBuffer component capable to audioframe buffering. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include <mmf/server/mmfaudiooutput.h> |
|
23 #include "mccjitterbuffer.h" |
|
24 #include "mccjitterbufferimpl.h" |
|
25 #include "mccinternaldef.h" |
|
26 #include "mccinternalevents.h" |
|
27 #include "mccjitterbufferlogs.h" |
|
28 #include "mccjitterbufferobserver.h" |
|
29 |
|
30 // LOCAL CONSTANTS |
|
31 const TUint KAdaptUpdateIval = 250; |
|
32 |
|
33 // ============================= LOCAL FUNCTIONS =============================== |
|
34 |
|
35 // ============================ MEMBER FUNCTIONS =============================== |
|
36 |
|
37 // ----------------------------------------------------------------------------- |
|
38 // CMccJitterBuffer::CMccJitterBuffer |
|
39 // C++ default constructor can NOT contain any code, that |
|
40 // might leave. |
|
41 // ----------------------------------------------------------------------------- |
|
42 // |
|
43 CMccJitterBuffer::CMccJitterBuffer( MJitterBufferObserver* aObserver ) : |
|
44 MDataSink( KMccJitterBufferUid ), MDataSource( KMccJitterBufferUid ), |
|
45 iState( EJBufStopped ), |
|
46 iObserver ( aObserver ) |
|
47 { |
|
48 |
|
49 } |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // CMccJitterBuffer::NewL |
|
53 // Static constructor. |
|
54 // ----------------------------------------------------------------------------- |
|
55 // |
|
56 EXPORT_C CMccJitterBuffer* CMccJitterBuffer::NewL( MJitterBufferObserver* aObserver ) |
|
57 { |
|
58 CMccJitterBuffer* self = new ( ELeave ) CMccJitterBuffer( aObserver ); |
|
59 return self; |
|
60 } |
|
61 |
|
62 // ----------------------------------------------------------------------------- |
|
63 // CMccJitterBuffer::~CMccJitterBuffer |
|
64 // Destructor deallocate memory. |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CMccJitterBuffer::~CMccJitterBuffer() |
|
68 { |
|
69 __JITTER_BUFFER_INT1( "CMccJitterBuffer::~CMccJitterBuffer:", |
|
70 reinterpret_cast<TInt>( this ) ) |
|
71 __JITTER_BUFFER_INT1( "CMccJitterBuffer::~CMccJitterBuffer iDataSink:", |
|
72 reinterpret_cast<TInt>( iDataSink ) ) |
|
73 __JITTER_BUFFER_INT1( "CMccJitterBuffer::~CMccJitterBuffer iDataSource:", |
|
74 reinterpret_cast<TInt>( iDataSource ) ) |
|
75 __JITTER_BUFFER_INT1( "CMccJitterBuffer::~CMccJitterBuffer iSinkBuffer:", |
|
76 reinterpret_cast<TInt>( iSinkBuffer ) ) |
|
77 __JITTER_BUFFER_INT1( "CMccJitterBuffer::~CMccJitterBuffer iBufferImpl:", |
|
78 reinterpret_cast<TInt>( iBufferImpl ) ) |
|
79 |
|
80 if ( iDataSink ) |
|
81 { |
|
82 iDataSink->SinkThreadLogoff(); |
|
83 } |
|
84 |
|
85 if ( !iSnkBufRef ) |
|
86 { |
|
87 delete iSinkBuffer; |
|
88 } |
|
89 |
|
90 delete iBufferImpl; |
|
91 } |
|
92 |
|
93 // ----------------------------------------------------------------------------- |
|
94 // CMccJitterBuffer::SetupL |
|
95 // Setup Jitterbuffer |
|
96 // ----------------------------------------------------------------------------- |
|
97 // |
|
98 EXPORT_C void CMccJitterBuffer::SetupL( TInt /*aBufferSize*/, TInt aPlayThreshold, |
|
99 const TMccCodecInfo& aCInfo ) |
|
100 { |
|
101 __JITTER_BUFFER( "CMccJitterBuffer::SetupL" ) |
|
102 |
|
103 __ASSERT_ALWAYS( iDataSink, User::Leave( KErrNotReady ) ); |
|
104 |
|
105 if( !iBufferImpl ) |
|
106 { |
|
107 iBufferImpl = CMccJitterBufferImpl::NewL( iObserver ); |
|
108 } |
|
109 |
|
110 MMMFAudioOutput* output = static_cast<MMMFAudioOutput*>( iDataSink ); |
|
111 iBufferImpl->SetupL( aPlayThreshold, |
|
112 aCInfo, |
|
113 output->SoundDevice(), |
|
114 iEventHandler, |
|
115 MCC_ENDPOINT_ID( iDataSink ) ); |
|
116 } |
|
117 |
|
118 // ----------------------------------------------------------------------------- |
|
119 // CMccJitterBuffer::ResetBuffer |
|
120 // Reset Jitterbuffer |
|
121 // ----------------------------------------------------------------------------- |
|
122 // |
|
123 EXPORT_C void CMccJitterBuffer::ResetBuffer( TBool aPlayTone ) |
|
124 { |
|
125 if ( iBufferImpl ) |
|
126 { |
|
127 iBufferImpl->ResetBuffer( aPlayTone ); |
|
128 } |
|
129 } |
|
130 |
|
131 // ----------------------------------------------------------------------------- |
|
132 // CMccJitterBuffer::DelayDownL |
|
133 // Delay Down |
|
134 // ----------------------------------------------------------------------------- |
|
135 // |
|
136 EXPORT_C void CMccJitterBuffer::DelayDownL() |
|
137 { |
|
138 User::LeaveIfNull( iBufferImpl ); |
|
139 iBufferImpl->DelayDownL(); |
|
140 } |
|
141 |
|
142 // ----------------------------------------------------------------------------- |
|
143 // CMccJitterBuffer::DelayUpL |
|
144 // Delay Up |
|
145 // ----------------------------------------------------------------------------- |
|
146 // |
|
147 EXPORT_C void CMccJitterBuffer::DelayUpL() |
|
148 { |
|
149 User::LeaveIfNull( iBufferImpl ); |
|
150 iBufferImpl->DelayUpL(); |
|
151 } |
|
152 |
|
153 // ----------------------------------------------------------------------------- |
|
154 // CMccJitterBuffer::SetSinkDataTypeCode |
|
155 // From MDataSink |
|
156 // ----------------------------------------------------------------------------- |
|
157 // |
|
158 TInt CMccJitterBuffer::SetSinkDataTypeCode( TFourCC aSinkFourCC, TMediaId aMediaId ) |
|
159 { |
|
160 if( KUidMediaTypeAudio == aMediaId.iMediaType ) |
|
161 { |
|
162 __JITTER_BUFFER( "CMccJitterBuffer::SetSinkDataTypeCode To iDataSink" ) |
|
163 |
|
164 return iDataSink->SetSinkDataTypeCode( aSinkFourCC, aMediaId ); |
|
165 } |
|
166 else |
|
167 { |
|
168 __JITTER_BUFFER( "CMccJitterBuffer::SetSinkDataTypeCode NOT SUPPORTED" ) |
|
169 |
|
170 return KErrNotSupported; |
|
171 } |
|
172 } |
|
173 |
|
174 // ----------------------------------------------------------------------------- |
|
175 // CMccJitterBuffer::SetSourceDataTypeCode |
|
176 // |
|
177 // ----------------------------------------------------------------------------- |
|
178 // |
|
179 TInt CMccJitterBuffer::SetSourceDataTypeCode( TFourCC aSourceFourCC, TMediaId aMediaId ) |
|
180 { |
|
181 if( KUidMediaTypeAudio == aMediaId.iMediaType ) |
|
182 { |
|
183 __JITTER_BUFFER( "CMccJitterBuffer::SetSourceDataTypeCode To iDataSource" ) |
|
184 |
|
185 return iDataSource->SetSourceDataTypeCode( aSourceFourCC, aMediaId ); |
|
186 } |
|
187 else |
|
188 { |
|
189 __JITTER_BUFFER( "CMccJitterBuffer::SetSourceDataTypeCode NOT SUPPORTED" ) |
|
190 |
|
191 return KErrNotSupported; |
|
192 } |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CMccJitterBuffer::SinkDataTypeCode |
|
197 // From MDataSink |
|
198 // ----------------------------------------------------------------------------- |
|
199 // |
|
200 TFourCC CMccJitterBuffer::SinkDataTypeCode( TMediaId aMediaId ) |
|
201 { |
|
202 if( KUidMediaTypeAudio == aMediaId.iMediaType ) |
|
203 { |
|
204 __JITTER_BUFFER( "CMccJitterBuffer::SinkDataTypeCode From iDataSink" ) |
|
205 |
|
206 return iDataSink->SinkDataTypeCode( aMediaId ); |
|
207 } |
|
208 else |
|
209 { |
|
210 // Default to NULL FourCC |
|
211 __JITTER_BUFFER( "CMccJitterBuffer::SinkDataTypeCode DEFAULT" ) |
|
212 |
|
213 return TFourCC(); |
|
214 } |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CMccJitterBuffer::SourceDataTypeCode |
|
219 // From MDataSource |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 TFourCC CMccJitterBuffer::SourceDataTypeCode( TMediaId aMediaId ) |
|
223 { |
|
224 if( KUidMediaTypeAudio == aMediaId.iMediaType ) |
|
225 { |
|
226 __JITTER_BUFFER( "CMccJitterBuffer::SourceDataTypeCode From iDataSource" ) |
|
227 |
|
228 return iDataSource->SourceDataTypeCode( aMediaId ); |
|
229 } |
|
230 else |
|
231 { |
|
232 // Default to NULL FourCC |
|
233 __JITTER_BUFFER( "CMccJitterBuffer::SourceDataTypeCode DEFAULT" ) |
|
234 |
|
235 return TFourCC(); |
|
236 } |
|
237 } |
|
238 |
|
239 // ----------------------------------------------------------------------------- |
|
240 // CMccJitterBuffer::ConstructSinkL |
|
241 // From MDataSink |
|
242 // ----------------------------------------------------------------------------- |
|
243 // |
|
244 void CMccJitterBuffer::ConstructSinkL( const TDesC8& /*aInitData*/ ) |
|
245 { |
|
246 User::Leave( KErrNotSupported ); |
|
247 } |
|
248 |
|
249 // ----------------------------------------------------------------------------- |
|
250 // CMccJitterBuffer::ConstructSourceL |
|
251 // From MDataSource |
|
252 // ----------------------------------------------------------------------------- |
|
253 // |
|
254 void CMccJitterBuffer::ConstructSourceL( const TDesC8& /*aInitData*/ ) |
|
255 { |
|
256 User::Leave( KErrNotSupported ); |
|
257 } |
|
258 |
|
259 // ----------------------------------------------------------------------------- |
|
260 // CMccJitterBuffer::SinkThreadLogon |
|
261 // From MDataSink |
|
262 // ----------------------------------------------------------------------------- |
|
263 // |
|
264 TInt CMccJitterBuffer::SinkThreadLogon( MAsyncEventHandler& aEventHandler ) |
|
265 { |
|
266 if( !iEventHandler ) |
|
267 { |
|
268 if( iDataSink ) |
|
269 { |
|
270 __JITTER_BUFFER( "CMccJitterBuffer::SinkThreadLogon NORMAL" ) |
|
271 |
|
272 iEventHandler = &aEventHandler; |
|
273 return iDataSink->SinkThreadLogon( aEventHandler ); |
|
274 } |
|
275 else |
|
276 { |
|
277 __JITTER_BUFFER( "CMccJitterBuffer::SinkThreadLogon KErrNotReady" ) |
|
278 |
|
279 return KErrNotReady; |
|
280 } |
|
281 } |
|
282 else |
|
283 { |
|
284 __JITTER_BUFFER( "CMccJitterBuffer::SinkThreadLogon KErrAlreadyExists" ) |
|
285 |
|
286 return KErrAlreadyExists; |
|
287 } |
|
288 } |
|
289 |
|
290 // ----------------------------------------------------------------------------- |
|
291 // CMccJitterBuffer::SourceThreadLogon |
|
292 // From MDataSource |
|
293 // ----------------------------------------------------------------------------- |
|
294 // |
|
295 TInt CMccJitterBuffer::SourceThreadLogon( MAsyncEventHandler& /*aEventHandler*/ ) |
|
296 { |
|
297 __JITTER_BUFFER( "CMccJitterBuffer::SourceThreadLogon" ) |
|
298 |
|
299 // Jitter buffer is used always as a datasink, so we do not support any |
|
300 // source threads logging on. |
|
301 return KErrNotSupported; |
|
302 } |
|
303 |
|
304 // ----------------------------------------------------------------------------- |
|
305 // CMccJitterBuffer::SinkThreadLogoff |
|
306 // From MDataSink |
|
307 // ----------------------------------------------------------------------------- |
|
308 // |
|
309 void CMccJitterBuffer::SinkThreadLogoff() |
|
310 { |
|
311 __JITTER_BUFFER( "CMccJitterBuffer::SinkThreadLogoff in" ) |
|
312 |
|
313 iEventHandler = NULL; |
|
314 |
|
315 if( iBufferImpl ) |
|
316 { |
|
317 delete iBufferImpl; |
|
318 iBufferImpl = NULL; |
|
319 } |
|
320 |
|
321 if( iDataSink ) |
|
322 { |
|
323 iDataSink->SinkThreadLogoff(); |
|
324 iDataSink = NULL; |
|
325 } |
|
326 |
|
327 if ( !iSnkBufRef ) |
|
328 { |
|
329 delete iSinkBuffer; |
|
330 } |
|
331 |
|
332 iSinkBuffer = NULL; |
|
333 |
|
334 __JITTER_BUFFER( "CMccJitterBuffer::SinkThreadLogoff out" ) |
|
335 } |
|
336 |
|
337 // ----------------------------------------------------------------------------- |
|
338 // CMccJitterBuffer::SinkPrimeL |
|
339 // |
|
340 // ----------------------------------------------------------------------------- |
|
341 // |
|
342 void CMccJitterBuffer::SinkPrimeL() |
|
343 { |
|
344 __JITTER_BUFFER( "CMccJitterBuffer::SinkPrimeL" ) |
|
345 |
|
346 iState = EJBufPrimed; |
|
347 this->ResetBuffer(); |
|
348 iDataSink->SinkPrimeL(); |
|
349 } |
|
350 |
|
351 // ----------------------------------------------------------------------------- |
|
352 // CMccJitterBuffer::SinkPlayL |
|
353 // |
|
354 // ----------------------------------------------------------------------------- |
|
355 // |
|
356 void CMccJitterBuffer::SinkPlayL() |
|
357 { |
|
358 __JITTER_BUFFER("CMccJitterBuffer::SinkPlayL iDataSink->SinkPlayL" ) |
|
359 |
|
360 iState = EJBufPlaying; |
|
361 iDataSink->SinkPlayL(); |
|
362 iSnkBufRef = ETrue; // Sinkbuffer owned by MMF |
|
363 iRequestSize = 0; |
|
364 |
|
365 __JITTER_BUFFER( "CMccJitterBuffer::SinkPlayL CreateSinkBufferL" ) |
|
366 |
|
367 iSinkBuffer = iDataSink->CreateSinkBufferL( KUidMediaTypeAudio, iSnkBufRef ); |
|
368 |
|
369 // If buffer has not been supplied via CreateSinkBufferL, must use |
|
370 // asynchronous buffer creation |
|
371 if ( !iSinkBuffer ) |
|
372 { |
|
373 __JITTER_BUFFER( "CMccJitterBuffer::SinkPlayL EmptyBufferL ASYNC CREATION" ) |
|
374 |
|
375 iDataSink->EmptyBufferL( iSinkBuffer, this, KUidMediaTypeAudio ); |
|
376 } |
|
377 else |
|
378 { |
|
379 //we have a sink buffer from CreateSinkBufferL |
|
380 __JITTER_BUFFER( "CMccJitterBuffer::SinkPlayL EmptyBufferL SYNC CREATION" ) |
|
381 |
|
382 iSinkBuffer->SetStatus( EAvailable ); |
|
383 } |
|
384 |
|
385 iPlayedFrames = 0; |
|
386 } |
|
387 |
|
388 // ----------------------------------------------------------------------------- |
|
389 // CMccJitterBuffer::SinkPauseL |
|
390 // |
|
391 // ----------------------------------------------------------------------------- |
|
392 // |
|
393 void CMccJitterBuffer::SinkPauseL() |
|
394 { |
|
395 __JITTER_BUFFER( "CMccJitterBuffer::SinkPauseL" ) |
|
396 |
|
397 iState = EJBufPaused; |
|
398 ResetBuffer(); |
|
399 iDataSink->SinkPauseL(); |
|
400 iPlayedFrames = 0; |
|
401 |
|
402 // If sinkbuffer is not a reference then we need to delete it here so that |
|
403 // play - pause - play works. Also devsound creates new buffers when |
|
404 // resuming from Pause through Play. |
|
405 if ( !iSnkBufRef ) |
|
406 { |
|
407 delete iSinkBuffer; |
|
408 } |
|
409 |
|
410 iSinkBuffer = NULL; |
|
411 } |
|
412 |
|
413 // ----------------------------------------------------------------------------- |
|
414 // CMccJitterBuffer::SinkStopL |
|
415 // |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 void CMccJitterBuffer::SinkStopL() |
|
419 { |
|
420 __JITTER_BUFFER( "CMccJitterBuffer::SinkStopL" ) |
|
421 |
|
422 iState = EJBufStopped; |
|
423 ResetBuffer(); |
|
424 iDataSink->SinkStopL(); |
|
425 iPlayedFrames = 0; |
|
426 if ( !iSnkBufRef ) |
|
427 { |
|
428 delete iSinkBuffer; |
|
429 } |
|
430 |
|
431 iSinkBuffer = NULL; |
|
432 } |
|
433 |
|
434 |
|
435 // ----------------------------------------------------------------------------- |
|
436 // CMccJitterBuffer::CanCreateSinkBuffer |
|
437 // From MDataSink |
|
438 // ----------------------------------------------------------------------------- |
|
439 // |
|
440 TBool CMccJitterBuffer::CanCreateSinkBuffer() |
|
441 { |
|
442 // CMccJitterBuffer can't create buffers |
|
443 return EFalse; |
|
444 } |
|
445 |
|
446 // ----------------------------------------------------------------------------- |
|
447 // CMccJitterBuffer::CanCreateSourceBuffer |
|
448 // From MDataSource |
|
449 // ----------------------------------------------------------------------------- |
|
450 // |
|
451 TBool CMccJitterBuffer::CanCreateSourceBuffer() |
|
452 { |
|
453 // CMccJitterBuffer can't create buffers |
|
454 return EFalse; |
|
455 } |
|
456 |
|
457 // ----------------------------------------------------------------------------- |
|
458 // CMccJitterBuffer::CreateSinkBufferL |
|
459 // From MDataSink |
|
460 // ----------------------------------------------------------------------------- |
|
461 // |
|
462 CMMFBuffer* CMccJitterBuffer::CreateSinkBufferL( TMediaId /*aMediaId*/, |
|
463 TBool& /*aReference*/ ) |
|
464 { |
|
465 // CMccJitterBuffer can't create buffers |
|
466 User::Leave( KErrNotSupported ); |
|
467 return NULL; |
|
468 } |
|
469 |
|
470 // ----------------------------------------------------------------------------- |
|
471 // CMccJitterBuffer::CreateSourceBufferL |
|
472 // From MDataSource |
|
473 // ----------------------------------------------------------------------------- |
|
474 // |
|
475 CMMFBuffer* CMccJitterBuffer::CreateSourceBufferL( TMediaId /*aMediaId*/, |
|
476 TBool& /*aReference*/ ) |
|
477 { |
|
478 // CMccJitterBuffer can't create buffers |
|
479 User::Leave( KErrNotSupported ); |
|
480 return NULL; |
|
481 } |
|
482 |
|
483 // ----------------------------------------------------------------------------- |
|
484 // CMccJitterBuffer::FillBufferL |
|
485 // From MDataSource |
|
486 // ----------------------------------------------------------------------------- |
|
487 // |
|
488 void CMccJitterBuffer::FillBufferL( CMMFBuffer* /*aBuffer*/, |
|
489 MDataSink* /*aConsumer*/, |
|
490 TMediaId /*aMediaId*/ ) |
|
491 { |
|
492 __JITTER_BUFFER( "CMccJitterBuffer::FillBufferL KErrNotSupported" ) |
|
493 |
|
494 User::Leave( KErrNotSupported ); |
|
495 } |
|
496 |
|
497 // ----------------------------------------------------------------------------- |
|
498 // CMccJitterBuffer::EmptyBufferL |
|
499 // From MDataSink |
|
500 // ----------------------------------------------------------------------------- |
|
501 // |
|
502 void CMccJitterBuffer::EmptyBufferL( CMMFBuffer* aBuffer, |
|
503 MDataSource* aSupplier, |
|
504 TMediaId /*aMediaId*/ ) |
|
505 { |
|
506 if( iBufferImpl && ( iState == EJBufPlaying ) ) |
|
507 { |
|
508 __ASSERT_ALWAYS( iBufferImpl->BufferLength(), User::Leave( KErrNotReady ) ); |
|
509 |
|
510 __JITTER_BUFFER_INT1( "CMccJitterBuffer::EmptyBufferL BUF_SZ:", aBuffer->BufferSize() ) |
|
511 __JITTER_BUFFER_INT1( "CMccJitterBuffer::EmptyBufferL REQ_SZ:", aBuffer->RequestSize() ) |
|
512 |
|
513 // Adaptation control will be done based on played frames |
|
514 iBufferImpl->AddDataFrameL( aBuffer ); |
|
515 aBuffer->SetStatus( EAvailable ); |
|
516 } |
|
517 |
|
518 // Inform the source immediately so that packets keep on flowing in |
|
519 if ( aSupplier ) |
|
520 { |
|
521 aSupplier->BufferEmptiedL( aBuffer ); |
|
522 } |
|
523 } |
|
524 |
|
525 // ----------------------------------------------------------------------------- |
|
526 // CMccJitterBuffer::BufferFilledL |
|
527 // |
|
528 // ----------------------------------------------------------------------------- |
|
529 // |
|
530 void CMccJitterBuffer::BufferFilledL( CMMFBuffer* /*aBuffer*/ ) |
|
531 { |
|
532 __JITTER_BUFFER( "CMccJitterBuffer::BufferFilledL KErrNotSupported" ) |
|
533 |
|
534 User::Leave( KErrNotSupported ); |
|
535 } |
|
536 |
|
537 // ----------------------------------------------------------------------------- |
|
538 // CMccJitterBuffer::BufferEmptiedL |
|
539 // |
|
540 // ----------------------------------------------------------------------------- |
|
541 // |
|
542 void CMccJitterBuffer::BufferEmptiedL( CMMFBuffer* aBuffer ) |
|
543 { |
|
544 __JITTER_BUFFER( "CMccJitterBuffer::BufferEmptiedL" ) |
|
545 |
|
546 User::LeaveIfNull( aBuffer ); |
|
547 iSinkBuffer = aBuffer; |
|
548 iSinkBuffer->SetStatus( EAvailable ); |
|
549 |
|
550 if( iBufferImpl && iBufferImpl->BufferLength() ) |
|
551 { |
|
552 __JITTER_BUFFER( "CMccJitterBuffer::BufferEmptiedL NORMAL" ) |
|
553 |
|
554 // Check for request size changes if current codec happens to support |
|
555 // dynamic codec frame length changes. Currently only needed for |
|
556 // supporting 10/20ms variants of G.711 codec. Also one frame has two |
|
557 // bytes extra for the frameheader, so we remove it here. |
|
558 const TInt reqSize( iSinkBuffer->RequestSize() - KVoIPHeaderLength ); |
|
559 if ( reqSize != iRequestSize && |
|
560 iBufferImpl->CurrentCodec() == KMccFourCCIdG711 ) |
|
561 { |
|
562 __JITTER_BUFFER_INT1( "CMccJitterBuffer::BufferEmptiedL reqSize: ", reqSize ) |
|
563 __JITTER_BUFFER_INT1( "CMccJitterBuffer::BufferEmptiedL iRequestSize: ", iRequestSize ) |
|
564 iRequestSize = reqSize; |
|
565 |
|
566 if ( iObserver ) |
|
567 { |
|
568 // We don't do this on emulator as it will kick us in the teeth |
|
569 // later when re-calculating jitterbuffer size. |
|
570 #ifndef __WINSCW__ |
|
571 iObserver->DynamicBufferChangeRequest( iRequestSize ); |
|
572 #endif |
|
573 } |
|
574 } |
|
575 |
|
576 iBufferImpl->GetDataFrameL( iSinkBuffer ); |
|
577 iPlayedFrames++; |
|
578 |
|
579 if( KAdaptUpdateIval == iPlayedFrames ) |
|
580 { |
|
581 // Don't care about the error if frames haven't been received yet |
|
582 // because it's sensible to do the adaptation only when there is |
|
583 // actual data in the buffer |
|
584 iPlayedFrames = 0; |
|
585 SendJitterBufferEventToClient(); |
|
586 } |
|
587 |
|
588 iSinkBuffer->SetStatus( EFull ); |
|
589 iDataSink->EmptyBufferL( iSinkBuffer, this, KUidMediaTypeAudio ); |
|
590 } |
|
591 else |
|
592 { |
|
593 __JITTER_BUFFER( "CMccJitterBuffer::BufferEmptiedL KErrNotReady" ) |
|
594 |
|
595 User::Leave( KErrNotReady ); |
|
596 } |
|
597 } |
|
598 |
|
599 // ----------------------------------------------------------------------------- |
|
600 // CMccJitterBuffer::AddDataSinkL |
|
601 // From MDataSource |
|
602 // ----------------------------------------------------------------------------- |
|
603 // |
|
604 EXPORT_C void CMccJitterBuffer::AddDataSinkL( MDataSink* aSink ) |
|
605 { |
|
606 if( iDataSink ) |
|
607 { |
|
608 __JITTER_BUFFER( "CMccJitterBuffer::AddDataSinkL KErrAlreadyExists" ) |
|
609 |
|
610 User::Leave( KErrAlreadyExists ); |
|
611 } |
|
612 else |
|
613 { |
|
614 User::LeaveIfNull( aSink ); |
|
615 if( KUidMmfAudioOutput == aSink->DataSinkType() ) |
|
616 { |
|
617 __JITTER_BUFFER( "CMccJitterBuffer::AddDataSinkL AUDIO SINK" ) |
|
618 |
|
619 iDataSink = aSink; |
|
620 } |
|
621 else |
|
622 { |
|
623 __JITTER_BUFFER( "CMccJitterBuffer::AddDataSinkL KErrArgument" ) |
|
624 |
|
625 User::Leave( KErrArgument ); |
|
626 } |
|
627 } |
|
628 } |
|
629 |
|
630 // ----------------------------------------------------------------------------- |
|
631 // CMccJitterBuffer::AddDataSourceL |
|
632 // From MDataSource |
|
633 // ----------------------------------------------------------------------------- |
|
634 // |
|
635 EXPORT_C void CMccJitterBuffer::AddDataSourceL( MDataSource* aSource ) |
|
636 { |
|
637 __JITTER_BUFFER( "CMccJitterBuffer::AddDataSourceL" ) |
|
638 |
|
639 User::LeaveIfNull( aSource ); |
|
640 iDataSource = aSource; |
|
641 } |
|
642 |
|
643 // ----------------------------------------------------------------------------- |
|
644 // CMccJitterBuffer::SendJitterBufferEventToClient |
|
645 // |
|
646 // ----------------------------------------------------------------------------- |
|
647 // |
|
648 void CMccJitterBuffer::SendJitterBufferEventToClient() |
|
649 { |
|
650 TMccJitterBufferEventData eventData; |
|
651 iBufferImpl->GenerateStatistics( eventData ); |
|
652 |
|
653 if( iEventHandler ) |
|
654 { |
|
655 TMccEvent event( 0, |
|
656 0, |
|
657 0, |
|
658 MCC_ENDPOINT_ID( iDataSink ), |
|
659 KMccEventCategoryStream, |
|
660 KMccEventNone, |
|
661 KErrNone, |
|
662 KNullDesC8 ); |
|
663 |
|
664 event.iEventData.Copy( TMccJitterBufferEventDataPackage( eventData ) ); |
|
665 |
|
666 TMccInternalEvent internalEvent( KMccJitterBufferUid, |
|
667 EMccInternalJitterEventStatusReport, |
|
668 event ); |
|
669 |
|
670 iEventHandler->SendEventToClient( internalEvent ); |
|
671 } |
|
672 else |
|
673 { |
|
674 __JITTER_BUFFER( "CMccJitterBuffer::RunError, iEventHandler=NULL" ) |
|
675 } |
|
676 } |
|
677 |
|
678 // ----------------------------------------------------------------------------- |
|
679 // CMccJitterBuffer::GetDataSink |
|
680 // Get DataSink |
|
681 // ----------------------------------------------------------------------------- |
|
682 // |
|
683 EXPORT_C MDataSink* CMccJitterBuffer::GetDataSink() |
|
684 { |
|
685 return iDataSink; |
|
686 } |
|
687 |
|
688 // ----------------------------------------------------------------------------- |
|
689 // CMccJitterBuffer::NegotiateL |
|
690 // From MDataSink |
|
691 // ----------------------------------------------------------------------------- |
|
692 // |
|
693 void CMccJitterBuffer::NegotiateL( MDataSource& aDataSource ) |
|
694 { |
|
695 if( iDataSink ) |
|
696 { |
|
697 __JITTER_BUFFER( "CMccJitterBuffer::NegotiateL" ) |
|
698 |
|
699 iDataSink->NegotiateL( aDataSource ); |
|
700 } |
|
701 else |
|
702 { |
|
703 __JITTER_BUFFER( "CMccJitterBuffer::NegotiateL KErrNotReady" ) |
|
704 |
|
705 User::Leave( KErrNotReady ); |
|
706 } |
|
707 } |
|
708 |
|
709 // End of File |
|
710 |