diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.cpp --- /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 + + +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(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; + } + } +