omxil/mmilapi/refomxil/src/omxilgenericilif/omxilgenericilifbodyimpl.cpp
changeset 0 40261b775718
child 16 eedf2dcd43c6
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // omxilgenericifilbodyimpl.cpp
       
    15 // 
       
    16 //
       
    17  
       
    18 #include "omxilgenericilifbodyimpl.h"
       
    19 #include "omxilcoreutils.h" 
       
    20 #include <e32base.h>
       
    21 #include <e32msgqueue.h>
       
    22 #include <mmf/server/mmfdatabuffer.h>
       
    23 
       
    24 
       
    25 const TInt KMaxMsgQueueEntries = 10;
       
    26 
       
    27 COmxBufferManager::COmxBufferManager(OMX_COMPONENTTYPE* aHandle)
       
    28 	: iHandle(aHandle)
       
    29 	{
       
    30 	}
       
    31 	
       
    32 COmxBufferManager::COmxBuffer::COmxBuffer()
       
    33 	{
       
    34 	}
       
    35 	
       
    36 	
       
    37 COmxBufferManager::COmxBuffer* COmxBufferManager::COmxBuffer::NewL(OMX_BUFFERHEADERTYPE* aBufferHeader, 
       
    38 																   CMMFBuffer* aBuffer)
       
    39 	{
       
    40 	COmxBuffer* self = new (ELeave) COmxBuffer;
       
    41 	CleanupStack::PushL(self);
       
    42 	self->ConstructL(aBufferHeader, aBuffer);
       
    43 	CleanupStack::Pop(self);
       
    44 	return self;
       
    45 	}
       
    46 	
       
    47 COmxBufferManager::COmxBuffer::~COmxBuffer()
       
    48 	{
       
    49 	if (iOwnsMmfBuffer)
       
    50 		{
       
    51 		delete iMmfBuffer;
       
    52 		}
       
    53 	}
       
    54 	
       
    55 CMMFBuffer* COmxBufferManager::COmxBuffer::MmfBuffer() const
       
    56 	{
       
    57 	return iMmfBuffer;
       
    58 	}
       
    59 	
       
    60 OMX_BUFFERHEADERTYPE* COmxBufferManager::COmxBuffer::BufferHeader() const
       
    61 	{
       
    62 	return iBufferHeader;
       
    63 	}
       
    64 
       
    65 void COmxBufferManager::COmxBuffer::SetPortObserver(MOmxILComponentIfObserver* aObserver)
       
    66 	{
       
    67 	iPortObserver = aObserver;
       
    68 	}
       
    69 
       
    70 MOmxILComponentIfObserver* COmxBufferManager::COmxBuffer::PortObserver() const
       
    71 	{
       
    72 	return iPortObserver;
       
    73 	}
       
    74 		
       
    75 COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(const CMMFBuffer* aBuffer) const
       
    76 	{
       
    77 	COmxBuffer* buffer = NULL;
       
    78 	for (TInt i=0;i<iBuffers.Count() && !buffer;i++)
       
    79 		{
       
    80 		if (iBuffers[i]->MmfBuffer() == aBuffer)
       
    81 			{
       
    82 			buffer = iBuffers[i];
       
    83 			}
       
    84 		}
       
    85 	return buffer;
       
    86 	}
       
    87 	
       
    88 COmxBufferManager::COmxBuffer* COmxBufferManager::FindBuffer(OMX_BUFFERHEADERTYPE* aBuffer) const
       
    89 	{
       
    90 	return reinterpret_cast<COmxBuffer*>(aBuffer->pAppPrivate);
       
    91 	}
       
    92 	
       
    93  TInt COmxBufferManager::UseBuffer(CMMFBuffer& aBuffer, TUint aPortIndex)
       
    94 	{
       
    95 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer.Type()))
       
    96 		{
       
    97 		OMX_BUFFERHEADERTYPE* buffer;
       
    98 		CMMFDataBuffer& dataBuffer = static_cast<CMMFDataBuffer&>(aBuffer);
       
    99 				
       
   100         TDes8& aBufferDes = dataBuffer.Data();
       
   101         OMX_ERRORTYPE error = iHandle->UseBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, (void*)&aBuffer, aBufferDes.MaxLength(), const_cast<TUint8*>(aBufferDes.Ptr()));
       
   102     	if (error != OMX_ErrorNone)
       
   103     		{
       
   104     		return ConvertOmxErrorType(error);
       
   105     		}
       
   106 		TRAPD(err, StoreBufferL(buffer, &aBuffer));
       
   107 		return err;
       
   108 		}
       
   109 	else
       
   110 		{
       
   111 		return KErrNotSupported;
       
   112 		}
       
   113 	}
       
   114 
       
   115 
       
   116  CMMFBuffer* COmxBufferManager::AllocateBufferL(TUint aPortIndex, 
       
   117  												TUint aSizeBytes)
       
   118 	{
       
   119 	OMX_BUFFERHEADERTYPE* buffer;
       
   120 	OMX_ERRORTYPE error = iHandle->AllocateBuffer(static_cast<OMX_HANDLETYPE>(iHandle), &buffer, aPortIndex, NULL, aSizeBytes);
       
   121 	User::LeaveIfError(ConvertOmxErrorType(error));
       
   122 
       
   123 	StoreBufferL(buffer,NULL); // transfers ownership
       
   124 
       
   125 	return FindBuffer(buffer)->MmfBuffer();
       
   126 	}
       
   127 	
       
   128 
       
   129  TInt COmxBufferManager::FreeBuffer(CMMFBuffer* aBuffer)
       
   130 	{
       
   131 	COmxBuffer* buffer;
       
   132 	for (TInt i=0;i<iBuffers.Count();i++)
       
   133 		{
       
   134 		buffer = iBuffers[i];
       
   135 		if (buffer->MmfBuffer() == aBuffer)
       
   136 			{
       
   137 			iBuffers.Remove(i);
       
   138 			OMX_ERRORTYPE err = iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, buffer->BufferHeader());
       
   139 			delete buffer;
       
   140 			return err;
       
   141 			}
       
   142 		}
       
   143 	return KErrNotFound;
       
   144 	}
       
   145 	
       
   146 void COmxBufferManager::COmxBuffer::ConstructL(OMX_BUFFERHEADERTYPE* aBufferHeader, 
       
   147 											   CMMFBuffer* aBuffer)
       
   148 	{
       
   149 	
       
   150 	// Now if CMMFBuffer is NULL, this is been called from allocate buffer, and we need to 
       
   151 	// Allocate a ptr buffer to correspond to the buffer created by OMX
       
   152 	ASSERT(aBufferHeader);
       
   153 	iBufferHeader = aBufferHeader;	
       
   154 	if (aBuffer == NULL)
       
   155 		{
       
   156 		TPtr8 ptr(iBufferHeader->pBuffer, iBufferHeader->nFilledLen, iBufferHeader->nAllocLen);
       
   157 		CMMFBuffer* mmfBuffer = CMMFPtrBuffer::NewL(ptr);
       
   158 		iMmfBuffer = mmfBuffer;
       
   159 		iOwnsMmfBuffer = ETrue;
       
   160 		}
       
   161 	else
       
   162 		{
       
   163 		iMmfBuffer = aBuffer;
       
   164 		}
       
   165 		
       
   166 	// store pointer to element in array
       
   167 	iBufferHeader->pAppPrivate = this;
       
   168 	}
       
   169 
       
   170 void COmxBufferManager::StoreBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, 
       
   171 									 CMMFBuffer* aBuffer)
       
   172 	{
       
   173 	COmxBuffer* buf = COmxBuffer::NewL(aBufferHeader, aBuffer);
       
   174 	CleanupStack::PushL(buf);
       
   175 	iBuffers.AppendL(buf);
       
   176 	CleanupStack::Pop(buf);
       
   177 	}
       
   178 	
       
   179  TInt COmxBufferManager::EmptyThisBuffer(const CMMFBuffer* aBuffer, 
       
   180  										 MOmxILComponentIfObserver* aObserver)
       
   181 	{
       
   182 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
       
   183 		{
       
   184 		COmxBuffer* omxBuffer = FindBuffer(aBuffer);
       
   185 		if (!omxBuffer)
       
   186 			{
       
   187 			return KErrNotFound;
       
   188 			}
       
   189 
       
   190 		omxBuffer->SetPortObserver(aObserver);
       
   191 		OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
       
   192 		const CMMFDataBuffer* buf = static_cast<const CMMFDataBuffer*>(aBuffer);
       
   193 		const TDesC8& des = buf->Data();
       
   194 		bufferHeader->nFilledLen = des.Length();
       
   195 		bufferHeader->nFlags = 0;
       
   196 		if (aBuffer->LastBuffer())
       
   197 			{	
       
   198 			bufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
       
   199 			}
       
   200 		else
       
   201 			{
       
   202 			bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
       
   203 			}
       
   204 		return ConvertOmxErrorType(iHandle->EmptyThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
       
   205 		}
       
   206 	else
       
   207 		{
       
   208 		return KErrNotSupported;
       
   209 		}
       
   210 	}
       
   211 
       
   212 
       
   213  TInt COmxBufferManager::FillThisBuffer(CMMFBuffer* aBuffer, 
       
   214  										MOmxILComponentIfObserver* aObserver)
       
   215 	{
       
   216 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
       
   217 		{
       
   218 		COmxBuffer* omxBuffer = FindBuffer(aBuffer);
       
   219 		if (!omxBuffer)
       
   220 			{
       
   221 			return KErrNotFound;
       
   222 			}
       
   223 		omxBuffer->SetPortObserver(aObserver);
       
   224 		OMX_BUFFERHEADERTYPE* bufferHeader = omxBuffer->BufferHeader();
       
   225 		
       
   226 		bufferHeader->nFilledLen = 0;
       
   227 		// clear last buffer flag
       
   228 		bufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
       
   229 		return ConvertOmxErrorType(iHandle->FillThisBuffer(static_cast<OMX_HANDLETYPE>(iHandle), bufferHeader));
       
   230 		}
       
   231 	else
       
   232 		{
       
   233 		return KErrNotSupported;
       
   234 		}
       
   235 	}
       
   236 
       
   237 	
       
   238 	
       
   239 COmxBufferManager::~COmxBufferManager()
       
   240 	{
       
   241 	for (TInt i=0;i<iBuffers.Count();i++)
       
   242 		{
       
   243 		COmxBuffer* omxBuffer = iBuffers[i];
       
   244 		iHandle->FreeBuffer(static_cast<OMX_HANDLETYPE>(iHandle), 0, omxBuffer->BufferHeader());
       
   245 		delete omxBuffer;
       
   246 		}
       
   247 	iBuffers.Close();
       
   248 	}
       
   249 
       
   250 
       
   251 COmxCallbacks* COmxCallbacks::NewL(MOmxILComponentIfObserver& aObserver)
       
   252 	{
       
   253 	COmxCallbacks* self = new (ELeave) COmxCallbacks(aObserver);
       
   254 	CleanupStack::PushL(self);
       
   255 	self->ConstructL();
       
   256 	CleanupStack::Pop(self);
       
   257 	return self;
       
   258 	}
       
   259 	
       
   260 	
       
   261 void COmxCallbacks::ConstructL()
       
   262 	{
       
   263 	OMX_CALLBACKTYPE h =
       
   264 			{
       
   265 			&::EventHandler,
       
   266 			&::EmptyBufferDone,
       
   267 			&::FillBufferDone
       
   268 			};
       
   269 			
       
   270 	iHandle = h;
       
   271 	CActiveScheduler::Add(this);
       
   272 
       
   273 	User::LeaveIfError(iMsgQueue.CreateLocal(KMaxMsgQueueEntries));
       
   274 	iMsgQueue.NotifyDataAvailable(iStatus);
       
   275 	SetActive();
       
   276 	}
       
   277 
       
   278 COmxCallbacks::COmxCallbacks(MOmxILComponentIfObserver& aObserver)
       
   279 	: CActive(EPriorityStandard),
       
   280 	iParent(aObserver)
       
   281 	{
       
   282 	}
       
   283 		
       
   284 	
       
   285 COmxCallbacks::operator OMX_CALLBACKTYPE*()
       
   286 	{
       
   287 	return &iHandle;
       
   288 	}
       
   289 	
       
   290 	
       
   291 void COmxCallbacks::RunL()
       
   292 	{
       
   293 	TOmxMessage msg;
       
   294 	
       
   295 	while (iMsgQueue.Receive(msg)==KErrNone)
       
   296 		{
       
   297 		switch (msg.iType)
       
   298 			{
       
   299 			case EEmptyBufferCallback:
       
   300 				{
       
   301 				MOmxILComponentIfObserver* callback = msg.iBuffer->PortObserver();
       
   302 				const CMMFBuffer* buffer = msg.iBuffer->MmfBuffer();
       
   303 				OMX_BUFFERHEADERTYPE* bufferHeader = msg.iBuffer->BufferHeader();
       
   304 				TInt portIndex = static_cast<TInt>(bufferHeader->nInputPortIndex);
       
   305 				User::LeaveIfError(callback->EmptyBufferDone(buffer, portIndex));
       
   306 				break;
       
   307 				}				
       
   308 
       
   309 			case EFillBufferCallback:
       
   310 				{
       
   311 				CMMFBuffer* mmfBuffer = msg.iBuffer->MmfBuffer();
       
   312 				OMX_BUFFERHEADERTYPE* bufferHeader = msg.iBuffer->BufferHeader();
       
   313 
       
   314 				if (CMMFBuffer::IsSupportedDataBuffer(mmfBuffer->Type()))
       
   315 					{
       
   316 					CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(mmfBuffer);
       
   317 					TDes8& aBufferDes = dataBuffer->Data();
       
   318 					aBufferDes.SetLength(bufferHeader->nFilledLen);
       
   319 					mmfBuffer->SetLastBuffer(bufferHeader->nFlags & OMX_BUFFERFLAG_EOS);
       
   320 					}				
       
   321 				else
       
   322 					{
       
   323 					ASSERT(EFalse);
       
   324 					}
       
   325 				MOmxILComponentIfObserver* callback = msg.iBuffer->PortObserver();
       
   326 				bufferHeader = msg.iBuffer->BufferHeader();
       
   327 				TInt portIndex = static_cast<TInt>(bufferHeader->nOutputPortIndex);
       
   328 				User::LeaveIfError(callback->FillBufferDone(mmfBuffer, portIndex));
       
   329 				break;
       
   330 				}				
       
   331 			case EEventCallback:
       
   332 				{
       
   333 				TInt err = KErrNone;
       
   334 				err = iParent.EventHandler(msg.iEventParams.iEvent, 
       
   335 								  		   msg.iEventParams.iData1, 
       
   336 									  	   msg.iEventParams.iData2, 
       
   337 									  	   msg.iEventParams.iExtraData);
       
   338 				if (err != KErrNone)
       
   339 					{
       
   340 					// Very possible the event is not supported by the IL Client. 
       
   341 					// Ignore for now
       
   342 					// ASSERT(EFalse); // Uncomment this line if interested in catching this case on debug mode.
       
   343 					}
       
   344 				break;
       
   345 				}				
       
   346 			default:
       
   347 				{
       
   348 				// This is an invalid state
       
   349 				ASSERT(EFalse);
       
   350 				}					
       
   351 			};
       
   352 		}
       
   353 
       
   354 	// setup for next callbacks		
       
   355 	iStatus = KRequestPending;
       
   356 	iMsgQueue.NotifyDataAvailable(iStatus);
       
   357 	SetActive();	
       
   358 	}
       
   359 	
       
   360 COmxCallbacks::~COmxCallbacks()
       
   361 	{
       
   362 	Cancel();	
       
   363 	iMsgQueue.Close();
       
   364 	}
       
   365 	
       
   366 	
       
   367 void COmxCallbacks::DoCancel()
       
   368 	{
       
   369 	if (iMsgQueue.Handle()!=NULL)
       
   370 		{
       
   371 		iMsgQueue.CancelDataAvailable();
       
   372 		}
       
   373 	}
       
   374 
       
   375 	
       
   376 TInt COmxCallbacks::FillBufferDone(OMX_HANDLETYPE aComponent, 
       
   377 								   COmxBufferManager::COmxBuffer* aBuffer)
       
   378 	{
       
   379 	TOmxMessage message;
       
   380 	message.iType = EFillBufferCallback;
       
   381 	message.iComponent = aComponent;
       
   382 	message.iBuffer = aBuffer;
       
   383 	return iMsgQueue.Send(message);
       
   384 	}
       
   385 	
       
   386 TInt COmxCallbacks::EmptyBufferDone(OMX_HANDLETYPE aComponent, 
       
   387 								    COmxBufferManager::COmxBuffer* aBuffer)
       
   388 	{
       
   389 	TOmxMessage message;
       
   390 	message.iType = EEmptyBufferCallback;
       
   391 	message.iComponent = aComponent;
       
   392 	message.iBuffer = aBuffer;
       
   393 	return iMsgQueue.Send(message);
       
   394 	}
       
   395 	
       
   396 TInt COmxCallbacks::EventHandler(OMX_HANDLETYPE aComponent, 
       
   397 								 const TEventParams& aEventParams)
       
   398 	{
       
   399 	TOmxMessage message;
       
   400 	message.iType = EEventCallback;
       
   401 	message.iComponent = aComponent;
       
   402 	message.iEventParams = aEventParams;
       
   403 	return iMsgQueue.Send(message);
       
   404 	}
       
   405 
       
   406 
       
   407 
       
   408 OMX_ERRORTYPE EventHandler(OMX_OUT OMX_HANDLETYPE aComponent, 
       
   409 						   OMX_OUT TAny* aAppData,
       
   410         				   OMX_OUT OMX_EVENTTYPE aEvent, 
       
   411         				   OMX_OUT TUint32 aData1,
       
   412         				   OMX_OUT TUint32 aData2,
       
   413         				   OMX_OUT TAny* aExtra)
       
   414 	{
       
   415 	COmxCallbacks::TEventParams eventParams;
       
   416 	eventParams.iEvent = aEvent;
       
   417 	eventParams.iData1 = aData1;
       
   418 	eventParams.iData2 = aData2;
       
   419 	eventParams.iExtraData = aExtra;
       
   420 	TInt error = static_cast<COmxCallbacks*>(aAppData)->EventHandler(aComponent, eventParams);
       
   421 	return ConvertSymbianErrorType(error);
       
   422 	}
       
   423         			
       
   424 OMX_ERRORTYPE EmptyBufferDone(OMX_HANDLETYPE aComponent,
       
   425        						  TAny* aAppData,
       
   426        						  OMX_BUFFERHEADERTYPE* aBuffer)
       
   427 	{
       
   428 	COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
       
   429 	TInt error = static_cast<COmxCallbacks*>(aAppData)->EmptyBufferDone(aComponent, buffer);
       
   430 	return ConvertSymbianErrorType(error);
       
   431 	}
       
   432         
       
   433 OMX_ERRORTYPE FillBufferDone(OMX_HANDLETYPE aComponent,
       
   434        						 TAny* aAppData,
       
   435        						 OMX_BUFFERHEADERTYPE* aBuffer)
       
   436 	{
       
   437 	COmxBufferManager::COmxBuffer* buffer = static_cast<COmxBufferManager::COmxBuffer*>(aBuffer->pAppPrivate);
       
   438 	TInt error = static_cast<COmxCallbacks*>(aAppData)->FillBufferDone(aComponent, buffer);
       
   439 	return ConvertSymbianErrorType(error);
       
   440 	}
       
   441