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