--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.cpp Fri Oct 08 22:09:17 2010 +0100
@@ -0,0 +1,429 @@
+/*
+* Copyright (c) 2008 - 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 "log.h"
+#include "comxil3gpdemuxerprocessingfunction.h"
+#include "comxil3gpdemuxerconfigmanager.h"
+#include "comxil3gpdemuxervideooutputport.h"
+#include "comxil3gpdemuxeraudiooutputport.h"
+#include "c3gpdemuxer.h"
+#include <openmax/il/common/omxilcallbacknotificationif.h>
+
+
+COmxIL3GPDemuxerProcessingFunction* COmxIL3GPDemuxerProcessingFunction::NewL(MOmxILCallbackNotificationIf& aCallbacks)
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::NewL"));
+
+ COmxIL3GPDemuxerProcessingFunction* self = new (ELeave) COmxIL3GPDemuxerProcessingFunction(aCallbacks);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+COmxIL3GPDemuxerProcessingFunction::COmxIL3GPDemuxerProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks) :
+ COmxILProcessingFunction(aCallbacks)
+ {
+ }
+
+void COmxIL3GPDemuxerProcessingFunction::ConstructL()
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::ConstructL"));
+
+ iDemuxer = C3GPDemuxer::NewL(iCallbacks);
+
+ // this is used in the Idle->Executing transition to issue the port changed events in the correct order
+ // we create the callback now so it cannot fail later on
+ iStreamDetectCallback = new(ELeave) CAsyncCallBack(TCallBack(StreamDetectCallBack, this), CAsyncCallBack::EPriorityHigh);
+
+ iRequestHelper = COmxIL3GPDemuxerRequestHelper::NewL(this);
+ }
+
+COmxIL3GPDemuxerProcessingFunction::~COmxIL3GPDemuxerProcessingFunction()
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::~COmxIL3GPDemuxerProcessingFunction"));
+
+ delete iDemuxer;
+ delete iStreamDetectCallback;
+ delete iRequestHelper;
+ }
+
+void COmxIL3GPDemuxerProcessingFunction::SetConfigManager(COmxIL3GPDemuxerConfigManager& aConfigManager)
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::SetConfigManager"));
+
+ iConfigManager = &aConfigManager;
+ iConfigManager->SetDemuxer(*iDemuxer);
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::StateTransitionIndication(TStateIndex aNewState)
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::StateTransitionIndication"));
+
+ return iRequestHelper->StateTransitionIndication(aNewState);
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::DoStateTransitionIndication(TStateIndex aNewState)
+ {
+ DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::DoStateTransitionIndication"));
+
+ OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+ switch(aNewState)
+ {
+ case EStateExecuting:
+ {
+ DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateExecuting"));
+
+ // Cause PortFormatDetected and PortSettingsChanged with
+ // the format detected from the file.
+
+ // However, we want this to occur after the idle->executing
+ // completion notification, which FsmTransition() will queue
+ // after this function completes. So we use a CAsyncCallBack
+ // to create the events at some time after FsmTransition()
+ // completes. A high priority is chosen to avoid being starved
+ // by other busy AOs, in particular the callback manager(s).
+
+ if(!iStreamsDetected)
+ {
+ iStreamDetectCallback->CallBack();
+ }
+ else
+ {
+ iDemuxer->Start();
+ iExecuting = ETrue;
+ }
+
+ break;
+ }
+
+ case ESubStateLoadedToIdle:
+ {
+ DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateLoadedToIdle"));
+
+ const HBufC* filename = iConfigManager->Filename();
+ if(filename)
+ {
+ // get the maximum buffer count for a port
+ omxError = iDemuxer->AcquireResources(*filename);
+ }
+ else
+ {
+ // no file name has been set
+ omxError = OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+
+ case EStateIdle:
+ {
+ DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateIdle"));
+
+ if (iExecuting)
+ {
+ iExecuting = EFalse;
+ iDemuxer->Stop();
+ }
+ break;
+ }
+
+ case EStateLoaded:
+ {
+ DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateLoaded"));
+
+ iDemuxer->ReleaseResources();
+ iStreamsDetected = EFalse;
+ break;
+ }
+
+ case EStatePause:
+ {
+ DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StatePause"));
+
+ iDemuxer->Pause();
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ return omxError;
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::BufferFlushingIndication(TUint32 aPortIndex,
+ OMX_DIRTYPE aDirection)
+ {
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferFlushingIndication : aPortIndex[%d]"), aPortIndex);
+
+ return iRequestHelper->BufferFlushingIndication(aPortIndex, aDirection);
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::DoBufferFlushingIndication(TUint32 aPortIndex,
+ OMX_DIRTYPE /*aDirection*/)
+ {
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::DoBufferFlushingIndication : aPortIndex[%d]"), aPortIndex);
+
+ iDemuxer->FlushBuffers(aPortIndex);
+ return OMX_ErrorNone;
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::ParamIndication(OMX_INDEXTYPE /*aParamIndex*/,
+ const TAny* /*apComponentParameterStructure*/)
+ {
+ return OMX_ErrorNone;
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/,
+ const TAny* /*apComponentConfigStructure*/)
+ {
+ return OMX_ErrorNone;
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader,
+ OMX_DIRTYPE /*aDirection*/)
+ {
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferIndication >: [%X]"), apBufferHeader);
+
+ // Check if the previous buffer processing invalidated the demuxer
+ if (iDemuxer->Invalid())
+ {
+ return OMX_ErrorInvalidState;
+ }
+
+ TUint32 portIndex;
+ portIndex = apBufferHeader->nOutputPortIndex;
+
+ if (portIndex >= COmxIL3GPDemuxer::EPortIndexMax)
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ TRAPD(err, iDemuxer->ProcessThisBufferL(apBufferHeader, portIndex));
+
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferIndication :< size [%d]"), apBufferHeader->nFilledLen);
+
+ if (err == KErrNone)
+ {
+ return OMX_ErrorNone;
+ }
+ else
+ {
+ return OMX_ErrorUndefined;
+ }
+ }
+
+OMX_BOOL COmxIL3GPDemuxerProcessingFunction::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader,
+ OMX_DIRTYPE aDirection)
+ {
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferRemovalIndication >: [%X]"), apBufferHeader);
+
+ return iRequestHelper->BufferRemovalIndication(apBufferHeader, aDirection);
+ }
+
+OMX_BOOL COmxIL3GPDemuxerProcessingFunction::DoBufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection)
+ {
+ DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::DoBufferRemovalIndication : BUFFER [%X]"), apBufferHeader);
+
+ if (iDemuxer->RemoveBuffer(apBufferHeader, aDirection))
+ {
+ return OMX_TRUE;
+ }
+
+ return OMX_FALSE;
+ }
+
+OMX_U32 COmxIL3GPDemuxerProcessingFunction::NumAvailableStreams(COmxIL3GPDemuxer::TPortIndex aPortType)
+ {
+ switch(aPortType)
+ {
+ case COmxIL3GPDemuxer::EPortIndexVideoOutput:
+ {
+ TSize frameSize;
+ TVideoFormat format;
+ TBool videoAvailable = iDemuxer->GetVideoFormat(frameSize, format);
+ return videoAvailable ? 1 : 0;
+ }
+
+ case COmxIL3GPDemuxer::EPortIndexAudioOutput:
+ {
+ TAudioFormat format;
+ return iDemuxer->GetAudioFormat(format) ? 1 : 0;
+ }
+
+ default:
+ User::Invariant();
+ return 0;
+ }
+ }
+
+OMX_U32 COmxIL3GPDemuxerProcessingFunction::ActiveStream(COmxIL3GPDemuxer::TPortIndex /*aPortType*/)
+ {
+ //TODO
+ return 0;
+ }
+
+OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::SetActiveStream(COmxIL3GPDemuxer::TPortIndex aPortType, OMX_U32 aActiveStream)
+ {
+ switch(aPortType)
+ {
+ case COmxIL3GPDemuxer::EPortIndexVideoOutput:
+ {
+ TSize frameSize;
+ TVideoFormat format;
+ TBool videoAvailable = iDemuxer->GetVideoFormat(frameSize, format);
+ if(videoAvailable && aActiveStream == 0)
+ {
+ return OMX_ErrorNone;
+ }
+ else
+ {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ case COmxIL3GPDemuxer::EPortIndexAudioOutput:
+ // TODO
+//ZK return OMX_ErrorNotImplemented;
+ return OMX_ErrorNone;
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+ }
+
+void COmxIL3GPDemuxerProcessingFunction::SetVideoPort(COmxIL3GPDemuxerVideoOutputPort& aVideoPort)
+ {
+ iVideoPort = &aVideoPort;
+ }
+
+void COmxIL3GPDemuxerProcessingFunction::SetAudioPort(COmxIL3GPDemuxerAudioOutputPort& aAudioPort)
+ {
+ iAudioPort = &aAudioPort;
+ }
+
+TInt COmxIL3GPDemuxerProcessingFunction::StreamDetectCallBack(TAny* aPtr)
+ {
+ reinterpret_cast<COmxIL3GPDemuxerProcessingFunction*>(aPtr)->DoStreamDetect();
+ return KErrNone;
+ }
+
+void COmxIL3GPDemuxerProcessingFunction::DoStreamDetect()
+ {
+ OMX_ERRORTYPE error = iDemuxer->DetectStreams();
+ if(error)
+ {
+ iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL);
+ return;
+ }
+
+ // video format has been discovered
+ // check against port definition
+ // if autodetect, cause a PortSettingsChanged event
+ // if not autodetect and detected format is different, cause an error event
+ TSize size;
+ TVideoFormat format;
+ TBool videoAvailable = iDemuxer->GetVideoFormat(size, format);
+ // errors from EventNotification are ignored - these will be
+ // OMX_ErrorInsufficientResources if the callback could not be
+ // created or added to the queue. In this case, we probably want
+ // the callback manager to send an out-of-band error event to the
+ // IL client but this does not happen in 1509 yet
+ if(format.iCoding == OMX_VIDEO_CodingMax)
+ {
+ // format could not be mapped, and so is unsupported
+ iCallbacks.EventNotification(OMX_EventError, (TUint32) OMX_ErrorFormatNotDetected, 0, NULL);
+ // only send FormatNotDetected once for the component, not for both ports
+ return;
+ }
+ else
+ {
+ if (iVideoPort->IsEnabled())
+ {
+ iStreamsDetected = ETrue;
+ if (iVideoPort->VideoFormat() == OMX_VIDEO_CodingAutoDetect)
+ {
+ if(videoAvailable)
+ {
+ iVideoPort->FormatDetected(size, format);
+ }
+ // TODO spec doesn't say what the params should be for PortFormatDetected
+ iCallbacks.EventNotification(OMX_EventPortFormatDetected, COmxIL3GPDemuxer::EPortIndexVideoOutput, 0, NULL);
+ iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_IndexParamPortDefinition, COmxIL3GPDemuxer::EPortIndexVideoOutput, NULL);
+ }
+ else
+ {
+ if (iVideoPort->VideoFormat() != format.iCoding)
+ {
+ iStreamsDetected = EFalse;
+ iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL);
+ return;
+ }
+ }
+ }
+ }
+
+ TAudioFormat audioFormat;
+ TBool audioAvailable = iDemuxer->GetAudioFormat(audioFormat);
+
+ if(audioFormat.iCoding == OMX_AUDIO_CodingMax)
+ {
+ // format could not be mapped, and so is unsupported
+ iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL);
+ return;
+ }
+ else
+ {
+ if (iAudioPort->IsEnabled())
+ {
+ iStreamsDetected = ETrue;
+ if (iAudioPort->AudioFormat() == OMX_AUDIO_CodingAutoDetect)
+ {
+ if (audioAvailable)
+ {
+ iAudioPort->FormatDetected(audioFormat);
+ }
+ iCallbacks.EventNotification(OMX_EventPortFormatDetected, COmxIL3GPDemuxer::EPortIndexAudioOutput, 0, NULL);
+ iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_IndexParamPortDefinition, COmxIL3GPDemuxer::EPortIndexAudioOutput, NULL);
+ }
+ else
+ {
+ if (iAudioPort->AudioFormat() != audioFormat.iCoding)
+ {
+ iStreamsDetected = EFalse;
+ iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL);
+ return;
+ }
+ }
+ }
+ }
+ //Only start the demuxer if one of its ports is enabled.
+ if (iStreamsDetected)
+ {
+ iDemuxer->Start();
+ iExecuting = ETrue;
+ }
+ }
+