omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.cpp
author hgs
Fri, 08 Oct 2010 22:09:17 +0100
changeset 0 5d29cba61097
permissions -rw-r--r--
2010wk38_02

/*
* 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:
*
*/


/**
@file
@internalComponent
*/
#include "buffercopier.h"
#include "comxilvideoscheduler.h"
#include "buffercopierstatemonitor.h"
#include "log.h"

CBufferCopierStateMonitor* CBufferCopierStateMonitor::NewL(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent)
    {
    CBufferCopierStateMonitor* self = new (ELeave) CBufferCopierStateMonitor(aCallback, aComponent);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

CBufferCopierStateMonitor::CBufferCopierStateMonitor(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent) :
CActive(EPriorityNormal),
iCallback(aCallback),
iComponent(aComponent),
iState(ENull)
    {
    CActiveScheduler::Add(this);
    }

CBufferCopierStateMonitor::~CBufferCopierStateMonitor()
    {
    Cancel();
    delete iBufferCopier;
    }

void CBufferCopierStateMonitor::ConstructL()
    {
    RThread me;
    iConstructionThreadId = me.Id();
    
    iStatus = KRequestPending;
    SetActive();
    }

void CBufferCopierStateMonitor::RunL()
    {
    iStatus = KRequestPending;
    SetActive();

    TInt err = DoSetState();

    TRequestStatus *status = iCallingStatus;
    RThread callingThread;
    callingThread.Open(iCallingThreadId);
    callingThread.RequestComplete(status, err);
    callingThread.Close();
    }

void CBufferCopierStateMonitor::DoCancel()
    {
    TRequestStatus* pStat = &iStatus;
    User::RequestComplete(pStat, KErrCancel);
    }

TInt CBufferCopierStateMonitor::RunError(TInt aError)
    {
    DEBUG_PRINTF2(_L8("CBufferCopierStateMonitor::RunError %d"), aError);
    aError=KErrNone; //Do not want to panic the server!
    return aError; 
    }

TInt CBufferCopierStateMonitor::SetState(TPFState aState)
    {
    DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::SetState"));

    TInt err = KErrNone;
    iState = aState;
    
    RThread me;
    if(me.Id() != iConstructionThreadId)
        {
        // in different thread to that which 'this' was constructed
        err = DoRequest();
        }
    else
        {
        // in same thread to that which 'this' was constructed therefore
        // active scheduler must exist and following call is safe
        err = DoSetState();
        }

    return err;
    }

TInt CBufferCopierStateMonitor::DoSetState()
    {
    DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::DoSetState"));

    TInt err = KErrNone;

    switch(iState)
        {
        case ESubLoadedToIdle:
            iMaxBuffers = iComponent.BufferCount();
            delete iBufferCopier;
            iBufferCopier = NULL;
            TRAP(err, iBufferCopier = CBufferCopier::NewL(iCallback, iMaxBuffers));
            break;
        case ESubIdleToLoaded:
            delete iBufferCopier;
            iBufferCopier = NULL;
            break;
        default:
            break;
        };

    return err;
    }

TInt CBufferCopierStateMonitor::DoRequest()
    {
    DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::DoRequest"));

    RThread me;
    iCallingThreadId = me.Id();
    TRequestStatus requestStatus = KRequestPending;
    iCallingStatus = &requestStatus;

    // send request to active scheduler thread
    RThread schedulerThread;
    TInt error = schedulerThread.Open(iConstructionThreadId);
    if(error != KErrNone)
        {
        return error;
        }

    TRequestStatus* schedulerRequest = &iStatus;
    schedulerThread.RequestComplete(schedulerRequest, KErrNone);
    schedulerThread.Close();

    // block until request completes
    User::WaitForRequest(requestStatus);

    return requestStatus.Int();
    }