khronosfws/openmax_al/src/mmf_adaptation/positionupdatetimer.cpp
author hgs
Fri, 11 Jun 2010 19:59:23 -0500
changeset 25 6f7ceef7b1d1
parent 19 4a629bc82c5e
permissions -rw-r--r--
201023
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19
hgs
parents:
diff changeset
     1
/*
25
hgs
parents: 19
diff changeset
     2
 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents: 19
diff changeset
     3
 * All rights reserved.
hgs
parents: 19
diff changeset
     4
 * This component and the accompanying materials are made available
hgs
parents: 19
diff changeset
     5
 * under the terms of "Eclipse Public License v1.0"
hgs
parents: 19
diff changeset
     6
 * which accompanies this distribution, and is available
hgs
parents: 19
diff changeset
     7
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents: 19
diff changeset
     8
 *
hgs
parents: 19
diff changeset
     9
 * Initial Contributors:
hgs
parents: 19
diff changeset
    10
 * Nokia Corporation - initial contribution.
hgs
parents: 19
diff changeset
    11
 *
hgs
parents: 19
diff changeset
    12
 * Contributors:
hgs
parents: 19
diff changeset
    13
 *
hgs
parents: 19
diff changeset
    14
 * Description: Handles new position timer implementation 
hgs
parents: 19
diff changeset
    15
 *
hgs
parents: 19
diff changeset
    16
 */
19
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include "positionupdatetimer.h"
hgs
parents:
diff changeset
    19
#include <mdaaudiosampleplayer.h>
hgs
parents:
diff changeset
    20
#include <videoplayer2.h>
hgs
parents:
diff changeset
    21
#include <e32math.h>
hgs
parents:
diff changeset
    22
25
hgs
parents: 19
diff changeset
    23
extern "C"
hgs
parents: 19
diff changeset
    24
    {
19
hgs
parents:
diff changeset
    25
#include "xarecorditfadaptationmmf.h"
25
hgs
parents: 19
diff changeset
    26
    }
19
hgs
parents:
diff changeset
    27
hgs
parents:
diff changeset
    28
#define RET_ERR_IF_ERR(s) if (s!=KErrNone) return s;
hgs
parents:
diff changeset
    29
#define RET_IF_ERR(s) if (s!=KErrNone) return;
hgs
parents:
diff changeset
    30
hgs
parents:
diff changeset
    31
CPositionUpdateTimer::CPositionUpdateTimer(
hgs
parents:
diff changeset
    32
        CMdaAudioPlayerUtility* aAudioPlayer,
25
hgs
parents: 19
diff changeset
    33
        CVideoPlayerUtility2* aVideoPlayer) :
hgs
parents: 19
diff changeset
    34
    CActive(CActive::EPriorityStandard), iAudioPlayer(aAudioPlayer),
hgs
parents: 19
diff changeset
    35
            iVideoPlayer(aVideoPlayer)
19
hgs
parents:
diff changeset
    36
    {
hgs
parents:
diff changeset
    37
    CActiveScheduler::Add(this);
hgs
parents:
diff changeset
    38
    }
hgs
parents:
diff changeset
    39
hgs
parents:
diff changeset
    40
CPositionUpdateTimer::~CPositionUpdateTimer()
hgs
parents:
diff changeset
    41
    {
hgs
parents:
diff changeset
    42
    Cancel();
hgs
parents:
diff changeset
    43
    iTimer.Close();
hgs
parents:
diff changeset
    44
    }
hgs
parents:
diff changeset
    45
hgs
parents:
diff changeset
    46
CPositionUpdateTimer* CPositionUpdateTimer::NewL(
hgs
parents:
diff changeset
    47
        CMdaAudioPlayerUtility* aAudioPlayer,
hgs
parents:
diff changeset
    48
        CVideoPlayerUtility2* aVideoPlayer)
hgs
parents:
diff changeset
    49
    {
25
hgs
parents: 19
diff changeset
    50
    CPositionUpdateTimer* self = new (ELeave) CPositionUpdateTimer(
hgs
parents: 19
diff changeset
    51
            aAudioPlayer, aVideoPlayer);
19
hgs
parents:
diff changeset
    52
    CleanupStack::PushL(self);
hgs
parents:
diff changeset
    53
    self->CostructL();
hgs
parents:
diff changeset
    54
    CleanupStack::Pop(self);
hgs
parents:
diff changeset
    55
    return self;
hgs
parents:
diff changeset
    56
    }
hgs
parents:
diff changeset
    57
hgs
parents:
diff changeset
    58
