omxilvideocomps/omxilvideoscheduler/src/buffercopier.cpp
author hgs
Fri, 08 Oct 2010 22:09:17 +0100
changeset 0 5d29cba61097
permissions -rw-r--r--
2010wk38_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     1
/*
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     2
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     3
* All rights reserved.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     8
*
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
     9
* Initial Contributors:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    11
*
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    12
* Contributors:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    13
*
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    14
* Description:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    15
*
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    16
*/
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    17
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    18
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    19
/**
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    20
@file
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    21
@internalComponent
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    22
*/
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    23
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    24
#include "buffercopier.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    25
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    26
_LIT(KBufferCopierPanic, "CBufferCopier");
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    27
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    28
CBufferCopier* CBufferCopier::NewL(MBufferCopierIf& aCallback, TInt aMaxBuffers)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    29
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    30
	CBufferCopier* self = new(ELeave) CBufferCopier(aCallback);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    31
	CleanupStack::PushL(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    32
	self->ConstructL(aMaxBuffers);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    33
	CleanupStack::Pop(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    34
	return self;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    35
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    36
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    37
CBufferCopier::CBufferCopier(MBufferCopierIf& aCallback):
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    38
CActive(EPriorityNormal),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    39
iCallback(aCallback)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    40
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    41
	CActiveScheduler::Add(this);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    42
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    43
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    44
void CBufferCopier::ConstructL(TInt aMaxBuffers)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    45
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    46
	User::LeaveIfError(iInQueue.CreateLocal(aMaxBuffers));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    47
	User::LeaveIfError(iOutQueue.CreateLocal(aMaxBuffers));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    48
	User::LeaveIfError(iRemoveQueue.CreateLocal(aMaxBuffers));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    49
	SetActive();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    50
	iInQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    51
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    52
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    53
CBufferCopier::~CBufferCopier()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    54
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    55
	Cancel();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    56
	iInQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    57
	iOutQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    58
	iRemoveQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    59
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    60
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    61
void CBufferCopier::DeliverBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    62
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    63
	RMsgQueue<OMX_BUFFERHEADERTYPE*>& queue = aDirection == OMX_DirInput ? iInQueue : iOutQueue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    64
	TInt err = queue.Send(aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    65
	// do not expect error as maximum buffer count already allocated
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    66
	if(err != KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    67
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    68
		User::Panic(KBufferCopierPanic, err);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    69
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    70
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    71
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    72
void CBufferCopier::RunL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    73
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    74
	if(iInBuffer == NULL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    75
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    76
		// ignore error, if KErrUnderflow then we go back to waiting on iInQueue
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    77
		iInQueue.Receive(iInBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    78
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    79
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    80
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    81
		OMX_BUFFERHEADERTYPE* outBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    82
		TInt err = iOutQueue.Receive(outBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    83
		// if KErrUnderflow then we go back to waiting on iOutQueue
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    84
		if(err == KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    85
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    86
			CopyBuffer(iInBuffer, outBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    87
			iInBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    88
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    89
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    90
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    91
	SetActive();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    92
	if(iInBuffer == NULL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    93
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    94
		iInQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    95
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    96
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    97
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    98
		iOutQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    99
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   100
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   101
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   102
void CBufferCopier::DoCancel()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   103
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   104
	iInQueue.CancelDataAvailable();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   105
	iOutQueue.CancelDataAvailable();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   106
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   107
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   108
void CBufferCopier::CopyBuffer(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   109
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   110
	aOutBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   111
	TPtr8 desPtr(aOutBuffer->pBuffer, aOutBuffer->nAllocLen);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   112
 	desPtr.Copy(aInBuffer->pBuffer + aInBuffer->nOffset, aInBuffer->nFilledLen);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   113
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   114
	aOutBuffer->nFilledLen			 = aInBuffer->nFilledLen;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   115
	aOutBuffer->hMarkTargetComponent = aInBuffer->hMarkTargetComponent;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   116
	aOutBuffer->pMarkData			 = aInBuffer->pMarkData;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   117
	aOutBuffer->nTickCount			 = aInBuffer->nTickCount;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   118
	aOutBuffer->nTimeStamp			 = aInBuffer->nTimeStamp;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   119
	aOutBuffer->nFlags				 = aInBuffer->nFlags;			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   120
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   121
	iCallback.MbcBufferCopied(aInBuffer, aOutBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   122
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   123
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   124
TBool CBufferCopier::RemoveBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   125
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   126
	switch(aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   127
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   128
	case OMX_DirInput:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   129
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   130
		if(aBuffer == iInBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   131
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   132
			// also check the slot used for storing the input buffer when waiting for an output buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   133
			iInBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   134
			return ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   135
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   136
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   137
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   138
			return RemoveFromQueue(iInQueue, aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   139
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   140
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   141
	case OMX_DirOutput:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   142
		return RemoveFromQueue(iOutQueue, aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   143
	default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   144
		User::Panic(KBufferCopierPanic, KErrArgument);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   145
		return EFalse;	// prevent compiler warning
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   146
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   147
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   148
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   149
void CBufferCopier::FlushBuffers(OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   150
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   151
	OMX_BUFFERHEADERTYPE* buffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   152
	if(aDirection == OMX_DirInput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   153
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   154
        if(iInBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   155
            {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   156
            iCallback.MbcBufferFlushed(iInBuffer, OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   157
            iInBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   158
            }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   159
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   160
		while(iInQueue.Receive(buffer) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   161
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   162
			iCallback.MbcBufferFlushed(buffer, OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   163
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   164
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   165
	else if(aDirection == OMX_DirOutput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   166
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   167
		while(iOutQueue.Receive(buffer) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   168
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   169
			iCallback.MbcBufferFlushed(buffer, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   170
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   171
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   172
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   173
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   174
		User::Panic(KBufferCopierPanic, KErrArgument);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   175
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   176
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   177
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   178
TBool CBufferCopier::RemoveFromQueue(RMsgQueue<OMX_BUFFERHEADERTYPE*>& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   179
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   180
	TBool removed = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   181
	OMX_BUFFERHEADERTYPE* bufferHeader = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   182
	while(aQueue.Receive(bufferHeader) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   183
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   184
		if(bufferHeader != aBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   185
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   186
			TInt err = iRemoveQueue.Send(bufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   187
			__ASSERT_DEBUG(err == KErrNone, User::Panic(KBufferCopierPanic, err));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   188
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   189
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   190
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   191
			removed = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   192
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   193
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   194
	while(iRemoveQueue.Receive(bufferHeader) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   195
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   196
		TInt err = aQueue.Send(bufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   197
		__ASSERT_DEBUG(err == KErrNone, User::Panic(KBufferCopierPanic, err));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   198
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   199
	return removed;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   200
	}