omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.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 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
#include "comxil3gpmuxeraudioinputport.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    25
#include "comxil3gpmuxervideoinputport.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    26
#include "c3gpmuxer.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    27
#include "log.h"
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    28
#include <openmax/il/common/omxilcallbacknotificationif.h>
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    29
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    30
_LIT(K3GPMuxerPanic, "C3GPMuxer");
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    31
const TUint KAudioTimeScale = 44100;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    32
static const TUint KThreadStackSize = 8192;	// 8KB
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    33
const TInt KMaxBufferSize = 62400 * 2;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    34
const TInt KMicroSecondsPerSecond = 1000000;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    35
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    36
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    37
C3GPMuxer* C3GPMuxer::NewL(MOmxILCallbackNotificationIf& aCallbacks)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    38
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    39
	DEBUG_PRINTF(_L8("C3GPMuxer::NewL"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    40
	C3GPMuxer* self = new (ELeave) C3GPMuxer(aCallbacks);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    41
	CleanupStack::PushL(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    42
	self->ConstructL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    43
	CleanupStack::Pop(self);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    44
	return self;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    45
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    46
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    47
C3GPMuxer::C3GPMuxer(MOmxILCallbackNotificationIf& aCallbacks): 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    48
 CActive(EPriorityStandard), 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    49
 iCallbacks(aCallbacks)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    50
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    51
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    52
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    53
void C3GPMuxer::ConstructL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    54
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    55
	User::LeaveIfError(iVideoQueue.CreateLocal(KMaxVideoBuffers));	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    56
	iPartialFrame.CreateL(KMaxBufferSize);	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    57
	User::LeaveIfError(iAudioQueue.CreateLocal(KMaxAudioBuffers));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    58
	User::LeaveIfError(iRemoveQueue.CreateLocal(Max(KMaxVideoBuffers, KMaxAudioBuffers)));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    59
	User::LeaveIfError(iQueMutex.CreateLocal());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    60
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    61
	iComposer = C3GPCompose::NewL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    62
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    63
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    64
void C3GPMuxer::StartL(TBool aAudioPortEnabled, TBool aVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    65
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    66
	DEBUG_PRINTF(_L8("C3GPMuxer::StartL"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    67
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    68
	iPaused = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    69
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    70
	if (!iThreadRunning)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    71
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    72
		iAudioPortEnabled = aAudioPortEnabled;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    73
		iVideoPortEnabled = aVideoPortEnabled;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    74
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    75
		TBuf<40> threadName;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    76
		threadName.Format(_L("C3GPMuxerThread@%08X"), this);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    77
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    78
		User::LeaveIfError(iThread.Create(threadName, ThreadEntryPoint, KThreadStackSize, NULL, this));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    79
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    80
		// start the thread and wait for it to start the active scheduler
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    81
		TRequestStatus status;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    82
		iThread.Rendezvous(status);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    83
		iThread.Resume();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    84
		User::WaitForRequest(status);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    85
		User::LeaveIfError(status.Int());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    86
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    87
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    88
	    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    89
	    // self complete
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    90
        iQueMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    91
        if (!iRequestOutstanding)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    92
            {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    93
            TRequestStatus* statusPtr = &iStatus;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    94
            iThread.RequestComplete(statusPtr, KErrNone);        
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    95
            }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    96
        iQueMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    97
	    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    98
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
    99
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   100
TInt C3GPMuxer::ThreadEntryPoint(TAny* aPtr)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   101
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   102
	CTrapCleanup* cleanup = CTrapCleanup::New();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   103
	if(!cleanup)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   104
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   105
		return KErrNoMemory;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   106
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   107
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   108
	// Call this objects clock initialisation routine
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   109
	TRAPD(err, static_cast<C3GPMuxer*>(aPtr)->RunThreadL());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   110
	delete cleanup;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   111
	return err;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   112
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   113
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   114
void C3GPMuxer::RunThreadL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   115
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   116
	DEBUG_PRINTF(_L8("C3GPMuxer::RunThreadL"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   117
	CActiveScheduler* sched = new (ELeave) CActiveScheduler;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   118
	CleanupStack::PushL(sched);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   119
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   120
	CActiveScheduler::Install(sched);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   121
	CActiveScheduler::Add(this);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   122
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   123
	if (iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   124
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   125
		iAudioQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   126
		SetActive();												
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   127
        iRequestOutstanding = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   128
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   129
	else if (iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   130
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   131
		iVideoQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   132
		SetActive();									
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   133
        iRequestOutstanding = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   134
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   135
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   136
	iEndWaitAO = CEndWaitAO::NewL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   137
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   138
	iThreadRunning = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   139
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   140
	iThread.Rendezvous(KErrNone);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   141
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   142
	CActiveScheduler::Start();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   143
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   144
	HandleError(iComposer->Complete());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   145
	iComposerOpened = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   146
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   147
	CleanupStack::PopAndDestroy(sched);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   148
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   149
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   150
C3GPMuxer::~C3GPMuxer()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   151
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   152
	DEBUG_PRINTF(_L8("C3GPMuxer::~C3GPMuxer"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   153
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   154
	if(iThreadRunning)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   155
		{		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   156
		iThreadRunning = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   157
		TRequestStatus logonStatus;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   158
		iThread.Logon(logonStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   159
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   160
		iEndWaitAO->Call();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   161
		User::WaitForRequest(logonStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   162
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   163
		delete iEndWaitAO;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   164
		iEndWaitAO = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   165
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   166
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   167
	iVideoQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   168
	iPartialFrame.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   169
	iAudioQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   170
	iRemoveQueue.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   171
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   172
	delete iComposer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   173
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   174
	iThread.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   175
	iQueMutex.Close();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   176
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   177
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   178
void C3GPMuxer::ProcessThisBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, TUint32 aPortIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   179
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   180
	DEBUG_PRINTF3(_L8("C3GPMuxer::ProcessThisBufferL : aBufferHeader[%X]; aPortIndex[%u]"), aBufferHeader, aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   181
	__ASSERT_ALWAYS(aBufferHeader->nOffset + aBufferHeader->nFilledLen <= aBufferHeader->nAllocLen, User::Invariant());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   182
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   183
	if (aPortIndex == COmxIL3GPMuxer::EPortIndexAudioInput && iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   184
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   185
		User::LeaveIfError(iAudioQueue.Send(aBufferHeader));		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   186
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   187
	else if (aPortIndex == COmxIL3GPMuxer::EPortIndexVideoInput && iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   188
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   189
		User::LeaveIfError(iVideoQueue.Send(aBufferHeader));		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   190
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   191
	// FIXME buffer arrived on disabled port?? if we don't consider this an error why bother checking?
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   192
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   193
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   194
void C3GPMuxer::FlushBuffers(TUint32 aPortIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   195
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   196
	DEBUG_PRINTF2(_L8("C3GPMuxer::FlushBuffers : aPortIndex[%u]"), aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   197
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   198
	__ASSERT_DEBUG(aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPMuxer::EPortIndexMax, User::Invariant());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   199
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   200
	if (aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPMuxer::EPortIndexMax)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   201
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   202
		iQueMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   203
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   204
		if (aPortIndex == OMX_ALL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   205
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   206
			for (TInt portIndex = 0; portIndex < COmxIL3GPMuxer::EPortIndexMax; ++portIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   207
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   208
				DoFlushBuffers(portIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   209
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   210
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   211
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   212
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   213
			DoFlushBuffers(aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   214
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   215
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   216
		iQueMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   217
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   218
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   219
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   220
void C3GPMuxer::DoFlushBuffers(TUint32 aPortIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   221
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   222
	DEBUG_PRINTF2(_L8("C3GPMuxer::DoFlushBuffers : aPortIndex[%u]"), aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   223
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   224
	OMX_BUFFERHEADERTYPE* buffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   225
	switch(aPortIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   226
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   227
		case COmxIL3GPMuxer::EPortIndexAudioInput:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   228
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   229
			if (iAudioBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   230
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   231
				ReturnBuffer(iAudioBuffer, aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   232
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   233
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   234
			while(iAudioQueue.Receive(buffer) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   235
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   236
				ReturnBuffer(buffer, aPortIndex); 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   237
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   238
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   239
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   240
		case COmxIL3GPMuxer::EPortIndexVideoInput:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   241
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   242
			if (iCurrentVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   243
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   244
				ReturnBuffer(iCurrentVideoBuffer, aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   245
				iCurrentVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   246
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   247
			if (iNextVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   248
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   249
				ReturnBuffer(iNextVideoBuffer, aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   250
				iNextVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   251
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   252
			while(iVideoQueue.Receive(buffer) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   253
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   254
				ReturnBuffer(buffer, aPortIndex); 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   255
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   256
			break;			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   257
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   258
		default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   259
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   260
			User::Panic(K3GPMuxerPanic, KErrArgument);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   261
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   262
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   263
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   264
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   265
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   266
TBool C3GPMuxer::RemoveBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   267
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   268
	DEBUG_PRINTF2(_L8("C3GPMuxer::RemoveBuffer : aBufferHeader[%X]"), aBufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   269
	iQueMutex.Wait();	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   270
	TBool found = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   271
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   272
	// check the current audio/video buffers first
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   273
	if(aBufferHeader == iAudioBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   274
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   275
		iAudioBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   276
		found = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   277
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   278
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   279
	if(!found && aBufferHeader == iCurrentVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   280
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   281
		iCurrentVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   282
		found = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   283
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   284
	if(!found && aBufferHeader == iNextVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   285
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   286
		iNextVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   287
		found = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   288
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   289
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   290
	if (!found)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   291
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   292
		found = RemoveFromQueue(iAudioQueue, aBufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   293
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   294
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   295
	if (!found)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   296
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   297
		found = RemoveFromQueue(iVideoQueue, aBufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   298
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   299
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   300
	iQueMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   301
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   302
	return found;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   303
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   304
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   305
void C3GPMuxer::SetFilename(const HBufC* aFilename)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   306
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   307
	DEBUG_PRINTF(_L8("C3GPMuxer::SetFilename"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   308
 	iFilename = aFilename;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   309
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   310
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   311
void C3GPMuxer::SetAudioVideoProperties(OMX_U32& aFrameWidth, OMX_U32& aFrameHeight, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   312
									OMX_U32& aFramerate, OMX_U32& aBitRate, OMX_U32& /*aAudioFramerate*/)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   313
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   314
	DEBUG_PRINTF(_L8("C3GPMuxer::SetAudioVideoProperties"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   315
	iVideoSize.iWidth = static_cast<TInt>(aFrameWidth);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   316
	iVideoSize.iHeight = static_cast<TInt>(aFrameHeight);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   317
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   318
	iBitRate = aBitRate;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   319
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   320
	CalculateVideoTimeScale(aFramerate);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   321
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   322
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   323
/**
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   324
Calculate video timescale and frame duration.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   325
The video timescale is the nearest whole number multiple of the frame rate.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   326
Where the frame rate includes more than 2 decimal places, it is rounded down
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   327
to 2 decimal places. This means the calculation is not wholly accurate in those
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   328
circumstances, but hopefully it is close enough.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   329
*/
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   330
void C3GPMuxer::CalculateVideoTimeScale(OMX_U32& aFramerate)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   331
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   332
	// Get rid of floating point and round to 2 decimal places
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   333
	TInt fps = ((static_cast<TReal>(aFramerate) / (1<<16)) * 100.0) + 0.5;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   334
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   335
	iVideoTimeScale = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   336
	iDefaultVideoFrameDuration = 1;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   337
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   338
	// Find nearest whole number multiple
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   339
	for (TInt i = 1; i <= 100; ++i)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   340
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   341
		if ((fps * i) % 100 == 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   342
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   343
			iVideoTimeScale = fps * i / 100;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   344
			iDefaultVideoFrameDuration = i;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   345
			break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   346
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   347
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   348
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   349
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   350
void C3GPMuxer::RunL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   351
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   352
	DEBUG_PRINTF(_L8("C3GPMuxer::RunL"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   353
	iQueMutex.Wait();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   354
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   355
	iRequestOutstanding = EFalse;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   356
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   357
	if (!iPaused)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   358
	    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   359
	    if (iAudioPortEnabled && iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   360
	        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   361
	        RunAudioVideoL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   362
	        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   363
	    else if (iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   364
	        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   365
	        RunAudioL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   366
	        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   367
	    else if (iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   368
	        {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   369
	        RunVideoL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   370
	        }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   371
	    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   372
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   373
	    {
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   374
	    iStatus = KRequestPending;	    
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   375
	    }
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   376
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   377
    SetActive();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   378
	iQueMutex.Signal();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   379
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   380
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   381
void C3GPMuxer::RunAudioVideoL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   382
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   383
	// When opening the composer, both audio and video properties must be passed in
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   384
	if(!iAudioBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   385
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   386
		// ignore error, if KErrUnderflow then we go back to waiting on iAudioQueue
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   387
		iAudioQueue.Receive(iAudioBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   388
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   389
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   390
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   391
		TInt err = KErrNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   392
		if (!iCurrentVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   393
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   394
			err = iVideoQueue.Receive(iCurrentVideoBuffer);					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   395
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   396
			// if KErrUnderflow then we go back to waiting on iVideoQueue
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   397
			if (err == KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   398
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   399
				// both audio and video buffers has been received
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   400
				if (!iComposerOpened)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   401
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   402
					OpenComposerL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   403
					iComposerOpened = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   404
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   405
					iVideoDuration = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   406
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   407
					ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   408
					iAudioBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   409
					// [SL] FIXME may also need to return iVideoBuffer in nFilledLen = 0
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   410
					// (VideoSpecificInfo was entire buffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   411
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   412
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   413
				// We need the timestamp of the next buffer to work out the frame duration of the current video buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   414
				// so wait to receive the next video buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   415
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   416
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   417
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   418
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   419
			if(!iNextVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   420
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   421
				err = iVideoQueue.Receive(iNextVideoBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   422
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   423
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   424
			// if KErrUnderflow then we go back to waiting on iVideoQueue
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   425
			if(err == KErrNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   426
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   427
				// next video buffer received
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   428
						
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   429
				// audio/video frames are added into the composer in the order of timestap
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   430
				if (iAudioBuffer->nTimeStamp < iCurrentVideoBuffer->nTimeStamp)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   431
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   432
					WriteAudioBuffer();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   433
					iAudioBuffer = NULL;					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   434
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   435
				else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   436
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   437
					WriteVideoBufferL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   438
					iCurrentVideoBuffer = iNextVideoBuffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   439
					iNextVideoBuffer = NULL;									
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   440
							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   441
					if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   442
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   443
						// this is the last video buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   444
						WriteVideoBufferL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   445
						iCurrentVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   446
						}			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   447
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   448
				}			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   449
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   450
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   451
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   452
	if(!iAudioBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   453
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   454
		iAudioQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   455
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   456
	else if(!iNextVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   457
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   458
		iVideoQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   459
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   460
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   461
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   462
		// already have both buffers available
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   463
		TRequestStatus* statusPtr = &iStatus;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   464
		User::RequestComplete(statusPtr, KErrNone);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   465
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   466
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   467
	iRequestOutstanding = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   468
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   469
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   470
void C3GPMuxer::RunAudioL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   471
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   472
	if(iAudioBuffer == NULL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   473
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   474
		TInt err = iAudioQueue.Receive(iAudioBuffer);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   475
		// KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   476
		if(err != KErrNone && err != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   477
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   478
			HandleError(err);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   479
			return;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   480
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   481
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   482
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   483
	if(iAudioBuffer != NULL)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   484
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   485
		if (!iComposerOpened)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   486
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   487
			OpenComposerL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   488
			iComposerOpened = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   489
			//return the buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   490
			ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   491
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   492
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   493
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   494
			//write the non header audio buffer.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   495
			WriteAudioBuffer();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   496
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   497
		iAudioBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   498
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   499
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   500
	iAudioQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   501
    iRequestOutstanding = ETrue;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   502
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   503
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   504
void C3GPMuxer::RunVideoL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   505
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   506
	if (!iCurrentVideoBuffer)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   507
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   508
		// FIXME KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   509
		HandleError(iVideoQueue.Receive(iCurrentVideoBuffer));				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   510
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   511
		if (!iComposerOpened)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   512
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   513
			OpenComposerL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   514
			iComposerOpened = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   515
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   516
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   517
		iVideoDuration = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   518
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   519
		// We need the timestamp of the next buffer to work out the frame duration of the current buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   520
		// so wait to receive the next buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   521
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   522
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   523
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   524
		// next buffer received
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   525
		// FIXME KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   526
		HandleError(iVideoQueue.Receive(iNextVideoBuffer));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   527
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   528
		WriteVideoBufferL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   529
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   530
		iCurrentVideoBuffer = iNextVideoBuffer;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   531
		iNextVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   532
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   533
		if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   534
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   535
			// this is the last buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   536
			WriteVideoBufferL();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   537
			iCurrentVideoBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   538
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   539
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   540
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   541
	iVideoQueue.NotifyDataAvailable(iStatus);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   542
	iRequestOutstanding = ETrue;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   543
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   544
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   545
void C3GPMuxer::OpenComposerL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   546
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   547
	DEBUG_PRINTF(_L8("C3GPMuxer::OpenComposer"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   548
	T3GPAudioPropertiesBase* audioProperties = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   549
	TPtr8 audioPtr(NULL,0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   550
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   551
	if (iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   552
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   553
 		// The first buffer is the decoder specific info.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   554
 		audioPtr.Set(iAudioBuffer->pBuffer + iAudioBuffer->nOffset, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   555
 					iAudioBuffer->nFilledLen, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   556
 					iAudioBuffer->nAllocLen - iAudioBuffer->nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   557
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   558
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   559
	//The following obj need to be declared in the scope of this function and 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   560
	//also after audioPtr is set.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   561
	//Mpeg4Audio is hardcoded for now.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   562
	T3GPAudioPropertiesMpeg4Audio audioPropertiesObj(KAudioTimeScale, audioPtr);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   563
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   564
	// If audio port is disabled, audioProperties needs to be NULL
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   565
	if (iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   566
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   567
		audioProperties=&audioPropertiesObj;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   568
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   569
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   570
	T3GPVideoPropertiesBase* videoProperties = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   571
	TPtr8 videoPtr(NULL,0);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   572
	TBool foundVideoFrame = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   573
	if (iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   574
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   575
		// get decoder specific info length
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   576
		TInt offset;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   577
		const TUint8* buf = reinterpret_cast<const TUint8*>(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   578
		TUint32 stitch = 0xFFFFFFFF;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   579
		for(offset = 0; offset < iCurrentVideoBuffer->nFilledLen; offset++)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   580
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   581
			stitch <<= 8;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   582
			stitch |= buf[offset];
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   583
			if(stitch == 0x000001B6)	// start of a frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   584
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   585
				foundVideoFrame = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   586
				break;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   587
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   588
			}		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   589
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   590
		if (foundVideoFrame)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   591
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   592
			offset -= 3;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   593
			videoPtr.Set(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   594
			             offset, iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   595
			iCurrentVideoBuffer->nOffset += offset;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   596
			iCurrentVideoBuffer->nFilledLen -= offset;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   597
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   598
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   599
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   600
			// We assume that the whole frame is the decoder specific info
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   601
			videoPtr.Set(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset,
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   602
			             iCurrentVideoBuffer->nFilledLen, iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   603
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   604
			// Whole buffer has been used. Set remaining length to zero so that when the
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   605
			// next buffer arrives we don't try to write out the decoder specific info
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   606
			// as a frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   607
			iCurrentVideoBuffer->nOffset += iCurrentVideoBuffer->nFilledLen;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   608
			iCurrentVideoBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   609
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   610
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   611
		// FIXME unhandled allocation error - store this on the stack?
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   612
		videoProperties = new T3GPVideoPropertiesMpeg4Video(iVideoTimeScale, iVideoSize, iBitRate, iBitRate, videoPtr);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   613
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   614
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   615
	HandleError(iComposer->Open(E3GP3GP, videoProperties, audioProperties, *iFilename, E3GPLongClip));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   616
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   617
	delete videoProperties;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   618
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   619
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   620
void C3GPMuxer::WriteVideoBufferL()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   621
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   622
	DEBUG_PRINTF(_L8("C3GPMuxer::WriteVideoBuffer"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   623
	TUint8* currentBuffer = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   624
	TInt currentBufferLength = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   625
	TInt currentBufferMaxLength = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   626
	TBool multipleFrameInBuffer = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   627
			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   628
	if (iPartialFrame.Length() > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   629
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   630
		// merge the partial frame from the previous buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   631
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   632
		if (iPartialFrame.Length()+iCurrentVideoBuffer->nFilledLen > KMaxBufferSize)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   633
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   634
			iPartialFrame.ReAllocL(iPartialFrame.Length()+iCurrentVideoBuffer->nFilledLen);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   635
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   636
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   637
		iPartialFrame.Append(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset, iCurrentVideoBuffer->nFilledLen);			
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   638
				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   639
		currentBuffer = const_cast<TUint8*>(iPartialFrame.Ptr());
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   640
		currentBufferLength = iPartialFrame.Length();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   641
		currentBufferMaxLength = iPartialFrame.MaxLength();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   642
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   643
		multipleFrameInBuffer = ETrue;		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   644
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   645
	else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   646
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   647
		currentBuffer = iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   648
		currentBufferLength = iCurrentVideoBuffer->nFilledLen;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   649
		currentBufferMaxLength = iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   650
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   651
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   652
	// Write video frames from buffer.
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   653
	// Check for non-zero buffer length in case we have been sent an empty buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   654
	if (currentBufferLength > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   655
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   656
		if(!multipleFrameInBuffer && (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   657
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   658
			// buffer contains one full I frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   659
			TInt nextFrameDuration = CalculateNextFrameDuration();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   660
			TPtr8 videoPtr(currentBuffer, currentBufferLength, currentBufferMaxLength);									
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   661
			HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, ETrue));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   662
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   663
		else if (!multipleFrameInBuffer && (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   664
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   665
			// buffer contains one full frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   666
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   667
			// Evaluate whether it is an I frame 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   668
			TInt offset = 0;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   669
			TUint32 stitch = 0xFFFFFFFF;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   670
			TBool isIframe = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   671
					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   672
			for(offset = 0; offset < currentBufferLength; offset++)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   673
				{					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   674
				stitch <<= 8;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   675
				stitch |= currentBuffer[offset];
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   676
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   677
				if(stitch == 0x000001B6)		// start of a frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   678
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   679
					TUint8 iframebits = currentBuffer[offset+1] >> 6;	// get the next 2 bits					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   680
					if (iframebits == 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   681
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   682
						isIframe = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   683
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   684
					else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   685
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   686
						isIframe = EFalse;							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   687
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   688
								
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   689
					break;		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   690
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   691
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   692
		 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   693
			TInt nextFrameDuration = CalculateNextFrameDuration();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   694
			TPtr8 videoPtr(currentBuffer, currentBufferLength, currentBufferMaxLength);								
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   695
			HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   696
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   697
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   698
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   699
			// buffer either contains multiple frames or part of a single frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   700
			// so need to parse the buffer to retrieve the frames
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   701
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   702
			TInt offset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   703
			TUint32 stitch = 0xFFFFFFFF;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   704
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   705
			TBool foundNextFrame = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   706
			TInt frameLength = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   707
			TInt frameOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   708
			TBool isIframe = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   709
			TBool frameWritten = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   710
					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   711
			// retieve and write video frames
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   712
			for(offset = 0; offset < currentBufferLength; offset++)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   713
				{					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   714
				stitch <<= 8;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   715
				stitch |= currentBuffer[offset];
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   716
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   717
				frameLength++;	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   718
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   719
				if(!foundNextFrame && stitch == 0x000001B6)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   720
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   721
					foundNextFrame = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   722
							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   723
					// Evaluate whether it is an I frame 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   724
					if (offset+1 >= currentBufferLength)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   725
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   726
						break; // reached the end of the buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   727
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   728
								
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   729
					TUint8 iframebits = currentBuffer[offset+1] >> 6;	// get the next 2 bits					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   730
					if (iframebits == 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   731
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   732
						isIframe = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   733
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   734
					else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   735
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   736
						isIframe = EFalse;							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   737
						}	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   738
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   739
				else if (foundNextFrame && (stitch == 0x000001B0 || stitch == 0x00000120))
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   740
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   741
					// start of next frame (which includes VOS and/or VOL header)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   742
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   743
					// write the current frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   744
					TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   745
					TPtr8 videoPtr(currentBuffer + frameOffset, frameLength - 4, currentBufferMaxLength - frameOffset);										
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   746
					HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   747
					frameWritten = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   748
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   749
					frameOffset = offset - 3; // to include the VOS/VOL start code in the next frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   750
					frameLength = 4;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   751
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   752
					foundNextFrame = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   753
					isIframe = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   754
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   755
				else if (foundNextFrame && stitch == 0x000001B6)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   756
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   757
					// start of next frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   758
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   759
					// write the current frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   760
					TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   761
					TPtr8 videoPtr(currentBuffer + frameOffset,	frameLength - 4, currentBufferMaxLength - frameOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   762
					HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   763
					frameWritten = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   764
		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   765
					frameOffset = offset - 3; // to include the VOP start code in the next frame		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   766
					frameLength = 4;						
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   767
							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   768
					foundNextFrame = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   769
							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   770
					// Evaluate whether it is an I frame 	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   771
					if (offset+1 >= currentBufferLength)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   772
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   773
						break; // reached the end of the buffer
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   774
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   775
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   776
					TUint8 iframebits = currentBuffer[offset+1] >> 6;  // get the next 2 bits						
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   777
					if (iframebits == 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   778
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   779
						isIframe = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   780
						}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   781
					else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   782
						{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   783
						isIframe = EFalse;							
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   784
						}	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   785
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   786
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   787
					
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   788
			if (frameLength > 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   789
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   790
				if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   791
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   792
					// this is the last buffer, so we can assume that the rest of the buffer contains one full frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   793
					TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   794
					TPtr8 videoPtr(currentBuffer + frameOffset,	frameLength, currentBufferMaxLength - frameOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   795
					HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   796
					frameWritten = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   797
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   798
				else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   799
					{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   800
					// the buffer may contain part of a frame
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   801
					// save it for use later
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   802
					iPartialFrame.Copy(currentBuffer + frameOffset, frameLength);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   803
					}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   804
				}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   805
			else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   806
				{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   807
				User::Panic(K3GPMuxerPanic, KErrGeneral);  // frameLength should never be 0
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   808
				}	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   809
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   810
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   811
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   812
	ReturnBuffer(iCurrentVideoBuffer, COmxIL3GPMuxer::EPortIndexVideoInput);										
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   813
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   814
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   815
TInt C3GPMuxer::CalculateNextFrameDuration()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   816
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   817
	TInt64 durationSinceStart = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   818
	TInt nextFrameDuration = durationSinceStart - iVideoDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   819
	if (nextFrameDuration < iDefaultVideoFrameDuration)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   820
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   821
		nextFrameDuration = iDefaultVideoFrameDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   822
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   823
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   824
	iVideoDuration = durationSinceStart;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   825
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   826
	return nextFrameDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   827
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   828
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   829
TInt C3GPMuxer::CalculateNextFrameDurationPartial(TBool aFrameWritten)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   830
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   831
	if (!aFrameWritten)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   832
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   833
		return CalculateNextFrameDuration();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   834
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   835
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   836
	iVideoDuration += iDefaultVideoFrameDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   837
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   838
	return iDefaultVideoFrameDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   839
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   840
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   841
void C3GPMuxer::WriteAudioBuffer()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   842
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   843
	DEBUG_PRINTF(_L8("C3GPMuxer::WriteAudioBuffer"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   844
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   845
	if (iAudioBuffer->nFilledLen != 0)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   846
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   847
		TPtr8 audioPtr(iAudioBuffer->pBuffer + iAudioBuffer->nOffset, 
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   848
								iAudioBuffer->nFilledLen, iAudioBuffer->nAllocLen - iAudioBuffer->nOffset);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   849
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   850
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   851
 		//Calculate the audio frame duration in timescale
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   852
		//nTimeStamp is in microseconds
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   853
		TUint durationInTimeSlice=KAudioTimeScale*iAudioBuffer->nTimeStamp/KMicroSecondsPerSecond;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   854
 		TUint duration=durationInTimeSlice-iAudioFrameDuration;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   855
 		iAudioFrameDuration=durationInTimeSlice;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   856
 		HandleError(iComposer->WriteAudioFrames(audioPtr, duration));		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   857
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   858
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   859
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   860
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   861
	ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   862
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   863
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   864
void C3GPMuxer::ReturnBuffer(OMX_BUFFERHEADERTYPE* aBuffer, TUint32 aPortIndex)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   865
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   866
	DEBUG_PRINTF3(_L8("C3GPMuxer::ReturnBuffer : aBuffer[%X]; aPortIndex[%u]"), aBuffer, aPortIndex);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   867
	OMX_U32 flags = aBuffer->nFlags;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   868
	aBuffer->nFilledLen = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   869
	aBuffer->nFlags = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   870
	aBuffer->nOffset = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   871
	aBuffer->nTimeStamp = 0;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   872
	iCallbacks.BufferDoneNotification(aBuffer, aPortIndex, OMX_DirInput);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   873
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   874
	if(flags & OMX_BUFFERFLAG_EOS)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   875
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   876
		iCallbacks.EventNotification(OMX_EventBufferFlag, aPortIndex, flags, NULL);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   877
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   878
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   879
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   880
void C3GPMuxer::DoCancel()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   881
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   882
	DEBUG_PRINTF(_L8("C3GPMuxer::DoCancel"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   883
	if (iAudioPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   884
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   885
		iAudioQueue.CancelDataAvailable();
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   886
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   887
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   888
	if (iVideoPortEnabled)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   889
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   890
		iVideoQueue.CancelDataAvailable();		
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   891
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   892
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   893
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   894
TBool C3GPMuxer::RemoveFromQueue(RMsgQueue<OMX_BUFFERHEADERTYPE*>& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   895
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   896
	DEBUG_PRINTF3(_L8("C3GPMuxer::RemoveFromQueue : aQueue[%X]; aBufferHeader[%X]"), &aQueue, aBufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   897
	TBool removed = EFalse;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   898
	OMX_BUFFERHEADERTYPE* bufferHeader = NULL;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   899
	while(aQueue.Receive(bufferHeader) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   900
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   901
		if(bufferHeader != aBufferHeader)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   902
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   903
			TInt error = iRemoveQueue.Send(bufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   904
			__ASSERT_DEBUG(error == KErrNone, User::Panic(K3GPMuxerPanic, error));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   905
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   906
		else
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   907
			{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   908
			removed = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   909
			}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   910
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   911
	while(iRemoveQueue.Receive(bufferHeader) != KErrUnderflow)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   912
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   913
		TInt error = aQueue.Send(bufferHeader);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   914
		__ASSERT_DEBUG(error == KErrNone, User::Panic(K3GPMuxerPanic, error));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   915
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   916
	return removed;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   917
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   918
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   919
void C3GPMuxer::Pause()
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   920
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   921
	DEBUG_PRINTF(_L8("C3GPMuxer::Pause"));
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   922
	iPaused = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   923
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   924
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   925
void C3GPMuxer::HandleError(TInt aError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   926
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   927
	DEBUG_PRINTF2(_L8("C3GPMuxer::HandleError : aError[%d]"), aError);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   928
	OMX_ERRORTYPE omxError = SymbianErrorToOmx(aError);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   929
	if (omxError != OMX_ErrorNone)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   930
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   931
		iMuxerInvalid = ETrue;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   932
		iCallbacks.ErrorEventNotification(omxError);
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   933
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   934
	}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   935
	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   936
TBool C3GPMuxer::IsMuxerInvalid() const
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   937
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   938
	return iMuxerInvalid;				
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   939
	}	
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   940
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   941
OMX_ERRORTYPE C3GPMuxer::SymbianErrorToOmx(TInt aError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   942
	{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   943
	switch(aError)
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   944
		{
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   945
	case KErrNone:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   946
		return OMX_ErrorNone;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   947
	case KErrNoMemory:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   948
		return OMX_ErrorInsufficientResources;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   949
	case KErrWrite:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   950
		return OMX_ErrorContentPipeOpenFailed;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   951
	default:
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   952
		return OMX_ErrorUndefined;
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   953
		}
5d29cba61097 2010wk38_02
hgs
parents:
diff changeset
   954
	}