void CPositionUpdateTimer::CostructL()
hgs
parents:
diff changeset
    59
    {
25
hgs
parents: 19
diff changeset
    60
    User::LeaveIfError(iTimer.CreateLocal());
19
hgs
parents:
diff changeset
    61
    }
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
void CPositionUpdateTimer::SetContext(TAny* aCtx)
hgs
parents:
diff changeset
    64
    {
25
hgs
parents: 19
diff changeset
    65
    iCtx = aCtx;
19
hgs
parents:
diff changeset
    66
    }
hgs
parents:
diff changeset
    67
hgs
parents:
diff changeset
    68
void CPositionUpdateTimer::SetPositionUpdatePeriod(XAmillisecond aPos)
hgs
parents:
diff changeset
    69
    {
hgs
parents:
diff changeset
    70
    iPositionUpdatePeriod = aPos;
25
hgs
parents: 19
diff changeset
    71
    iDelay = TTimeIntervalMicroSeconds32(aPos * 1000);
19
hgs
parents:
diff changeset
    72
    }
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
void CPositionUpdateTimer::SetCallbackEventMask(XAuint32 aMask)
hgs
parents:
diff changeset
    75
    {
hgs
parents:
diff changeset
    76
    iCallbackEventMask = aMask;
hgs
parents:
diff changeset
    77
    }
hgs
parents:
diff changeset
    78
hgs
parents:
diff changeset
    79
void CPositionUpdateTimer::RegisterCallback(xaPlayCallback aCallback)
hgs
parents:
diff changeset
    80
    {
hgs
parents:
diff changeset
    81
    iCallback = aCallback;
hgs
parents:
diff changeset
    82
    }
hgs
parents:
diff changeset
    83
hgs
parents:
diff changeset
    84
void CPositionUpdateTimer::UseAudioPlayer()
hgs
parents:
diff changeset
    85
    {
25
hgs
parents: 19
diff changeset
    86
    iPlayerToUse = static_cast<CBase*> (iAudioPlayer);
19
hgs
parents:
diff changeset
    87
    }
hgs
parents:
diff changeset
    88
void CPositionUpdateTimer::UseVideoPlayer()
hgs
parents:
diff changeset
    89
    {
25
hgs
parents: 19
diff changeset
    90
    iPlayerToUse = static_cast<CBase*> (iVideoPlayer);
19
hgs
parents:
diff changeset
    91
    }
hgs
parents:
diff changeset
    92
hgs
parents:
diff changeset
    93
void CPositionUpdateTimer::ResetPlayer()
hgs
parents:
diff changeset
    94
    {
hgs
parents:
diff changeset
    95
    iPlayerToUse = NULL;
hgs
parents:
diff changeset
    96
    }
hgs
parents:
diff changeset
    97
hgs
parents:
diff changeset
    98
TInt CPositionUpdateTimer::Start()
hgs
parents:
diff changeset
    99
    {
hgs
parents:
diff changeset
   100
    TInt retVal(KErrNone);
hgs
parents:
diff changeset
   101
    if (IsActive())
hgs
parents:
diff changeset
   102
        {
hgs
parents:
diff changeset
   103
        Cancel();
hgs
parents:
diff changeset
   104
        }
25
hgs
parents: 19
diff changeset
   105
    if ((iCallbackEventMask & XA_PLAYEVENT_HEADATNEWPOS) && iCallback
hgs
parents: 19
diff changeset
   106
            && iPlayerToUse)
19
hgs
parents:
diff changeset
   107
        {
hgs
parents:
diff changeset
   108
        TTimeIntervalMicroSeconds curPlayPos;
hgs
parents:
diff changeset
   109
        /* Convert milli to micro */
25
hgs
parents: 19
diff changeset
   110
        TTimeIntervalMicroSeconds posUpdatePeriod(iPositionUpdatePeriod
hgs
parents: 19
diff changeset
   111
                * 1000);
19
hgs
parents:
diff changeset
   112
        TTimeIntervalMicroSeconds32 delay;
hgs
parents:
diff changeset
   113
        /* Convert milli to micro */
hgs
parents:
diff changeset
   114
        TReal res;
hgs
parents:
diff changeset
   115
        TReal p;
hgs
parents:
diff changeset
   116
        TReal q(posUpdatePeriod.Int64());
hgs
parents:
diff changeset
   117
hgs
parents:
diff changeset
   118
        iSyncToPlayHead = ETrue;
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
        retVal = GetCurrentPlayPosition(iSyncToPlayHeadStartPos);
hgs
parents:
diff changeset
   121
        RET_ERR_IF_ERR(retVal);
hgs
parents:
diff changeset
   122
hgs
parents:
diff changeset
   123
        p = iSyncToPlayHeadStartPos.Int64();
hgs
parents:
diff changeset
   124
        /* Adjust delay based on current play position
hgs
parents:
diff changeset
   125
         * user may call this in the middle of playback */
hgs
parents:
diff changeset
   126
        retVal = Math::Mod(res, p, q);
hgs
parents:
diff changeset
   127
        RET_ERR_IF_ERR(retVal);
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
        /* Let the timer go off early and then re-adjust 
hgs
parents:
diff changeset
   130
         * the remaining time based on then current position */
hgs
parents:
diff changeset
   131
        delay = (posUpdatePeriod.Int64() - res) / 2;
hgs
parents:
diff changeset
   132
#ifdef POSITIONUPDATETIMERLOG
hgs
parents:
diff changeset
   133
        // Keep this block for debugging purposes
hgs
parents:
diff changeset
   134
        RDebug::Print(_L("CPositionUpdateTimer::RunL:SyncPlayHead[%u]Delay Reset[%u]microSec"),
hgs
parents:
diff changeset
   135
                iSyncToPlayHeadStartPos.Int64(),
hgs
parents:
diff changeset
   136
                delay.Int());
hgs
parents:
diff changeset
   137
#endif /* POSITIONUPDATETIMERLOG */
25
hgs
parents: 19
diff changeset
   138
        if (delay >= TTimeIntervalMicroSeconds32(0))
19
hgs
parents:
diff changeset
   139
            {
hgs
parents:
diff changeset
   140
            iStatus = KRequestPending;
hgs
parents:
diff changeset
   141
            iTimer.After(iStatus, delay);
hgs
parents:
diff changeset
   142
            SetActive();
hgs
parents:
diff changeset
   143
            }
hgs
parents:
diff changeset
   144
        }
hgs
parents:
diff changeset
   145
    return retVal;
hgs
parents:
diff changeset
   146
    }
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
void CPositionUpdateTimer::Stop()
hgs
parents:
diff changeset
   149
    {
hgs
parents:
diff changeset
   150
    Cancel();
hgs
parents:
diff changeset
   151
    }
