1 /* |
|
2 * Copyright (c) 2006-2007 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: ?Description |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32property.h> |
|
20 #include "irpubsubkeys.h" |
|
21 |
|
22 #include "irctrlcmdobserver.h" |
|
23 #include "irdebug.h" |
|
24 #include "irmediaclient.h" |
|
25 #include "irmediaenginebuffer.h" |
|
26 #include "irmediaengineinterface.h" |
|
27 #include "ircontrolparams.h" |
|
28 |
|
29 const TInt KZeroVolumeLevel = 0; |
|
30 const TInt KIRBitRateDivider = 8; // To convert bits to bytes. |
|
31 const TInt KIRByteMultiplier = 1024; // To convert kilo bytes to bytes. |
|
32 const TInt KIRValidBitRate = 0; // Starting point for valid bit rate. |
|
33 const TInt KIRDefBitRate = 64; // Default bit rate for buffer size calculation. |
|
34 const TInt KIRMinBitRate = 8; // Minimum bit rate for buffer size calculation. |
|
35 const TInt KIRMaxBitRate = 192; // Maximum bit rate for buffer size calculation. |
|
36 |
|
37 // ============================ MEMBER FUNCTIONS =============================== |
|
38 |
|
39 // --------------------------------------------------------------------------- |
|
40 // Function : NewL |
|
41 // Two Phase Constructor - NewL |
|
42 // --------------------------------------------------------------------------- |
|
43 // |
|
44 CIRMediaClient* CIRMediaClient::NewL(CIRCtrlCmdObserver* aChannel) |
|
45 { |
|
46 IRLOG_DEBUG( "CIRMediaClient::NewL - Entering" ); |
|
47 CIRMediaClient* self = NewLC(aChannel); |
|
48 CleanupStack::Pop(self); |
|
49 IRLOG_DEBUG( "CIRMediaClient::NewL - Exiting." ); |
|
50 return self; |
|
51 } |
|
52 |
|
53 // --------------------------------------------------------------------------- |
|
54 // Function : NewLC |
|
55 // Two Phase Constructor - NewLC |
|
56 // --------------------------------------------------------------------------- |
|
57 // |
|
58 CIRMediaClient* CIRMediaClient::NewLC(CIRCtrlCmdObserver* aChannel) |
|
59 { |
|
60 IRLOG_DEBUG( "CIRMediaClient::NewLC - Entering" ); |
|
61 CIRMediaClient* self = new (ELeave) CIRMediaClient(); |
|
62 CleanupStack::PushL(self); |
|
63 self->ConstructL(aChannel); |
|
64 IRLOG_DEBUG( "CIRMediaClient::NewLC - Exiting." ); |
|
65 return self; |
|
66 } |
|
67 |
|
68 // --------------------------------------------------------------------------- |
|
69 // destructor function |
|
70 // destructor of the player component |
|
71 // --------------------------------------------------------------------------- |
|
72 // |
|
73 CIRMediaClient::~CIRMediaClient() |
|
74 { |
|
75 IRLOG_DEBUG( "CIRMediaClient::~CIRMediaClient - Entering" ); |
|
76 //deletes the player |
|
77 delete iPlayer; |
|
78 //deletes the buffers associated with player |
|
79 delete[] iTempBuffer; |
|
80 delete[] iCurrentBuffer; |
|
81 IRLOG_DEBUG( "CIRMediaClient::~CIRMediaClient - Exiting." ); |
|
82 } |
|
83 |
|
84 // --------------------------------------------------------------------------- |
|
85 // This is default Constructor |
|
86 // for the class CIRMediaClient |
|
87 // --------------------------------------------------------------------------- |
|
88 // |
|
89 CIRMediaClient::CIRMediaClient():iInputBuffer(NULL,0,0) |
|
90 { |
|
91 IRLOG_DEBUG( "CIRMediaClient::CIRMediaClient" ); |
|
92 } |
|
93 |
|
94 // --------------------------------------------------------------------------- |
|
95 // Two phase ConstructL |
|
96 // network component is taken as input |
|
97 // --------------------------------------------------------------------------- |
|
98 // |
|
99 void CIRMediaClient::ConstructL(CIRCtrlCmdObserver* aChannel) |
|
100 { |
|
101 IRLOG_DEBUG( "CIRMediaClient::ConstructL - Entering" ); |
|
102 iChannel = aChannel; |
|
103 IRLOG_DEBUG( "CIRMediaClient::ConstructL - Exiting" ); |
|
104 } |
|
105 |
|
106 //For Play control |
|
107 |
|
108 // --------------------------------------------------------------------------- |
|
109 // Function : PlayL |
|
110 // Starts to play the stream |
|
111 // --------------------------------------------------------------------------- |
|
112 // |
|
113 TInt CIRMediaClient::Play() |
|
114 { |
|
115 IRLOG_DEBUG( "CIRMediaClient::Play - Entering" ); |
|
116 IRLOG_DEBUG( "CIRMediaClient::Play - Exiting" ); |
|
117 //sents a play request to media engine |
|
118 if( iPlayer ) |
|
119 { |
|
120 iPlayer->Play(); |
|
121 IRLOG_DEBUG( "CIRMediaClient::Play - Exiting (1)." ); |
|
122 return KErrNone; |
|
123 } |
|
124 else |
|
125 { |
|
126 IRLOG_DEBUG( "CIRMediaClient::Play - Exiting (2)." ); |
|
127 return KErrNotFound; |
|
128 } |
|
129 } |
|
130 |
|
131 // --------------------------------------------------------------------------- |
|
132 // Function : StopL |
|
133 // Stops to play the stream |
|
134 // --------------------------------------------------------------------------- |
|
135 // |
|
136 void CIRMediaClient::Stop() |
|
137 { |
|
138 IRLOG_DEBUG( "CIRMediaClient::Stop - Entering" ); |
|
139 //sents a stop request to media engine |
|
140 if( iPlayer ) |
|
141 { |
|
142 iPlayer->Stop(); |
|
143 } |
|
144 else |
|
145 { |
|
146 iCommand = EStoppedPlaying; |
|
147 iChannel->SentRequest(iCommand,KErrNone); |
|
148 } |
|
149 IRLOG_DEBUG( "CIRMediaClient::Stop - Exiting." ); |
|
150 } |
|
151 |
|
152 //For Volume Control |
|
153 // --------------------------------------------------------------------------- |
|
154 // Function : SetVolume |
|
155 // function to set the volume, |
|
156 // --------------------------------------------------------------------------- |
|
157 // |
|
158 void CIRMediaClient::SetVolume(TInt aVolume ) |
|
159 { |
|
160 IRLOG_DEBUG( "CIRMediaClient::SetVolume - Entering" ); |
|
161 //if player is exists it will set the volume |
|
162 if( iPlayer ) |
|
163 { |
|
164 iPlayer->SetVolume(aVolume); |
|
165 } |
|
166 IRLOG_DEBUG( "CIRMediaClient::SetVolume - Exiting." ); |
|
167 } |
|
168 |
|
169 // --------------------------------------------------------------------------- |
|
170 // Function : MaxVolume |
|
171 // --------------------------------------------------------------------------- |
|
172 // |
|
173 TInt CIRMediaClient::MaxVolume() const |
|
174 { |
|
175 IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Entering" ); |
|
176 IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting" ); |
|
177 //if player is created it will sent the max volume else return zero instead of MaxVolume |
|
178 if( iPlayer ) |
|
179 { |
|
180 IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting (1)." ); |
|
181 //returns maximum volume if player exists |
|
182 return iPlayer->MaxVolume(); |
|
183 } |
|
184 else |
|
185 { |
|
186 //else zero is returned |
|
187 IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting (2)." ); |
|
188 return KZeroVolumeLevel; |
|
189 } |
|
190 } |
|
191 |
|
192 // --------------------------------------------------------------------------- |
|
193 // Function : Volume |
|
194 // function to returns the volume |
|
195 // --------------------------------------------------------------------------- |
|
196 // |
|
197 TInt CIRMediaClient::Volume() const |
|
198 { |
|
199 IRLOG_DEBUG( "CIRMediaClient::Volume - Entering" ); |
|
200 IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting" ); |
|
201 //if player is created it will sent the volume else return zero instead of Volume |
|
202 if( iPlayer ) |
|
203 { |
|
204 //if player exist it returns the current volume |
|
205 IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting (1)." ); |
|
206 return iPlayer->Volume(); |
|
207 } |
|
208 else |
|
209 { |
|
210 //else will return negative volume |
|
211 IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting (2)." ); |
|
212 return KZeroVolumeLevel; |
|
213 } |
|
214 } |
|
215 |
|
216 // --------------------------------------------------------------------------- |
|
217 // Function: BufferFilled |
|
218 // Set the whether a Fill Buffer is currently active |
|
219 // --------------------------------------------------------------------------- |
|
220 // |
|
221 void CIRMediaClient::BufferFilled() |
|
222 { |
|
223 IRLOG_DEBUG( "CIRMediaClient::BufferFilled - Entering" ); |
|
224 if( iFirstTime ) |
|
225 { |
|
226 //First all the buffers are filled |
|
227 iInputBufferPtr += iConfig.iPlayBufferSize; |
|
228 if( (iInputBufferPtr + iConfig.iPlayBufferSize) <= |
|
229 (iTempBuffer + iConfig.iPlayBufferCount*iConfig.iPlayBufferSize) ) |
|
230 { |
|
231 //buffer is not completely filled |
|
232 iInputBuffer.Set(iInputBufferPtr,iConfig.iPlayBufferSize,iConfig.iPlayBufferSize); |
|
233 |
|
234 if( iStopBuffering ) |
|
235 { |
|
236 //if iStopBuffering is true we won't continue in this loop |
|
237 return; |
|
238 } |
|
239 else // if not stop buffering is called |
|
240 { |
|
241 //fills the buffer and sents the buffer percentage |
|
242 iChannel->FilltheBuffer(iInputBuffer); |
|
243 } |
|
244 } |
|
245 else |
|
246 { |
|
247 //buffer is completely filled |
|
248 iFirstTime = EFalse; |
|
249 iNewPlayer = EFalse; |
|
250 if( iStopBuffering ) |
|
251 { |
|
252 //if stop buffering is true we will not proceed further |
|
253 return; |
|
254 } |
|
255 else |
|
256 { |
|
257 // Error reporting done inside CreatePlayer |
|
258 if ( CreatePlayer() ) |
|
259 { |
|
260 // Sending this event causes NowPlayingView activation |
|
261 iBufferPercentage = K100Percentage; |
|
262 iChannel->SentRequest( EBufferFillStop, iBufferPercentage ); |
|
263 |
|
264 //player has already buffered completely for the first time |
|
265 //so even if StopInitialBuffering is called media client is help less |
|
266 //to handle this situation iStopBuffering is made ETrue |
|
267 iStopBuffering = ETrue; |
|
268 |
|
269 //called for intializing a new player |
|
270 InitializePlayer( iConfig,iChannel ); |
|
271 |
|
272 //calls play for the first time |
|
273 iPlayer->Play(); |
|
274 } |
|
275 } |
|
276 } |
|
277 } |
|
278 else |
|
279 { |
|
280 //buffer is already filled for first time |
|
281 //media engine is created and playing so Buffer filled |
|
282 //function of media Engine should be called |
|
283 iPlayer->BufferFilled(); |
|
284 } |
|
285 IRLOG_DEBUG( "CIRMediaClient::BufferFilled - Exiting." ); |
|
286 } |
|
287 |
|
288 // --------------------------------------------------------------------------- |
|
289 // Function: StartNewPlayerL |
|
290 // Set the whether a Fill Buffer is currently active |
|
291 // --------------------------------------------------------------------------- |
|
292 // |
|
293 void CIRMediaClient::StartNewPlayerL(TConfig& aConfig,const TDesC8& aFormat |
|
294 ) |
|
295 { |
|
296 IRLOG_DEBUG( "CIRMediaClient::StartNewPlayerL - Entering" ); |
|
297 //format is copied |
|
298 iFormat.Copy(aFormat); |
|
299 |
|
300 //stop of intial buffering from media client is enable |
|
301 iStopBuffering = EFalse; |
|
302 |
|
303 iConfig = aConfig; |
|
304 |
|
305 TInt bitRate(0); |
|
306 RProperty::Get ( KUidActiveInternetRadioApp, KIRPSBitrate, bitRate ); |
|
307 // Next line will round the bitrate down to be divisible by KIRBitRateDivider. |
|
308 bitRate = bitRate - (bitRate % KIRBitRateDivider); |
|
309 if( bitRate <= KIRValidBitRate ) |
|
310 { |
|
311 // If invalid bit rate info, use default bit rate for calculating buffer sizes. |
|
312 bitRate = KIRDefBitRate; |
|
313 } |
|
314 else if( bitRate < KIRMinBitRate ) |
|
315 { |
|
316 // If small bit rate info, use minimum bit rate for calculating buffer sizes. |
|
317 // To make single buffer minimum size 1 kB. |
|
318 bitRate = KIRMinBitRate; |
|
319 } |
|
320 else if( bitRate > KIRMaxBitRate ) |
|
321 { |
|
322 // If large bit rate info, use maximum bit rate for calculating buffer sizes. |
|
323 // To make single buffer maximum size 24 kB. |
|
324 bitRate = KIRMaxBitRate; |
|
325 } |
|
326 else |
|
327 { |
|
328 } |
|
329 iConfig.iPlayBufferCount = KIRInputBufferCount; |
|
330 iConfig.iPlayBufferSize = KIRByteMultiplier*bitRate/KIRBitRateDivider; |
|
331 |
|
332 //creates a new instance of media buffer for new player |
|
333 iTempBuffer = new (ELeave) TUint8[iConfig.iPlayBufferCount*iConfig.iPlayBufferSize]; |
|
334 iInputBufferPtr = iTempBuffer; |
|
335 |
|
336 //initial buffering starts |
|
337 iInputBuffer.Set(iInputBufferPtr,iConfig.iPlayBufferSize,iConfig.iPlayBufferSize); |
|
338 iNewPlayer = ETrue; |
|
339 iFirstTime = ETrue; |
|
340 |
|
341 //initial buffering starts |
|
342 iChannel->FilltheBuffer(iInputBuffer); |
|
343 |
|
344 //starts audio fade out for the previous channel |
|
345 IRLOG_DEBUG( "CIRMediaClient::StartNewPlayerL - Exiting." ); |
|
346 } |
|
347 |
|
348 // --------------------------------------------------------------------------- |
|
349 // Function: StopMediaBuffering |
|
350 // stops buffering of media engine, the change cannot be reverted |
|
351 // --------------------------------------------------------------------------- |
|
352 // |
|
353 void CIRMediaClient::StopMediaBuffering() |
|
354 { |
|
355 IRLOG_DEBUG( "CIRMediaClient::StopMediaBuffering - Entering" ); |
|
356 //calls media engine's stop buffering cancels the buffering in media engine |
|
357 if( iPlayer ) |
|
358 { |
|
359 iPlayer->StopPlayerBuffering(); |
|
360 } |
|
361 IRLOG_DEBUG( "CIRMediaClient::StopMediaBuffering - Exiting." ); |
|
362 } |
|
363 |
|
364 // --------------------------------------------------------------------------- |
|
365 // Function: StopInitialBuffering |
|
366 // stops buffering from media client, media engine is not stopped |
|
367 // --------------------------------------------------------------------------- |
|
368 // |
|
369 void CIRMediaClient::StopInitialBuffering() |
|
370 { |
|
371 IRLOG_DEBUG( "CIRMediaClient::StopInitialBuffering - Entering" ); |
|
372 //initially buffering is taken care by media client and then |
|
373 //it shift the responsibility to media engine |
|
374 //this is done because audio fade out has to take place when other channel buffers |
|
375 //if media client is handling the buffer it should be stopped |
|
376 //media client is handling the buffering |
|
377 iStopBuffering = ETrue; |
|
378 |
|
379 delete[] iTempBuffer; |
|
380 iTempBuffer = NULL; |
|
381 |
|
382 iCommand=EStereo; |
|
383 iChannel->SentRequest(iCommand,KErrNone); |
|
384 delete iPlayer; |
|
385 iPlayer = NULL; |
|
386 |
|
387 iStopBuffering = ETrue; |
|
388 //return true to indicate success of cancelling of buffer |
|
389 IRLOG_DEBUG( "CIRMediaClient::StopInitialBuffering - Exiting." ); |
|
390 } |
|
391 |
|
392 // --------------------------------------------------------------------------- |
|
393 // Function: SetCodecSettings |
|
394 // Creates an instance of the players and initialize it |
|
395 // --------------------------------------------------------------------------- |
|
396 // |
|
397 TBool CIRMediaClient::CreatePlayer() |
|
398 { |
|
399 IRLOG_DEBUG( "CIRMediaClient::CreatePlayer" ); |
|
400 TBool createResult( ETrue ); |
|
401 //delete the instance of previously created player |
|
402 iCommand=EStereo; |
|
403 iChannel->SentRequest(iCommand,KErrNone); |
|
404 if ( iPlayer ) |
|
405 { |
|
406 delete iPlayer; |
|
407 iPlayer = NULL; |
|
408 } |
|
409 |
|
410 //media engine's instance is created type is stored in iFormat (basically the mime type) |
|
411 TRAPD(error,iPlayer = CIRMediaEngineInterface::NewL(iFormat)); |
|
412 if( error ) |
|
413 { |
|
414 iChannel->SentRequest( EError, KIRCtrlCmdPlayerNotCreated ); |
|
415 createResult = EFalse; |
|
416 } |
|
417 |
|
418 return createResult; |
|
419 } |
|
420 // --------------------------------------------------------------------------- |
|
421 // CIRMediaClient::InitializePlayer |
|
422 // --------------------------------------------------------------------------- |
|
423 // |
|
424 void CIRMediaClient::InitializePlayer( TConfig& aConfig, |
|
425 CIRCtrlCmdObserver* aChannel) |
|
426 { |
|
427 IRLOG_DEBUG( "CIRMediaClient::SetCodecSettings" ); |
|
428 |
|
429 //delete the instance of buffer associated with previously playing player |
|
430 delete[] iCurrentBuffer; |
|
431 iCurrentBuffer = NULL; |
|
432 |
|
433 //current buffer is made same as previous buffer |
|
434 iCurrentBuffer = iTempBuffer; |
|
435 iTempBuffer = NULL; |
|
436 |
|
437 //intialize the media engine |
|
438 iPlayer->Intialize(aConfig,iCurrentBuffer,aChannel); |
|
439 IRLOG_DEBUG( "CIRMediaClient::SetCodecSettings - Exiting." ); |
|
440 } |
|
441 |
|
442 // --------------------------------------------------------------------------- |
|
443 // CIRNowPlayingWrapper::GetMediaClientInstance() |
|
444 // Returns the Audio Player Instance |
|
445 // --------------------------------------------------------------------------- |
|
446 // |
|
447 CMdaAudioOutputStream* CIRMediaClient::GetPlayerInstance() |
|
448 { |
|
449 IRLOG_DEBUG( "CIRMediaClient::GetMediaClientInstance " ); |
|
450 return (iPlayer->GetAudioPlayer()); |
|
451 } |
|