diff -r a36789189b53 -r 095bea5f582e khronosfws/openmax_al/src/mmf_adaptation/positionupdatetimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/khronosfws/openmax_al/src/mmf_adaptation/positionupdatetimer.cpp Tue Aug 31 15:43:02 2010 +0300 @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2009 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: Handles new position timer implementation + * + */ + +#include "positionupdatetimer.h" +#include +#include +#include + +extern "C" + { +#include "xarecorditfadaptationmmf.h" + } + +#define RET_ERR_IF_ERR(s) if (s!=KErrNone) return s; +#define RET_IF_ERR(s) if (s!=KErrNone) return; + +CPositionUpdateTimer::CPositionUpdateTimer( + CMdaAudioPlayerUtility* aAudioPlayer, + CVideoPlayerUtility2* aVideoPlayer) : + CActive(CActive::EPriorityStandard), iAudioPlayer(aAudioPlayer), + iVideoPlayer(aVideoPlayer) + { + CActiveScheduler::Add(this); + } + +CPositionUpdateTimer::~CPositionUpdateTimer() + { + Cancel(); + iTimer.Close(); + } + +CPositionUpdateTimer* CPositionUpdateTimer::NewL( + CMdaAudioPlayerUtility* aAudioPlayer, + CVideoPlayerUtility2* aVideoPlayer) + { + CPositionUpdateTimer* self = new (ELeave) CPositionUpdateTimer( + aAudioPlayer, aVideoPlayer); + CleanupStack::PushL(self); + self->CostructL(); + CleanupStack::Pop(self); + return self; + } + +void CPositionUpdateTimer::CostructL() + { + User::LeaveIfError(iTimer.CreateLocal()); + } + +void CPositionUpdateTimer::SetContext(TAny* aCtx) + { + iCtx = aCtx; + } + +void CPositionUpdateTimer::SetPositionUpdatePeriod(XAmillisecond aPos) + { + iPositionUpdatePeriod = aPos; + iDelay = TTimeIntervalMicroSeconds32(aPos * 1000); + } + +void CPositionUpdateTimer::SetCallbackEventMask(XAuint32 aMask) + { + iCallbackEventMask = aMask; + } + +void CPositionUpdateTimer::RegisterCallback(xaPlayCallback aCallback) + { + iCallback = aCallback; + } + +void CPositionUpdateTimer::UseAudioPlayer() + { + iPlayerToUse = static_cast (iAudioPlayer); + } +void CPositionUpdateTimer::UseVideoPlayer() + { + iPlayerToUse = static_cast (iVideoPlayer); + } + +void CPositionUpdateTimer::ResetPlayer() + { + iPlayerToUse = NULL; + } + +TInt CPositionUpdateTimer::Start() + { + TInt retVal(KErrNone); + if (IsActive()) + { + Cancel(); + } + if ((iCallbackEventMask & XA_PLAYEVENT_HEADATNEWPOS) && iCallback + && iPlayerToUse) + { + TTimeIntervalMicroSeconds curPlayPos; + /* Convert milli to micro */ + TTimeIntervalMicroSeconds posUpdatePeriod(iPositionUpdatePeriod + * 1000); + TTimeIntervalMicroSeconds32 delay; + /* Convert milli to micro */ + TReal res; + TReal p; + TReal q(posUpdatePeriod.Int64()); + + iSyncToPlayHead = ETrue; + + retVal = GetCurrentPlayPosition(iSyncToPlayHeadStartPos); + RET_ERR_IF_ERR(retVal); + + p = iSyncToPlayHeadStartPos.Int64(); + /* Adjust delay based on current play position + * user may call this in the middle of playback */ + retVal = Math::Mod(res, p, q); + RET_ERR_IF_ERR(retVal); + + /* Let the timer go off early and then re-adjust + * the remaining time based on then current position */ + delay = (posUpdatePeriod.Int64() - res) / 2; +#ifdef POSITIONUPDATETIMERLOG + // Keep this block for debugging purposes + RDebug::Print(_L("CPositionUpdateTimer::RunL:SyncPlayHead[%u]Delay Reset[%u]microSec"), + iSyncToPlayHeadStartPos.Int64(), + delay.Int()); +#endif /* POSITIONUPDATETIMERLOG */ + if (delay >= TTimeIntervalMicroSeconds32(0)) + { + iStatus = KRequestPending; + iTimer.After(iStatus, delay); + SetActive(); + } + } + return retVal; + } + +void CPositionUpdateTimer::Stop() + { + Cancel(); + } + +void CPositionUpdateTimer::RunL() + { + TInt retVal(KErrNone); + /* Make sure some of the attributes are not unset */ + if ((iStatus == KErrNone) && iCtx && (iCallbackEventMask + & XA_PLAYEVENT_HEADATNEWPOS) && iCallback && iPlayerToUse) + { + TTimeIntervalMicroSeconds curPlayPos; + if (iSyncToPlayHead) + { + retVal = GetCurrentPlayPosition(curPlayPos); + RET_IF_ERR(retVal); + + /* If the play head hasn't moved, re-start all over again */ + if (curPlayPos == iSyncToPlayHeadStartPos) + { +#ifdef POSITIONUPDATETIMERLOG + RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]microSec. Restart"), + iSyncToPlayHeadStartPos.Int64(), + curPlayPos.Int64()); +#endif /* POSITIONUPDATETIMERLOG */ + Start(); + return; + } + /* Play head has moved. calculate remaining time and set the timer */ + /* Convert milli to micro */ + TTimeIntervalMicroSeconds posUpdatePeriod(iPositionUpdatePeriod + * 1000); + TReal res; + TReal p; + TReal q(posUpdatePeriod.Int64()); + + p = curPlayPos.Int64(); + iSyncToPlayHead = EFalse; + + retVal = Math::Mod(res, p, q); + RET_IF_ERR(retVal); + + TTimeIntervalMicroSeconds32 delay = (posUpdatePeriod.Int64() + - res); +#ifdef POSITIONUPDATETIMERLOG + RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]Delay Reset[%u]microSec"), + iSyncToPlayHeadStartPos.Int64(), + curPlayPos.Int64(), + delay.Int()); +#endif /* POSITIONUPDATETIMERLOG */ + if (delay >= TTimeIntervalMicroSeconds32(0)) + { + iStatus = KRequestPending; + iTimer.After(iStatus, delay); + SetActive(); + } + return; + } /* of if (iSyncToPlayHead) */ + +#ifdef POSITIONUPDATETIMERLOG + retVal = GetCurrentPlayPosition(curPlayPos); + RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]microSec. Posting XA_PLAYEVENT_HEADATNEWPOS."), curPlayPos.Int64()); +#endif /* POSITIONUPDATETIMERLOG */ + XAAdaptEvent xaevent = + { + XA_PLAYITFEVENTS, XA_PLAYEVENT_HEADATNEWPOS, 0, 0 + }; + XAAdaptationBase_SendAdaptEvents((XAAdaptationBaseCtx*) iCtx, + &xaevent); + iStatus = KRequestPending; + iTimer.After(iStatus, iDelay); + SetActive(); + } + } + +void CPositionUpdateTimer::DoCancel() + { + iTimer.Cancel(); + } + +TInt CPositionUpdateTimer::RunError(TInt aError) + { + return aError; + } + +TInt CPositionUpdateTimer::GetCurrentPlayPosition( + TTimeIntervalMicroSeconds& aPos) + { + TTimeIntervalMicroSeconds pos; + TInt err(KErrNone); + if (iPlayerToUse && (iPlayerToUse == iAudioPlayer)) + { + iAudioPlayer->GetPosition(aPos); + } + else if (iPlayerToUse && (iPlayerToUse == iVideoPlayer)) + { + TRAP(err, aPos = iVideoPlayer->PositionL()); + } + return err; + }