mmlibs/mmfw/src/server/BaseClasses/mmfdatapath.cpp
author hgs
Thu, 07 Oct 2010 22:34:12 +0100
changeset 0 b8ed18f6c07b
child 5 b220a9341636
permissions -rw-r--r--
2010wk40
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     1
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     2
// All rights reserved.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     7
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     8
// Initial Contributors:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    10
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    11
// Contributors:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    12
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    13
// Description:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    14
// source\server\mmfdatapath.cpp
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    15
// 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    16
//
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    17
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    18
#include <e32math.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    19
#include <mmf/common/mmffourcc.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    20
#include <mmf/common/mmfpaniccodes.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    21
#include <mmf/server/mmfaudiooutput.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    22
#include <mmf/server/mmfaudioinput.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    23
#include <mmf/server/mmfdatapath.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    24
#include "mmfclientaudiostreamutils.h"
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    25
#include <mmf/common/mmfaudio.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    26
#include <mmf/plugin/mmfcodecimplementationuids.hrh> // KUidMmfCodecAudioSettings
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    27
#include <mmf/server/devsoundstandardcustominterfaces.h>
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    28
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    29
const TUid KUidCodecAudioConfig = {KUidMmfCodecAudioSettings};
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    30
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    31
void Panic(TMMFDataPathPanicCode aPanicCode, TInt aSourceLineNumber)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    32
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    33
	_LIT(KMMFDataPathPanicCategory, "MMFDataPath");
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    34
	User::Panic(KMMFDataPathPanicCategory, STATIC_CAST(TInt,aPanicCode) + aSourceLineNumber);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    35
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    36
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    37
//all functions are exported form the DLL and are virtual to allow plugins to define there own CMMFDataPaths
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    38
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    39
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    40
Allocates and constructs a data path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    41
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    42
Use this function if the codec UID is not already known by CMMFController
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    43
and there is no data path ambiguity - ie only one data path is possible.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    44
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    45
Will create codec via fourCC.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    46
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    47
@param  aEventHandler
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    48
        Installs an event handler to provide message passing between clients and sources/sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    49
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    50
@return Newly constructed data path object.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    51
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    52
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    53
EXPORT_C CMMFDataPath* CMMFDataPath::NewL(MAsyncEventHandler& aEventHandler)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    54
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    55
	CMMFDataPath* self = new(ELeave) CMMFDataPath(TMediaId(), aEventHandler);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    56
	CleanupStack::PushL(self);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    57
	self->ConstructL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    58
	CleanupStack::Pop();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    59
	return self;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    60
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    61
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    62
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    63
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    64
Allocates and constructs a data path according to the specified media ID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    65
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    66
Use this function if the codec UID is not already known by CMMFController
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    67
and there is ambiguity with the data path ie. there is more than one possible data path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    68
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    69
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    70
        Optional media ID parameter when there are multiple media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    71
@param  aEventHandler
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    72
        Installs an event handler to provide message passing between clients and sources/sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    73
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    74
@return A newly constructed data path object.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    75
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    76
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    77
EXPORT_C CMMFDataPath* CMMFDataPath::NewL(TMediaId aMediaId, MAsyncEventHandler& aEventHandler)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    78
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    79
	CMMFDataPath* self = new(ELeave) CMMFDataPath(aMediaId, aEventHandler);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    80
	CleanupStack::PushL(self);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    81
	self->ConstructL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    82
	CleanupStack::Pop();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    83
	return self;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    84
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    85
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    86
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    87
Allocates and constructs a data path according to the specified codec UID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    88
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    89
Use this function if the codec UID is already known by CMMFController
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    90
and there is no data path ambiguity ie. only one data path is possible
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    91
will create codec explicitly using the supplied codec Uid
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    92
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    93
@param  aCodecUid
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    94
        Optional mediaID parameter when there are multiple media types
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    95
@param  aEventHandler
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    96
        Installs an event handler to provide message passing between clients and sources/sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    97
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    98
@return A newly constructed data path object.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
    99
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   100
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   101
EXPORT_C CMMFDataPath* CMMFDataPath::NewL(TUid aCodecUid, MAsyncEventHandler& aEventHandler)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   102
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   103
	CMMFDataPath* self = new(ELeave) CMMFDataPath(TMediaId(), aEventHandler);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   104
	CleanupStack::PushL(self);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   105
	self->ConstructL(aCodecUid);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   106
	CleanupStack::Pop();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   107
	return self;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   108
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   109
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   110
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   111
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   112
Allocates and constructs a data path according to the specified codec UID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   113
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   114
Use this function if the codec UID is already known by CMMFController
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   115
and there is ambiguity ie. more than one possible data path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   116
TMediaId used to select the path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   117
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   118
@param  aCodecUid
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   119
		The codec UID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   120
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   121
        Optional mediaID parameter when there are multiple media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   122
