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