khronosfws/openmax_al/src/mmf_adaptation/markerpositiontimer.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 marker 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 "markerpositiontimer.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
CMarkerPositionTimer::CMarkerPositionTimer(
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
CMarkerPositionTimer::~CMarkerPositionTimer()
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
CMarkerPositionTimer* CMarkerPositionTimer::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
    CMarkerPositionTimer* self = new (ELeave) CMarkerPositionTimer(
hgs
parents: 19
diff changeset
    51
            aAudioPlayer, aVideoPlayer);
19
hgs
parents:
diff changeset
    52
    CleanupStack::PushL(self);
hgs
parents:
diff changeset
    53
    self->ConstructL();
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 CMarkerPositionTimer::ConstructL()
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 CMarkerPositionTimer::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 CMarkerPositionTimer::SetMarkerPosition(XAmillisecond aMarkerPos)
hgs
parents:
diff changeset
    69
    {
hgs
parents:
diff changeset
    70
    iMarkerPosition = aMarkerPos;
hgs
parents:
diff changeset
    71
    }
hgs
parents:
diff changeset
    72
hgs
parents:
diff changeset
    73
void CMarkerPositionTimer::SetCallbackEventMask(XAuint32 aMask)
hgs
parents:
diff changeset
    74
    {
hgs
parents:
diff changeset
    75
    iCallbackEventMask = aMask;
hgs
parents:
diff changeset
    76
    }
hgs
parents:
diff changeset
    77
hgs
parents:
diff changeset
    78
void CMarkerPositionTimer::RegisterCallback(xaPlayCallback aCallback)
hgs
parents:
diff changeset
    79
    {
hgs
parents:
diff changeset
    80
    iCallback = aCallback;
hgs
parents:
diff changeset
    81
    }
hgs
parents:
diff changeset
    82
hgs
parents:
diff changeset
    83
void CMarkerPositionTimer::UseAudioPlayer()
hgs
parents:
diff changeset
    84
    {
25
hgs
parents: 19
diff changeset
    85
    iPlayerToUse = static_cast<CBase*> (iAudioPlayer);
19
hgs
parents:
diff changeset
    86
    }
hgs
parents:
diff changeset
    87
void CMarkerPositionTimer::UseVideoPlayer()
hgs
parents:
diff changeset
    88
    {
25
hgs
parents: 19
diff changeset
    89
    iPlayerToUse = static_cast<CBase*> (iVideoPlayer);
19
hgs
parents:
diff changeset
    90
    }
hgs
parents:
diff changeset
    91
hgs
parents:
diff changeset
    92
void CMarkerPositionTimer::ResetPlayer()
hgs
parents:
diff changeset
    93
    {
hgs
parents:
diff changeset
    94
    iPlayerToUse = NULL;
hgs
parents:
diff changeset
    95
    }
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
TInt CMarkerPositionTimer::Start()
hgs
parents:
diff changeset
    98
    {
hgs
parents:
diff changeset
    99
    TInt retVal(KErrNone);
hgs
parents:
diff changeset
   100
    if (IsActive())
hgs
parents:
diff changeset
   101
        {
hgs
parents:
diff changeset
   102
        Cancel();
hgs
parents:
diff changeset
   103
        }
25
hgs
parents: 19
diff changeset
   104
    if ((iMarkerPosition != XA_TIME_UNKNOWN) && (iCallbackEventMask
hgs
parents: 19
diff changeset
   105
            & XA_PLAYEVENT_HEADATMARKER) && iCallback && iPlayerToUse)
19
hgs
parents:
diff changeset
   106
        {
hgs
parents:
diff changeset
   107
        TTimeIntervalMicroSeconds32 delay;
hgs
parents:
diff changeset
   108
        /* Convert milli to micro */
hgs
parents:
diff changeset
   109
        TTimeIntervalMicroSeconds markerPos(iMarkerPosition * 1000);
hgs
parents:
diff changeset
   110
        TReal res;
hgs
parents:
diff changeset
   111
        TReal p;
hgs
parents:
diff changeset
   112
        TReal q(markerPos.Int64());
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
        iSyncToPlayHead = ETrue;
hgs
parents:
diff changeset
   115
hgs
parents:
diff changeset
   116
        retVal = GetCurrentPlayPosition(iSyncToPlayHeadStartPos);
hgs
parents:
diff changeset
   117
        RET_ERR_IF_ERR(retVal);
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
        p = iSyncToPlayHeadStartPos.Int64();
hgs
parents:
diff changeset
   120
        /* Adjust delay based on current play position
hgs
parents:
diff changeset
   121
         * user may call this in the middle of playback */
hgs
parents:
diff changeset
   122
        retVal = Math::Mod(res, p, q);
hgs
parents:
diff changeset
   123
        RET_ERR_IF_ERR(retVal);
hgs
parents:
diff changeset
   124
hgs
parents:
diff changeset
   125
        /* Let the timer go off early and then re-adjust 
hgs
parents:
diff changeset
   126
         * the remaining time based on then current position */
hgs
parents:
diff changeset
   127
        delay = (markerPos.Int64() - res) / 2;
hgs
parents:
diff changeset
   128
#ifdef MARKERPOSITIONTIMERLOG
hgs
parents:
diff changeset
   129
        // Keep this block for debugging purposes
hgs
parents:
diff changeset
   130
        RDebug::Print(_L("CMarkerPositionTimer::RunL:SyncPlayHead[%u]Delay Reset[%u]microSec"),
hgs
parents:
diff changeset
   131
                iSyncToPlayHeadStartPos.Int64(),
hgs
parents:
diff changeset
   132
                delay.Int());
hgs
parents:
diff changeset
   133
#endif /* MARKERPOSITIONTIMERLOG */
25
hgs
parents: 19
diff changeset
   134
        if (delay >= TTimeIntervalMicroSeconds32(0))
19
hgs
parents:
diff changeset
   135
            {
hgs
parents:
diff changeset
   136
            iStatus = KRequestPending;
hgs
parents:
diff changeset
   137
            iTimer.After(iStatus, delay);
hgs
parents:
diff changeset
   138
            SetActive();
hgs
parents:
diff changeset
   139
            }
hgs
parents:
diff changeset
   140
        }
hgs
parents:
diff changeset
   141
    return retVal;
hgs
parents:
diff changeset
   142
    }
hgs
parents:
diff changeset
   143
hgs
parents:
diff changeset
   144
void CMarkerPositionTimer::Stop()
hgs
parents:
diff changeset
   145
    {
hgs
parents:
diff changeset
   146
    Cancel();
hgs
parents:
diff changeset
   147
    }
hgs
parents:
diff changeset
   148
hgs
parents:
diff changeset
   149
void CMarkerPositionTimer::RunL()
hgs
parents:
diff changeset
   150
    {
hgs
parents:
diff changeset
   151
    TInt retVal(KErrNone);
hgs
parents:
diff changeset
   152
    /* Make sure some of the attributes are not unset */
25
hgs
parents: 19
diff changeset
   153
    if ((iStatus == KErrNone) && iCtx && (iMarkerPosition != XA_TIME_UNKNOWN)
hgs
parents: 19
diff changeset
   154
            && (iCallbackEventMask & XA_PLAYEVENT_HEADATMARKER) && iCallback
hgs
parents: 19
diff changeset
   155
            && iPlayerToUse)
19
hgs
parents:
diff changeset
   156
        {
hgs
parents:
diff changeset
   157
        TTimeIntervalMicroSeconds curPlayPos;
hgs
parents:
diff changeset
   158
        if (iSyncToPlayHead)
hgs
parents:
diff changeset
   159
            {
hgs
parents:
diff changeset
   160
            retVal = GetCurrentPlayPosition(curPlayPos);
hgs
parents:
diff changeset
   161
            RET_IF_ERR(retVal);
hgs
parents:
diff changeset
   162
hgs
parents:
diff changeset
   163
            /* If the play head hasn't moved, re-start all over again */
hgs
parents:
diff changeset
   164
            if (curPlayPos == iSyncToPlayHeadStartPos)
hgs
parents:
diff changeset
   165
                {
hgs
parents:
diff changeset
   166
#ifdef MARKERPOSITIONTIMERLOG
25
hgs
parents: 19
diff changeset
   167
                RDebug::Print(_L("CMarkerPositionTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]microSec. Restart"),
hgs
parents: 19
diff changeset
   168
                        iSyncToPlayHeadStartPos.Int64(),
hgs
parents: 19
diff changeset
   169
                        curPlayPos.Int64());
19
hgs
parents:
diff changeset
   170
#endif /* MARKERPOSITIONTIMERLOG */
hgs
parents:
diff changeset
   171
                Start();
hgs
parents:
diff changeset
   172
                return;
hgs
parents:
diff changeset
   173
                }
hgs
parents:
diff changeset
   174
            /* Play head has moved. calculate remaining time and set the timer */
hgs
parents:
diff changeset
   175
            /* Convert milli to micro */
hgs
parents:
diff changeset
   176
            TTimeIntervalMicroSeconds markerPos(iMarkerPosition * 1000);
hgs
parents:
diff changeset
   177
            TReal res;
hgs
parents:
diff changeset
   178
            TReal p;
hgs
parents:
diff changeset
   179
            TReal q(markerPos.Int64());
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
            p = curPlayPos.Int64();
hgs
parents:
diff changeset
   182
            iSyncToPlayHead = EFalse;
hgs
parents:
diff changeset
   183
hgs
parents:
diff changeset
   184
            retVal = Math::Mod(res, p, q);
hgs
parents:
diff changeset
   185
            RET_IF_ERR(retVal);
hgs
parents:
diff changeset
   186
hgs
parents:
diff changeset
   187
            TTimeIntervalMicroSeconds32 delay = (markerPos.Int64() - res);
hgs
parents:
diff changeset
   188
#ifdef MARKERPOSITIONTIMERLOG
hgs
parents:
diff changeset
   189
            RDebug::Print(_L("CMarkerPositionTimer::RunL:CurPlayPos[%u]SyncPlayHead[%u]Delay Reset[%u]microSec"),
hgs
parents:
diff changeset
   190
                    iSyncToPlayHeadStartPos.Int64(),
hgs
parents:
diff changeset
   191
                    curPlayPos.Int64(),
hgs
parents:
diff changeset
   192
                    delay.Int());
hgs
parents:
diff changeset
   193
#endif /* MARKERPOSITIONTIMERLOG */
25
hgs
parents: 19
diff changeset
   194
            if (delay >= TTimeIntervalMicroSeconds32(0))
19
hgs
parents:
diff changeset
   195
                {
hgs
parents:
diff changeset
   196
                iStatus = KRequestPending;
hgs
parents:
diff changeset
   197
                iTimer.After(iStatus, delay);
hgs
parents:
diff changeset
   198
                SetActive();
hgs
parents:
diff changeset
   199
                }
hgs
parents:
diff changeset
   200
            return;
hgs
parents:
diff changeset
   201
            } /* of if (iSyncToPlayHead) */
hgs
parents:
diff changeset
   202
hgs
parents:
diff changeset
   203
#ifdef MARKERPOSITIONTIMERLOG
hgs
parents:
diff changeset
   204
        retVal = GetCurrentPlayPosition(curPlayPos);
hgs
parents:
diff changeset
   205
        RDebug::Print(_L("CMarkerPositionTimer::RunL:CurPlayPos[%u]microSec. Posting XA_PLAYEVENT_HEADATMARKER."), curPlayPos.Int64());
hgs
parents:
diff changeset
   206
#endif /* MARKERPOSITIONTIMERLOG */
25
hgs
parents: 19
diff changeset
   207
        XAAdaptEvent xaevent =
hgs
parents: 19
diff changeset
   208
            {
hgs
parents: 19
diff changeset
   209
            XA_PLAYITFEVENTS, XA_PLAYEVENT_HEADATMARKER, 0, 0
hgs
parents: 19
diff changeset
   210
            };
hgs
parents: 19
diff changeset
   211
        XAAdaptationBase_SendAdaptEvents((XAAdaptationBaseCtx*) iCtx,
hgs
parents: 19
diff changeset
   212
                &xaevent);
19
hgs
parents:
diff changeset
   213
        }
hgs
parents:
diff changeset
   214
    }
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
void CMarkerPositionTimer::DoCancel()
hgs
parents:
diff changeset
   217
    {
hgs
parents:
diff changeset
   218
    iTimer.Cancel();
hgs
parents:
diff changeset
   219
    }
hgs
parents:
diff changeset
   220
hgs
parents:
diff changeset
   221
TInt CMarkerPositionTimer::RunError(TInt /*aError*/)
hgs
parents:
diff changeset
   222
    {
hgs
parents:
diff changeset
   223
    return KErrNone;
hgs
parents:
diff changeset
   224
    }
hgs
parents:
diff changeset
   225
25
hgs
parents: 19
diff changeset
   226
TInt CMarkerPositionTimer::GetCurrentPlayPosition(
hgs
parents: 19
diff changeset
   227
        TTimeIntervalMicroSeconds& aPos)
19
hgs
parents:
diff changeset
   228
    {
hgs
parents:
diff changeset
   229
    TTimeIntervalMicroSeconds pos;
hgs
parents:
diff changeset
   230
    TInt err(KErrNone);
hgs
parents:
diff changeset
   231
    if (iPlayerToUse == iAudioPlayer)
hgs
parents:
diff changeset
   232
        {
hgs
parents:
diff changeset
   233
        iAudioPlayer->GetPosition(aPos);
hgs
parents:
diff changeset
   234
        }
hgs
parents:
diff changeset
   235
    else if (iPlayerToUse == iVideoPlayer)
hgs
parents:
diff changeset
   236
        {
hgs
parents:
diff changeset
   237
        TRAP(err, aPos = iVideoPlayer->PositionL());
hgs
parents:
diff changeset
   238
        }
hgs
parents:
diff changeset
   239
    return err;
hgs
parents:
diff changeset
   240
    }