@param  aEventHandler
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   123
        Installs an event handler to provide message passing between clients and sources/sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   124
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   125
@return A newly constructed data path object.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   126
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   127
EXPORT_C CMMFDataPath* CMMFDataPath::NewL(TUid aCodecUid, TMediaId aMediaId, MAsyncEventHandler& aEventHandler)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   128
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   129
	CMMFDataPath* self = new(ELeave) CMMFDataPath(aMediaId, aEventHandler);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   130
	CleanupStack::PushL(self);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   131
	self->ConstructL(aCodecUid);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   132
	CleanupStack::Pop();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   133
	return self;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   134
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   135
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   136
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   137
Standard destructor.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   138
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   139
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   140
EXPORT_C CMMFDataPath::~CMMFDataPath()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   141
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   142
	Cancel();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   143
	delete iCodec;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   144
 	DoCleanupBuffers();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   145
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   146
	//log off the source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   147
	if (iDataSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   148
		iDataSource->SourceThreadLogoff();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   149
	if (iDataSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   150
		iDataSink->SinkThreadLogoff();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   151
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   152
	if (iCompleteCallback)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   153
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   154
		iCompleteCallback->Cancel();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   155
		delete iCompleteCallback;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   156
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   157
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   158
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   159
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   160
Deletes buffers if this datapath's sources and sinks own the buffers returned by PrimeL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   161
Typically if buffers are created asychronously, the datapath doesn't own the buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   162
so leaves cleanup handling to the owner sources/sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   163
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   164
Called when source and sink needs to be de-referenced. Sets iDataPathCreated, iSinkCanReceive, 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   165
iSnkBufRef and iSrcBufRef to EFalse; sets iState to EStopped.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   166
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   167
EXPORT_C void CMMFDataPath::ResetL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   168
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   169
	delete iCodec;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   170
	iCodec = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   171
	DoCleanupBuffers(); // Delete buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   172
	//logoff and dereference source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   173
	if (iDataSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   174
		{ iDataSource->SourceThreadLogoff(); iDataSource = NULL; }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   175
	if (iDataSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   176
		{ iDataSink->SinkThreadLogoff(); iDataSink = NULL; }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   177
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   178
	// Reset states
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   179
	iDataPathCreated = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   180
	iState = EStopped;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   181
	iSrcBufRef = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   182
	iSnkBufRef = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   183
	iPauseCalled = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   184
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   185
	delete iCompleteCallback; iCompleteCallback = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   186
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   187
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   188
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   189
Delete source and/or sink buffers that are owned by DataPath.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   190
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   191
Ownership indicated by iSrcBufRef and iSnkBufRef.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   192
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   193
Ownership is assigned during buffer allocation within the datapath PrimeL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   194
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   195
void CMMFDataPath::DoCleanupBuffers()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   196
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   197
	// delete source and/or sink buffer that is owned by DataPath
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   198
	if ( !iSrcBufRef && iSourceBuffer )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   199
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   200
		delete iSourceBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   201
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   202
	iSourceBuffer = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   203
	if ( !iSnkBufRef && iSinkBuffer )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   204
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   205
		delete iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   206
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   207
	iSinkBuffer = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   208
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   209
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   210
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   211
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   212
Obtain source and/or sink buffer using the synchronous API CreateSourceBufferL() and CreateSinkBufferL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   213
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   214
void CMMFDataPath::ObtainSyncBuffersL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   215
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   216
	//Try to create source and sink buffers. If we can't create them synchronously via
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   217
	//CreateSourceBufferL and CreateSinkBufferL we will need to obtain them by 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   218
	//asynchronous buffer creation when playing starts.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   219
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   220
	if (iBuffersToUse & ENeedSourceBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   221
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   222
		if (!iSourceBuffer) //we may already have a buffer from a previous initialization
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   223
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   224
			TRAPD(err, iSourceBuffer = iDataSource->CreateSourceBufferL(iMediaId,*iSinkBuffer, iSrcBufRef));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   225
			if(err != KErrNone && err != KErrNotSupported)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   226
				{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   227
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   228
	RDebug::Print(_L("DP::ObtainSyncBuffersL - Leaving %d  (this 0x%x)\n"),err, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   229
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   230
				User::Leave(err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   231
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   232
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   233
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   234
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   235
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   236
	if (iBuffersToUse & ENeedSinkBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   237
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   238
		if (!iSinkBuffer) //we may already have a buffer from a previous initialization
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   239
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   240
			TRAPD(err, iSinkBuffer = iDataSink->CreateSinkBufferL(iMediaId, iSnkBufRef));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   241
			if(err != KErrNone && err != KErrNotSupported)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   242
				{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   243
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   244
	RDebug::Print(_L("DP::ObtainSyncBuffersL - Leaving %d  (this 0x%x)\n"),err, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   245
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   246
				User::Leave(err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   247
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   248
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   249
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   250
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   251
	if (iSourceBuffer && !(iBuffersToUse & ENeedSinkBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   252
		{//only need one buffer, use source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   253
		iSinkBuffer =iSourceBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   254
		iSnkBufRef = ETrue; //the sink buffer is not to be deleted
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   255
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   256
	else if (iSinkBuffer && !(iBuffersToUse & ENeedSourceBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   257
		{//only need one buffer, use sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   258
		iSourceBuffer =iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   259
		iSrcBufRef = ETrue; //the sink buffer is not to be deleted
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   260
		}	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   261
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   262
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   263
	RDebug::Print(_L("DP::ObtainSyncBuffersL - DONE  iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   264
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   265
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   266
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   267
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   268
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   269
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   270
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   271
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   272
Constructs a source.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   273
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   274
The default implementation leaves with KErrNotSupported.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   275
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   276
@param  aInitData
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   277
        The initialisation data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   278
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   279
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   280
EXPORT_C void CMMFDataPath::ConstructSourceL( const TDesC8& /*aInitData*/ )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   281
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   282
	User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   283
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   284
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   285
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   286
Constructs a sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   287
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   288
Overridable constuction specific to this datasource.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   289
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   290
The default implementation leaves with KErrNotSupported.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   291
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   292
@param  aInitData
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   293
        The initialisation data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   294
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   295
EXPORT_C void CMMFDataPath::ConstructSinkL( const TDesC8& /*aInitData*/ )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   296
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   297
	User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   298
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   299
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   300
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   301
Takes UID of codec on construction, and if not an NULL codec sets the datapath up for codec instantiation.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   302
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   303
@param  aCodecUid
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   304
        The UID of the codec.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   305
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   306
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   307
EXPORT_C void CMMFDataPath::ConstructL(TUid aCodecUid)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   308
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   309
	iUseSuppliedCodecUid = EFalse; //initially assume no supplied codec uid
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   310
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   311
	if (aCodecUid != KNullUid)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   312
		{//the data path NewL has specified a specific codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   313
		//create CMMFCodec here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   314
		iCodec = CMMFCodec::NewL(aCodecUid);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   315
		if (iCodec)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   316
			iUseSuppliedCodecUid = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   317
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   318
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   319
	iSrcBufRef = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   320
	iSnkBufRef = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   321
	iObtainingAsyncSourceBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   322
	iObtainingAsyncSinkBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   323
	iSourceBufferWithSource = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   324
	iSinkBufferWithSink = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   325
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   326
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   327
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   328
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   329
Adds a data source to the datapath and, if the sink already exists, tries to establish a connection
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   330
between the source and sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   331
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   332
@param  aSource
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   333
        The data source to add to the data path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   334
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   335
EXPORT_C void CMMFDataPath::AddDataSourceL(MDataSource* aSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   336
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   337
	if (!iDataSink) iDataSource=aSource; //can't create a data path without the MDataSink as well
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   338
	else if (!iUseSuppliedCodecUid) //no supplied uid need to see if we can create codec to establish a data path
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   339
		{//we have a data sink as well so check a data path can be established between source&sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   340
		CreateDataPathL(aSource, iDataSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   341
		iDataSource = aSource;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   342
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   343
	else //the CMMFController specified the codec uid so must use existing codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   344
		{//note we are assuming here that the CMMFController knows what it is doing ie the supplied codec uid 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   345
		//can make the appropriate data conversion
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   346
		iDataPathCreated = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   347
		iDataSource = aSource;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   348
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   349
	ClearPlayWindowL() ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   350
	User::LeaveIfError(iDataSource->SourceThreadLogon(*this));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   351
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   352
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   353
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   354
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   355
Adds a data sink to the datapath and, if the source already exists, tries to establish a connection
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   356
between the source and sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   357
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   358
@param  aSink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   359
        The data sink to add to the data path.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   360
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   361
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   362
EXPORT_C void CMMFDataPath::AddDataSinkL(MDataSink* aSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   363
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   364
	if (!iDataSource) iDataSink=aSink; //can't create a data path without the MDataSource as well
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   365
	else if (!iUseSuppliedCodecUid) //no supplied uid need to see if we can create codec to establish a data path
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   366
		{//we have a data source as well so check a media path can be established between source&sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   367
		CreateDataPathL(iDataSource, aSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   368
		iDataSink = aSink;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   369
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   370
	else //the CMMFController specified the codec uid so must use existing codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   371
		{//note we are assuming here that the CMMFController knows what it is doing ie the supplied codec uid 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   372
		//can make the appropriate data conversion
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   373
		iDataPathCreated = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   374
		iDataSink = aSink;	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   375
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   376
		//set 4CCs
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   377
		iSourceFourCC  = iDataSink->SinkDataTypeCode(iMediaId);//sink because CMMFDataPath is an MDataSink to its MDataSource!
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   378
		iSinkFourCC = iDataSource->SourceDataTypeCode(iMediaId);//source because CMMFDataPath is an MDataSource to its MDataSink!
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   379
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   380
	User::LeaveIfError(iDataSink->SinkThreadLogon(*this));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   381
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   382
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   383
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   384
/* 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   385
 *  CreateDataPathL 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   386
 * 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   387
 *  internal function to establish a datapath between the source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   388
 *	the data supplied by the sink adn expected by the source are checked and 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   389
 *	a codec is instantiated if necessary
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   390
 *
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   391
 *	@param	aSource
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   392
 *	@param	aSink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   393
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   394
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   395
void CMMFDataPath::CreateDataPathL(MDataSource* aSource, MDataSink* aSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   396
	{ //procedure to attempt to match the source to the sink creating a codec if necessary
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   397
	// returns ETrue if the datapath could be constructed else false
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   398
	//sets iCodec to the appropriate codec.& sets its own iSink/iSource FourCC datatype codes
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   399
	iDataPathCreated = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   400
	if (aSource && aSink) //have a source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   401
		{ //we have a data source & sink but no codec so try and find one - if required
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   402
		TFourCC sourceFourCCCode = aSource->SourceDataTypeCode(iMediaId); //get MDataSource data type fourCC code
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   403
		TFourCC sinkFourCCCode = aSink->SinkDataTypeCode(iMediaId); //get MDataSink data type fourCC code
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   404
		if ((sourceFourCCCode != sinkFourCCCode) && //MDataSource & MDataSink datatypes are not compatible
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   405
			(sourceFourCCCode != KMMFFourCCCodeNULL) && (sinkFourCCCode != KMMFFourCCCodeNULL)) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   406
			{//we need a codec to make the conversion between the source and the sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   407
			CMMFCodec* codec = CMMFCodec::NewL(sourceFourCCCode, sinkFourCCCode);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   408
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   409
			if (codec)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   410
				{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   411
				delete iCodec;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   412
				iCodec = codec;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   413
				//data path created ie have source/sink and can match their datatypes
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   414
				iDataPathCreated = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   415
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   416
				//now we have an source attached we need to configure the codec for sample rate
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   417
				//and number of channels
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   418
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   419
				//prepare a package to send to a codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   420
				TMMFAudioConfig audioSettings;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   421
				
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   422
				//test for decoder
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   423
				if (aSource->DataSourceType() == KUidMmfFormatDecode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   424
					{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   425
					audioSettings.iSampleRate = static_cast<CMMFFormatDecode*>(aSource)->SampleRate();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   426
					audioSettings.iChannels = static_cast<CMMFFormatDecode*>(aSource)->NumChannels();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   427
					}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   428
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   429
				//package up to send to codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   430
				TPckgBuf<TMMFAudioConfig> configPackage(audioSettings);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   431
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   432
				//we need to catch User::Leave(KErrNotSupported) as by default most codecs
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   433
				//do not support the ConfigureL method.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   434
				TRAPD(err,iCodec->ConfigureL(KUidCodecAudioConfig, configPackage));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   435
				// need to check other error here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   436
				if (err != KErrNone && err != KErrNotSupported)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   437
					{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   438
					User::Leave(err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   439
					}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   440
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   441
			else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   442
				{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   443
				User::Leave( KErrNotSupported ) ; //couldn't find suitable codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   444
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   445
			} //if (sourceFourCCCode != sinkFourCCCode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   446
		else 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   447
			{ //source & sink fourCC datatypes are the same so no codec is required
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   448
			__ASSERT_DEBUG(iCodec == NULL,  Panic(EMMFDataPathPanicProgrammingError,__LINE__)); 			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   449
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   450
			iDataPathCreated = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   451
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   452
		//can assign FourCC codes for the CMMFDataPath
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   453
		iSinkFourCC = sourceFourCCCode; //sink because CMMFDataPath is an MDataSink to its MDataSource!
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   454
		iSourceFourCC = sinkFourCCCode; //source because CMMFDataPath is an MDataSource to its MDataSink!
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   455
		//If sink & source need its own Prime() done in controller	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   456
		} 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   457
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   458
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   459
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   460
Clears the specified buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   461
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   462
Pure virtual dummy implementation, not needed by datapath
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   463
comes from MDataSink - CMMFData path is a sink to its MDataSource.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   464
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   465
This is only required for an active push MDataSource requesting a buffer empty.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   466
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   467
@param  aBuffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   468
        The buffer to empty.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   469
@param  aSupplier
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   470
        The MDataSource supplying this buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   471
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   472
        An optional mediaID parameter when there are multiple buffers arriving of different media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   473
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   474
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   475
EXPORT_C void CMMFDataPath::EmptyBufferL(CMMFBuffer* /* aBuffer */, MDataSource* /*aSupplier*/, TMediaId /*aMediaId*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   476
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   477
	//not implemented
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   478
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   479
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   480
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   481
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   482
/* 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   483
 *  FillSourceBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   484
 * 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   485
 *	Function to get data from the datapath's iDataSource
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   486
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   487
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   488
void CMMFDataPath::FillSourceBufferL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   489
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   490
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   491
	RDebug::Print(_L("DP::FillSourceBufferL tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   492
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   493
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   494
	__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording), Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   495
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   496
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   497
	// clear the no-more-source flag here (as well as in PlayL()) because 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   498
	// there may have been a re-position since the last call to BufferFilledL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   499
	iNoMoreSourceData = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   500
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   501
	if(!iObtainingAsyncSourceBuffer) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   502
		{//this is a normal request for data. 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   503
		//If we are getting asynchronous buffers, then can't do this as iSourceBuffer == NULL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   504
		iSourceBuffer->SetFrameNumber(++iCurrentSourceFrameNumber); //so source knows which data to load buffer with
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   505
		iSourceBuffer->SetStatus(EBeingFilled);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   506
		iSourceBuffer->SetLastBuffer(EFalse);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   507
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   508
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   509
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   510
	RDebug::Print(_L("DP asking for buffer %d  - ptr=0x%x   (this 0x%x)\n"), iCurrentSourceFrameNumber, iSourceBuffer,this);	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   511
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   512
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   513
	iSourceBufferWithSource = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   514
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   515
	// wait for BufferFilled callback from source. Do this here as some sources cause
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   516
	//re-entrancy into data path via BufferFilledL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   517
	ChangeDataPathTransferState(EWaitSource);  
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   518
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   519
	iDataSource->FillBufferL(iSourceBuffer, this, iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   520
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   521
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   522
	RDebug::Print(_L("DP::FillSourceBufferL - DONE tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   523
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   524
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   525
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   526
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   527
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   528
Indicates the data source has filled the specified buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   529
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   530
Called by the CMMFDataPath's MDataSource when it has filled the buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   531
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   532
@param aBuffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   533
       A pointer to the filled buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   534
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   535
EXPORT_C void CMMFDataPath::BufferFilledL(CMMFBuffer* aBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   536
	{	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   537
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   538
	RDebug::Print(_L("DP::BufferFilledL src has filled buffer %d (ptr=0x%x) with %d bytes EoF = %d  tick-%d    (this 0x%x)\n"),aBuffer->FrameNumber(),aBuffer, aBuffer->BufferSize(),aBuffer->LastBuffer(), User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   539
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   540
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   541
	//This assertion is commented because of PDEF117405
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   542
	//state only used if we are passing data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   543
	//__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording), Panic(EMMFDataPathPanicBadState,__LINE__));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   544
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   545
	__ASSERT_DEBUG((!iNoMoreSourceData), Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   546
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   547
	iSourceBufferWithSource = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   548
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   549
	//Has the datapath stopped running, if so were not interested in any callbacks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   550
	if(iState == EStopped || iState == EPrimed || (iPauseCalled && iState != ERecording))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   551
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   552
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   553
		RDebug::Print(_L("DP::BufferFilledL called while not expecting callback iState=%d  iPauseCalled=%d  (this 0x%x)\n"),iState, iPauseCalled,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   554
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   555
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   556
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   557
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   558
#ifdef REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   559
	// if the source has been re-positioned, then go & get some more source data now
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   560
	if (!iObtainingAsyncSourceBuffer && iSourceBuffer->FrameNumber() != iCurrentSourceFrameNumber)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   561
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   562
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   563
		RDebug::Print(_L("DP::BufferFilledL source was re-positioned re-requesting source data (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   564
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   565
		ChangeDataPathTransferState(ENeedSourceData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   566
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   567
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   568
#endif //REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   569
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   570
	//bufer is NULL, indicating no more source data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   571
	if (!aBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   572
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   573
		//If we only hold a reference to the source buffer, set that to NULL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   574
		if(iSnkBufRef)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   575
			iSourceBuffer = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   576
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   577
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   578
		iNoMoreSourceData = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   579
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   580
		if(!iCodec || //there's only one buffer and that has been returned as NULL, so must be end of data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   581
		  iSinkBufferWithSink) //buffer is with sink, we don't have any more data to put in it, so must be end of data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   582
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   583
			ChangeDataPathTransferState(EEndOfData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   584
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   585
		else //sink buffer is with datapath, see if there is anything to send to sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   586
			ChangeDataPathTransferState(ENeedToMatchSourceToSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   587
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   588
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   589
		RDebug::Print(_L("DP::BufferFilledL DONE aBuffer==NULL tick-%d (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   590
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   591
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   592
		} 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   593
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   594
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   595
	//We were waiting for a response from the source to get an asynchronous buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   596
	//We now have it, and we proceed to transfer this data to the sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   597
	if	(iObtainingAsyncSourceBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   598
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   599
		iObtainingAsyncSourceBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   600
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   601
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   602
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   603
	aBuffer->SetStatus(EFull);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   604
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   605
	if(iSourceBuffer != aBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   606
		{//buffer has been changed by the source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   607
		iSourceBuffer = aBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   608
		if (!(iBuffersToUse & ENeedSinkBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   609
			{//we only need one buffer and use source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   610
			iSinkBuffer = iSourceBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   611
			iSnkBufRef = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   612
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   613
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   614
	RDebug::Print(_L("DP::BufferFilledL - iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   615
#endif	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   616
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   617
	//Is this the last buffer from the source (0 length or LastBuffer flag set)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   618
	//or have reached the end of the play window; we only look at the play window here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   619
	//if we are converting. For conversion we look at the data we have read. This is then passed onto 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   620
	//the source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   621
	if (!iSourceBuffer->BufferSize() || iSourceBuffer->LastBuffer() ||
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   622
		(((iState == EConverting) || (iState == EPlaying)) && (iPlayWindowEndPosition < iCachedSourceDuration) && ( InputPosition() >= iPlayWindowEndPosition ))) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   623
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   624
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   625
		RDebug::Print(_L("DP::BufferFilledL end of input data  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   626
		RDebug::Print(_L("iSourceBuffer->BufferSize()=%d\n"),iSourceBuffer->BufferSize());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   627
		RDebug::Print(_L("iSourceBuffer->LastBuffer()=%d\n"),iSourceBuffer->LastBuffer());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   628
		RDebug::Print(_L("InputPosition()=%d  >= iPlayWindowEndPosition=%d\n"),I64INT(InputPosition().Int64()),I64INT(iPlayWindowEndPosition.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   629
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   630
		iNoMoreSourceData = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   631
		iSourceBuffer->SetLastBuffer(ETrue); //just in-case we are terminating on BufferSize == 0 or play window
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   632
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   633
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   634
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   635
	if (!iCodec)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   636
		ChangeDataPathTransferState(ESendDataToSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   637
	else if(!iSinkBufferWithSink) //sink buffer is with data path, can try to fill it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   638
		ChangeDataPathTransferState(ENeedToMatchSourceToSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   639
	//else wait for sink to return buffer BufferEmptied will send us into ENeedToMatchSourceToSink state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   640
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   641
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   642
	RDebug::Print(_L("DP::BufferFilledL - DONE tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   643
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   644
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   645
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   646
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   647
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   648
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   649
/* 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   650
 *  FillSinkBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   651
 * 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   652
 *	Function to take the data from an already full source buffer and by using
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   653
 *	a codec if necessary fills the sink buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   654
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   655
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   656
void CMMFDataPath::FillSinkBufferL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   657
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   658
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   659
	RDebug::Print(_L("DP::FillSinkBufferL tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   660
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   661
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   662
	//This state is only used if we are passing data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   663
	__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording), Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   664
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   665
	//This state is only used if we have a real codec
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   666
	__ASSERT_DEBUG(iCodec, Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   667
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   668
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   669
	//The sink buffer is with the sink so we can't fill it.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   670
	//When it has been emptied, this state will be re-entered from BufferEmptiedL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   671
	if(iSinkBufferWithSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   672
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   673
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   674
		RDebug::Print(_L("DP::FillSinkBufferL buffer is in use by SINK - DONE   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   675
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   676
		ChangeDataPathTransferState(EWaitSink);  // wait for BufferEmptied callback from sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   677
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   678
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   679
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   680
	//The source buffer is with the source so we can't take data from it.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   681
	//When it has been filled, this state will be re-entered from BufferFilledL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   682
	if(iSourceBufferWithSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   683
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   684
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   685
		RDebug::Print(_L("DP::FillSinkBufferL buffer is in use by SOURCE - DONE   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   686
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   687
		ChangeDataPathTransferState(EWaitSource);  // wait for BufferFilled callback from source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   688
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   689
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   690
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   691
	//source buffer is NULL, can't be any more data to send.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   692
	//iNoMoreSourceData is set and the source buffer is empty, can't be any more data to send.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   693
	if(!iSourceBuffer || (iNoMoreSourceData && !iSourceBuffer->BufferSize()))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   694
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   695
		if(iSinkBuffer->Status() == EBeingFilled)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   696
			{//if we have data in sink buffer, mark it as last buffer and send
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   697
			iSinkBuffer->SetLastBuffer(ETrue);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   698
			ChangeDataPathTransferState(ESendDataToSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   699
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   700
		else //the sink buffer can't have anything in it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   701
			ChangeDataPathTransferState(EEndOfData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   702
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   703
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   704
#ifdef REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   705
	// if the source has been re-positioned, 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   706
	// speed things up by getting some more source data now
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   707
	if(iSourceBuffer && iSourceBuffer->FrameNumber() != iCurrentSourceFrameNumber)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   708
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   709
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   710
		RDebug::Print(_L("DP::FillSinkBufferL() source was re-positioned re-requesting source data (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   711
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   712
		ChangeDataPathTransferState(ENeedSourceData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   713
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   714
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   715
#endif //REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   716
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   717
	iSinkBuffer->SetStatus(EBeingFilled);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   718
	iSinkBuffer->SetLastBuffer(EFalse);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   719
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   720
	//pass buffer to codec for processing
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   721
	iCodecProcessResult = iCodec->ProcessL(*iSourceBuffer, *iSinkBuffer);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   722
	//the codec tries to fill the sink buffer to its max length
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   723
	//TCodecProcessResult returns the status of the codec Process -
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   724
	//this can result in result conditions such as:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   725
	//EProcessComplete - the codec processed all the source data into the sink buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   726
	//EProcessIncomplete - the codec filled sink buffer before all the source buffer was processed
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   727
	//EDstNotFilled - the codec processed the source buffer but the sink buffer was not filled
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   728
	//EEndOfData - the codec detected the end data - all source data in processed but sink may not be full
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   729
	//EProcessError - the codec process error condition
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   730
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   731
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   732
	switch (iCodecProcessResult.iStatus)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   733
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   734
	case TCodecProcessResult::EProcessComplete:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   735
	//finished procesing source data - all data in sink buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   736
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   737
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   738
		RDebug::Print(_L("CMMFDataPath::FillSinkBufferL codec EProcessComplete   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   739
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   740
		iSourceBuffer->SetStatus(EAvailable); //source buffer is now avaialble
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   741
		iSinkBuffer->SetStatus(EFull);	//sink buffer is full	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   742
		if (iNoMoreSourceData) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   743
			iSinkBuffer->SetLastBuffer(ETrue);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   744
		ChangeDataPathTransferState(ESendDataToSink);// the full sink buffer needs to be sent to the sink 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   745
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   746
	break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   747
	case TCodecProcessResult::EProcessIncomplete:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   748
		// the sink was filled before all the src was processed 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   749
		// therefore still send everything to sink 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   750
		//but datapath needs to carry on processing the source buffer before it gets more source data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   751
		//when sink has emptied data path needs to send rest of data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   752
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   753
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   754
		RDebug::Print(_L("CMMFDataPath::FillSinkBufferL codec EProcessIncomplete   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   755
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   756
		TUint sourceBufferPosition = iCodecProcessResult.iSrcBytesProcessed + iSourceBuffer->Position();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   757
		iSourceBuffer->SetPosition(sourceBufferPosition);//update source buffer position
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   758
		iSinkBuffer->SetStatus(EFull); //sink & source buffers are both full
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   759
		ChangeDataPathTransferState(ESendDataToSink); // the full sink buffer needs to be sent to the sink 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   760
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   761
	break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   762
	case TCodecProcessResult::EDstNotFilled:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   763
		// the destination is not full 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   764
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   765
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   766
		RDebug::Print(_L("CMMFDataPath::FillSinkBufferL codec EDstNotFilled   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   767
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   768
		iSourceBuffer->SetStatus(EAvailable); //source buffer is now available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   769
		TUint sinkBufferPosition = iCodecProcessResult.iDstBytesAdded + iSinkBuffer->Position();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   770
		iSinkBuffer->SetPosition(sinkBufferPosition);//update sink  buffer position (still EBeingFilled)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   771
		// if this was the last source buffer, send what we've got (if anything) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   772
		// to the sink... EmptySinkBuffer() should then enter EEndOfData state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   773
		if (iNoMoreSourceData)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   774
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   775
			iSinkBuffer->SetLastBuffer(ETrue);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   776
			ChangeDataPathTransferState(ESendDataToSink);//send what we've got to the sink - 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   777
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   778
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   779
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   780
			ChangeDataPathTransferState(ENeedSourceData); //need to get more source data to fill sink buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   781
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   782
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   783
	break;	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   784
	case TCodecProcessResult::EEndOfData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   785
		//no more data - send what we've got to the sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   786
		//note we can't always rely on this  - in many cases the codec will not know when
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   787
		//it has reached the end of data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   788
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   789
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   790
		RDebug::Print(_L("CMMFDataPath::FillSinkBufferL codec EEndOfData   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   791
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   792
		iSourceBuffer->SetStatus(EAvailable); //source buffer is now avaialble
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   793
		iSinkBuffer->SetStatus(EFull);//sink buffer may not really be 'full' but its as full as it going to get
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   794
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   795
		//This only occurs where the codec can detect the end of data, but the source can't
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   796
		iNoMoreSourceData=ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   797
		iSinkBuffer->SetLastBuffer(ETrue); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   798
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   799
		ChangeDataPathTransferState(ESendDataToSink);//send what we've got to the sink - 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   800
		//doesn't matter if sink buffer is not full
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   801
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   802
	break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   803
	case TCodecProcessResult::EProcessError:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   804
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   805
		RDebug::Print(_L("DP::FillSinkBufferL tick-%d  DONE %d   (this 0x%x)\n"),User::TickCount(), __LINE__,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   806
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   807
		User::Leave(KErrCorrupt); //codec process error
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   808
	break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   809
	default:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   810
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   811
		RDebug::Print(_L("DP::FillSinkBufferL tick-%d  DONE %d   (this 0x%x)\n"),User::TickCount(), __LINE__,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   812
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   813
		User::Leave(KErrCorrupt); //should never get here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   814
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   815
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   816
	RDebug::Print(_L("DP::FillSinkBufferL - done  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   817
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   818
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   819
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   820
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   821
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   822
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   823
Tests whether the data path can create a sink buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   824
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   825
The default implementation returns false.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   826
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   827
@return ETrue if the data path can create a sink buffer. EFalse if the data path cannot create a sink buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   828
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   829
EXPORT_C TBool CMMFDataPath::CanCreateSinkBuffer()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   830
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   831
	return NULL; //CMMFDataPath cannot create buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   832
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   833
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   834
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   835
Creates a sink buffer according to the specifed media ID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   836
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   837
Intended for synchronous usage (buffers supplied by datapath for an MDataSink).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   838
This method is essentially a dummy implementation of an MDataSink pure virtual.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   839
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   840
The default implementation returns NULL.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   841
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   842
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   843
        An optional mediaID parameter when there are multiple buffers arriving of different media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   844
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   845
@return Returns NULL in this instance as datapath can't create sink buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   846
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   847
EXPORT_C CMMFBuffer* CMMFDataPath::CreateSinkBufferL(TMediaId /*aMediaId*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   848
	{//CMMFDataPath can't create buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   849
	return NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   850
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   851
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   852
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   853
Creates a sink buffer according to the specifed media ID and reference.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   854
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   855
Intended for asynchronous usage (buffers supplied by Devsound device).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   856
This method is essentially a dummy implementation of an MDataSink pure virtual.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   857
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   858
The default implementation returns NULL.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   859
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   860
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   861
        An optional mediaID parameter when there are multiple buffers arriving for different media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   862
@param  aReference
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   863
        A boolean indicating buffer ownership.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   864
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   865
@return	Returns NULL in this instance as datapath can't create sink buffers.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   866
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   867
EXPORT_C CMMFBuffer* CMMFDataPath::CreateSinkBufferL(TMediaId /*aMediaId*/, TBool& /*aReference*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   868
	{//CMMFDataPath can't create buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   869
	return NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   870
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   871
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   872
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   873
Gets the sink's data type for the specified media ID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   874
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   875
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   876
        An optional parameter to specifiy the specific stream when datasource contains more than one stream of data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   877
@return The sink's data type.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   878
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   879
EXPORT_C TFourCC CMMFDataPath::SinkDataTypeCode(TMediaId /*aMediaId*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   880
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   881
	return(iSinkFourCC);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   882
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   883
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   884
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   885
Fills the specified buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   886
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   887
Pure virtual dummy implementation, not needed by datapath
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   888
comes from MDataSink - CMMFData path is a source to its MDataSink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   889
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   890
Only required for an active pull MDataSink requesting a buffer fill. The default implementation is empty.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   891
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   892
@param  aBuffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   893
        The buffer to fill.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   894
@param  aConsumer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   895
        The MDataSink supplying this buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   896
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   897
        An optional mediaID parameter when there are multiple buffers arriving of different media types
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   898
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   899
EXPORT_C void CMMFDataPath::FillBufferL(CMMFBuffer* /*aBuffer*/, MDataSink* /*aConsumer*/, TMediaId /*aMediaId*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   900
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   901
	//not implementated
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   902
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   903
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   904
void CMMFDataPath::SetBuffersAvailable()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   905
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   906
	// set source buffer to be available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   907
  	if (iSourceBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   908
  		iSourceBuffer->SetStatus(EAvailable);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   909
	// set sink buffer to be available
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   910
  	if (iSinkBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   911
  		iSinkBuffer->SetStatus(EAvailable);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   912
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   913
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   914
void CMMFDataPath::ResetRefBuffers()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   915
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   916
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   917
	RDebug::Print(_L("DP::ResetRefBuffers iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   918
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   919
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   920
	// Reset the buffer pointers to NULL if they are supplied by DevSound
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   921
	// We do this because buffers that are not owned by the datapath may not be valid any more.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   922
	if (iSrcBufRef)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   923
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   924
		iSourceBuffer = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   925
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   926
	if (iSnkBufRef)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   927
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   928
		iSinkBuffer = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   929
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   930
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   931
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   932
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   933
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   934
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   935
TInt CMMFDataPath::DetermineBuffersToUseL(void) const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   936
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   937
	TInt buffs = ENoBuffers;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   938
	if(iCodec)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   939
		{//Using a real Codec, need both sets of buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   940
		if(!iDataSink->CanCreateSinkBuffer() || ! iDataSource->CanCreateSourceBuffer())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   941
			User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   942
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   943
		buffs = CMMFDataPath::ENeedSinkBuffer | CMMFDataPath::ENeedSourceBuffer;	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   944
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   945
	else //we are using a Null Codec, only need one buffer, but which one?
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   946
		{//use buffer from DevSound, if no DevSound (ie, clip to clip), prefer source buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   947
		//If preferring source but it can't create buffers, use sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   948
		if ((iDataSink->DataSinkType() == KUidMmfAudioOutput) && (iDataSink->CanCreateSinkBuffer()))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   949
			buffs = ENeedSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   950
		else if(iDataSource->CanCreateSourceBuffer())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   951
			buffs = ENeedSourceBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   952
		else if(iDataSink->CanCreateSinkBuffer())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   953
			buffs = ENeedSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   954
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   955
			User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   956
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   957
	return buffs;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   958
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   959
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   960
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   961
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   962
/*
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   963
 *  InitializeSinkL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   964
 *
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   965
 *	Function to initialize iDataSink before it can start sending data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   966
 *	This is a one time prime. This will synchronize DataPath's data driving
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   967
 *	mechanism with HwDevice implementation.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   968
 *
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   969
 *  This initialisation method detects its attached sources and sinks and makes adjustments to the state machine
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   970
 *  This avoid the possibility of NULL buffers (not yet returned by an asychronous sink or source) being passed around the MMF
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   971
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   972
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   973
void CMMFDataPath::InitializeSinkL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   974
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   975
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   976
	RDebug::Print(_L("DP::InitializeSinkL  iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   977
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   978
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   979
	//state only used if we are passing data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   980
	__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording), Panic(EMMFDataPathPanicBadState,__LINE__));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   981
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   982
	iObtainingAsyncSinkBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   983
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   984
	if (iBuffersToUse & ENeedSinkBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   985
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   986
		//Buffers are initially created in the Prime method. But following a pause, we must re-create 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   987
		//any referenced buffers, so try direct creation.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   988
		//NB: this does mean we are trying this twice, Prime and here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   989
		if (!iSinkBuffer) //we may already have a buffer from a previous initialization
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   990
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   991
			TRAPD(err, iSinkBuffer = iDataSink->CreateSinkBufferL(iMediaId, iSnkBufRef));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   992
			if(err != KErrNone && err != KErrNotSupported)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   993
				User::Leave(err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   994
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   995
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   996
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   997
		//If buffer has not been supplied via CreateSinkBufferL, 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   998
		//must use asynchronous buffer creation		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
   999
		if (!iSinkBuffer) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1000
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1001
			iObtainingAsyncSinkBuffer = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1002
			ChangeDataPathTransferState(EWaitSink);  // wait for BufferEmptied callback from sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1003
			iDataSink->EmptyBufferL(iSinkBuffer, this, iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1004
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1005
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1006
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1007
			//we have a sink buffer from CreateSinkBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1008
			iSinkBuffer->SetStatus(EAvailable);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1009
			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1010
			if (iBuffersToUse & ENeedSourceBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1011
				{//need a source buffer, go get it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1012
				ChangeDataPathTransferState(EInitializeSource);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1013
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1014
			else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1015
				{//only need one buffer, use sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1016
				iSourceBuffer = iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1017
				iSrcBufRef = ETrue; //the src buffer is not to be deleted
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1018
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1019
				ChangeDataPathTransferState(ENeedSourceData); //got all buffers, start getting data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1020
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1021
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1022
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1023
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1024
		{//don't need a sink buffer, but we need a source one
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1025
		ChangeDataPathTransferState(EInitializeSource);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1026
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1027
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1028
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1029
	RDebug::Print(_L("DP::InitializeSinkL - DONE  iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1030
#endif	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1031
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1032
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1033
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1034
/*
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1035
 *  InitializeSourceL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1036
 *
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1037
 *	Function to initialize iDataSource before it can start sending data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1038
 *	This is a one time prime. This will synchronize DataPath's data driving
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1039
 *	mechanism with HwDevice implementation.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1040
 *
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1041
 *  This initialisation method detects its attached sources and sinks and makes adjustments to the state machine
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1042
 *  This avoid the possibility of NULL buffers (not yet returned by an asychronous sink or source) being passed around the MMF
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1043
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1044
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1045
void CMMFDataPath::InitializeSourceL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1046
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1047
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1048
	RDebug::Print(_L("DP::InitializeSourceL -  iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1049
#endif	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1050
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1051
	//state only used if we are passing data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1052
	__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording), Panic(EMMFDataPathPanicBadState,__LINE__));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1053
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1054
	iObtainingAsyncSourceBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1055
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1056
	if (iBuffersToUse & ENeedSourceBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1057
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1058
		//Buffers are initially created in the Prime method. But following a pause, we must re-create 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1059
		//any referenced buffers, so try direct creation.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1060
		//NB: this does mean we are trying this twice, Prime and here.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1061
		if (!iSourceBuffer) //we may already have a buffer from a previous initialization
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1062
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1063
			TRAPD(err, iSourceBuffer = iDataSource->CreateSourceBufferL(iMediaId,*iSinkBuffer, iSrcBufRef));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1064
			if(err != KErrNone && err != KErrNotSupported)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1065
				User::Leave(err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1066
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1067
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1068
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1069
		//If buffer has not been supplied via CreateSourceBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1070
		//must use asynchronous buffer creation
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1071
		if (!iSourceBuffer) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1072
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1073
			iObtainingAsyncSourceBuffer = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1074
			ChangeDataPathTransferState(ENeedSourceData);			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1075
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1076
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1077
			{//we have a source buffer from CreateSourceBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1078
			iSourceBuffer->SetStatus(EAvailable);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1079
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1080
			if (!(iBuffersToUse & ENeedSinkBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1081
				{//only need one buffer, use sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1082
				iSinkBuffer = iSourceBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1083
				iSnkBufRef = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1084
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1085
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1086
			ChangeDataPathTransferState(ENeedSourceData); //got all buffers, start getting data			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1087
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1088
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1089
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1090
		{//don't need a source buffer, use sinks
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1091
		if(iSinkBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1092
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1093
			iSourceBuffer = iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1094
			iSrcBufRef = iSnkBufRef;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1095
			SetBuffersAvailable();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1096
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1097
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1098
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1099
			Panic(EMMFDataPathPanicProgrammingError,__LINE__);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1100
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1101
		ChangeDataPathTransferState(ENeedSourceData); //got all buffers, start getting data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1102
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1103
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1104
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1105
	RDebug::Print(_L("DP::InitializeSourceL -  iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1106
#endif			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1107
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1108
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1109
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1110
/*
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1111
 *  EmptySinkBufferL
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1112
 * 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1113
 *	Function to pass a full databuffer to the iDataSink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1114
 */
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1115
void CMMFDataPath::EmptySinkBufferL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1116
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1117
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1118
	RDebug::Print(_L("DP::EmptySinkBufferL pass data to sink  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1119
	if(iSinkBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1120
		RDebug::Print(_L("iSinkBuffer %d contains %d bytes  eof = %d line %d   (this 0x%x)\n"),iSinkBuffer->FrameNumber(), iSinkBuffer->BufferSize(),iSinkBuffer->LastBuffer(),__LINE__,this);		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1121
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1122
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1123
	//Before emptying the sink buffer we need to check it has data to empty - this
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1124
	//may not be the case if there is no more data ie iNoMoreSourceData is true.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1125
	//In this case we need to check to see if there is any data left in the sink 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1126
	//buffer, ie the sink buffer is either full or being filled. If there is not any
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1127
	//data in the sink buffer, ie it is not in the state of EBeingFilled or EFull
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1128
	//then there is nothing to empty so the datapath state is set to EEndOfData and
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1129
	//we return from the procedure.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1130
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1131
	//state only used if we are passing data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1132
	__ASSERT_DEBUG((iState == EPlaying || iState == EConverting || iState == ERecording || (iState == EPrimed && iPauseCalled)), Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1133
	__ASSERT_DEBUG(iSinkBuffer &&
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1134
				   ((iSinkBuffer->Status()==EBeingFilled) || (iSinkBuffer->Status()==EFull)),
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1135
				   Panic(EMMFDataPathPanicProgrammingError,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1136
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1137
	__ASSERT_DEBUG(iSinkBufferWithSink == EFalse, Panic(EMMFDataPathPanicBadState,__LINE__)); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1138
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1139
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1140
	//Due to sinks that may call BuferEmptied directly (ie. re-entrancy onto DataPath) we
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1141
	//must work out next state here. If re-entrancy, the next state may validly get overwritten 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1142
	// in BuferEmptied.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1143
	if(iObtainingAsyncSinkBuffer) //wait for buffer to be returned in BufferEmptied
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1144
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1145
		ChangeDataPathTransferState(EWaitSink);  // wait for BufferEmptied callback from sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1146
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1147
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1148
#ifdef REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1149
	// if the source has been re-positioned, 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1150
	// speed things up by getting some more source data now
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1151
	if(iSourceBuffer && iSourceBuffer->FrameNumber() != iCurrentSourceFrameNumber)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1152
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1153
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1154
		RDebug::Print(_L("DP::EmptySinkBufferL() source was re-positioned re-requesting source data (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1155
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1156
		ChangeDataPathTransferState(ENeedSourceData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1157
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1158
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1159
#endif //REPOSITION_SPEEDUP
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1160
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1161
	//We have sent data to sink, if we are using a real Codec, we can now get more data from source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1162
	//if there is any more to get and the codec has emptied it.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1163
	//NB: No need to check we own the source buffer as we will no be in this state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1164
	//if we have asked for more source data and haven't received it.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1165
	else if (iCodec && !iNoMoreSourceData && (iSourceBuffer->Status() == EAvailable))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1166
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1167
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1168
		RDebug::Print(_L("ASKING for more source data iCodec = 0x%x  iNoMoreSourceData=%d  iSourceBufferWithSource = %d   (this 0x%x)\n"), iCodec, iNoMoreSourceData, iSourceBufferWithSource,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1169
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1170
		ChangeDataPathTransferState(ENeedSourceData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1171
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1172
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1173
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1174
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1175
		RDebug::Print(_L("Not asking for any more source data iCodec = 0x%x  iNoMoreSourceData=%d  iSourceBufferWithSource = %d   iSourceBuffer->Status=%d   (this 0x%x)\n"), iCodec, iNoMoreSourceData, iSourceBufferWithSource ,iSourceBuffer->Status(), this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1176
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1177
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1178
		//if this is the last buffer, set this flag so we can deal with KErrUnderflow 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1179
		//as a valid termination of playing
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1180
		if(iSinkBuffer->LastBuffer())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1181
			iAllDataSentToSink=ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1182
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1183
		ChangeDataPathTransferState(EWaitSink);  // wait for BufferEmptied callback from sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1184
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1185
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1186
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1187
	if(!iObtainingAsyncSinkBuffer) //normal data transfer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1188
		iSinkBuffer->SetFrameNumber(++iCurrentSinkFrameNumber);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1189
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1190
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1191
	RDebug::Print(_L("DP sending buffer %d ptr=0x%x of %d bytes to sink   (this 0x%x)\n"), iSinkBuffer->FrameNumber(),iSinkBuffer,iSinkBuffer->BufferSize(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1192
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1193
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1194
	iSinkBufferWithSink = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1195
	TRAPD(error, iDataSink->EmptyBufferL(iSinkBuffer, this, iMediaId));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1196
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1197
	// Check that we haven't exceeded the maximum clip length - if so, go to the EndOfData state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1198
	// so we perform necessary cleanup.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1199
	if (error == KErrEof || error == KErrOverflow || error == KErrUnderflow)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1200
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1201
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1202
		RDebug::Print(_L("DP::EmptySinkBufferL DONE %d error = %d  tick-%d   (this 0x%x)\n"),__LINE__, error, User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1203
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1204
		iDataPathCompletedErrorCode = error;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1205
		ChangeDataPathTransferState(EEndOfData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1206
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1207
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1208
	User::LeaveIfError(error);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1209
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1210
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1211
	RDebug::Print(_L("DP::EmptySinkBufferL - done  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1212
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1213
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1214
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1215
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1216
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1217
Indicates the data sink has emptied the buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1218
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1219
Called by the CMMFDataPath's MDataSink when it has emptied the buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1220
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1221
@param  aBuffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1222
		The emptied buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1223
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1224
EXPORT_C void CMMFDataPath::BufferEmptiedL(CMMFBuffer* aBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1225
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1226
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1227
	TInt bufNum = 9999;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1228
	if(aBuffer)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1229
		bufNum = aBuffer->FrameNumber();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1230
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1231
		RDebug::Print(_L("DP::BufferEmptiedL returned NULL   (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1232
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1233
	RDebug::Print(_L("DP::BufferEmptiedL sink has taken buffer %d (ptr=0x%x) bytes %d eof= %d   iNoMoreSourceData = %d tick-%d   (this 0x%x)\n"),
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1234
		bufNum, aBuffer, aBuffer->BufferSize(),aBuffer->LastBuffer(), iNoMoreSourceData, User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1235
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1236
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1237
	iSinkBufferWithSink = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1238
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1239
    //Has the datapath stopped running, if so were not interested in any callbacks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1240
    if(iState == EStopped || (iState == EPrimed && !iPauseCalled))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1241
        {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1242
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1243
		RDebug::Print(_L("DP::BufferEmptiedL called while not expecting callback iState=%d  iPauseCalled=%d  (this 0x%x)\n"),iState, iPauseCalled,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1244
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1245
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1246
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1247
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1248
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1249
	// This will allow MDataSink to send dynamic buffer to DataPath with each BufferEmptiedL request.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1250
	if (iSinkBuffer != aBuffer) //buffer has been updated
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1251
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1252
		iSinkBuffer = aBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1253
		if (!(iBuffersToUse & ENeedSourceBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1254
			{ //can use a single buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1255
			iSourceBuffer = iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1256
			iSrcBufRef = iSnkBufRef;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1257
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1258
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1259
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1260
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1261
	iSinkBuffer->SetStatus(EAvailable);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1262
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1263
	if (iObtainingAsyncSinkBuffer) //we are creating an asynchronous sink buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1264
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1265
		iObtainingAsyncSinkBuffer = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1266
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1267
		//we have a sink buffer, should this also be used by the source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1268
		if (!(iBuffersToUse & ENeedSourceBuffer))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1269
			{//using a single buffer, so start getting data
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1270
			iSourceBuffer = iSinkBuffer;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1271
			iSrcBufRef = iSnkBufRef;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1272
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1273
			ChangeDataPathTransferState(ENeedSourceData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1274
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1275
		else //obtain a separate source buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1276
			ChangeDataPathTransferState(EInitializeSource);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1277
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1278
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1279
	RDebug::Print(_L("DP::BufferEmptiedL - DONE iSourceBuffer=0x%x ref=%d   iSinkBuffer=0x%x ref=%d (this 0x%x)\n"),iSourceBuffer,iSrcBufRef,iSinkBuffer,iSnkBufRef, this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1280
#endif	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1281
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1282
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1283
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1284
	if(!iCodec) //No Codec in use
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1285
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1286
		if(iNoMoreSourceData)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1287
			ChangeDataPathTransferState(EEndOfData);//final buffer returned from sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1288
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1289
			ChangeDataPathTransferState(ENeedSourceData);//get more data from source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1290
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1291
	else //real codecs
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1292
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1293
		//There is more source data and src buffer is being filled or we are about to go into 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1294
		// ENeedSourceData state to fill it, so wait for source data to arrive.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1295
		//NB:if there was more source data and we are using a real codec and source buffer was empty,
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1296
		//more source data would have been requested in EmptySinkBuffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1297
		if(!iNoMoreSourceData && (iSourceBufferWithSource || iTransferState == ENeedSourceData))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1298
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1299
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1300
			RDebug::Print(_L("DP::BufferEmptiedL - waiting for more source data - DONE tick-%d line %d   (this 0x%x)\n"),User::TickCount(),__LINE__,this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1301
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1302
			return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1303
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1304
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1305
		//source has supplied a NULL buffer or it has been emptied; no more data to send.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1306
		if(!iSourceBuffer || (iSourceBuffer->Status() == EAvailable))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1307
			ChangeDataPathTransferState(EEndOfData);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1308
		else if(iSourceBuffer->Status() == EFull) //there is data in the source buffer, go and get it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1309
			ChangeDataPathTransferState(ENeedToMatchSourceToSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1310
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1311
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1312
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1313
			Panic(EMMFDataPathPanicProgrammingError,__LINE__);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1314
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1315
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1316
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1317
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1318
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1319
	RDebug::Print(_L("DP::BufferEmptiedL - DONE  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1320
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1321
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1322
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1323
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1324
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1325
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1326
Tests whether the data path can create a source buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1327
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1328
Would expect datapath to always return NULL, so this is a default implementation of a pure virtual from MDataSink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1329
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1330
The default implementation returns EFalse.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1331
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1332
@return ETrue if the data path can create a source buffer. EFalse if the data path cannot create a source buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1333
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1334
EXPORT_C TBool CMMFDataPath::CanCreateSourceBuffer() //from both MDataSource & MDataSink?
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1335
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1336
	return EFalse; //CMMFDataPath cannot create buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1337
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1338
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1339
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1340
Creates a source buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1341
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1342
Intended for synchronous usage (buffers supplied by datapath for a MDataSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1343
This method is essentially a dummy implementation of an MDataSource pure virtual.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1344
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1345
The default implementation leaves with KErrNotSupported and returns NULL.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1346
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1347
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1348
        An optional mediaID parameter when there are multiple buffers arriving of different media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1349
@return A pointer to a newly created buffer. Returns NULL in this instance as datapath can't create source buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1350
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1351
EXPORT_C CMMFBuffer* CMMFDataPath::CreateSourceBufferL(TMediaId /*aMediaId*/) //CMMFDataPath can't create buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1352
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1353
	User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1354
	return NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1355
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1356
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1357
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1358
Creates a source buffer according to the specifed media ID and reference.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1359
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1360
Intended for asynchronous usage (buffers supplied by datapath for a MDataSource)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1361
This method is essentially a dummy implementation of an MDataSource pure virtual.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1362
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1363
The default implementation leaves with KErrNotSupported and returns NULL.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1364
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1365
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1366
        An optional mediaID parameter when there are multiple buffers arriving of different media types.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1367
@param  aReference
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1368
        A boolean indicating buffer ownership. ETrue if the MDataSource owns the buffer, EFalse if the caller owns the buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1369
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1370
@return A pointer to a newly created buffer. Returns NULL in this instance as datapath can't create source buffers.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1371
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1372
EXPORT_C CMMFBuffer* CMMFDataPath::CreateSourceBufferL(TMediaId /*aMediaId*/, TBool& /*aReference*/) //CMMFDataPath can't create buffers
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1373
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1374
	User::Leave(KErrNotSupported);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1375
	return NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1376
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1377
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1378
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1379
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1380
Gets the source data type for the specified media ID.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1381
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1382
@param  aMediaId
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1383
        An optional parameter to specifiy specific stream when datasource contains more than one stream of data.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1384
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1385
@return The source data type.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1386
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1387
EXPORT_C TFourCC CMMFDataPath::SourceDataTypeCode(TMediaId /*aMediaId*/)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1388
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1389
	return(iSourceFourCC);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1390
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1391
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1392
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1393
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1394
Allocates buffers in preparation to play.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1395
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1396
Must be called before calling PlayL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1397
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1398
iSnkBufRef and iSrcBufRef contain ETrue if these buffers are created and owned by a MDataSource or MDataSink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1399
For clean-up purposes, datapath only cleans up buffers allocated directly by PrimeL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1400
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1401
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1402
EXPORT_C void CMMFDataPath::PrimeL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1403
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1404
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1405
	RDebug::Print(_L("DP::PrimeL  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1406
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1407
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1408
	//allocate resources ie buffers & prepare to play
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1409
	if (iDataPathCreated && (iState == EStopped))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1410
		//luckily the client utility does this.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1411
		{//can only prime from the stopped state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1412
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1413
		//This will determine what buffers we need to run the datapath.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1414
		//Can leave KERRNotSupported
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1415
		iBuffersToUse = DetermineBuffersToUseL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1416
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1417
		//Try to create source and sink buffers. If we can't create them in the Prime, 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1418
		//we will need to obtain them by asynchronous buffer creation when playing starts.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1419
		ObtainSyncBuffersL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1420
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1421
		iDataSource->SourcePrimeL(); //propogate state change to source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1422
		iDataSink->SinkPrimeL(); //propogate state change to sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1423
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1424
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1425
		//If Client has set these, they will be set following the prime
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1426
		iPlayWindowStartPosition = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1427
		iPlayWindowEndPosition = Duration();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1428
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1429
		iState = EPrimed;	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1430
		iPauseCalled = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1431
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1432
		if (iCompleteCallback)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1433
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1434
			delete iCompleteCallback;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1435
			iCompleteCallback = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1436
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1437
		TBool waitForSink = (iDataSink->DataSinkType() == KUidMmfAudioOutput)?ETrue:EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1438
		iCompleteCallback = new (ELeave) CCompleteCallback(*this,waitForSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1439
		}		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1440
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1441
	RDebug::Print(_L("DP::PrimeL  Done  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1442
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1443
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1444
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1445
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1446
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1447
Starts an active scheduler 'play' loop.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1448
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1449
Can only play from the primed state.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1450
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1451
EXPORT_C void CMMFDataPath::PlayL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1452
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1453
#if defined(__PROFILING)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1454
	RDebug::ProfileEnd(1);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1455
#endif  // defined(__PROFILING)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1456
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1457
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1458
	RDebug::Print(_L("DP::PlayL, on src buff %d  sink buf %d (this 0x%x)\n"), iCurrentSourceFrameNumber, iCurrentSinkFrameNumber,this);		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1459
	RDebug::Print(_L("iStartPosition = %d\n"), I64INT(iStartPosition.Int64()));		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1460
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1461
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1462
	if ((iDataPathCreated) && (iState == EPrimed))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1463
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1464
		//can only play from the primed state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1465
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1466
		TBool savedPauseCalled=EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1467
		if(iPauseCalled) //sink and source will have been stopped, and we will not have been re-primed
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1468
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1469
			savedPauseCalled=ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1470
			iDataSink->SinkPrimeL(); //propagate change down to sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1471
			iPauseCalled = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1472
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1473
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1474
		iCurrentSourceFrameNumber = 0; //reset to beginning
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1475
		iCurrentSinkFrameNumber = 0; //reset to beginning
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1476
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1477
		iSourceBufferWithSource = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1478
		iSinkBufferWithSink = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1479
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1480
		iNoMoreSourceData = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1481
		iAllDataSentToSink=EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1482
		iDataPathCompletedErrorCode=KErrNone;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1483
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1484
		SetPositionL( iStartPosition ) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1485
		iReferenceAudioSamplesPlayed = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1486
		iReferenceAudioSamplesRecorded = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1487
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1488
		//complete a request on iStatus to invoke play code
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1489
		iDataSource->SourcePlayL(); //propagate state change to source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1490
		if (!(savedPauseCalled && (iTransferState==EWaitSink || iTransferState==EInitializeSink)))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1491
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1492
			iDataSink->SinkPlayL(); //propogate state change to sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1493
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1494
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1495
		if (iDataSink->DataSinkType() == KUidMmfAudioOutput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1496
			iState = EPlaying;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1497
		else if(iDataSource->DataSourceType() == KUidMmfAudioInput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1498
			iState = ERecording;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1499
		else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1500
			iState = EConverting;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1501
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1502
		//need to re-initialize any buffer(s) that we only own references to
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1503
		ChangeDataPathTransferState(EInitializeSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1504
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1505
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1506
	RDebug::Print(_L("DP::Play - DONE\n"));		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1507
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1508
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1509
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1510
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1511
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1512
Pauses playing.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1513
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1514
Sends KMMFErrorCategoryDataPathGeneralError to the client if an error occurs.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1515
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1516
EXPORT_C void CMMFDataPath::Pause()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1517
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1518
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1519
	RDebug::Print(_L("DP::Pause, on src buff %d  sink buf %d   (this 0x%x)\n"), iCurrentSourceFrameNumber, iCurrentSinkFrameNumber,this);			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1520
	RDebug::Print(_L("DP::Pause current state=%d  tick-%d    (this 0x%x)\n"),iTransferState, User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1521
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1522
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1523
	TRAPD(err, DoPauseL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1524
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1525
	if (err)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1526
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1527
		DoSendEventToClient(KMMFErrorCategoryDataPathGeneralError, err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1528
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1529
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1530
	RDebug::Print(_L("DP::Pause - DONE tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1531
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1532
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1533
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1534
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1535
Stops playing.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1536
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1537
Resets datapath position - currently does not clean up buffers. Sends KMMFErrorCategoryDataPathGeneralError 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1538
to the client if an error occurs.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1539
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1540
EXPORT_C void CMMFDataPath::Stop()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1541
	{ 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1542
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1543
	RDebug::Print(_L("DP::Stop current state=%d  tick-%d   (this 0x%x)\n"), iTransferState, User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1544
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1545
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1546
	if ((iDataPathCreated)  && (iState != EStopped))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1547
		{ 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1548
		TRAPD(err, DoStopL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1549
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1550
		if (err)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1551
			DoSendEventToClient(KMMFErrorCategoryDataPathGeneralError, err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1552
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1553
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1554
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1555
Forces and end of data state on the datapath
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1556
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1557
EXPORT_C void CMMFDataPath::EndOfData()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1558
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1559
	TRAPD(err, DoEndOfDataL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1560
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1561
	if (err)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1562
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1563
		DoSendEventToClient(KMMFErrorCategoryDataPathGeneralError, err);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1564
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1565
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1566
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1567
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1568
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1569
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1570
TInt CMMFDataPath::AudioSamplesPlayed() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1571
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1572
	if (iDataSink->DataSinkType() != KUidMmfAudioOutput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1573
		return 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1574
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1575
	CMMFAudioOutput* audioOutput = STATIC_CAST(CMMFAudioOutput*,iDataSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1576
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1577
	TInt samples = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1578
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1579
	if(iState == EPlaying)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1580
		samples = audioOutput->SoundDevice().SamplesPlayed();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1581
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1582
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1583
	RDebug::Print(_L("DP::AudioSamplesPlayed = %d\n"),samples);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1584
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1585
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1586
	return samples;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1587
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1588
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1589
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1590
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1591
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1592
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1593
TInt CMMFDataPath::AudioSamplesRecorded() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1594
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1595
	if (iDataSource->DataSourceType() != KUidMmfAudioInput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1596
		return 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1597
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1598
	CMMFAudioInput* audioInput = STATIC_CAST(CMMFAudioInput*,iDataSource);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1599
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1600
	TInt samples = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1601
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1602
	if(iState == ERecording)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1603
		samples = audioInput->SoundDevice().SamplesRecorded();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1604
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1605
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1606
	RDebug::Print(_L("DP::AudioSamplesRecorded = %d\n"),samples);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1607
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1608
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1609
	return samples;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1610
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1611
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1612
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1613
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1614
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1615
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1616
TTimeIntervalMicroSeconds CMMFDataPath::CalculateAudioOutputPosition() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1617
    {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1618
	//This operation can only be carried out on an Audio Output
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1619
	__ASSERT_ALWAYS(iDataSink->DataSinkType() == KUidMmfAudioOutput, Panic(EMMFDataPathPanicProgrammingError,__LINE__));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1620
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1621
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1622
	//If we are not playing, simply return where we will play from
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1623
	if(iState != EPlaying || iCurrentSinkFrameNumber == 0)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1624
		return iStartPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1625
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1626
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1627
	RDebug::Print(_L("DP::CalculateAudioOutputDuration from %d\n"),iReferenceAudioSamplesPlayed);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1628
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1629
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1630
	TReal samplesPlayed = AudioSamplesPlayed() - iReferenceAudioSamplesPlayed;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1631
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1632
	CMMFAudioOutput* audioOutput = STATIC_CAST(CMMFAudioOutput*,iDataSink);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1633
	CMMFDevSound& devSound = audioOutput->SoundDevice();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1634
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1635
	TMMFCapabilities devSoundConfig = devSound.Config();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1636
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1637
	TInt samplingFreq = StreamUtils::SampleRateAsValue(devSoundConfig);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1638
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1639
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1640
	RDebug::Print(_L("samplingFreq %d\n"),samplingFreq);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1641
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1642
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1643
	TReal timePlayedSeconds = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1644
	if(samplesPlayed)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1645
		timePlayedSeconds = samplesPlayed/samplingFreq;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1646
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1647
	TInt64 timePlayed(I64DOUBLECAST(timePlayedSeconds * 1000000));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1648
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1649
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1650
	RDebug::Print(_L("timePlayed %d\n"), I64LOW(timePlayed));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1651
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1652
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1653
	return TTimeIntervalMicroSeconds(timePlayed + iStartPosition.Int64());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1654
    }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1655
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1656
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1657
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1658
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1659
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1660
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1661
TTimeIntervalMicroSeconds CMMFDataPath::CalculateAudioInputPosition() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1662
    {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1663
	//This operation can only be carried out on an Audio Input
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1664
	__ASSERT_ALWAYS(iDataSource->DataSourceType() == KUidMmfAudioInput, Panic(EMMFDataPathPanicProgrammingError,__LINE__));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1665
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1666
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1667
	//If we are not playing, simply return where we will play from
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1668
	if(iState != ERecording)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1669
		return iStartPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1670
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1671
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1672
	RDebug::Print(_L("DP::CalculateAudioInputPosition from %d\n"),iReferenceAudioSamplesRecorded);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1673
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1674
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1675
	TReal samplesRecorded = AudioSamplesRecorded() - iReferenceAudioSamplesRecorded;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1676
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1677
	CMMFAudioInput* audioInput = STATIC_CAST(CMMFAudioInput*,iDataSource);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1678
	CMMFDevSound& devSound = audioInput->SoundDevice();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1679
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1680
	TMMFCapabilities devSoundConfig = devSound.Config();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1681
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1682
	TInt samplingFreq = StreamUtils::SampleRateAsValue(devSoundConfig);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1683
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1684
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1685
	RDebug::Print(_L("samplingFreq %d\n"),samplingFreq);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1686
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1687
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1688
	TReal timeRecordedSeconds = 0;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1689
	if(samplesRecorded)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1690
		timeRecordedSeconds = samplesRecorded/samplingFreq;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1691
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1692
	TInt64 timeRecorded(I64DOUBLECAST(timeRecordedSeconds * 1000000));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1693
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1694
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1695
	RDebug::Print(_L("timeRecorded %d\n"), I64LOW(timeRecorded));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1696
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1697
	return TTimeIntervalMicroSeconds(timeRecorded);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1698
    }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1699
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1700
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1701
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1702
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1703
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1704
TTimeIntervalMicroSeconds CMMFDataPath::OutputPosition() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1705
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1706
	TTimeIntervalMicroSeconds interval;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1707
	TTimeIntervalMicroSeconds position;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1708
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1709
    if (iDataSink->DataSinkType() == KUidMmfAudioOutput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1710
        {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1711
		position = CalculateAudioOutputPosition();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1712
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1713
		RDebug::Print(_L("DP::OutputPosition from audio output= %d\n"),I64INT(position.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1714
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1715
        }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1716
	else if (iDataSink->DataSinkType() == KUidMmfFormatEncode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1717
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1718
		//note Encode format position takes priority if both source & sink are formats?
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1719
        // try to get the position directly from the format. If that fails, work it out here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1720
        TRAPD(error, position = ((CMMFFormatEncode*)iDataSink)->PositionL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1721
        if (error)//getting the position from the format didn't work so calculate it here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1722
            {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1723
		    interval = ((CMMFFormatEncode*)iDataSink)->FrameTimeInterval(iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1724
			TInt64 position64 = interval.Int64() * iCurrentSinkFrameNumber;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1725
			position = position64;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1726
            }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1727
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1728
		TTimeIntervalMicroSeconds duration = CONST_CAST(CMMFDataPath*,this)->Duration(); //need this to check position doesn't exceed duration
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1729
		if (position > duration)//this can happen on last buffer 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1730
			position = duration;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1731
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1732
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1733
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1734
		RDebug::Print(_L("DP::OutputPosition  from format= %d\n"),I64INT(position.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1735
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1736
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1737
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1738
		{//can only read output position if sink is a format or an audio output
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1739
		return TTimeIntervalMicroSeconds(0);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1740
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1741
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1742
	return position;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1743
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1744
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1745
TTimeIntervalMicroSeconds CMMFDataPath::InputPosition() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1746
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1747
	TTimeIntervalMicroSeconds interval;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1748
	TTimeIntervalMicroSeconds position;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1749
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1750
    if (iDataSource->DataSourceType() == KUidMmfAudioInput)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1751
        {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1752
		position = CalculateAudioInputPosition();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1753
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1754
		RDebug::Print(_L("DP::InputPosition from audio input= %d\n"),I64INT(position.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1755
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1756
        }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1757
	else if (iDataSource->DataSourceType() == KUidMmfFormatDecode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1758
		{//note Decode format position takes priority if both source & sink are formats?
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1759
        // try to get the position directly from the format. If that fails, work it out here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1760
        TRAPD(error, position = ((CMMFFormatDecode*)iDataSource)->PositionL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1761
        if (error)//getting the position from the format didn't work so calculate it here
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1762
            {
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1763
		    interval = ((CMMFFormatDecode*)iDataSource)->FrameTimeInterval(iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1764
		    TInt64 position64 = interval.Int64() * iCurrentSourceFrameNumber;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1765
		    position = position64;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1766
            }
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1767
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1768
		TTimeIntervalMicroSeconds duration = CONST_CAST(CMMFDataPath*,this)->Duration(); //need this to check position doesn't exceed duration
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1769
		if (position > duration)//this can happen on last buffer 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1770
			position = duration;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1771
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1772
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1773
		RDebug::Print(_L("DP::InputPosition from format = %d\n"),I64INT(position.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1774
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1775
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1776
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1777
		{//can only read input position if source is a format or an audio input
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1778
		return TTimeIntervalMicroSeconds(0);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1779
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1780
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1781
	return position;	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1782
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1783
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1784
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1785
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1786
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1787
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1788
Gets the data path position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1789
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1790
@return The data path position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1791
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1792
EXPORT_C  TTimeIntervalMicroSeconds CMMFDataPath::Position() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1793
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1794
	if ((iState == ERecording) || (iState == EConverting))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1795
		return InputPosition();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1796
	else if(iState == EPlaying)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1797
		return OutputPosition();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1798
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1799
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1800
		return iStartPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1801
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1802
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1803
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1804
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1805
Sets the data path position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1806
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1807
@param  aPosition
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1808
		The data path position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1809
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1810
EXPORT_C void CMMFDataPath::SetPositionL(const TTimeIntervalMicroSeconds& aPosition)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1811
	{//need to map to source position to frame position 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1812
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1813
	RDebug::Print(_L("DP::SetPositionL = %d  ticks-%d   (this 0x%x)\n"),I64INT(aPosition.Int64()), User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1814
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1815
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1816
	if (iState == EStopped)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1817
		User::Leave(KErrNotReady); //can only set position if primed
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1818
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1819
	//As this will affect the position, we need to know how many bytes were 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1820
	//played when position was updated. Future Position() requests will
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1821
	//then use this refernce to determine the current position.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1822
	iReferenceAudioSamplesPlayed = AudioSamplesPlayed();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1823
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1824
	// Force the new position to be inside the play window (also within the file duration)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1825
	if ( aPosition < iPlayWindowStartPosition )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1826
		iStartPosition = iPlayWindowStartPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1827
	else if ( aPosition > iPlayWindowEndPosition )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1828
		iStartPosition = iPlayWindowEndPosition; //clearly this will cause nothing to be played
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1829
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1830
		iStartPosition = aPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1831
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1832
	TTimeIntervalMicroSeconds interval;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1833
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1834
	//can only set the position on an MDataSource that is a format object
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1835
	//Note: position defaults to source if both source & sink are clips
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1836
	if (iDataSource->DataSourceType() == KUidMmfFormatDecode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1837
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1838
		//position is not beyond the end of file
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1839
		interval = ((CMMFFormatDecode*)iDataSource)->FrameTimeInterval(iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1840
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1841
		// for some reason this code won't compile without these intermediate steps
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1842
		TInt64 position = iStartPosition.Int64();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1843
		TInt64 interval64 = interval.Int64();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1844
		if (interval64 == 0)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1845
			User::Leave(KErrDivideByZero); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1846
		TInt64 datapos64 = position/interval64; 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1847
		iCurrentSourceFrameNumber = I64LOW(datapos64);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1848
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1849
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1850
        // Try to set the position directly on the format
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1851
        TRAP_IGNORE(((CMMFFormatDecode*)iDataSource)->SetPositionL(iStartPosition));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1852
        //NB: don't worry about error, since we'll reposition anyway when we get the next buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1853
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1854
	else if (iDataSink->DataSinkType() == KUidMmfFormatEncode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1855
		{			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1856
		//position is not beyond the end of file
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1857
		interval = ((CMMFFormatEncode*)iDataSink)->FrameTimeInterval(iMediaId);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1858
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1859
		//convert to TUint - for some reason it won't compile without these intermediate steps
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1860
		TInt64 position = iStartPosition.Int64();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1861
		TInt64 interval64 = interval.Int64();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1862
		if (interval64 == 0)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1863
			User::Leave(KErrDivideByZero); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1864
		TInt64 datapos64 = position/interval64; 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1865
		iCurrentSinkFrameNumber = I64LOW(datapos64);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1866
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1867
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1868
        // Try to set the position directly on the format
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1869
        TRAP_IGNORE(((CMMFFormatEncode*)iDataSink)->SetPositionL(iStartPosition));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1870
        //NB: don't worry about error, since we'll reposition anyway when we get the next buffer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1871
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1872
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1873
		{//can only set position if source or sink is a format
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1874
		//If both source and sink are formats position is relative to the source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1875
		User::Leave(KErrNotSupported); //can't set position if neither source nor sink are clips
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1876
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1877
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1878
	if(iCodec) //we have a real codec, must reset it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1879
		iCodec->ResetL(); // Need to preserve sync when resuming play
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1880
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1881
	// Once we've sent the last buffer to the sink it's too late to start
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1882
	// changing the state since we may get a RunError(KErrUnderflow) at any time.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1883
	// Once this happens, the sound driver may have unloaded etc..and recovery
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1884
	// would be complicated.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1885
	if (iAllDataSentToSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1886
		return;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1887
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1888
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1889
	RDebug::Print(_L("DP::SetPosition - Done iCurrentSourceFrameNumber=%d  iStartPosition=%d  ticks-%d   (this 0x%x)\n"),iCurrentSourceFrameNumber, I64INT(iStartPosition.Int64()), User::TickCount(),this);	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1890
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1891
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1892
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1893
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1894
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1895
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1896
/** 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1897
Sets the play window absolutely (i.e. the parameters are relative to the start of the entire clip).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1898
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1899
@param  aStart
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1900
        The offset from the start of the Clip
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1901
@param  aEnd
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1902
        The offset from the end of the clip (if this is less than aStart, then the two will be inverted).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1903
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1904
EXPORT_C void CMMFDataPath::SetPlayWindowL( const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd ) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1905
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1906
	// Clear the existing Play window
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1907
	ClearPlayWindowL() ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1908
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1909
	// Check that the parameters are legitimate.  0 <= startpos < endpos <= duration & update member variables
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1910
	TTimeIntervalMicroSeconds duration = Duration();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1911
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1912
	if ( aStart < TTimeIntervalMicroSeconds(0) ) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1913
		iPlayWindowStartPosition = TTimeIntervalMicroSeconds(0);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1914
	else if ( aStart > duration )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1915
		iPlayWindowStartPosition = duration;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1916
	else iPlayWindowStartPosition = aStart;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1917
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1918
	if ( aEnd < TTimeIntervalMicroSeconds(0) )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1919
		iPlayWindowEndPosition = TTimeIntervalMicroSeconds(0);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1920
	else if ( aEnd > duration )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1921
		iPlayWindowEndPosition = duration;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1922
	else iPlayWindowEndPosition = aEnd;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1923
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1924
	// ensure that the current position is inside the new play window
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1925
	if ( iPlayWindowEndPosition != TTimeIntervalMicroSeconds(0) )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1926
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1927
		TTimeIntervalMicroSeconds currentPosition = Position() ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1928
		if ( currentPosition < iPlayWindowStartPosition )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1929
			SetPositionL( iPlayWindowStartPosition ) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1930
		else if ( currentPosition > iPlayWindowEndPosition )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1931
			SetPositionL( iPlayWindowEndPosition ) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1932
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1933
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1934
		ClearPlayWindowL() ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1935
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1936
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1937
	RDebug::Print(_L("DP::SetPlayWindowL iPlayWindowStartPosition=%d iPlayWindowEndPosition=%d\n"),I64INT(iPlayWindowStartPosition.Int64()),I64INT(iPlayWindowEndPosition.Int64()));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1938
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1939
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1940
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1941
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1942
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1943
Sets the play window to the full length of clip.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1944
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1945
EXPORT_C void CMMFDataPath::ClearPlayWindowL() 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1946
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1947
	iPlayWindowStartPosition = TTimeIntervalMicroSeconds(0) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1948
	iPlayWindowEndPosition = Duration();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1949
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1950
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1951
	if(iState == EStopped)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1952
		iStartPosition = iPlayWindowStartPosition;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1953
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1954
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1955
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1956
Returns the current data path state.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1957
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1958
EXPORT_C  TInt CMMFDataPath::State()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1959
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1960
	return iState ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1961
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1962
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1963
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1964
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1965
Uses the AO mechanism to drive state changes between sources and sinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1966
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1967
RunL() moves and assigns buffers between its attached MDataSource/MDataSinks.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1968
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1969
void CMMFDataPath::ChangeDataPathTransferState(TTransferState aNewDataPathTransferState)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1970
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1971
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1972
		switch (aNewDataPathTransferState)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1973
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1974
		case EWaitSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1975
	RDebug::Print(_L("Next State EWaitSink ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1976
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1977
		case EWaitSource:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1978
	RDebug::Print(_L("Next State EWaitSource ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1979
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1980
		case EInitializeSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1981
	RDebug::Print(_L("Next State EInitializeSink ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1982
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1983
		case EInitializeSource:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1984
	RDebug::Print(_L("Next State EInitializeSource ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1985
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1986
		case ENeedSourceData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1987
	RDebug::Print(_L("Next State ENeedSourceData ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1988
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1989
		case ENeedSinkData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1990
	RDebug::Print(_L("Next State ENeedSinkData ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1991
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1992
		case ENeedToMatchSourceToSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1993
	RDebug::Print(_L("Next State ENeedToMatchSourceToSink ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1994
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1995
		case ESendDataToSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1996
	RDebug::Print(_L("Next State ESendDataToSink ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1997
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1998
		case EEndOfData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  1999
	RDebug::Print(_L("Next State EEndOfData ticks-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2000
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2001
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2002
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2003
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2004
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2005
	TRequestStatus* stat = &iStatus;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2006
	//change state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2007
	iTransferState = aNewDataPathTransferState;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2008
	if ((iTransferState != EWaitSink) && (iTransferState != EWaitSource) && 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2009
		(iState == EPlaying || iState == ERecording || iState == EConverting || (iState == EPrimed && iPauseCalled)))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2010
		{//can go ahead with transfer
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2011
		if (!IsActive())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2012
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2013
			User::RequestComplete(stat, KErrNone);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2014
			SetActive();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2015
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2016
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2017
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2018
	else
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2019
		RDebug::Print(_L("Datapath is no longer active, not going to new state (this 0x%x)\n"),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2020
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2021
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2022
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2023
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2024
Runs the clip depending on the current data path and transfer state.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2025
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2026
For example, fills the sink buffer if TDataPathState is EPlaying and TTransferState is ENeedSinkData.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2027
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2028
EXPORT_C void CMMFDataPath::RunL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2029
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2030
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2031
	RDebug::Print(_L("DP::RunL tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2032
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2033
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2034
	switch (iState)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2035
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2036
	case EStopped:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2037
		break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2038
	case EPrimed:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2039
		//paused with stored position
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2040
		break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2041
	case EPlaying:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2042
	case ERecording:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2043
	case EConverting:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2044
		switch (iTransferState)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2045
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2046
		case EWaitSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2047
		case EWaitSource:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2048
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2049
		case EInitializeSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2050
			InitializeSinkL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2051
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2052
		case EInitializeSource:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2053
			InitializeSourceL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2054
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2055
		case ENeedSourceData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2056
			FillSourceBufferL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2057
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2058
		case ENeedSinkData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2059
			FillSinkBufferL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2060
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2061
		case ENeedToMatchSourceToSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2062
			FillSinkBufferL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2063
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2064
		case ESendDataToSink:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2065
			EmptySinkBufferL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2066
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2067
		case EEndOfData:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2068
			EndOfData();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2069
			break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2070
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2071
		break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2072
	default:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2073
		break;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2074
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2075
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2076
	RDebug::Print(_L("DP::RunL DONE\n"));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2077
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2078
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2079
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2080
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2081
Cancels the clip.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2082
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2083
The default implementation is empty.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2084
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2085
EXPORT_C void CMMFDataPath::DoCancel()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2086
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2087
	//don't need to do anything as we don't have any async requests to other objects
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2088
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2089
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2090
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2091
Handles errors coming from attached sources and passes them to the clients.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2092
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2093
@param  aError
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2094
        Standard error code (KErrNone = No Error).
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2095
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2096
@return The event code returned to the data path. KErrNone if end of file is encountered.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2097
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2098
EXPORT_C TInt CMMFDataPath::RunError(TInt aError)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2099
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2100
	return DoSendEventToClient(KMMFErrorCategoryDataPathGeneralError, aError);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2101
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2102
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2103
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2104
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2105
Returns the duration of the clip.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2106
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2107
@return The length of clip in TTimeIntervalMicroSeconds.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2108
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2109
TTimeIntervalMicroSeconds CMMFDataPath::Duration() const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2110
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2111
	TTimeIntervalMicroSeconds duration(0);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2112
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2113
	if ( iDataSource &&  ( iDataSource->DataSourceType() == KUidMmfFormatDecode ) )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2114
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2115
		//this updated version of datapath caches the duration of the
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2116
		//source clip for efficiency - since this meathod is const
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2117
		//we need to cast away the constness to set iCachedSourceDuration
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2118
		CMMFDataPath* thisNonConst = const_cast<CMMFDataPath*>(this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2119
		duration = STATIC_CAST(CMMFFormatDecode*, thisNonConst->iDataSource )->Duration( iMediaId ) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2120
		thisNonConst->iCachedSourceDuration = duration;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2121
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2122
	else if ( iDataSink && ( iDataSink->DataSinkType() == KUidMmfFormatEncode ) )
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2123
		duration = STATIC_CAST(CMMFFormatEncode*, iDataSink )->Duration( iMediaId ) ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2124
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2125
	return duration ;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2126
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2127
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2128
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2129
This is a virtual function datapath (or derivations off) that can be implemented but may be left blank for default behaviour.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2130
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2131
Additional Stop() method specific to this datapath.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2132
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2133
void CMMFDataPath::DoStopL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2134
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2135
	// Note that the datapath needs to be paused first
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2136
	// before it can be stopped - this is important for audio play
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2137
	// for instance to effect an immediate stop rather than playing out
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2138
	// the current buffer.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2139
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2140
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2141
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2142
	// Stop data source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2143
	iDataSource->SourceStopL();					// propagate state change to source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2144
	iDataSink->SinkStopL();						// propagate change down to sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2145
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2146
	iSinkBufferWithSink = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2147
	iSourceBufferWithSource = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2148
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2149
	//Contains the completion code if the datapath completes as a result of an error
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2150
	iDataPathCompletedErrorCode = KErrNone;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2151
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2152
	ResetRefBuffers();							// buffer references may not be valid any more
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2153
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2154
	SetPositionL(iPlayWindowStartPosition);		// reset position
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2155
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2156
	iState = EStopped;							// stop succeeded, set state to stopped
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2157
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2158
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2159
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2160
This is a virtual function datapath (or derivations off) that can be implemented but may be left blank for default behaviour.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2161
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2162
Additional Pause method specific to this datapath.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2163
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2164
The DataPath implements pause by recording the current position and stopping the source and sink.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2165
When Play is called the DataPath uses the stored position as the starting point and resumes
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2166
playing. The reason for this (rather than using the PauseL() API on sources and sinks) is that
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2167
some implementations do not support a suitable pause, therefore the DataPath is implemented to
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2168
support the lowest common denominator.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2169
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2170
Note:
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2171
A suitable pause implementation will retain any buffers in use. There will be no
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2172
need to call PrimeL() prior to PlayL().
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2173
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2174
void CMMFDataPath::DoPauseL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2175
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2176
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2177
	RDebug::Print(_L("DP::DoPauseL tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2178
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2179
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2180
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2181
	if ((iDataPathCreated) && ((iState == EPlaying) || (iState == EConverting)))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2182
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2183
		// try to pause source and sink
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2184
		iDataSource->SourcePauseL();		// propagate state change to source
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2185
		SetPositionL(Position());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2186
		iDataSink->SinkStopL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2187
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2188
		iPauseCalled = ETrue;				// indicate pause is called
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2189
		
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2190
		iState = EPrimed;					// go back to primed state (we're not playing)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2191
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2192
		iSinkBufferWithSink = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2193
		iSourceBufferWithSource = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2194
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2195
		ResetRefBuffers();					// buffer references may not be valid any more
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2196
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2197
		Cancel(); //Stop the state machine
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2198
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2199
	else if(iState == ERecording)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2200
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2201
		iPauseCalled = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2202
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2203
		RDebug::Print(_L("DP::DoPauseL Recording, pause datasource\n"));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2204
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2205
		iDataSource->SourcePauseL();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2206
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2207
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2208
	RDebug::Print(_L("DP::DoPauseL - Done iReferenceAudioSamplesPlayed = %d\n"),iReferenceAudioSamplesPlayed);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2209
	RDebug::Print(_L("DP::DoPauseL - Done restart at %d tick-%d   (this 0x%x)\n"),I64INT(iStartPosition.Int64()), User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2210
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2211
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2212
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2213
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2214
This is a virtual function datapath (or derivations off) that can be implemented or may be left blank for default behaviour.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2215
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2216
Additional Pause method specific to this datapath.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2217
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2218
void CMMFDataPath::DoEndOfDataL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2219
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2220
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2221
	RDebug::Print(_L("DP::DoEndOfDataL tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2222
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2223
	SetPositionL(iPlayWindowStartPosition);	// reset position
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2224
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2225
	ASSERT(iCompleteCallback);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2226
	iCompleteCallback->SignalDataPathComplete(iDataPathCompletedErrorCode);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2227
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2228
	ResetRefBuffers();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2229
	iState = EStopped;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2230
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2231
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2232
	RDebug::Print(_L("DP::DoEndOfDataL - Done  tick-%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2233
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2234
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2235
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2236
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2237
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2238
Passes error handling and general messages up to clients.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2239
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2240
@param  aEventType
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2241
        Category code for the event. Category codes can be used as unique identifers.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2242
@param  aErrorCode
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2243
        Standard error code.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2244
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2245
@return The event code sent to client.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2246
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2247
//error handling
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2248
EXPORT_C TInt CMMFDataPath::DoSendEventToClient(TUid aEventType, TInt aErrorCode)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2249
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2250
	TMMFEvent event(aEventType, aErrorCode);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2251
	return iEventHandler.SendEventToClient(event);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2252
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2253
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2254
/**
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2255
Passes error handling and general messages to clients.
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2256
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2257
@param  aEvent
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2258
        TMMFEvent supplied by callee (typically DoSendEventToClient)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2259
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2260
@return The Event Message sent to the datapath event handler
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2261
*/
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2262
EXPORT_C TInt CMMFDataPath::SendEventToClient(const TMMFEvent& aEvent)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2263
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2264
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2265
	RDebug::Print(_L("CMMFDataPath::SendEventToClient CODE = %d  ticks=%d   (this 0x%x)\n"),aEvent.iErrorCode,User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2266
	RDebug::Print(_L("CMMFDataPath::SendEventToClient iEventType = %d  == %d\n"),aEvent.iEventType, KMMFEventCategoryPlaybackComplete);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2267
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2268
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2269
		//If we have sent all the data to the sink, it is legal for it to send KErrUnderFlow
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2270
		//to us and we can go through a clean shutdown, otherwise we pass the error to the 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2271
		//controller and it is responsible for determining what to do
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2272
		if(iAllDataSentToSink &&
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2273
			(aEvent.iEventType == KMMFEventCategoryPlaybackComplete) &&
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2274
			(aEvent.iErrorCode == KErrUnderflow))
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2275
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2276
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2277
			RDebug::Print(_L("CMMFDataPath::SendEventToClient Clean complete\n"));
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2278
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2279
			//sink may not return the final buffer once it has finished with it
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2280
			//force ourselves into the EndOfData state
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2281
			if(iTransferState != EEndOfData)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2282
				{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2283
				iDataPathCompletedErrorCode = KErrNone;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2284
				TRAP_IGNORE(DoEndOfDataL());
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2285
				}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2286
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2287
			iCompleteCallback->SignalSinkComplete(KErrNone);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2288
			return KErrNone;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2289
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2290
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2291
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2292
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2293
	return iEventHandler.SendEventToClient(aEvent);	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2294
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2295
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2296
CMMFDataPath::CCompleteCallback::CCompleteCallback(CMMFDataPath& aDataPath, TBool aWaitForSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2297
	: CActive(EPriorityStandard), 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2298
	iDataPath(aDataPath),
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2299
	iWaitForSink(aWaitForSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2300
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2301
	CActiveScheduler::Add(this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2302
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2303
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2304
CMMFDataPath::CCompleteCallback::~CCompleteCallback()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2305
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2306
	Cancel();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2307
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2308
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2309
void CMMFDataPath::CCompleteCallback::SignalDataPathComplete(TInt aDataPathError)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2310
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2311
	iDataPathComplete = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2312
	iDataPathError = aDataPathError;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2313
	if (!IsActive()) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2314
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2315
		// Signal ourselves to run with the given completion code
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2316
		TRequestStatus* status = &ActiveStatus();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2317
		User::RequestComplete(status, KErrNone);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2318
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2319
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2320
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2321
void CMMFDataPath::CCompleteCallback::SignalSinkComplete(TInt aSinkError)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2322
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2323
	iSinkComplete = ETrue;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2324
	iSinkError = aSinkError;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2325
	if (!IsActive()) 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2326
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2327
		// Signal ourselves to run with the given completion code
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2328
		TRequestStatus* status = &ActiveStatus();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2329
		User::RequestComplete(status, KErrNone);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2330
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2331
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2332
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2333
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2334
TRequestStatus& CMMFDataPath::CCompleteCallback::ActiveStatus()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2335
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2336
	SetActive();
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2337
	return iStatus;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2338
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2339
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2340
void CMMFDataPath::CCompleteCallback::DoCancel()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2341
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2342
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2343
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2344
void CMMFDataPath::CCompleteCallback::RunL()
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2345
	{			
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2346
	if (iWaitForSink)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2347
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2348
		if (iDataPathComplete && iSinkComplete)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2349
			{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2350
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2351
			RDebug::Print(_L("CMMFDataPath::CCompleteCallback::RunL STOPPING src & sink ticks=%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2352
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2353
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2354
			TRAP_IGNORE(iDataPath.DoStopL())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2355
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2356
			iDataPathComplete = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2357
			iSinkComplete = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2358
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2359
			// if we have to wait for the sink to complete, always use the sink error
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2360
			iDataPath.DoSendEventToClient(KMMFEventCategoryPlaybackComplete, iSinkError);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2361
			}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2362
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2363
	else if (iDataPathComplete)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2364
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2365
#ifdef _DP_DEBUG
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2366
		RDebug::Print(_L("CMMFDataPath::CCompleteCallback::RunL STOPPING src & sink ticks=%d   (this 0x%x)\n"),User::TickCount(),this);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2367
#endif
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2368
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2369
		TRAP_IGNORE(iDataPath.DoStopL())
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2370
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2371
		iDataPathComplete = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2372
		iSinkComplete = EFalse;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2373
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2374
		iDataPath.DoSendEventToClient(KMMFEventCategoryPlaybackComplete, iDataPathError);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2375
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2376
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2377
	
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2378
EXPORT_C TInt CMMFDataPath::SetBlockLength(TUint aBlockLength)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2379
	{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2380
	MMMFDevSoundCustomInterfaceFileBlockLength* fileBlockLengthCI = NULL;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2381
	TInt err = KErrNotSupported;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2382
	if (iCodec)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2383
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2384
		err = iCodec->ExtensionInterface(KUidCustomInterfaceDevSoundFileBlockLength.iUid, (TAny*&)fileBlockLengthCI); 
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2385
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2386
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2387
	if (err == KErrNone)
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2388
		{
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2389
		fileBlockLengthCI->SetFileBlockLength(aBlockLength);
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2390
		}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2391
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2392
	return err;
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2393
	}
b8ed18f6c07b 2010wk40
hgs
parents:
diff changeset
  2394