--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/mmapi_akn/baseline/src/cmmavideoframepositioningcontrol.cpp Wed Sep 01 12:33:18 2010 +0100
@@ -0,0 +1,284 @@
+/*
+* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This class implements FramePositioningControl for video player
+*
+*/
+
+
+// INCLUDE FILES
+#include <jdebug.h>
+#include <e32base.h>
+#include <e32math.h>
+
+#include "cmmavideoframepositioningcontrol.h"
+
+namespace
+{
+const TInt32 KMMAFramePosMicroSecMultiplier = 1000000;
+}
+
+CMMAVideoFramePositioningControl*
+CMMAVideoFramePositioningControl::NewL(CMMAVideoPlayer* aPlayer)
+{
+ CMMAVideoFramePositioningControl* self =
+ new(ELeave) CMMAVideoFramePositioningControl(aPlayer);
+ return self;
+
+}
+CMMAVideoFramePositioningControl::
+CMMAVideoFramePositioningControl(CMMAVideoPlayer* aPlayer)
+ : CMMAFramePositioningControl(aPlayer), iPlayer(aPlayer)
+{
+ DEBUG("MMA:CMMAVideoFramePositioningControl::CMMAVideoFramePositioningControl");
+}
+
+CMMAVideoFramePositioningControl::~CMMAVideoFramePositioningControl()
+{
+ DEBUG("MMA:CMMAVideoFramePositioningControl::~CMMAVideoFramePositioningControl");
+}
+
+TInt CMMAVideoFramePositioningControl::SeekL(TInt aFrameNumber)
+{
+ DEBUG_INT("CMMAVideoFramePositioningControl::SeekL, aFrameNumber: %d", aFrameNumber);
+
+ RMMFController& controller = iPlayer->Controller();
+
+ // Controller is paused before changing position to increase
+ // accuracy
+ TBool playerStarted = EFalse;
+ if (iPlayer->State() == CMMAPlayer::EStarted)
+ {
+ playerStarted = ETrue;
+ }
+
+ if (playerStarted)
+ {
+ User::LeaveIfError(controller.Pause());
+ }
+
+ // Frame number must be positive
+ TInt frameNumber = aFrameNumber;
+ if (frameNumber < 0)
+ {
+ frameNumber = 0;
+ }
+
+ // Find out framerate of video
+ TReal32 frameRate = 0;
+ GetAndCheckFrameRateL(frameRate);
+
+ // Calculate new media time
+ TReal tempReal = ((TReal32)frameNumber *
+ KMMAFramePosMicroSecMultiplier) / frameRate;
+ User::LeaveIfError(Math::Round(tempReal, tempReal, 0));
+ TInt64 newMediaTime = tempReal;
+
+ // New media time is clamped to duration
+ TInt err = ClampMediaTime(newMediaTime);
+ // Clamp fails if duration of content is not known.
+ // Two additional resorts are (in preferred order):
+ // 1) Return current frame position if it can be calculated.
+ // 2) Or seek to 0.
+
+ // First resort
+ if (err != KErrNone)
+ {
+ iPlayer->GetMediaTime(&newMediaTime);
+ // Second resort
+ if (newMediaTime < 0)
+ {
+ newMediaTime = 0;
+ }
+ }
+ iPlayer->SetMediaTimeL(&newMediaTime);
+ // Error condition
+ if (newMediaTime < KErrNotFound)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Calculate actually set frame number
+ tempReal = (((TReal32)newMediaTime / KMMAFramePosMicroSecMultiplier) *
+ (TReal32) frameRate);
+ User::LeaveIfError(Math::Round(tempReal, tempReal, 0));
+
+ // Restart controller
+ if (playerStarted)
+ {
+ User::LeaveIfError(controller.Play());
+ }
+
+ return tempReal;
+}
+
+TInt CMMAVideoFramePositioningControl::SkipL(TInt aFramesToSkip)
+{
+ DEBUG_INT("CMMAVideoFramePositioningControl::SkipL, aFramesToSkip: %d", aFramesToSkip);
+
+ RMMFController& controller = iPlayer->Controller();
+
+ // Controller is paused before changing position to increase
+ // accuracy
+ TBool playerStarted = EFalse;
+ if (iPlayer->State() == CMMAPlayer::EStarted)
+ {
+ playerStarted = ETrue;
+ }
+
+ if (playerStarted)
+ {
+ User::LeaveIfError(controller.Pause());
+ }
+
+ // Find out framerate of video
+ TReal32 frameRate = 0;
+ GetAndCheckFrameRateL(frameRate);
+
+ // Find out current media time
+ TInt64 currentMediaTime = 0;
+ iPlayer->GetMediaTime(¤tMediaTime);
+
+ // Error condition
+ if (currentMediaTime < KErrNone)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Find out current frame number
+ TReal tempReal =
+ ((TReal32) currentMediaTime / KMMAFramePosMicroSecMultiplier) *
+ frameRate;
+ User::LeaveIfError(Math::Round(tempReal, tempReal, 0));
+ TInt currentFrameNumber = tempReal;
+
+ // Calculate new media time
+ TInt64 newMediaTime = currentMediaTime +
+ (((TReal32) aFramesToSkip / frameRate) * KMMAFramePosMicroSecMultiplier);
+
+ // New media time is clamped to duration
+ TInt err = ClampMediaTime(newMediaTime);
+
+ // If clamping fails, no frames are skipped
+ TInt framesSkipped = 0;
+ if (err == KErrNone)
+ {
+ iPlayer->SetMediaTimeL(&newMediaTime);
+ // Error condition
+ if (newMediaTime < KErrNone)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Calculate actual amount of frames skipped
+ tempReal = ((((TReal32) newMediaTime / KMMAFramePosMicroSecMultiplier) *
+ (TReal32) frameRate) - currentFrameNumber);
+
+ User::LeaveIfError(Math::Round(tempReal, tempReal, 0));
+ framesSkipped = tempReal;
+ }
+
+ // Restart controller
+ if (playerStarted)
+ {
+ User::LeaveIfError(controller.Play());
+ }
+
+ return framesSkipped;
+}
+
+void CMMAVideoFramePositioningControl::MapFrameToTimeL(TInt aFrameNumber, TInt64* aMediaTime)
+{
+ DEBUG_INT("CMMAVideoFramePositioningControl::MapFrameToTimeL, aFrameNumber: %d", aFrameNumber);
+ // Find out framerate of video
+ TReal32 frameRate = 0;
+ GetAndCheckFrameRateL(frameRate);
+
+ // Find out frame mediatime
+ TInt64 frameMediaTime =
+ ((TReal32)aFrameNumber / (TReal32)frameRate) *
+ KMMAFramePosMicroSecMultiplier;
+
+ TInt64 duration;
+ iPlayer->GetDuration(&duration);
+
+ if (frameMediaTime < 0)
+ {
+ frameMediaTime = KErrNotFound;
+ }
+ else if (frameMediaTime > duration)
+ {
+ frameMediaTime = KErrNotFound;
+ // With some medias last frame media time is few hundred microsec's
+ // over duration. This is because framerate is not accurate.
+ // If given frame number is last frame and frameMediaTime > duration,
+ // return duration
+ // Find out last frame
+ TReal lastFrame = (frameRate * (TReal32)duration) /
+ KMMAFramePosMicroSecMultiplier;
+ User::LeaveIfError(Math::Round(lastFrame, lastFrame, 0));
+ if (aFrameNumber == lastFrame)
+ {
+ frameMediaTime = duration;
+ }
+ }
+ *aMediaTime = frameMediaTime;
+}
+
+TInt CMMAVideoFramePositioningControl::MapTimeToFrameL(TInt64* aMediaTime)
+{
+ DEBUG_INT("CMMAVideoFramePositioningControl::MapTimeToFrameL, aMediaTime: %d", *aMediaTime);
+ TInt64 mediaTime = *aMediaTime;
+
+ // If given media time is < 0 or > duration, cannot map time to frame
+ // conversion fails, -1 is returned
+ TInt64 duration;
+ iPlayer->GetDuration(&duration);
+ if (mediaTime > duration || mediaTime < 0)
+ {
+ return KErrNotFound;
+ }
+
+ // Find out framerate of video
+ TReal32 frameRate = 0;
+ GetAndCheckFrameRateL(frameRate);
+
+ // Calculate frame number from media time
+ TReal tempReal = (TInt)((TReal64)(mediaTime * frameRate) /
+ KMMAFramePosMicroSecMultiplier);
+ User::LeaveIfError(Math::Round(tempReal, tempReal, 0));
+
+ return tempReal;
+}
+
+
+void CMMAVideoFramePositioningControl::GetAndCheckFrameRateL(
+ TReal32& aFrameRate)
+{
+ DEBUG("CMMAVideoFramePositioningControl::GetAndCheckFrameRateL");
+ RMMFVideoControllerCustomCommands customCommands =
+ RMMFVideoControllerCustomCommands(iPlayer->Controller());
+
+ User::LeaveIfError(customCommands.GetFrameRate(aFrameRate));
+ DEBUG_INT("CMMAVideoFramePositioningControl::GetAndCheckFrameRateL, aFrameRate: %d", aFrameRate);
+ if (aFrameRate <= 0)
+ {
+ // zero framerate is not accepted because cannot
+ // divide by zero. Negative framerate is not
+ // acceptable aswell.
+ DEBUG("CMMAVideoFramePositioningControl::GetAndCheckFrameRateL: invalid framerate");
+ User::Leave(KErrNotFound);
+ }
+}
+
+// END OF FILE