|
1 /* |
|
2 * Copyright (c) 2007-2009 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: VoIP Audio Services - Uplink stream API |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <e32base.h> |
|
19 #include <mmffourcc.h> |
|
20 #include <voipdatabuffer.h> |
|
21 #include "debugtracemacros.h" |
|
22 #include "VoIPAudioSession.h" |
|
23 #include "VoIPAudioClientServer.h" |
|
24 #include "VoIPFormatIntfcImpl.h" |
|
25 #include "VoIPFormatIntfcImpl.h" |
|
26 #include "VoIPBaseCodecIntfcImpl.h" |
|
27 #include "VoIPILBCEncoderIntfcImpl.h" |
|
28 #include "VoIPG711EncoderIntfcImpl.h" |
|
29 #include "VoIPSharedData.h" |
|
30 #include "VoIPUplinkStreamImpl.h" |
|
31 |
|
32 // --------------------------------------------------------------------------- |
|
33 // CVoIPAudioUplinkStreamImpl::NewL |
|
34 // --------------------------------------------------------------------------- |
|
35 // |
|
36 CVoIPAudioUplinkStreamImpl* |
|
37 CVoIPAudioUplinkStreamImpl::NewL(const TMMFPrioritySettings aPriority) |
|
38 { |
|
39 CVoIPAudioUplinkStreamImpl* self = |
|
40 new (ELeave) CVoIPAudioUplinkStreamImpl(); |
|
41 CleanupStack::PushL(self); |
|
42 self->ConstructL(aPriority); |
|
43 CleanupStack::Pop(self); |
|
44 return self; |
|
45 } |
|
46 |
|
47 // --------------------------------------------------------------------------- |
|
48 // CVoIPAudioUplinkStreamImpl::~CVoIPAudioUplinkStreamImpl |
|
49 // --------------------------------------------------------------------------- |
|
50 // |
|
51 CVoIPAudioUplinkStreamImpl::~CVoIPAudioUplinkStreamImpl() |
|
52 { |
|
53 Close(); |
|
54 |
|
55 if (iMsgQHandler) |
|
56 { |
|
57 iMsgQHandler->Cancel(); |
|
58 delete iMsgQHandler; |
|
59 } |
|
60 |
|
61 if (iMsgQComHandler) |
|
62 { |
|
63 iMsgQComHandler->Cancel(); |
|
64 delete iMsgQComHandler; |
|
65 } |
|
66 |
|
67 if (iMsgQueue.Handle() > 0) |
|
68 { |
|
69 iMsgQueue.Close(); |
|
70 } |
|
71 |
|
72 if (iMsgComQueue.Handle() > 0) |
|
73 { |
|
74 iMsgComQueue.Close(); |
|
75 } |
|
76 |
|
77 if (iVoIPAudioSession.Handle() > 0) |
|
78 { |
|
79 iVoIPAudioSession.Close(); |
|
80 } |
|
81 } |
|
82 |
|
83 // --------------------------------------------------------------------------- |
|
84 // CVoIPAudioUplinkStreamImpl::CVoIPAudioUplinkStreamImpl |
|
85 // --------------------------------------------------------------------------- |
|
86 // |
|
87 CVoIPAudioUplinkStreamImpl::CVoIPAudioUplinkStreamImpl() : |
|
88 iBufferPtr(0, 0, 0) |
|
89 { |
|
90 } |
|
91 |
|
92 // --------------------------------------------------------------------------- |
|
93 // CVoIPAudioUplinkStreamImpl::ConstructL |
|
94 // --------------------------------------------------------------------------- |
|
95 // |
|
96 void CVoIPAudioUplinkStreamImpl::ConstructL( |
|
97 const TMMFPrioritySettings aPriority) |
|
98 { |
|
99 // Pass ownership to the parent class |
|
100 CVoIPAudioUplinkStream::ConstructL(this); |
|
101 iPriority = aPriority; |
|
102 iG711FrameSize = KVoIPG711FrameLen20ms; |
|
103 iFormat = EG711; |
|
104 TInt err = iVoIPAudioSession.Connect(); |
|
105 User::LeaveIfError(err); |
|
106 } |
|
107 |
|
108 // --------------------------------------------------------------------------- |
|
109 // CVoIPAudioUplinkStreamImpl::Open |
|
110 // --------------------------------------------------------------------------- |
|
111 // |
|
112 TInt CVoIPAudioUplinkStreamImpl::Open(MVoIPUplinkObserver& aObserver) |
|
113 { |
|
114 iObserver = &aObserver; |
|
115 |
|
116 TInt err = CreateQueue(KUpLinkQueue, KVoIPMsgQSlots, EMsgBufQueue); |
|
117 |
|
118 if (err == KErrNone) |
|
119 { |
|
120 err = CreateQueue(KUpLinkComQueue, KVoIPMsgComQSlots, EMsgComQueue); |
|
121 } |
|
122 |
|
123 if (err == KErrNone) |
|
124 { |
|
125 err = iVoIPAudioSession.OpenUplink(iPriority); |
|
126 } |
|
127 |
|
128 return err; |
|
129 } |
|
130 |
|
131 // --------------------------------------------------------------------------- |
|
132 // CVoIPAudioUplinkStreamImpl::GetVersion |
|
133 // --------------------------------------------------------------------------- |
|
134 // |
|
135 TInt CVoIPAudioUplinkStreamImpl::GetVersion(TVersion& aVersion) |
|
136 { |
|
137 aVersion = TVersion(1, 0, 0); |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 // --------------------------------------------------------------------------- |
|
142 // CVoIPAudioUplinkStreamImpl::GetMaxGain |
|
143 // --------------------------------------------------------------------------- |
|
144 // |
|
145 TInt CVoIPAudioUplinkStreamImpl::GetMaxGain(TInt& aGain) |
|
146 { |
|
147 aGain = iVoIPAudioSession.GetMaxGain(); |
|
148 return KErrNone; |
|
149 } |
|
150 |
|
151 // --------------------------------------------------------------------------- |
|
152 // CVoIPAudioUplinkStreamImpl::SetGain |
|
153 // --------------------------------------------------------------------------- |
|
154 // |
|
155 TInt CVoIPAudioUplinkStreamImpl::SetGain(TInt aGain) |
|
156 { |
|
157 TInt err = iVoIPAudioSession.SetGain(aGain); |
|
158 return err; |
|
159 } |
|
160 |
|
161 // --------------------------------------------------------------------------- |
|
162 // CVoIPAudioUplinkStreamImpl::GetGain |
|
163 // --------------------------------------------------------------------------- |
|
164 // |
|
165 TInt CVoIPAudioUplinkStreamImpl::GetGain(TInt& aGain) |
|
166 { |
|
167 aGain = iVoIPAudioSession.GetGain(); |
|
168 return KErrNone; |
|
169 } |
|
170 |
|
171 // --------------------------------------------------------------------------- |
|
172 // CVoIPAudioUplinkStreamImpl::GetSupportedFormatsL |
|
173 // --------------------------------------------------------------------------- |
|
174 // |
|
175 void CVoIPAudioUplinkStreamImpl::GetSupportedFormatsL( |
|
176 const TMMFPrioritySettings aPriority, |
|
177 RArray<TVoIPCodecFormat>& aFormats) |
|
178 { |
|
179 if (!iCodecFormats || aFormats.Count() <= 0) |
|
180 { |
|
181 RArray<TUint32> codecIDs; |
|
182 CleanupClosePushL(codecIDs); |
|
183 codecIDs.Reset(); |
|
184 iVoIPAudioSession.GetSupportedEncoders(aPriority, codecIDs, |
|
185 iG711FrameSize); |
|
186 |
|
187 TUint32 codec = 0; |
|
188 TInt count = codecIDs.Count(); |
|
189 TVoIPCodecFormat format; |
|
190 aFormats.Reset(); |
|
191 |
|
192 for (TInt i = 0; i < count; i++) |
|
193 { |
|
194 codec = codecIDs[i]; |
|
195 |
|
196 #ifdef _DEBUG |
|
197 TInt8 a = codec; |
|
198 TInt8 b = codec >> 8; |
|
199 TInt8 c = codec >> 16; |
|
200 TInt8 d = codec >> 24; |
|
201 RDebug::Print(_L("%c%c%c%c"), a, b, c, d); |
|
202 #endif |
|
203 format = ConvertFourCC(codec); |
|
204 if (format != ENULL) |
|
205 { |
|
206 aFormats.Append(format); |
|
207 } |
|
208 } |
|
209 |
|
210 iCodecFormats = &aFormats; |
|
211 CleanupStack::PopAndDestroy(&codecIDs); |
|
212 } |
|
213 } |
|
214 |
|
215 // --------------------------------------------------------------------------- |
|
216 // CVoIPAudioUplinkStreamImpl::SetFormatL |
|
217 // --------------------------------------------------------------------------- |
|
218 // |
|
219 void CVoIPAudioUplinkStreamImpl::SetFormatL(TVoIPCodecFormat aFormat, |
|
220 CVoIPFormatIntfc*& aIntfc) |
|
221 { |
|
222 // Check if requested codec is on the list of supported codecs |
|
223 if (!IsCodecSupportedL(aFormat)) |
|
224 { |
|
225 iFormat = ENULL; |
|
226 } |
|
227 |
|
228 // TODO: reuse when switching codecs on the fly and same codec is selected |
|
229 delete aIntfc; |
|
230 aIntfc = NULL; |
|
231 |
|
232 switch (iFormat) |
|
233 { |
|
234 case EG711: |
|
235 case EG711_10MS: |
|
236 { |
|
237 aIntfc = CVoIPG711EncoderIntfcImpl::NewL(this); |
|
238 iBufferLen = iG711FrameSize; |
|
239 break; |
|
240 } |
|
241 case EG729: |
|
242 { |
|
243 aIntfc = CVoIPBaseCodecIntfcImpl::NewL(this); |
|
244 iBufferLen = KVoIPG729FrameLen; |
|
245 break; |
|
246 } |
|
247 case EILBC: |
|
248 { |
|
249 aIntfc = CVoIPILBCEncoderIntfcImpl::NewL(this); |
|
250 iBufferLen = KVoIPILBCFrameLen; |
|
251 break; |
|
252 } |
|
253 case EAMR_NB: |
|
254 { |
|
255 aIntfc = CVoIPBaseCodecIntfcImpl::NewL(this); |
|
256 iBufferLen = KVoIPAMRNBFrameLen; |
|
257 break; |
|
258 } |
|
259 case EPCM16: |
|
260 { |
|
261 aIntfc = CVoIPBaseCodecIntfcImpl::NewL(this); |
|
262 iBufferLen = KVoIPPCM16FrameLen; |
|
263 break; |
|
264 } |
|
265 default: |
|
266 { |
|
267 iFormat = ENULL; |
|
268 iBufferLen = 0; |
|
269 User::Leave(KErrNotSupported); |
|
270 } |
|
271 } |
|
272 |
|
273 TUint32 codecFourCC = CodecFourCC(aFormat); |
|
274 iVoIPAudioSession.SetEncoder(codecFourCC); |
|
275 } |
|
276 |
|
277 // --------------------------------------------------------------------------- |
|
278 // CVoIPAudioUplinkStreamImpl::GetFormat |
|
279 // --------------------------------------------------------------------------- |
|
280 // |
|
281 TVoIPCodecFormat CVoIPAudioUplinkStreamImpl::GetFormat() |
|
282 { |
|
283 return iFormat; |
|
284 } |
|
285 |
|
286 // --------------------------------------------------------------------------- |
|
287 // CVoIPAudioUplinkStreamImpl::Start |
|
288 // --------------------------------------------------------------------------- |
|
289 // |
|
290 TInt CVoIPAudioUplinkStreamImpl::Start() |
|
291 { |
|
292 iIsClosing = EFalse; |
|
293 TInt err = iVoIPAudioSession.StartUplink(); |
|
294 return err; |
|
295 } |
|
296 |
|
297 // --------------------------------------------------------------------------- |
|
298 // CVoIPAudioUplinkStreamImpl::Stop |
|
299 // --------------------------------------------------------------------------- |
|
300 // |
|
301 TInt CVoIPAudioUplinkStreamImpl::Stop() |
|
302 { |
|
303 TInt err = iVoIPAudioSession.StopUplink(); |
|
304 return err; |
|
305 } |
|
306 |
|
307 // --------------------------------------------------------------------------- |
|
308 // CVoIPAudioUplinkStreamImpl::Close |
|
309 // --------------------------------------------------------------------------- |
|
310 // |
|
311 void CVoIPAudioUplinkStreamImpl::Close() |
|
312 { |
|
313 iIsClosing = ETrue; |
|
314 iVoIPAudioSession.CloseUplink(); |
|
315 } |
|
316 |
|
317 // --------------------------------------------------------------------------- |
|
318 // CVoIPAudioUplinkStreamImpl::BufferEmptied |
|
319 // --------------------------------------------------------------------------- |
|
320 // |
|
321 TInt CVoIPAudioUplinkStreamImpl::BufferEmptied(CVoIPDataBuffer* aBuffer) |
|
322 { |
|
323 aBuffer->GetPayloadPtr(iBufferPtr); |
|
324 TInt err = iVoIPAudioSession.BufferEmptied(iBufferPtr); |
|
325 return err; |
|
326 } |
|
327 |
|
328 // --------------------------------------------------------------------------- |
|
329 // CVoIPAudioUplinkStreamImpl::GetSession |
|
330 // --------------------------------------------------------------------------- |
|
331 // |
|
332 RVoIPAudioSession* CVoIPAudioUplinkStreamImpl::GetSession() |
|
333 { |
|
334 return &iVoIPAudioSession; |
|
335 } |
|
336 |
|
337 // --------------------------------------------------------------------------- |
|
338 // CVoIPAudioUplinkStreamImpl::CreateQueue |
|
339 // --------------------------------------------------------------------------- |
|
340 // |
|
341 TInt CVoIPAudioUplinkStreamImpl::CreateQueue(const TDesC& aQueueName, |
|
342 const TInt aNumSlots, const TQueueType aQueueType) |
|
343 { |
|
344 TInt err = KErrNone; |
|
345 |
|
346 if (aQueueType == EMsgBufQueue) |
|
347 { |
|
348 if (iMsgQueue.Handle() <= 0) |
|
349 { |
|
350 err = iMsgQueue.CreateGlobal(aQueueName, aNumSlots); |
|
351 if (err != KErrNone) |
|
352 { |
|
353 return err; |
|
354 } |
|
355 } |
|
356 |
|
357 TRAP(err, ReceiveMsgQHandlerEventsL()); |
|
358 } |
|
359 else if (aQueueType == EMsgComQueue) |
|
360 { |
|
361 if (iMsgComQueue.Handle() <= 0) |
|
362 { |
|
363 err = iMsgComQueue.CreateGlobal(aQueueName, aNumSlots); |
|
364 if (err != KErrNone) |
|
365 { |
|
366 return err; |
|
367 } |
|
368 } |
|
369 |
|
370 TRAP(err, ReceiveMsgQComHandlerEventsL()); |
|
371 } |
|
372 |
|
373 return err; |
|
374 } |
|
375 |
|
376 // --------------------------------------------------------------------------- |
|
377 // CVoIPAudioUplinkStreamImpl::ReceiveMsgQHandlerEventsL |
|
378 // Starts message queue handler (A/O) to monitor server side events |
|
379 // --------------------------------------------------------------------------- |
|
380 // |
|
381 void CVoIPAudioUplinkStreamImpl::ReceiveMsgQHandlerEventsL() |
|
382 { |
|
383 if (iMsgQHandler) |
|
384 { |
|
385 iMsgQHandler->Cancel(); |
|
386 } |
|
387 else |
|
388 { |
|
389 iMsgQHandler = CQueueHandler::NewL(this, &iMsgQueue, iBufferLen); |
|
390 } |
|
391 |
|
392 iMsgQHandler->Start(); |
|
393 } |
|
394 |
|
395 // --------------------------------------------------------------------------- |
|
396 // CVoIPAudioUplinkStreamImpl::ReceiveMsgQComHandlerEventsL |
|
397 // Starts message queue handler (A/O) to monitor server side events |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 void CVoIPAudioUplinkStreamImpl::ReceiveMsgQComHandlerEventsL() |
|
401 { |
|
402 if (iMsgQComHandler) |
|
403 { |
|
404 iMsgQComHandler->Cancel(); |
|
405 } |
|
406 else |
|
407 { |
|
408 iMsgQComHandler = CQueueHandler::NewL(this, &iMsgComQueue); |
|
409 } |
|
410 |
|
411 iMsgQComHandler->Start(); |
|
412 } |
|
413 |
|
414 // --------------------------------------------------------------------------- |
|
415 // CVoIPAudioUplinkStreamImpl::CodecFourCC |
|
416 // --------------------------------------------------------------------------- |
|
417 // |
|
418 TUint32 CVoIPAudioUplinkStreamImpl::CodecFourCC(TVoIPCodecFormat aFormat) |
|
419 { |
|
420 TUint32 codecFourCC; |
|
421 |
|
422 switch (aFormat) |
|
423 { |
|
424 case EG711_10MS: |
|
425 case EG711: |
|
426 { |
|
427 codecFourCC = KMccFourCCIdG711; |
|
428 break; |
|
429 } |
|
430 case EG729: |
|
431 { |
|
432 codecFourCC = KMccFourCCIdG729; |
|
433 break; |
|
434 } |
|
435 case EILBC: |
|
436 { |
|
437 codecFourCC = KMccFourCCIdILBC; |
|
438 break; |
|
439 } |
|
440 case EAMR_NB: |
|
441 { |
|
442 codecFourCC = KMccFourCCIdAMRNB; |
|
443 break; |
|
444 } |
|
445 case EPCM16: |
|
446 { |
|
447 codecFourCC = KMMFFourCCCodePCM16; |
|
448 break; |
|
449 } |
|
450 default: |
|
451 { |
|
452 codecFourCC = KFourCCNULL; |
|
453 } |
|
454 } |
|
455 |
|
456 return codecFourCC; |
|
457 } |
|
458 |
|
459 // ----------------------------------------------------------------------------- |
|
460 // CVoIPAudioUplinkStreamImpl::ConvertFourCC |
|
461 // ----------------------------------------------------------------------------- |
|
462 // |
|
463 TVoIPCodecFormat CVoIPAudioUplinkStreamImpl::ConvertFourCC(TUint32 aCodec) |
|
464 { |
|
465 TVoIPCodecFormat format; |
|
466 |
|
467 switch (aCodec) |
|
468 { |
|
469 case KMccFourCCIdG711: |
|
470 { |
|
471 if (iG711FrameSize == KVoIPG711FrameLen10ms) |
|
472 { |
|
473 format = EG711_10MS; |
|
474 TRACE_PRN_N(_L("VoIP->UPL: G711 10ms frame rate detected")); |
|
475 } |
|
476 else |
|
477 { |
|
478 format = EG711; |
|
479 } |
|
480 break; |
|
481 } |
|
482 case KMccFourCCIdG729: |
|
483 format = EG729; |
|
484 break; |
|
485 case KMccFourCCIdILBC: |
|
486 format = EILBC; |
|
487 break; |
|
488 case KMccFourCCIdAMRNB: |
|
489 format = EAMR_NB; |
|
490 break; |
|
491 case KMMFFourCCCodePCM16: |
|
492 format = EPCM16; |
|
493 break; |
|
494 default: |
|
495 format = ENULL; |
|
496 break; |
|
497 } |
|
498 |
|
499 return format; |
|
500 } |
|
501 |
|
502 // ----------------------------------------------------------------------------- |
|
503 // CVoIPAudioUplinkStreamImpl::IsCodecSupportedL |
|
504 // ----------------------------------------------------------------------------- |
|
505 // |
|
506 TBool CVoIPAudioUplinkStreamImpl::IsCodecSupportedL(TVoIPCodecFormat aFormat) |
|
507 { |
|
508 TBool status = EFalse; |
|
509 |
|
510 if (!iCodecFormats) |
|
511 { |
|
512 // Client hasn't called GetSupportedFormatsL |
|
513 RArray<TVoIPCodecFormat> codecs; |
|
514 CleanupClosePushL(codecs); |
|
515 codecs.Reset(); |
|
516 GetSupportedFormatsL(iPriority, codecs); //sets iCodecFormats |
|
517 status = FindFormat(aFormat); |
|
518 CleanupStack::PopAndDestroy(&codecs); |
|
519 iCodecFormats = NULL; |
|
520 } |
|
521 else |
|
522 { |
|
523 status = FindFormat(aFormat); |
|
524 } |
|
525 |
|
526 return status; |
|
527 } |
|
528 |
|
529 // ----------------------------------------------------------------------------- |
|
530 // CVoIPAudioUplinkStreamImpl::FindFormat |
|
531 // ----------------------------------------------------------------------------- |
|
532 // |
|
533 TBool CVoIPAudioUplinkStreamImpl::FindFormat(TVoIPCodecFormat aFormat) |
|
534 { |
|
535 TBool found = EFalse; |
|
536 |
|
537 if (iCodecFormats) |
|
538 { |
|
539 if (iCodecFormats->Count() > 0) |
|
540 { |
|
541 if (iCodecFormats->Find(aFormat) == KErrNotFound) |
|
542 { |
|
543 // For backward compatibility with VAS 1.0 |
|
544 if (aFormat == EG711) |
|
545 { |
|
546 if (iCodecFormats->Find(EG711_10MS) != KErrNotFound) |
|
547 { |
|
548 iFormat = EG711_10MS; |
|
549 found = ETrue; |
|
550 } |
|
551 } |
|
552 } |
|
553 else |
|
554 { |
|
555 iFormat = aFormat; |
|
556 found = ETrue; |
|
557 } |
|
558 } |
|
559 } |
|
560 |
|
561 return found; |
|
562 } |
|
563 |
|
564 // ======== CALLBACK FUNCTIONS ======== |
|
565 |
|
566 // --------------------------------------------------------------------------- |
|
567 // CVoIPAudioUplinkStreamImpl::EmptyBuffer |
|
568 // --------------------------------------------------------------------------- |
|
569 // |
|
570 void CVoIPAudioUplinkStreamImpl::EmptyBuffer(CVoIPDataBuffer* aBuffer) |
|
571 { |
|
572 // Recorded packets may still be flowing despite client's Close request. |
|
573 // It is safer just to throw them away here. |
|
574 if (!iIsClosing) |
|
575 { |
|
576 iObserver->EmptyBuffer(*this, aBuffer); |
|
577 } |
|
578 } |
|
579 |
|
580 // --------------------------------------------------------------------------- |
|
581 // CVoIPAudioUplinkStreamImpl::Event |
|
582 // --------------------------------------------------------------------------- |
|
583 // |
|
584 void CVoIPAudioUplinkStreamImpl::Event(TInt aEventType, TInt aError) |
|
585 { |
|
586 iObserver->Event(*this, aEventType, aError); |
|
587 } |
|
588 |
|
589 // --------------------------------------------------------------------------- |
|
590 // CVoIPAudioUplinkStreamImpl::Event |
|
591 // From MVoIPFormatObserver |
|
592 // --------------------------------------------------------------------------- |
|
593 // |
|
594 void CVoIPAudioUplinkStreamImpl::Event(const CVoIPFormatIntfc& /*aSrc*/, |
|
595 TInt /*aEventType*/) |
|
596 { |
|
597 } |
|
598 |
|
599 // End of file |