|
1 /* |
|
2 * Copyright (c) 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 // USER |
|
19 #include "musengclipvideoplayer.h" |
|
20 #include "musengcamerahandler.h" |
|
21 #include "musengmceutils.h" |
|
22 #include "musengdisplayhandler.h" |
|
23 #include "muslogger.h" |
|
24 |
|
25 // SYSTEM |
|
26 #include <mcesession.h> |
|
27 #include <mcevideostream.h> |
|
28 #include <mcefilesource.h> |
|
29 #include <drmcommon.h> |
|
30 |
|
31 // CONSTANTS |
|
32 const TInt64 KMicroSecondsInOneSecond = 1000000; |
|
33 const TInt KFastWindingFactor = 4; |
|
34 |
|
35 // ----------------------------------------------------------------------------- |
|
36 // |
|
37 // ----------------------------------------------------------------------------- |
|
38 // |
|
39 CMusEngClipVideoPlayer* CMusEngClipVideoPlayer::NewL( |
|
40 MMusEngDisplayHandler& aDisplayHandler, |
|
41 MLcAudioControl& aLcAudioControl ) |
|
42 { |
|
43 return new( ELeave )CMusEngClipVideoPlayer( |
|
44 aDisplayHandler, aLcAudioControl ); |
|
45 } |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // |
|
49 // ----------------------------------------------------------------------------- |
|
50 // |
|
51 CMusEngClipVideoPlayer::CMusEngClipVideoPlayer( |
|
52 MMusEngDisplayHandler& aDisplayHandler, |
|
53 MLcAudioControl& aLcAudioControl ) : |
|
54 CMusEngLocalVideoPlayer( aDisplayHandler, aLcAudioControl ) |
|
55 { |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // |
|
60 // ----------------------------------------------------------------------------- |
|
61 // |
|
62 CMusEngClipVideoPlayer::~CMusEngClipVideoPlayer() |
|
63 { |
|
64 } |
|
65 |
|
66 // ----------------------------------------------------------------------------- |
|
67 // |
|
68 // ----------------------------------------------------------------------------- |
|
69 // |
|
70 TBool CMusEngClipVideoPlayer::HasClipEnded() |
|
71 { |
|
72 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::HasClipEnded" ) |
|
73 |
|
74 TBool hasClipEnded( EFalse ); |
|
75 |
|
76 if ( iMceSession ) |
|
77 { |
|
78 CMceVideoStream* videoOut = NULL; |
|
79 |
|
80 TRAPD( err, |
|
81 videoOut = MusEngMceUtils::GetVideoOutStreamL( *iMceSession ) ); |
|
82 if ( err != KErrNone ) |
|
83 { |
|
84 MUS_LOG1( "mus: [ENGINE] Error in GetVideoOutStreamL %d", err ) |
|
85 return EFalse; |
|
86 } |
|
87 |
|
88 CMceFileSource* filesource = NULL; |
|
89 TRAP( err, filesource = MusEngMceUtils::GetFileSourceL( *iMceSession ) ) |
|
90 |
|
91 if ( err == KErrNone ) |
|
92 { |
|
93 TTimeIntervalMicroSeconds position; |
|
94 TTimeIntervalMicroSeconds duration; |
|
95 TRAP( err, position = filesource->PositionL() ); |
|
96 TRAPD( err2, duration = filesource->DurationL() ); |
|
97 if ( err != KErrNone || err2 != KErrNone ) |
|
98 { |
|
99 return EFalse; |
|
100 } |
|
101 |
|
102 MUS_LOG2( "mus: [ENGINE] position = %Ld, duration = %Ld", |
|
103 position.Int64(), duration.Int64() ) |
|
104 |
|
105 hasClipEnded = |
|
106 ( position.Int64() == 0 && |
|
107 !filesource->IsEnabled() && |
|
108 videoOut->State() == CMceMediaStream::EDisabled ); |
|
109 } |
|
110 } |
|
111 |
|
112 if ( hasClipEnded ) |
|
113 { |
|
114 iDelayFileEndingPos = 0; |
|
115 } |
|
116 |
|
117 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::HasClipEnded" ) |
|
118 |
|
119 return hasClipEnded; |
|
120 } |
|
121 |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 void CMusEngClipVideoPlayer::SetBufferingPeriod( |
|
127 const TTimeIntervalMicroSeconds& aPeriod ) |
|
128 { |
|
129 iBufferingPeriod = aPeriod; |
|
130 } |
|
131 |
|
132 // ----------------------------------------------------------------------------- |
|
133 // From MLcVideoPlayer |
|
134 // ----------------------------------------------------------------------------- |
|
135 // |
|
136 TBool CMusEngClipVideoPlayer::LcIsPlayingL() |
|
137 { |
|
138 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
139 return ( MusEngMceUtils::GetFileSourceL( *iMceSession )->IsEnabled() ); |
|
140 } |
|
141 |
|
142 // ----------------------------------------------------------------------------- |
|
143 // From MLcVideoPlayer |
|
144 // ----------------------------------------------------------------------------- |
|
145 // |
|
146 void CMusEngClipVideoPlayer::LcPlayL() |
|
147 { |
|
148 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::LcPlayL" ) |
|
149 |
|
150 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
151 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
152 |
|
153 if ( !file->IsEnabled() ) |
|
154 { |
|
155 file->EnableL(); |
|
156 } |
|
157 |
|
158 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::LcPlayL" ) |
|
159 } |
|
160 |
|
161 // ----------------------------------------------------------------------------- |
|
162 // From MLcVideoPlayer |
|
163 // ----------------------------------------------------------------------------- |
|
164 // |
|
165 void CMusEngClipVideoPlayer::LcPauseL() |
|
166 { |
|
167 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::LcPauseL" ) |
|
168 |
|
169 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
170 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
171 |
|
172 if ( file->IsEnabled() ) |
|
173 { |
|
174 file->DisableL(); |
|
175 } |
|
176 |
|
177 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::LcPauseL" ) |
|
178 } |
|
179 |
|
180 // ----------------------------------------------------------------------------- |
|
181 // From MLcVideoPlayer |
|
182 // ----------------------------------------------------------------------------- |
|
183 // |
|
184 MLcSourceFileControl* CMusEngClipVideoPlayer::LcSourceFileControl() |
|
185 { |
|
186 return this; |
|
187 } |
|
188 |
|
189 // ----------------------------------------------------------------------------- |
|
190 // From MLcSourceFileControl |
|
191 // ----------------------------------------------------------------------------- |
|
192 // |
|
193 void CMusEngClipVideoPlayer::SetLcFileNameL( const TFileName& aFileName ) |
|
194 { |
|
195 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::SetLcFileNameL" ) |
|
196 |
|
197 __ASSERT_ALWAYS( !IsProtectedFileL( aFileName ), |
|
198 User::Leave( KErrPermissionDenied ) ); |
|
199 |
|
200 if ( iMceSession ) |
|
201 { |
|
202 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
203 file->UpdateL( aFileName ); |
|
204 } |
|
205 |
|
206 iFileName = aFileName; |
|
207 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::SetLcFileNameL" ) |
|
208 } |
|
209 |
|
210 // ----------------------------------------------------------------------------- |
|
211 // From MLcSourceFileControl |
|
212 // ----------------------------------------------------------------------------- |
|
213 // |
|
214 TFileName& CMusEngClipVideoPlayer::LcFileName() |
|
215 { |
|
216 return iFileName; |
|
217 } |
|
218 |
|
219 // ----------------------------------------------------------------------------- |
|
220 // From MLcSourceFileControl |
|
221 // Since MCE does not at the moment support SetFastForwardL function, this |
|
222 // functionality is implemented by taking a timestamp when forwarding is |
|
223 // started and calculating a new position when it is ended. |
|
224 // ----------------------------------------------------------------------------- |
|
225 // |
|
226 void CMusEngClipVideoPlayer::LcFastForwardL( TBool aUseFFWD ) |
|
227 { |
|
228 MUS_LOG1( "mus: [ENGINE] -> CMusEngClipVideoPlayer::FastForward( %d )", |
|
229 aUseFFWD ) |
|
230 |
|
231 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
232 |
|
233 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
234 |
|
235 if ( aUseFFWD ) |
|
236 { |
|
237 // Ignore if we are already fastforwarding |
|
238 if ( iFFWDStartTime.Int64() > 0 ) |
|
239 { |
|
240 return; |
|
241 } |
|
242 |
|
243 // Stop rewinding if ongoing, else just pause file source |
|
244 if ( iFRWDStartTime.Int64() > 0 ) |
|
245 { |
|
246 LcFastRewindL( EFalse ); |
|
247 } |
|
248 else |
|
249 { |
|
250 file->DisableL(); |
|
251 } |
|
252 |
|
253 // Get timestamp for starttime |
|
254 iFFWDStartTime.HomeTime(); |
|
255 } |
|
256 else |
|
257 { |
|
258 // Leave if we are not fastforwarding |
|
259 if ( iFFWDStartTime.Int64() == 0 ) |
|
260 { |
|
261 User::Leave( KErrAlreadyExists ); |
|
262 } |
|
263 |
|
264 // Set new position |
|
265 file->SetPositionL( PositionMicroSecondsL( ETrue ) ); |
|
266 |
|
267 // Reset timer |
|
268 iFFWDStartTime = TTime( 0 ); |
|
269 } |
|
270 |
|
271 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::FastForward" ) |
|
272 } |
|
273 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // From MLcSourceFileControl |
|
276 // Since MCE does not at the moment support SetFastRewindL function, this |
|
277 // functionality is implemented by taking a timestamp when rewinding is |
|
278 // started and calculating a new position when it is ended. |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 void CMusEngClipVideoPlayer::LcFastRewindL( TBool aUseFRWD ) |
|
282 { |
|
283 MUS_LOG1( "mus: [ENGINE] -> CMusEngClipVideoPlayer::FastRewind( %d )", |
|
284 aUseFRWD ) |
|
285 |
|
286 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
287 |
|
288 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
289 |
|
290 if ( aUseFRWD ) |
|
291 { |
|
292 // Ignore if we are already fastrewinding |
|
293 if ( iFRWDStartTime.Int64() > 0 ) |
|
294 { |
|
295 return; |
|
296 } |
|
297 |
|
298 // Stop fastforwarding if ongoing, else just pause file source |
|
299 if ( iFFWDStartTime.Int64() > 0 ) |
|
300 { |
|
301 LcFastForwardL( EFalse ); |
|
302 } |
|
303 else |
|
304 { |
|
305 file->DisableL(); |
|
306 } |
|
307 |
|
308 // Get timestamp for starttime |
|
309 iFRWDStartTime.HomeTime(); |
|
310 } |
|
311 else |
|
312 { |
|
313 // Leave if we are not fastrewinding |
|
314 if ( iFRWDStartTime.Int64() == 0 ) |
|
315 { |
|
316 User::Leave( KErrAlreadyExists ); |
|
317 } |
|
318 |
|
319 // Set new position |
|
320 file->SetPositionL( PositionMicroSecondsL( ETrue ) ); |
|
321 |
|
322 // Reset timer |
|
323 iFRWDStartTime = TTime( 0 ); |
|
324 } |
|
325 |
|
326 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::FastRewind" ) |
|
327 } |
|
328 |
|
329 // ----------------------------------------------------------------------------- |
|
330 // From MLcSourceFileControl |
|
331 // ----------------------------------------------------------------------------- |
|
332 // |
|
333 TTimeIntervalSeconds CMusEngClipVideoPlayer::LcFileDurationL() |
|
334 { |
|
335 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::DurationL" ) |
|
336 |
|
337 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
338 |
|
339 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
340 |
|
341 TTimeIntervalMicroSeconds duration = file->DurationL(); |
|
342 |
|
343 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::DurationL" ) |
|
344 |
|
345 return TTimeIntervalSeconds( static_cast< TInt >( |
|
346 duration.Int64() / KMicroSecondsInOneSecond ) ); |
|
347 } |
|
348 |
|
349 // ----------------------------------------------------------------------------- |
|
350 // From MLcSourceFileControl |
|
351 // ----------------------------------------------------------------------------- |
|
352 // |
|
353 TTimeIntervalSeconds CMusEngClipVideoPlayer::LcFilePositionL() |
|
354 { |
|
355 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::LcFilePositionL" ) |
|
356 |
|
357 TTimeIntervalMicroSeconds currentPosition = PositionMicroSecondsL(); |
|
358 |
|
359 MUS_LOG1( "mus: [ENGINE] <- CMusEngClipVideoPlayer::LcFilePositionL, %d", |
|
360 currentPosition.Int64() ) |
|
361 |
|
362 return TTimeIntervalSeconds( static_cast< TInt >( |
|
363 currentPosition.Int64() / KMicroSecondsInOneSecond ) ); |
|
364 } |
|
365 |
|
366 // ----------------------------------------------------------------------------- |
|
367 // From MLcSourceFileControl |
|
368 // ----------------------------------------------------------------------------- |
|
369 // |
|
370 void CMusEngClipVideoPlayer::SetLcFilePositionL( |
|
371 const TTimeIntervalSeconds& aPosition ) |
|
372 { |
|
373 MUS_LOG1( "mus: [ENGINE] -> CMusEngClipVideoPlayer::SetPositionL ( %d )", |
|
374 aPosition.Int() ) |
|
375 |
|
376 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
377 |
|
378 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
379 |
|
380 TTimeIntervalMicroSeconds position( |
|
381 KMicroSecondsInOneSecond * static_cast< TInt64 >( aPosition.Int() ) ); |
|
382 |
|
383 if ( position == 0 ) |
|
384 { |
|
385 iRewindedToBeginning = ETrue; |
|
386 } |
|
387 |
|
388 file->SetPositionL( position ); |
|
389 |
|
390 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::SetPositionL ()" ) |
|
391 } |
|
392 |
|
393 // ----------------------------------------------------------------------------- |
|
394 // Check is file DRM protected. |
|
395 // ----------------------------------------------------------------------------- |
|
396 // |
|
397 TBool CMusEngClipVideoPlayer::IsProtectedFileL( const TDesC& aClipFile ) |
|
398 { |
|
399 MUS_LOG( "mus: [ENGINE] -> CMusEngClipVideoPlayer::IsProtectedFileL(...)" ) |
|
400 |
|
401 TBool isDRMProtected = EFalse; |
|
402 DRMCommon* drmapi = DRMCommon::NewL(); |
|
403 CleanupStack::PushL( drmapi ); |
|
404 |
|
405 User::LeaveIfError( drmapi->Connect() ); |
|
406 //Check DRM file protection |
|
407 User::LeaveIfError( drmapi->IsProtectedFile( aClipFile, isDRMProtected ) ); |
|
408 drmapi->Disconnect(); |
|
409 |
|
410 CleanupStack::PopAndDestroy( drmapi ); |
|
411 |
|
412 MUS_LOG( "mus: [ENGINE] <- CMusEngClipVideoPlayer::IsProtectedFileL(...)" ) |
|
413 return isDRMProtected; |
|
414 } |
|
415 |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 // ----------------------------------------------------------------------------- |
|
419 // |
|
420 TTimeIntervalMicroSeconds CMusEngClipVideoPlayer::PositionMicroSecondsL( |
|
421 TBool aActualPosition ) |
|
422 { |
|
423 __ASSERT_ALWAYS( iMceSession, User::Leave( KErrNotReady ) ); |
|
424 |
|
425 CMceFileSource* file = MusEngMceUtils::GetFileSourceL( *iMceSession ); |
|
426 |
|
427 TTimeIntervalMicroSeconds position = file->PositionL(); |
|
428 TTimeIntervalMicroSeconds duration = file->DurationL(); |
|
429 |
|
430 TTimeIntervalMicroSeconds calculatedPosition; |
|
431 |
|
432 // Adjust position if we are fastforwarding or -rewinding |
|
433 if ( iFFWDStartTime.Int64() != 0 ) |
|
434 { |
|
435 TTime now; |
|
436 now.HomeTime(); |
|
437 calculatedPosition = KFastWindingFactor * |
|
438 now.MicroSecondsFrom( iFFWDStartTime ).Int64() + |
|
439 position.Int64(); |
|
440 if ( calculatedPosition > duration ) |
|
441 { |
|
442 calculatedPosition = duration; |
|
443 } |
|
444 } |
|
445 else if ( iFRWDStartTime.Int64() != 0 ) |
|
446 { |
|
447 TTime now; |
|
448 now.HomeTime(); |
|
449 calculatedPosition = position.Int64() - |
|
450 KFastWindingFactor * |
|
451 now.MicroSecondsFrom( iFRWDStartTime ).Int64(); |
|
452 if ( calculatedPosition < 0 ) |
|
453 { |
|
454 calculatedPosition = 0; |
|
455 } |
|
456 |
|
457 if ( calculatedPosition == 0 ) |
|
458 { |
|
459 iRewindedToBeginning = ETrue; |
|
460 } |
|
461 } |
|
462 else |
|
463 { |
|
464 calculatedPosition = position; |
|
465 } |
|
466 |
|
467 if ( !aActualPosition ) |
|
468 { |
|
469 calculatedPosition = |
|
470 GetVideoSinkRelativeFilePos( calculatedPosition, duration ); |
|
471 } |
|
472 |
|
473 return calculatedPosition; |
|
474 } |
|
475 |
|
476 // ----------------------------------------------------------------------------- |
|
477 // Modifies file position if position has reached end before clip has ended. |
|
478 // File position is not going in sync with local video playback as playback |
|
479 // buffers media before starting playing. |
|
480 // ----------------------------------------------------------------------------- |
|
481 // |
|
482 TTimeIntervalMicroSeconds CMusEngClipVideoPlayer::GetVideoSinkRelativeFilePos( |
|
483 const TTimeIntervalMicroSeconds& aActualPosition, |
|
484 const TTimeIntervalMicroSeconds& aDuration ) |
|
485 { |
|
486 MUS_LOG1( "mus: [ENGINE] PositionMicroSecondsL, pos before mod:%d", |
|
487 aActualPosition.Int64() ) |
|
488 |
|
489 TTimeIntervalMicroSeconds tempCalculatedPosition( aActualPosition ); |
|
490 |
|
491 if ( iDelayFileEndingPos != 0 ) |
|
492 { |
|
493 iDelayFileEndingPos = aDuration; |
|
494 tempCalculatedPosition = iDelayFileEndingPos; |
|
495 } |
|
496 else |
|
497 { |
|
498 // FRWD can go to zero even if clip has not ended, do not modify |
|
499 // time in such situation. |
|
500 if ( aActualPosition == 0 && |
|
501 !HasClipEnded() && |
|
502 iFRWDStartTime.Int64() == 0 && |
|
503 !iRewindedToBeginning ) |
|
504 { |
|
505 const TInt KMusDelayEndingModifier = 2; |
|
506 iDelayFileEndingPos = aDuration.Int64() - |
|
507 iBufferingPeriod.Int64() / KMusDelayEndingModifier; |
|
508 tempCalculatedPosition = iDelayFileEndingPos; |
|
509 if ( iPreviousPos > tempCalculatedPosition ) |
|
510 { |
|
511 tempCalculatedPosition = iPreviousPos; |
|
512 } |
|
513 } |
|
514 else |
|
515 { |
|
516 iDelayFileEndingPos = 0; |
|
517 } |
|
518 |
|
519 if ( iRewindedToBeginning && aActualPosition > 0 ) |
|
520 { |
|
521 iRewindedToBeginning = EFalse; |
|
522 } |
|
523 |
|
524 if ( tempCalculatedPosition < 0 ) |
|
525 { |
|
526 tempCalculatedPosition = 0; |
|
527 } |
|
528 } |
|
529 |
|
530 iPreviousPos = tempCalculatedPosition; |
|
531 |
|
532 return tempCalculatedPosition; |
|
533 } |
|
534 |
|
535 // End of file |