hgs
parents:
diff changeset
   152
hgs
parents:
diff changeset
   153
void CPositionUpdateTimer::RunL()
hgs
parents:
diff changeset
   154
    {
hgs
parents:
diff changeset
   155
    TInt retVal(KErrNone);
hgs
parents:
diff changeset
   156
    /* Make sure some of the attributes are not unset */
25
hgs
parents: 19
diff changeset
   157
    if ((iStatus == KErrNone) && iCtx && (iCallbackEventMask
hgs
parents: 19
diff changeset
   158
            & XA_PLAYEVENT_HEADATNEWPOS) && iCallback && iPlayerToUse)
19
hgs
parents:
diff changeset
   159
        {
hgs
parents:
diff changeset
   160
        TTimeIntervalMicroSeconds curPlayPos;
hgs
parents:
diff changeset
   161
        if (iSyncToPlayHead)
hgs
parents:
diff changeset
   162
            {
hgs
parents:
diff changeset
   163
            retVal = GetCurrentPlayPosition(curPlayPos);
hgs
parents:
diff changeset
   164
            RET_IF_ERR(retVal);
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
            /* If the play head hasn't moved, re-start all over again */
hgs
parents:
diff changeset
   167
            if (curPlayPos == iSyncToPlayHeadStartPos)
hgs
parents:
diff changeset
   168
                {
hgs
parents:
diff changeset
   169
#ifdef POSITIONUPDATETIMERLOG
25
hgs
parents: 19
diff changeset
   170
                RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]microSec. Restart"),
hgs
parents: 19
diff changeset
   171
                        iSyncToPlayHeadStartPos.Int64(),
hgs
parents: 19
diff changeset
   172
                        curPlayPos.Int64());
19
hgs
parents:
diff changeset
   173
#endif /* POSITIONUPDATETIMERLOG */
hgs
parents:
diff changeset
   174
                Start();
hgs
parents:
diff changeset
   175
                return;
hgs
parents:
diff changeset
   176
                }
hgs
parents:
diff changeset
   177
            /* Play head has moved. calculate remaining time and set the timer */
hgs
parents:
diff changeset
   178
            /* Convert milli to micro */
25
hgs
parents: 19
diff changeset
   179
            TTimeIntervalMicroSeconds posUpdatePeriod(iPositionUpdatePeriod
hgs
parents: 19
diff changeset
   180
                    * 1000);
19
hgs
parents:
diff changeset
   181
            TReal res;
hgs
parents:
diff changeset
   182
            TReal p;
hgs
parents:
diff changeset
   183
            TReal q(posUpdatePeriod.Int64());
hgs
parents:
diff changeset
   184
hgs
parents:
diff changeset
   185
            p = curPlayPos.Int64();
hgs
parents:
diff changeset
   186
            iSyncToPlayHead = EFalse;
hgs
parents:
diff changeset
   187
hgs
parents:
diff changeset
   188
            retVal = Math::Mod(res, p, q);
hgs
parents:
diff changeset
   189
            RET_IF_ERR(retVal);
hgs
parents:
diff changeset
   190
25
hgs
parents: 19
diff changeset
   191
            TTimeIntervalMicroSeconds32 delay = (posUpdatePeriod.Int64()
hgs
parents: 19
diff changeset
   192
                    - res);
19
hgs
parents:
diff changeset
   193
#ifdef POSITIONUPDATETIMERLOG
hgs
parents:
diff changeset
   194
            RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]Delay Reset[%u]microSec"),
