omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.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-2009 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
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    25
#include <openmax/il/common/omxilutil.h>
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    26
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    27
#include "comxilvideoschedulerpf.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    28
#include "comxilvideoscheduler.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    29
#include "resourcefilereader.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    30
#include "buffercopierstatemonitor.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    31
#include "omxilvideoschedulerextensionsindexes.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    32
#include <openmax/il/extensions/omxildroppedframeeventextension.h>
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    33
#include <openmax/il/common/omxilcallbacknotificationif.h>
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    34
#include "log.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    35
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    36
_LIT(KVideoSchedulerPanicCategory, "omxilvscheduler"); //should restrict to 16 characters as it is used in User::Panic
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    37
_LIT(KResourceFileName, "Z:\\resource\\videoscheduler\\videoscheduler.rsc");
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    38
const TInt KMaxRenderTime = 1000000;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    39
const TInt KMaxGraphicSinkBufferCount(2); //This is set as the maximum number of buffers that can be sent to the graphic sink without the risk of overloading it.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    40
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    41
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    42
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    43
COmxILVideoSchedulerPF* COmxILVideoSchedulerPF::NewL(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    44
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    45
	COmxILVideoSchedulerPF* self = new (ELeave) COmxILVideoSchedulerPF(aCallbacks, aComponent, aHandle);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    46
	CleanupStack::PushL(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    47
	self->ConstructL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    48
	CleanupStack::Pop(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    49
	return self;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    50
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    51
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    52
COmxILVideoSchedulerPF::COmxILVideoSchedulerPF(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    53
: COmxILProcessingFunction(aCallbacks),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    54
  iComponent(aComponent),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    55
  iIsClockStopped(ETrue),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    56
  iInvalid(EFalse),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    57
  iTimeStamp(KMinTInt64),
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    58
  iHandle(aHandle)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    59
 	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    60
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    61
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    62
void COmxILVideoSchedulerPF::ConstructL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    63
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    64
	User::LeaveIfError(iMutex.CreateLocal());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    65
	iBufferCopierStateMonitor = CBufferCopierStateMonitor::NewL(*this, iComponent);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    66
	// get timer info
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    67
	CResourceFileReader* reader = CResourceFileReader::NewLC(KResourceFileName);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    68
	reader->ReadTimerInfoL(iRenderTime, iMaxLateness);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    69
	CleanupStack::PopAndDestroy(reader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    70
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    71
	// Prefill the render time array with the default render time read from resource file
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    72
	for (TInt count = 0; count < KRenderTimeListLength; ++count)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    73
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    74
		iRenderTimeList[count] = iRenderTime;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    75
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    76
	iRenderTimeSum = iRenderTime * KRenderTimeListLength;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    77
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    78
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    79
COmxILVideoSchedulerPF::~COmxILVideoSchedulerPF()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    80
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    81
	delete iBufferCopierStateMonitor;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    82
    iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    83
	iWaitingBuffers.Reset();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    84
	iCompletedBuffersHeldByPause.Reset();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    85
    iMutex.Signal();	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    86
	iMutex.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    87
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    88
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    89
OMX_ERRORTYPE COmxILVideoSchedulerPF::StateTransitionIndication(TStateIndex aNewState)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    90
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    91
	switch(aNewState)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    92
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    93
		case EStateExecuting:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    94
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    95
			if (iPausedState)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    96
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    97
			    iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    98
				iPausedState = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    99
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   100
				// send any buffers that received time updates during paused state
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   101
				if (iOutputBufferSentCount < KMaxGraphicSinkBufferCount)   // only allowed to send 2 buffers at a time
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   102
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   103
					SubmitBufferHeldByPause();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   104
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   105
                iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   106
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   107
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   108
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   109
		case EStatePause:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   110
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   111
			iPausedState = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   112
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   113
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   114
		case ESubStateLoadedToIdle:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   115
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   116
			TUint32 bufferCount = iComponent.BufferCount();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   117
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   118
			TInt error = iBufferCopierStateMonitor->SetState(CBufferCopierStateMonitor::ESubLoadedToIdle);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   119
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   120
			if (error != KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   121
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   122
			    return SymbianErrorToOmx(error);                    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   123
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   124
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   125
			error = iWaitingBuffers.Reserve(bufferCount);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   126
			if (error != KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   127
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   128
			    return SymbianErrorToOmx(error);                    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   129
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   130
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   131
			error = iCompletedBuffersHeldByPause.Reserve(bufferCount);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   132
			if (error != KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   133
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   134
			    return SymbianErrorToOmx(error);                    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   135
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   136
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   137
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   138
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   139
		case EStateIdle:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   140
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   141
			iOutputBufferSentCount = iComponent.BufferCount();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   142
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   143
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   144
		case ESubStateIdleToLoaded:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   145
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   146
			TInt error = iBufferCopierStateMonitor->SetState(CBufferCopierStateMonitor::ESubIdleToLoaded);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   147
			if (error != KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   148
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   149
			    return SymbianErrorToOmx(error);                    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   150
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   151
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   152
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   153
		default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   154
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   155
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   156
			}	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   157
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   158
    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   159
	return OMX_ErrorNone;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   160
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   161
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   162
OMX_ERRORTYPE COmxILVideoSchedulerPF::BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   163
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   164
	// called from command thread
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   165
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   166
    iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   167
	if (iBufferCopierStateMonitor->BufferCopier())
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   168
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   169
		if (aPortIndex == OMX_ALL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   170
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   171
			iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   172
			iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   173
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   174
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   175
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   176
			iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(aDirection);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   177
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   178
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   179
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   180
	if (aDirection == OMX_DirOutput || aPortIndex == OMX_ALL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   181
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   182
		while (iWaitingBuffers.Count() > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   183
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   184
			iWaitingBuffers[0]->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   185
			iWaitingBuffers[0]->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   186
			iWaitingBuffers[0]->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   187
			iCallbacks.BufferDoneNotification(iWaitingBuffers[0], 1, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   188
			iWaitingBuffers.Remove(0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   189
			iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   190
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   191
		if(iSinkPendingBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   192
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   193
			iSinkPendingBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   194
			iSinkPendingBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   195
			iSinkPendingBuffer->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   196
			iCallbacks.BufferDoneNotification(iSinkPendingBuffer, 1, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   197
			iSinkPendingBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   198
			iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   199
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   200
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   201
    iMutex.Signal();        
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   202
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   203
	return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   204
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   205
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   206
OMX_ERRORTYPE COmxILVideoSchedulerPF::ParamIndication(OMX_INDEXTYPE aParamIndex,
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   207
													const TAny* apComponentParameterStructure)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   208
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   209
	DEBUG_PRINTF(_L8("COmxILVideoSchedulerProcessingFunction::ParamIndication"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   210
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   211
	if(aParamIndex == OMX_NokiaIndexParamDroppedFrameEvent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   212
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   213
		const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT* dropFrame = static_cast<const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT*>(apComponentParameterStructure);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   214
		iEnableDropFrameEvent = dropFrame->bEnabled;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   215
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   216
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   217
	return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   218
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   219
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   220
OMX_ERRORTYPE COmxILVideoSchedulerPF::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/, const TAny* /*apComponentConfigStructure*/)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   221
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   222
	return OMX_ErrorNone;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   223
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   224
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   225
OMX_ERRORTYPE COmxILVideoSchedulerPF::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader,
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   226
	  												   OMX_DIRTYPE aDirection)			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   227
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   228
	if (iInvalid)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   229
	    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   230
	    return OMX_ErrorInvalidState;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   231
	    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   232
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   233
	// called from decoder data thread or sink data thread
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   234
	iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   235
	if(aDirection == OMX_DirOutput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   236
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   237
		apBufferHeader->nFlags = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   238
		iOutputBufferSentCount--;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   239
		ASSERT(iOutputBufferSentCount <= iComponent.BufferCount());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   240
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   241
		DEBUG_PRINTF2(_L8("VS2::BufferIndication : apBufferHeader->nTickCount = %d"), apBufferHeader->nTickCount);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   242
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   243
		// update the render time if it is set
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   244
		if (apBufferHeader->nTickCount > 0 && apBufferHeader->nTickCount <= KMaxRenderTime)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   245
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   246
			// Add new render time to render time list, and recalculate average
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   247
			iRenderTimeSum -= iRenderTimeList[iRenderTimeListPos];
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   248
			iRenderTimeSum += apBufferHeader->nTickCount;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   249
			iRenderTimeList[iRenderTimeListPos] = apBufferHeader->nTickCount;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   250
			++iRenderTimeListPos;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   251
			iRenderTimeListPos %= KRenderTimeListLength;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   252
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   253
			iRenderTime = iRenderTimeSum / KRenderTimeListLength;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   254
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   255
			DEBUG_PRINTF2(_L8("VS2::BufferIndication : New iRenderTime = %ld"), iRenderTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   256
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   257
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   258
		// previously sent buffer has come back
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   259
		// send any buffers that received time updates
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   260
		// at startup, iOutputBufferSentCount may be >2 if output port is non-supplier
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   261
		if (!iPausedState && iOutputBufferSentCount < KMaxGraphicSinkBufferCount)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   262
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   263
			SubmitBufferHeldByPause();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   264
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   265
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   266
	else if(apBufferHeader->nFlags & OMX_BUFFERFLAG_DECODEONLY)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   267
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   268
		// this frame is not to be rendered (probably as part of an accurate seek)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   269
		// drop the data and send it back to the decoder
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   270
		apBufferHeader->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   271
		apBufferHeader->nFlags = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   272
		apBufferHeader->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   273
		iCallbacks.BufferDoneNotification(apBufferHeader, 0, OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   274
		iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   275
		return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   276
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   277
	if (iBufferCopierStateMonitor->BufferCopier())
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   278
	    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   279
	    iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(apBufferHeader, aDirection);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   280
	    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   281
    iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   282
    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   283
	return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   284
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   285
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   286
OMX_ERRORTYPE COmxILVideoSchedulerPF::MediaTimeIndication(const OMX_TIME_MEDIATIMETYPE& aTimeInfo)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   287
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   288
	// called from clock thread
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   289
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   290
	switch(aTimeInfo.eUpdateType)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   291
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   292
	case OMX_TIME_UpdateRequestFulfillment:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   293
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   294
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   295
		iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   296
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   297
		TInt index = -1;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   298
		OMX_BUFFERHEADERTYPE* buffer = reinterpret_cast<OMX_BUFFERHEADERTYPE*>(aTimeInfo.nClientPrivate);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   299
		__ASSERT_DEBUG(buffer->nTimeStamp == aTimeInfo.nMediaTimestamp, Panic(EPanicBadAssociation));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   300
		if(FindWaitingBuffer(buffer, aTimeInfo.nMediaTimestamp, index))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   301
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   302
			if (iPausedState || iCompletedBuffersHeldByPause.Count() > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   303
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   304
				TBufferMessage bufferMessage;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   305
				bufferMessage.iBufferHeader = buffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   306
				bufferMessage.iMediaTimeInfo = aTimeInfo;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   307
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   308
				OMX_ERRORTYPE error = SymbianErrorToOmx(iCompletedBuffersHeldByPause.Append(bufferMessage)); // note append cannot fail, allocated enough slots
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   309
				iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   310
				return error;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   311
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   312
			else 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   313
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   314
				SendTimedOutputBuffer(buffer, aTimeInfo, index);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   315
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   316
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   317
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   318
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   319
			// TODO [SL] now what?
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   320
			User::Invariant();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   321
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   322
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   323
		iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   324
		return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   325
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   326
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   327
	case OMX_TIME_UpdateScaleChanged:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   328
		if(aTimeInfo.xScale >= 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   329
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   330
			// the clock takes care completing requests at the correct media time
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   331
			return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   332
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   333
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   334
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   335
			// TODO think harder about implications of negative scale
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   336
			// certainly the iTimeStamp checking must be reversed
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   337
			ASSERT(0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   338
			return OMX_ErrorNotImplemented;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   339
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   340
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   341
	case OMX_TIME_UpdateClockStateChanged:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   342
		iClockState.eState = aTimeInfo.eState;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   343
		switch(aTimeInfo.eState)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   344
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   345
		case OMX_TIME_ClockStateStopped:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   346
		    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   347
		    // clock stopped so remove any pending buffers from the list as time requests
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   348
		    // will be resent when the clock is running again
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   349
		    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   350
	        iIsClockStopped	= ETrue;	 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   351
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   352
	        iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   353
			while (iCompletedBuffersHeldByPause.Count() > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   354
                { 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   355
				iCompletedBuffersHeldByPause.Remove(0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   356
                }           	         
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   357
	        
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   358
			if(iSinkPendingBuffer && iBufferCopierStateMonitor)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   359
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   360
				// if sink pending buffer exist (as sink is bottleneck) then drop the frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   361
				iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(iSinkPendingBuffer, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   362
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   363
				// dropped a frame, so send an event if the dropped frame extension is enabled
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   364
				if (iEnableDropFrameEvent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   365
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   366
					//TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   367
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   368
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   369
				iSinkPendingBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   370
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   371
            iMutex.Signal();            
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   372
	        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   373
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   374
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   375
		case OMX_TIME_ClockStateWaitingForStartTime:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   376
		    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   377
		    iIsClockStopped = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   378
		    // if now in WaitingForStartTime state and start time already received, send it now
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   379
		    if (iStartTimePending)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   380
		        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   381
		        OMX_ERRORTYPE error = iComponent.SetVideoStartTime(iStartTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   382
		        if (error != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   383
		            {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   384
		            // iStartTimePending = EFalse; // FIXME - Is this required?
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   385
		            return error;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   386
		            }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   387
		        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   388
		    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   389
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   390
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   391
		case OMX_TIME_ClockStateRunning:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   392
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   393
			iTimeStamp = KMinTInt64;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   394
			if(iIsClockStopped)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   395
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   396
				// the clock is running after being stopped previously
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   397
				// resend time requests for waiting buffers
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   398
				iIsClockStopped = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   399
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   400
				for (TInt i = 0; i < iWaitingBuffers.Count(); ++i)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   401
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   402
					iComponent.MediaTimeRequest(iWaitingBuffers[i], iWaitingBuffers[i]->nTimeStamp, iRenderTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   403
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   404
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   405
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   406
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   407
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   408
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   409
		iStartTimePending = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   410
		DEBUG_PRINTF2(_L8("VS2::MediaTimeIndication : ClockStateChanged = %d"), aTimeInfo.eState);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   411
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   412
		return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   413
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   414
	default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   415
		return OMX_ErrorBadParameter;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   416
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   417
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   418
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   419
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   420
/* Check if aBuffer still exist in the waiting queue */ 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   421
TBool COmxILVideoSchedulerPF::FindWaitingBuffer(const OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TICKS& aMediaTime, TInt& aIndex) const
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   422
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   423
	__ASSERT_DEBUG(const_cast<RMutex&>(iMutex).IsHeld(), Panic(EPanicMutexUnheld));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   424
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   425
	TBool found = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   426
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   427
	for (TInt i=0; i<iWaitingBuffers.Count(); ++i)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   428
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   429
		if ((iWaitingBuffers[i] == aBuffer) && (iWaitingBuffers[i]->nTimeStamp == aMediaTime))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   430
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   431
			found = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   432
			aIndex = i;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   433
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   434
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   435
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   436
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   437
	return found;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   438
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   439
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   440
/**
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   441
Check if a specified buffer is currently held by the processing function,
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   442
and remove it if found.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   443
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   444
@param apBufferHeader Buffer to remove
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   445
@param aDirection Port direction
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   446
@return Flag to indicate if buffer was removed.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   447
*/
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   448
OMX_BOOL COmxILVideoSchedulerPF::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   449
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   450
    iMutex.Wait();	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   451
	if(iBufferCopierStateMonitor->BufferCopier() && iBufferCopierStateMonitor->BufferCopier()->RemoveBuffer(apBufferHeader, aDirection))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   452
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   453
		if(aDirection == OMX_DirOutput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   454
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   455
			iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   456
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   457
		iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   458
		return OMX_TRUE;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   459
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   460
	else if(aDirection == OMX_DirOutput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   461
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   462
		for (TInt i = 0; i < iWaitingBuffers.Count(); ++i)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   463
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   464
			if (iWaitingBuffers[i] == apBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   465
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   466
				iWaitingBuffers[i]->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   467
				iWaitingBuffers.Remove(i);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   468
				iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   469
			    iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   470
				return OMX_TRUE;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   471
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   472
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   473
		if(apBufferHeader == iSinkPendingBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   474
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   475
			iSinkPendingBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   476
			iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   477
			iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   478
			return OMX_TRUE;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   479
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   480
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   481
 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   482
	iMutex.Signal();    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   483
	return OMX_FALSE;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   484
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   485
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   486
/* Submit the first time update buffer that still exists in the waiting queue. */
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   487
void COmxILVideoSchedulerPF::SubmitBufferHeldByPause()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   488
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   489
	__ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   490
	__ASSERT_DEBUG(iOutputBufferSentCount < KMaxGraphicSinkBufferCount, Panic(EPanicBadOutputRegulation));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   491
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   492
	if(iSinkPendingBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   493
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   494
		DEBUG_PRINTF(_L8("VS2::SubmitBufferHeldByPause ***************************SEND SINK PENDING BUFFER"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   495
		OMX_BUFFERHEADERTYPE* buffer = iSinkPendingBuffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   496
		iSinkPendingBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   497
		SendOutputBuffer(buffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   498
		return;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   499
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   500
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   501
	TInt index = -1;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   502
	TBool bufferSent = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   503
	while (iCompletedBuffersHeldByPause.Count() > 0 && !bufferSent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   504
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   505
		TBufferMessage& msg = iCompletedBuffersHeldByPause[0];
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   506
		if (FindWaitingBuffer(msg.iBufferHeader, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   507
					msg.iMediaTimeInfo.nMediaTimestamp, index))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   508
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   509
			DEBUG_PRINTF(_L8("VS2::SubmitBufferHeldByPause ***************************SEND HELD BUFFER"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   510
			bufferSent = SendTimedOutputBuffer(msg.iBufferHeader, msg.iMediaTimeInfo, index);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   511
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   512
		iCompletedBuffersHeldByPause.Remove(0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   513
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   514
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   515
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   516
/** Returns ETrue if aBuffer was sent, EFalse otherwise */
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   517
TBool COmxILVideoSchedulerPF::SendTimedOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TIME_MEDIATIMETYPE& aMediaTimeInfo, TInt aIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   518
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   519
	__ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   520
	__ASSERT_DEBUG(aBuffer->nTimeStamp == aMediaTimeInfo.nMediaTimestamp, Panic(EPanicBadAssociation));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   521
	__ASSERT_DEBUG(aBuffer == reinterpret_cast<OMX_BUFFERHEADERTYPE*>(aMediaTimeInfo.nClientPrivate), Panic(EPanicBadAssociation));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   522
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   523
#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   524
	DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer **********************************"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   525
	TTime t;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   526
	t.HomeTime();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   527
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : t.HomeTime() = %ld"), t.Int64());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   528
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nClientPrivate = 0x%X"), aMediaTimeInfo.nClientPrivate);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   529
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nMediaTimestamp = %ld"), aMediaTimeInfo.nMediaTimestamp);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   530
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nOffset = %ld"), aMediaTimeInfo.nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   531
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nWallTimeAtMediaTime = %ld"), aMediaTimeInfo.nWallTimeAtMediaTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   532
#endif
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   533
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   534
	TBool bufferSent = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   535
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   536
	OMX_U32 flags = aBuffer->nFlags;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   537
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   538
	// Work out how long it is from now until the frame will be rendered.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   539
	// This will be the time it takes the sink to render, minus the offset
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   540
	// value from the clock completion (i.e how far before the requested
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   541
	// time that the clock has completed us). A lateness of 0 means we are at
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   542
	// the correct time to send the buffer, a positive lateness means we are
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   543
	// late sending the buffer, and a lateness waitTime means we are early.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   544
	// For the first frame we were not able to request an early completion to
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   545
	// offset the render time, so assume that the render time is 0.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   546
	OMX_TICKS lateness = 0 - aMediaTimeInfo.nOffset;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   547
	if (!(flags & OMX_BUFFERFLAG_STARTTIME))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   548
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   549
		lateness += iRenderTime;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   550
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   551
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   552
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iRenderTime = %ld"), iRenderTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   553
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : lateness = %ld"), lateness);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   554
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iMaxLateness = %ld"), iMaxLateness);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   555
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iTimeStamp = %ld"), iTimeStamp);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   556
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iFrameDroppedCount = %d"), iFrameDroppedCount);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   557
	DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : flags = %d"), flags);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   558
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   559
	iWaitingBuffers.Remove(aIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   560
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   561
	// Send the buffer if the wait time is within the maximum allowed delay and timestamp is later than the previous timestamp, otherwise skip the buffer	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   562
	if ((lateness <= iMaxLateness || iFrameDroppedCount >= KMaxGraphicSinkBufferCount) && aMediaTimeInfo.nMediaTimestamp > iTimeStamp)   // shouldn't drop more than 2 frames at a time when decoder is slow
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   563
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   564
		DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************SHOW"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   565
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   566
		bufferSent = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   567
		iFrameDroppedCount = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   568
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   569
		SendOutputBuffer(aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   570
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   571
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   572
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   573
		DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************DROP"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   574
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   575
		iFrameDroppedCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   576
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   577
		// dropped a frame, so send an event if the dropped frame extension is enabled
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   578
		if(iEnableDropFrameEvent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   579
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   580
            //TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   581
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   582
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   583
		// if EOS was on the buffer, send an empty buffer with EOS and send the EOS event
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   584
		// if not, discard the buffer contents and post the buffer for another copy
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   585
		if(flags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   586
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   587
			DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************SEND EMPTY EOS BUFFER"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   588
			aBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   589
			aBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   590
			aBuffer->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   591
			SendOutputBuffer(aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   592
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   593
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   594
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   595
			TOmxILUtil::ClearBufferContents(aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   596
			aBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   597
			if (iBufferCopierStateMonitor->BufferCopier())
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   598
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   599
			    iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(aBuffer, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   600
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   601
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   602
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   603
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   604
	return bufferSent;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   605
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   606
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   607
void COmxILVideoSchedulerPF::SendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   608
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   609
	__ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   610
	__ASSERT_DEBUG(iTimeStamp < aBuffer->nTimeStamp || aBuffer->nFlags & OMX_BUFFERFLAG_EOS, Panic(EPanicTimestampEmissionUnordered));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   611
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   612
	if(iOutputBufferSentCount >= KMaxGraphicSinkBufferCount)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   613
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   614
		DEBUG_PRINTF(_L8("VS2::SendOutputBuffer : *****************STORING SINK PENDING BUFFER"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   615
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   616
		// sink is bottleneck, keep the most recent pending frame but return the rest so decoder keeps running
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   617
		// when sink returns a buffer send the most recent frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   618
		if(iSinkPendingBuffer && iBufferCopierStateMonitor->BufferCopier())
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   619
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   620
			if (iSinkPendingBuffer->nFlags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   621
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   622
			    //if (bizarrely) pending buffer has EOS flag and another buffer replaces it.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   623
			    DoSendOutputBuffer(iSinkPendingBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   624
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   625
			else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   626
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   627
			    iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(iSinkPendingBuffer, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   628
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   629
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   630
			DEBUG_PRINTF(_L8("VS2::SendOutputBuffer : *****************DROPPED EXISTING SINK PENDING BUFFER"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   631
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   632
			// dropped a frame, so send an event if the dropped frame extension is enabled
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   633
			if(iEnableDropFrameEvent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   634
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   635
                //TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   636
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   637
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   638
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   639
		iSinkPendingBuffer = aBuffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   640
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   641
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   642
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   643
		DoSendOutputBuffer(aBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   644
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   645
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   646
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   647
/** Called when the buffer copier has transferred the data from an input buffer to an output buffer. */
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   648
void COmxILVideoSchedulerPF::MbcBufferCopied(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   649
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   650
	iMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   651
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   652
	// send input buffer back
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   653
	aInBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   654
	aInBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   655
	aInBuffer->nFlags = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   656
	aInBuffer->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   657
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   658
	// Deal with any buffer marks. Currently the component framework makes an attempt to deal with
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   659
	// them, but it cannot associate the input buffer mark with the corresponding output buffer so
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   660
	// we may need to do some tweaking here.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   661
	if (aInBuffer->hMarkTargetComponent)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   662
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   663
		if (aInBuffer->hMarkTargetComponent == iHandle)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   664
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   665
			// There was a buffer mark on the input buffer intended for us. That means there is no
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   666
			// need to send it out on the output buffer. Also, it is OK to let the component framework
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   667
			// deal with it in this situation.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   668
			aOutBuffer->hMarkTargetComponent = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   669
			aOutBuffer->pMarkData = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   670
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   671
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   672
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   673
			// There was a buffer mark on the input buffer but it is not intended for us. If
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   674
			// we let the component framework deal with it then we will get multiple marks sent
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   675
			// out because we have copied it to the output buffer, and the framework will also
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   676
			// store it to send out later. Clear it here so the framework does not see it.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   677
			aInBuffer->hMarkTargetComponent = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   678
			aInBuffer->pMarkData = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   679
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   680
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   681
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   682
	OMX_ERRORTYPE error;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   683
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   684
	iCallbacks.BufferDoneNotification(aInBuffer, 0, OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   685
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   686
	if(aOutBuffer->nFilledLen > 0 || (aOutBuffer->nFlags & OMX_BUFFERFLAG_EOS))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   687
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   688
		iWaitingBuffers.Append(aOutBuffer);  // note append cannot fail, allocated enough slots
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   689
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   690
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   691
	if(aOutBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   692
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   693
		if(OMX_TIME_ClockStateWaitingForStartTime == iClockState.eState)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   694
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   695
			error = iComponent.SetVideoStartTime(aOutBuffer->nTimeStamp);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   696
			if (error != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   697
			    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   698
			    HandleIfError(error);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   699
			    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   700
			iStartTimePending = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   701
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   702
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   703
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   704
			// delay sending until clock transitions to WaitingForStartTime
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   705
			iStartTime = aOutBuffer->nTimeStamp;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   706
			iStartTimePending = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   707
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   708
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   709
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   710
#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   711
	DEBUG_PRINTF(_L8("VS2::MbcBufferCopied **********************************"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   712
	TTime t;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   713
	t.HomeTime();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   714
	DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : t.HomeTime() = %ld"), t.Int64());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   715
	DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : aOutBuffer = 0x%X"), aOutBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   716
	DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : aOutBuffer->nTimeStamp = %ld"), aOutBuffer->nTimeStamp);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   717
#endif	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   718
	iMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   719
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   720
	if (aOutBuffer->nFilledLen == 0 && !(aOutBuffer->nFlags & OMX_BUFFERFLAG_EOS))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   721
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   722
		// A likely cause of receiving an empty buffer is if the decoder implements a flush as
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   723
		// returning buffers to supplier or always sending buffers to peer, rather than emptied
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   724
		// and queued on the output port. In this case we return the buffer immediately without
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   725
		// making a media time request. Probably the timestamp is invalid or the clock is not in
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   726
		// the running state, in either case we could deadlock by queueing the empty buffers after
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   727
		// a flush and preventing new data from being delivered. However these buffers were not
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   728
		// returned in BufferIndication() in case there were any flags that need processing.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   729
		iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(aOutBuffer, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   730
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   731
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   732
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   733
		if (!iIsClockStopped)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   734
		    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   735
		    error = iComponent.MediaTimeRequest(aOutBuffer, aOutBuffer->nTimeStamp, iRenderTime);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   736
		    if (error != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   737
		        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   738
		        HandleIfError(error);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   739
		        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   740
		    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   741
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   742
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   743
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   744
/** Called when a buffer is flushed from the buffer copier. */
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   745
void COmxILVideoSchedulerPF::MbcBufferFlushed(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   746
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   747
	TInt portIndex = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   748
	aBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   749
	aBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   750
	aBuffer->nFlags = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   751
	aBuffer->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   752
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   753
	if (aDirection == OMX_DirOutput)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   754
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   755
		++iOutputBufferSentCount;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   756
		portIndex = 1;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   757
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   758
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   759
	iCallbacks.BufferDoneNotification(aBuffer, portIndex, aDirection);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   760
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   761
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   762
void COmxILVideoSchedulerPF::DoSendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   763
    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   764
    OMX_ERRORTYPE error;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   765
    // A zero length buffer means this buffer is just being sent because it
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   766
    // has the EOS flag.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   767
    if (aBuffer->nFilledLen > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   768
        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   769
        aBuffer->nTickCount = 0xC0C0C0C0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   770
        iTimeStamp = aBuffer->nTimeStamp;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   771
        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   772
    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   773
    error = iCallbacks.BufferDoneNotification(aBuffer, 1, OMX_DirOutput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   774
    if (error != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   775
        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   776
        HandleIfError(error);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   777
        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   778
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   779
    iOutputBufferSentCount++;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   780
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   781
    OMX_U32 flags = aBuffer->nFlags;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   782
    if(flags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   783
        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   784
        error = iCallbacks.EventNotification(OMX_EventBufferFlag, 1, flags, NULL);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   785
        if (error != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   786
            {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   787
            HandleIfError(error);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   788
            }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   789
        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   790
    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   791
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   792
void COmxILVideoSchedulerPF::HandleIfError(OMX_ERRORTYPE aOmxError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   793
    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   794
    if (aOmxError != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   795
        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   796
        iInvalid = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   797
        iCallbacks.ErrorEventNotification(aOmxError);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   798
        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   799
    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   800
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   801
OMX_ERRORTYPE COmxILVideoSchedulerPF::SymbianErrorToOmx(TInt aError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   802
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   803
	switch(aError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   804
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   805
	case KErrNone:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   806
		return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   807
	case KErrNoMemory:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   808
		return OMX_ErrorInsufficientResources;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   809
	default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   810
		return OMX_ErrorUndefined;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   811
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   812
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   813
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   814
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   815
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   816
void COmxILVideoSchedulerPF::Panic(TVideoSchedulerPanic aPanicCode) const
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   817
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   818
	// const allows const methods to panic using this method
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   819
	// however we wish to release the mutex to avoid blocking other threads
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   820
	RMutex& mutex = const_cast<RMutex&>(iMutex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   821
	if(mutex.IsHeld())
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   822
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   823
		mutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   824
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   825
	User::Panic(KVideoSchedulerPanicCategory, aPanicCode);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   826
	}