1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmfdes.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,566 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +
1.20 +#include <f32file.h>
1.21 +#include <e32std.h>
1.22 +#include <mmf/server/mmfdes.h>
1.23 +#include <mmf/server/mmfdatabuffer.h>
1.24 +#include <mmf/common/mmfpaniccodes.h>
1.25 +
1.26 +void Panic(TMMFDescriptorPanicCode aPanicCode)
1.27 + {
1.28 + _LIT(KMMFDescriptorPanicCategory, "MMFDescriptor");
1.29 + User::Panic(KMMFDescriptorPanicCategory, aPanicCode);
1.30 + }
1.31 +
1.32 +/**
1.33 +Protected constructor.
1.34 +
1.35 +Sets the offset to zero.
1.36 +*/
1.37 +CMMFDescriptor::CMMFDescriptor( ) : CMMFClip( KUidMmfDescriptorSource, KUidMmfDescriptorSink )
1.38 + {
1.39 + }
1.40 +
1.41 +/**
1.42 +Destructor.
1.43 +
1.44 +The default implementation closes the descriptor thread.
1.45 +*/
1.46 +CMMFDescriptor::~CMMFDescriptor()
1.47 + {
1.48 + iDesThread.Close() ;
1.49 + }
1.50 +
1.51 +/**
1.52 +Constructs a CMMFDescriptor MDataSource.
1.53 +
1.54 +@return A pointer to a new CMMFDescriptor.
1.55 +*/
1.56 +MDataSource* CMMFDescriptor::NewSourceL( )
1.57 + {
1.58 + CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
1.59 + return STATIC_CAST( MDataSource*, self ) ;
1.60 + }
1.61 +
1.62 +/**
1.63 +Constructs a CMMFDescriptor MDataSink.
1.64 +
1.65 +@return A pointer to a new CMMFDescriptor.
1.66 +*/
1.67 +MDataSink* CMMFDescriptor::NewSinkL( )
1.68 + {
1.69 + CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
1.70 + return STATIC_CAST( MDataSink*, self ) ;
1.71 + }
1.72 +
1.73 +/**
1.74 +Performs source construction dependant on the source construction
1.75 +initialisation data aInitData.
1.76 +
1.77 +@param aInitData
1.78 + The TPckgC<TMMFDescriptorParams> descriptor package containing the descriptor and the thread
1.79 + ID for the descriptor.
1.80 +*/
1.81 +void CMMFDescriptor::ConstructSourceL( const TDesC8& aInitData )
1.82 + {
1.83 + ConstructL( aInitData ) ;
1.84 + }
1.85 +
1.86 +
1.87 +/***
1.88 +Sets how much of the underlying descriptor will be used, up to the underlying descriptor's maximum
1.89 +length.
1.90 +
1.91 +@param aSize
1.92 + The size of the descriptor.
1.93 +
1.94 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.95 + another of the system-wide error codes.
1.96 +*/
1.97 +TInt CMMFDescriptor::SetSize( TInt aSize )
1.98 + {
1.99 + //[ precondition aSize >= 0
1.100 + // precondition sSize < MaxSize()
1.101 + // iDes is not null]
1.102 + if(!iDes )
1.103 + return KErrNotReady;
1.104 +
1.105 + if( aSize > MaxLength() )
1.106 + return KErrOverflow;
1.107 +
1.108 + if( aSize < 0 )
1.109 + return KErrUnderflow;
1.110 +
1.111 + // [ actually do the work ]
1.112 + iDes->SetLength( aSize );
1.113 +
1.114 + //[ assert the post condition
1.115 + // aSize == Length()
1.116 + // descriptor is still ok]
1.117 + ASSERT( aSize == iDes->Length());
1.118 + ASSERT( iDes );
1.119 +
1.120 + return KErrNone;
1.121 + }
1.122 +
1.123 +
1.124 +/**
1.125 +Performs sink construction dependant on the sink construction initialisation data aInitData.
1.126 +
1.127 +@param aInitData
1.128 + The TPckgC<TMMFDescriptorParams> descriptor package containing
1.129 + the descriptor and the thread ID for the descriptor.
1.130 +*/
1.131 +void CMMFDescriptor::ConstructSinkL( const TDesC8& aInitData )
1.132 + {
1.133 + ConstructL( aInitData ) ;
1.134 + }
1.135 +
1.136 +void CMMFDescriptor::ConstructL( const TDesC8& aInitData )
1.137 + {
1.138 + TMMFDescriptorParams params;
1.139 + TPckgC<TMMFDescriptorParams> config(params);
1.140 + if (aInitData.Length() < config.Length())
1.141 + User::Leave(KErrGeneral);
1.142 + config.Set(aInitData);
1.143 + iDes = STATIC_CAST( TDes8*, config().iDes);
1.144 + User::LeaveIfError( iDesThread.Open( config().iDesThreadId ) );
1.145 + }
1.146 +
1.147 +
1.148 +/**
1.149 +Loads aBuffer from iDes.
1.150 +
1.151 +File read is asynchronous. CReadRequest is created to respond to completion.
1.152 +
1.153 +@param aBuffer
1.154 + The buffer to be filled from the descriptor.
1.155 +@param aConsumer
1.156 + The data sink consumer of the buffer.
1.157 +@param aMediaId
1.158 + Not used.
1.159 +*/
1.160 +void CMMFDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/ )
1.161 + {
1.162 + // Current position in Descriptor is iOffset.
1.163 +
1.164 + // Read from iDes in iDesThread into Des in aBuffer.
1.165 +
1.166 + // Assume that the amount to be read is the size of the buffer descriptor
1.167 + // Should check that there is sufficient data in the source buffer
1.168 + // If there is not enough to fill the target then copy what there is
1.169 + // How should the function deal with no data in the source buffer?
1.170 +
1.171 + // Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
1.172 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.173 + {
1.174 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.175 +
1.176 + //if request size is set, use it, else use max length of buffer
1.177 + TInt targetMaxLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
1.178 +
1.179 + //ensure RequestSize was within bounds
1.180 + if(targetMaxLength > bufferDes.MaxLength())
1.181 + targetMaxLength = bufferDes.MaxLength();
1.182 +
1.183 + TInt sourceLengthRemaining = iDes->Length() - iOffset;
1.184 + if ( ( sourceLengthRemaining - targetMaxLength ) > 0 )
1.185 + {
1.186 + bufferDes = iDes->Mid(iOffset,targetMaxLength);
1.187 + iOffset += targetMaxLength;
1.188 + }
1.189 + else if (sourceLengthRemaining > 0)
1.190 + {
1.191 + bufferDes = iDes->Mid(iOffset,sourceLengthRemaining);
1.192 + iOffset += sourceLengthRemaining;
1.193 + aBuffer->SetLastBuffer(ETrue);
1.194 + }
1.195 + else
1.196 + {
1.197 + bufferDes.SetLength(0);
1.198 + aBuffer->SetLastBuffer(ETrue);
1.199 + }
1.200 +
1.201 + aConsumer->BufferFilledL( aBuffer ) ;
1.202 + }
1.203 + else
1.204 + User::Leave(KErrNotSupported);
1.205 + }
1.206 +
1.207 +/**
1.208 +Empties aBuffer into iDes.
1.209 +
1.210 +@param aBuffer
1.211 + The buffer to be written to the descriptor.
1.212 +@param aSupplier
1.213 + The data source supplier of the buffer.
1.214 +@param aMediaId
1.215 + The Media ID.
1.216 +*/
1.217 +void CMMFDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
1.218 + {
1.219 + // Does the buffer type need to be checked?
1.220 +
1.221 + // Assume that the amount to be read is the size of the buffer descriptor
1.222 + // Should check that there is sufficient data in the source buffer
1.223 + // If there is not enough to fill the target then copy what there is
1.224 + // How should the function deal with no data in the source buffer?
1.225 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.226 + {
1.227 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.228 +
1.229 + TInt sourceLength = bufferDes.Length() ;
1.230 + TInt targetLength = iDes->MaxLength() - iDes->Length();
1.231 + if ( targetLength>0 )
1.232 + {
1.233 + if (sourceLength>targetLength)
1.234 + {
1.235 + sourceLength = targetLength;
1.236 + bufferDes.SetLength(targetLength);
1.237 + }
1.238 +
1.239 + iDes->Append(bufferDes) ;
1.240 + }
1.241 + else
1.242 + bufferDes.SetLength(0);
1.243 +
1.244 + aSupplier->BufferEmptiedL( aBuffer ) ;
1.245 + }
1.246 + else
1.247 + User::Leave(KErrNotSupported);
1.248 + }
1.249 +
1.250 +/**
1.251 +Loads aLength number of bytes into aBuffer from specified point in iDes.
1.252 +
1.253 +@param aLength
1.254 + The number of bytes to be read into buffer.
1.255 +@param aBuffer
1.256 + The buffer to be filled from the descriptor.
1.257 +@param aPosition
1.258 + The offset into the descriptor at which to start reading.
1.259 +@param aConsumer
1.260 + The data sink consumer of the buffer
1.261 +*/
1.262 +void CMMFDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
1.263 + {
1.264 + if (!aBuffer)
1.265 + User::Leave(KErrArgument);
1.266 +
1.267 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.268 + {
1.269 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.270 +
1.271 + if (aLength>bufferDes.MaxLength())
1.272 + User::Leave(KErrOverflow);
1.273 +
1.274 + if ((aLength<0) || (aPosition<0))
1.275 + User::Leave(KErrArgument);
1.276 +
1.277 + TInt sourceLength = iDes->Length() ;
1.278 +
1.279 + //ensure not trying to read more than is available
1.280 + if(aPosition + aLength > sourceLength)
1.281 + aLength = sourceLength - aPosition;
1.282 +
1.283 + if (aLength>0)
1.284 + {
1.285 + TPtrC8 srcPtr(iDes->Mid(aPosition,aLength));
1.286 + bufferDes.Copy(srcPtr.Ptr(),aLength);
1.287 + }
1.288 + else
1.289 + bufferDes.SetLength(0);
1.290 +
1.291 + //have we read all the available data
1.292 + if(aPosition + aLength >= sourceLength)
1.293 + aBuffer->SetLastBuffer(ETrue);
1.294 +
1.295 + if (aConsumer)
1.296 + aConsumer->BufferFilledL(aBuffer);
1.297 + }
1.298 + else
1.299 + User::Leave(KErrNotSupported);
1.300 + }
1.301 +
1.302 +/**
1.303 +Loads aBuffer from specified point in iDes
1.304 +
1.305 +@param aBuffer
1.306 + The buffer to be filled from the descriptor.
1.307 +@param aPosition
1.308 + The offset into the descriptor at which to start reading.
1.309 +@param aConsumer
1.310 + The data sink consumer of the buffer.
1.311 +*/
1.312 +void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
1.313 + {
1.314 + if (!aBuffer)
1.315 + User::Leave(KErrArgument);
1.316 +
1.317 + if (aPosition<0)
1.318 + User::Leave(KErrArgument);
1.319 +
1.320 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.321 + {
1.322 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.323 + //if request size is set, use it, else use max length of buffer
1.324 + TUint copyLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
1.325 +
1.326 + ReadBufferL(copyLength, aBuffer, aPosition, aConsumer);
1.327 + }
1.328 + else
1.329 + User::Leave(KErrNotSupported);
1.330 + }
1.331 +
1.332 + /**
1.333 +Loads aBuffer from specified point in iDes. Note that this is a synchronous read.
1.334 +
1.335 +@param aBuffer
1.336 + The buffer to be filled from the descriptor.
1.337 +@param aPosition
1.338 + The offset into the descriptor at which to start reading.
1.339 +*/
1.340 +void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition)
1.341 + {
1.342 + ReadBufferL(aBuffer, aPosition, NULL);
1.343 + }
1.344 +
1.345 +/**
1.346 +Empties aBuffer into iDes at specified location.
1.347 +
1.348 +@param aBuffer
1.349 + The data buffer containing bytes to be written.
1.350 +@param aPosition
1.351 + The offset into the descriptor at which to start writing.
1.352 +@param aSupplier
1.353 + The data source to be notified when the write has been completed.
1.354 +*/
1.355 +void CMMFDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
1.356 + {
1.357 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.358 + {
1.359 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.360 +
1.361 + WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier);
1.362 + }
1.363 + else
1.364 + User::Leave(KErrNotSupported);
1.365 + }
1.366 +
1.367 +/**
1.368 +Empties aLength bytes from aBuffer into iDes at specified location.
1.369 +
1.370 +@param aLength
1.371 + The number of bytes to be emptied from buffer.
1.372 +@param aBuffer
1.373 + The data buffer containing bytes to be written.
1.374 +@param aPosition
1.375 + The offset into the descriptor at which to start writing.
1.376 +@param aSupplier
1.377 + The data source to be notified when the write has been completed.
1.378 +
1.379 +@leave KErrNotReady
1.380 + If SinkPrimeL() and SinkThreadLogon() have not been called.
1.381 +@leave KErrArgument
1.382 + If aLength<0 or aPosition<0 or aSupplier is NULL.
1.383 +@leave KErrNotSupported
1.384 + If aBuffer is not of type KMMFDataBuffer.
1.385 +*/
1.386 +void CMMFDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
1.387 + {
1.388 + if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
1.389 + {
1.390 + TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
1.391 +
1.392 + if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0))
1.393 + User::Leave(KErrArgument);
1.394 +
1.395 + TInt sourceLength = aLength;
1.396 + TPtr8 bufferPtr(((sourceLength) ? &bufferDes[0] : NULL), sourceLength, sourceLength);
1.397 + TInt targetLength = iDes->MaxLength() - aPosition;
1.398 + if (targetLength>0 && sourceLength > 0)
1.399 + {
1.400 + if (sourceLength>targetLength)
1.401 + User::Leave(KErrOverflow);
1.402 +
1.403 + if ((iDes->Length() - aPosition) > 0)
1.404 + {
1.405 + TInt bytesToReplace = iDes->Length() - aPosition;
1.406 + if (sourceLength > bytesToReplace)
1.407 + {
1.408 + TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace);
1.409 + TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace);
1.410 + iDes->Replace(aPosition, bytesToReplace, replaceBuf);
1.411 + iDes->Append(appendBuf);
1.412 + }
1.413 + else
1.414 + iDes->Replace(aPosition, sourceLength, bufferPtr);
1.415 +
1.416 + }
1.417 + else
1.418 + iDes->Append(bufferPtr.Ptr(),sourceLength);
1.419 + }
1.420 + else if (targetLength<0)
1.421 + User::Leave(KErrArgument);
1.422 + else if (aLength != 0)
1.423 + User::Leave(KErrOverflow);
1.424 +
1.425 + if (aSupplier)
1.426 + aSupplier->BufferEmptiedL(aBuffer);
1.427 + }
1.428 + else
1.429 + User::Leave(KErrNotSupported);
1.430 + }
1.431 +
1.432 +/**
1.433 +Empties aBuffer into iFile at specified location. Note that this is a synchronous write
1.434 +
1.435 +@param aBuffer
1.436 + The data buffer containing bytes to be written.
1.437 +@param aPosition
1.438 + The offset into file at which to start writing.
1.439 +*/
1.440 +void CMMFDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition)
1.441 + {
1.442 + WriteBufferL( aBuffer, aPosition, NULL );
1.443 + }
1.444 +
1.445 +/**
1.446 +Returns the amount of space available for the clip.
1.447 +
1.448 +@return The space available in descriptor (difference between length and maxlength).
1.449 +*/
1.450 +TInt64 CMMFDescriptor::BytesFree()
1.451 + {
1.452 + TInt64 length = iDes->Length() ;
1.453 + TInt64 maxLength = iDes->MaxLength() ;
1.454 + return( maxLength - length ) ;
1.455 + }
1.456 +
1.457 +/**
1.458 +Returns the length of the clip.
1.459 +
1.460 +@return The length (not max length) of the descriptor.
1.461 +*/
1.462 +TInt CMMFDescriptor::Size()
1.463 + {
1.464 + TInt length = iDes->Length();
1.465 + return(length);
1.466 + }
1.467 +
1.468 +/**
1.469 +Returns the data type as a fourCC code for the CMMFDescriptor data source.
1.470 +
1.471 +@param aMediaId
1.472 + The ID of the media for which the codec is obtained.
1.473 +
1.474 +@return The data type fourCC code.
1.475 +*/
1.476 +TFourCC CMMFDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/)
1.477 + {
1.478 + return iSourceFourCC ;
1.479 + }
1.480 +
1.481 +/**
1.482 +Returns the data type as a fourCC code of the CMMFDescriptor data sink.
1.483 +
1.484 +Used by MDataSource and MDataSink.
1.485 +
1.486 +@return The data type fourCC code.
1.487 +*/
1.488 +TFourCC CMMFDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/)
1.489 + {
1.490 + return iSinkFourCC ;
1.491 + }
1.492 +
1.493 +/**
1.494 +CMMFDescriptor as a source is always passive so this function is not supported.
1.495 +
1.496 +@param aBuffer
1.497 + The emptied buffer.
1.498 +*/
1.499 +void CMMFDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
1.500 + {
1.501 + Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported);
1.502 + }
1.503 +
1.504 +/**
1.505 +Tests whether a source buffer can be created.
1.506 +
1.507 +@return A boolean indicating if the buffer can be created. EFalse if a CMMFDescriptor cannot create
1.508 + it's own buffer
1.509 +*/
1.510 +TBool CMMFDescriptor::CanCreateSourceBuffer()
1.511 + {
1.512 + return EFalse ;
1.513 + }
1.514 +
1.515 +/**
1.516 +Creates a source buffer.
1.517 +
1.518 +@param aMediaId
1.519 + The Media ID.
1.520 +@param aReference
1.521 + A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
1.522 + EFalse if the caller owns the buffer.
1.523 +
1.524 +@return NULL as a CMMFFile cannot create it's own buffer
1.525 +*/
1.526 +CMMFBuffer* CMMFDescriptor::CreateSourceBufferL( TMediaId /*aMediaId*/, TBool& /*aReference*/ )
1.527 + {
1.528 + User::Leave(KErrNotSupported);
1.529 + return NULL;
1.530 + }
1.531 +
1.532 +/**
1.533 +CMMFDescriptor as a sink is always passive so this function is not supported.
1.534 +
1.535 +@param aBuffer
1.536 + The filled buffer.
1.537 +*/
1.538 +void CMMFDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
1.539 + {
1.540 + Panic(EMMFDescriptorPanicBufferFilledLNotSupported);
1.541 + }
1.542 +
1.543 +/**
1.544 +Tests whether a sink buffer can be created.
1.545 +
1.546 +@return A boolean indicating if the sink buffer can be created. EFalse if a CMMFDescriptor cannot
1.547 + create it's own buffer.
1.548 +*/
1.549 +TBool CMMFDescriptor::CanCreateSinkBuffer()
1.550 + {
1.551 + return EFalse ;
1.552 + }
1.553 +
1.554 +/**
1.555 +Creates a sink buffer.
1.556 +
1.557 +@param aMediaId
1.558 + The Media ID.
1.559 +@param aReference
1.560 + A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
1.561 + EFalse if the caller owns the buffer.
1.562 +
1.563 +@return NULL as a CMMFDescriptor cannot create it's own buffer
1.564 + */
1.565 +CMMFBuffer* CMMFDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
1.566 + {
1.567 + User::Leave(KErrNotSupported);
1.568 + return NULL;
1.569 + }