hgs
parents:
diff changeset
   195
                    iSyncToPlayHeadStartPos.Int64(),
hgs
parents:
diff changeset
   196
                    curPlayPos.Int64(),
hgs
parents:
diff changeset
   197
                    delay.Int());
hgs
parents:
diff changeset
   198
#endif /* POSITIONUPDATETIMERLOG */
25
hgs
parents: 19
diff changeset
   199
            if (delay >= TTimeIntervalMicroSeconds32(0))
19
hgs
parents:
diff changeset
   200
                {
hgs
parents:
diff changeset
   201
                iStatus = KRequestPending;
hgs
parents:
diff changeset
   202
                iTimer.After(iStatus, delay);
hgs
parents:
diff changeset
   203
                SetActive();
hgs
parents:
diff changeset
   204
                }
hgs
parents:
diff changeset
   205
            return;
hgs
parents:
diff changeset
   206
            } /* of if (iSyncToPlayHead) */
hgs
parents:
diff changeset
   207
hgs
parents:
diff changeset
   208
#ifdef POSITIONUPDATETIMERLOG
hgs
parents:
diff changeset
   209
        retVal = GetCurrentPlayPosition(curPlayPos);
hgs
parents:
diff changeset
   210
        RDebug::Print(_L("CPositionUpdateTimer::RunL:CurPlayPos[%u]microSec. Posting XA_PLAYEVENT_HEADATNEWPOS."), curPlayPos.Int64());
hgs
parents:
diff changeset
   211
#endif /* POSITIONUPDATETIMERLOG */
25
hgs
parents: 19
diff changeset
   212
        XAAdaptEvent xaevent =
hgs
parents: 19
diff changeset
   213
            {
hgs
parents: 19
diff changeset
   214
            XA_PLAYITFEVENTS, XA_PLAYEVENT_HEADATNEWPOS, 0, 0
hgs
parents: 19
diff changeset
   215
            };
hgs
parents: 19
diff changeset
   216
        XAAdaptationBase_SendAdaptEvents((XAAdaptationBaseCtx*) iCtx,
hgs
parents: 19
diff changeset
   217
                &xaevent);
19
hgs
parents:
diff changeset
   218
        iStatus = KRequestPending;
hgs
parents:
diff changeset
   219
        iTimer.After(iStatus, iDelay);
hgs
parents:
diff changeset
   220
        SetActive();
hgs
parents:
diff changeset
   221
        }
hgs
parents:
diff changeset
   222
    }
hgs
parents:
diff changeset
   223
hgs
parents:
diff changeset
   224
void CPositionUpdateTimer::DoCancel()
hgs
parents:
diff changeset
   225
    {
hgs
parents:
diff changeset
   226
    iTimer.Cancel();
hgs
parents:
diff changeset
   227
    }
hgs
parents:
diff changeset
   228
25
hgs
parents: 19
diff changeset
   229
TInt CPositionUpdateTimer::RunError(TInt aError)
19
hgs
parents:
diff changeset
   230
    {
25
hgs
parents: 19
diff changeset
   231
    return aError;
19
hgs
parents:
diff changeset
   232
    }
hgs
parents:
diff changeset
   233
25
hgs
parents: 19
diff changeset
   234
TInt CPositionUpdateTimer::GetCurrentPlayPosition(
hgs
parents: 19
diff changeset
   235
        TTimeIntervalMicroSeconds& aPos)
19
hgs
parents:
diff changeset
   236
    {
hgs
parents:
diff changeset
   237
    TTimeIntervalMicroSeconds pos;
hgs
parents:
diff changeset
   238
    TInt err(KErrNone);
25
hgs
parents: 19
diff changeset
   239
    if (iPlayerToUse && (iPlayerToUse == iAudioPlayer))
19
hgs
parents:
diff changeset
   240
        {
hgs
parents:
diff changeset
   241
        iAudioPlayer->GetPosition(aPos);
hgs
parents:
diff changeset
   242
        }
25
hgs
parents: 19
diff changeset
   243
    else if (iPlayerToUse && (iPlayerToUse == iVideoPlayer))
19
hgs
parents:
diff changeset
   244
        {
hgs
parents:
diff changeset
   245
        TRAP(err, aPos = iVideoPlayer->PositionL());
hgs
parents:
diff changeset
   246
        }
hgs
parents:
diff changeset
   247
    return err;
hgs
parents:
diff changeset
   248
    }