examples/Multimedia/MmfExSinkSource/Mmfdes.cpp

00001 // mmfdes.cpp
00002 //
00003 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
00004 // All rights reserved.
00005 // This component and the accompanying materials are made available
00006 // under the terms of "Eclipse Public License v1.0"
00007 // which accompanies this distribution, and is available
00008 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00009 //
00010 // Initial Contributors:
00011 // Nokia Corporation - initial contribution.
00012 //
00013 // Contributors:
00014 //
00015 // Description:
00016 //
00017 
00018 
00019 
00020 #include <f32file.h>
00021 #include <e32std.h>
00022 #include <mmfdatabuffer.h>
00023 
00024 #include "mmfexdes.h"
00025 #include "MmfExSinkSourceUIDs.hrh"
00026 
00027 // Panic function
00028 void Panic(TMMFExDescriptorPanicCode aPanicCode)
00029         {
00030         _LIT(KMMFExDescriptorPanicCategory, "MMFExDescriptor");
00031         User::Panic(KMMFExDescriptorPanicCategory, aPanicCode);
00032         }
00033 
00034 //
00035 // CMMFExDescriptor
00036 //
00037 
00038 // Plugin implementation UIDs
00039 const TUid KDescriptorSourceUIDObject   = {KDescriptorSourceUID};
00040 const TUid KDescriptorSinkUIDObject     = {KDescriptorSinkUID};
00041 
00042 // Constructor
00043 CMMFExDescriptor::CMMFExDescriptor( ) : CMMFClip( TUid(KDescriptorSourceUIDObject), TUid(KDescriptorSinkUIDObject )) 
00044         {
00045         iOffset = 0 ;
00046         }
00047 
00048 // Destructor
00049 CMMFExDescriptor::~CMMFExDescriptor()
00050         {
00051         iDesThread.Close() ;
00052         }
00053 
00054 // Factory function for source plug-in
00055 MDataSource* CMMFExDescriptor::NewSourceL( )
00056         {
00057         CMMFExDescriptor* self = new (ELeave) CMMFExDescriptor( ) ;
00058         return STATIC_CAST( MDataSource*, self ) ;
00059         }
00060         
00061 // Factory function for sink plug-in
00062 MDataSink* CMMFExDescriptor::NewSinkL( )
00063         {
00064         CMMFExDescriptor* self = new (ELeave) CMMFExDescriptor( ) ;
00065         return STATIC_CAST( MDataSink*, self ) ;
00066         }
00067 
00068 // MDataSource factory
00069 // aInitData is a packaged TMMFExDescriptorParams
00070 void CMMFExDescriptor::ConstructSourceL( const TDesC8& aInitData )
00071         {
00072         ConstructL( aInitData ) ;
00073         }
00074 
00075 // MDataSink factory
00076 // aInitData is a packaged TMMFExDescriptorParams
00077 void CMMFExDescriptor::ConstructSinkL( const TDesC8& aInitData )
00078         {
00079         ConstructL( aInitData ) ;
00080         }
00081 
00082 // Construction helper
00083 // aInitData is a packaged TMMFExDescriptorParams
00084 void CMMFExDescriptor::ConstructL( const TDesC8& aInitData ) 
00085         {
00086         // get descriptor to which to read/write, and the thread 
00087         // to which it belongs
00088         TMMFExDescriptorParams params;
00089         TPckgC<TMMFExDescriptorParams> config(params);
00090         config.Set(aInitData);
00091         iDes = STATIC_CAST( TDes8*, config().iDes);
00092         User::LeaveIfError( iDesThread.Open( config().iDesThreadId ) );
00093         }
00094 
00095 
00096 // From MDataSource
00097 
00098 TFourCC CMMFExDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/) 
00099         {
00100         return iSourceFourCC ;
00101         }
00102 
00103 // Fills a buffer from the source descriptor
00104 void CMMFExDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/  ) 
00105         {
00106         // Current position in Descriptor is iOffset.
00107 
00108         // Read from iDes in iDesThread into Des in aBuffer.
00109 
00110         // Assume that the amount to be read is the size of the buffer descriptor
00111         // Should check that there is sufficient data in the source buffer
00112         // If there is not enough to fill the target then copy what there is
00113 
00114         // Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
00115         if ( aBuffer->Type() == KUidMmfDataBuffer  ) 
00116                 {
00117                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00118                 TInt targetMaxLength = bufferDes.MaxLength();
00119                 TInt sourceLength = iDes->Length();
00120                 
00121                 if ( ( sourceLength - iOffset - targetMaxLength ) > 0 )
00122                         {
00123                         bufferDes = iDes->Mid(iOffset,targetMaxLength);
00124                         iOffset += targetMaxLength;
00125                         }
00126                 else
00127                         bufferDes.SetLength(0);
00128 
00129                 // Check if the buffer is the last buffer and if so set the last buffer flag on the CMMFDataBuffer
00130                 TInt requestSize = aBuffer->RequestSize();
00131                 if (requestSize)
00132                         { // The buffer has a request size  - so assume last buffer if length is less than the request size
00133                         if (bufferDes.Length() < requestSize)   
00134                                 aBuffer->SetLastBuffer(ETrue);
00135                         }
00136                 else
00137                         { // There is no request size so assume last buffer if length is less than the max length
00138                         if (bufferDes.Length() < bufferDes.MaxLength()) 
00139                                 aBuffer->SetLastBuffer(ETrue);
00140                         }
00141 
00142                 aConsumer->BufferFilledL( aBuffer ) ;
00143                 }
00144         else
00145                 User::Leave(KErrNotSupported);
00146         }
00147 
00148 // called by MDataSink to pass back emptied buffer to the source
00149 void CMMFExDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
00150         {
00151         // not supported in this plug-in
00152         __ASSERT_DEBUG(EFalse, Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported));
00153         }
00154 
00155 // tests if the plug-in can create a source buffer
00156 TBool CMMFExDescriptor::CanCreateSourceBuffer()
00157         {
00158         // this can't: it needs a descriptor from another thread
00159         return EFalse ;
00160         }
00161 
00162 // creates a source buffer
00163 CMMFBuffer* CMMFExDescriptor::CreateSourceBufferL(  TMediaId /*aMediaId*/, TBool& /*aReference*/ )
00164         {
00165         // is not supported in this plug-in
00166         User::Leave(KErrNotSupported);
00167         return NULL;
00168         }
00169 
00170 
00171 // from MDataSink
00172 
00173 // gets sink codec type
00174 TFourCC CMMFExDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/) 
00175         {
00176         return iSinkFourCC ;
00177         }
00178 
00179 // Empties supplied buffer into the sink descriptor 
00180 void CMMFExDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
00181         {
00182         // Current position in Descriptor is iOffset.
00183 
00184         // Assume that the amount to be read is the size of the buffer descriptor
00185         // Should check that there is sufficient data in the source buffer
00186         // If there is not enough to fill the target then copy what there is
00187 
00188         // Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
00189 
00190         if ( aBuffer->Type() == KUidMmfDataBuffer  ) 
00191                 {
00192                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00193 
00194                 TInt sourceLength = bufferDes.Length() ;        
00195                 TInt targetLength = iDes->MaxLength() - iOffset;
00196                 if ( targetLength>0 )
00197                         {
00198                         if (sourceLength>targetLength)
00199                                 {
00200                                 sourceLength = targetLength;
00201                                 bufferDes.SetLength(targetLength);
00202                                 }
00203 
00204                         iDes->Append(bufferDes) ;
00205 
00206                         iOffset += sourceLength ;
00207                         }
00208                 else
00209                         bufferDes.SetLength(0);
00210 
00211                 aSupplier->BufferEmptiedL( aBuffer ) ;
00212                 }
00213         }
00214 
00215 // called by MDataSource to pass back full buffer to the sink
00216 void CMMFExDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
00217         {
00218         // not supported in this plug-in
00219         __ASSERT_DEBUG(EFalse, Panic(EMMFDescriptorPanicBufferFilledLNotSupported));
00220         }
00221 
00222 // tests if the plug-in can create a sink buffer
00223 TBool CMMFExDescriptor::CanCreateSinkBuffer()
00224         {
00225         // this can't: it needs a descriptor from another thread        
00226         return EFalse ;
00227         }
00228 
00229 // creates a sink buffer
00230 CMMFBuffer* CMMFExDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
00231         {
00232         // not supported in this plug-in
00233         User::Leave(KErrNotSupported);
00234         return NULL;
00235         }
00236 
00237 // from CMMFClip
00238 
00239 // Loads aBuffer with specified amount of data from a specified point in the source descriptor 
00240 void CMMFExDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
00241         {
00242         if (aBuffer->Type() == KUidMmfDataBuffer) 
00243                 {
00244                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00245 
00246                 if (aLength>bufferDes.MaxLength())
00247                         User::Leave(KErrOverflow);
00248 
00249                 if ((aLength<0) || (aPosition<0))
00250                         User::Leave(KErrArgument);
00251 
00252                 ReadBufferL(aBuffer, aPosition, aConsumer);
00253                 }
00254         else
00255                 User::Leave(KErrNotSupported);
00256         }
00257 
00258 // Loads aBuffer from a specified point in the source descriptor  
00259 void CMMFExDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
00260         {
00261         if (aBuffer->Type() == KUidMmfDataBuffer) 
00262                 {
00263                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00264 
00265                 TInt sourceLength = iDes->Length() ;
00266                 TInt destinationMaxLength = bufferDes.MaxLength();
00267                 TInt len = sourceLength - aPosition;
00268                 if (len > destinationMaxLength)
00269                         len = destinationMaxLength;
00270 
00271                 if (len>0)
00272                         {
00273                         TPtrC8 srcPtr(iDes->Mid(aPosition,len));
00274                         bufferDes.Copy(srcPtr);
00275                         }
00276                 else
00277                         bufferDes.SetLength(0);
00278 
00279                 // Check if the buffer is the last buffer and if so set the last buffer flag on the CMMFDataBuffer
00280                 TInt requestSize = aBuffer->RequestSize();
00281                 if (requestSize)
00282                         { // The buffer has a request size  - so assume last buffer if length is less than the request size
00283                         if (bufferDes.Length() < requestSize)   
00284                                 aBuffer->SetLastBuffer(ETrue);
00285                         }
00286                 else
00287                         { // There is no request size so assume last buffer if length is less than the max length
00288                         if (bufferDes.Length() < bufferDes.MaxLength()) 
00289                                 aBuffer->SetLastBuffer(ETrue);
00290                         }
00291 
00292                 if (aConsumer)
00293                         aConsumer->BufferFilledL(aBuffer);
00294                 }
00295         else
00296                 User::Leave(KErrNotSupported);
00297         }
00298 
00299 // Loads aBuffer from a specified point in the source descriptor 
00300 // This is intended for synchronous usage
00301 void CMMFExDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition)
00302         {
00303         ReadBufferL(aBuffer, aPosition, NULL);
00304         }
00305 
00306 // Writes aBuffer at specified location into the sink descriptor
00307 void CMMFExDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier) 
00308         {
00309         if (aBuffer->Type() == KUidMmfDataBuffer)
00310                 {
00311                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00312 
00313                 WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier);
00314                 }
00315         else
00316                 User::Leave(KErrNotSupported);
00317         }
00318 
00319 // Writes specified length of aBuffer at specified location into the sink descriptor
00320 void CMMFExDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
00321         {
00322         if (aBuffer->Type() == KUidMmfDataBuffer) 
00323                 {
00324                 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
00325 
00326                 if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0))
00327                         User::Leave(KErrArgument);
00328 
00329                 TInt sourceLength = aLength;
00330                 TPtr8 bufferPtr(((sourceLength) ? &bufferDes[0] : NULL), sourceLength, sourceLength);
00331                 TInt targetLength = iDes->MaxLength() - aPosition;
00332                 if (targetLength>0 && sourceLength > 0)
00333                         {
00334                         if (sourceLength>targetLength)
00335                                 User::Leave(KErrOverflow);
00336 
00337                         if ((iDes->Length() - aPosition) > 0)
00338                                 {
00339                                 TInt bytesToReplace = iDes->Length() - aPosition;
00340                                 if (sourceLength > bytesToReplace) 
00341                                         {
00342                                         TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace);
00343                                         TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace);
00344                                         iDes->Replace(aPosition, bytesToReplace, replaceBuf);
00345                                         iDes->Append(appendBuf);
00346                                         } 
00347                                 else
00348                                         iDes->Replace(aPosition, sourceLength, bufferPtr);
00349 
00350                                 } 
00351                         else if (aPosition == iDes->Length())
00352                                 iDes->Append(bufferPtr.Ptr(),sourceLength);
00353                         else
00354                                 {
00355                                 iDes->AppendFill(0,aPosition - iDes->Length());
00356                                 iDes->Append(bufferPtr.Ptr(),sourceLength);
00357                                 }
00358                         }
00359                 else if (targetLength<0)
00360                         User::Leave(KErrArgument);
00361                 else if (aLength != 0)
00362                         User::Leave(KErrOverflow);
00363 
00364                 if (aSupplier)
00365                         aSupplier->BufferEmptiedL(aBuffer);
00366                 }
00367         else
00368                 User::Leave(KErrNotSupported);
00369         }
00370 
00371 // Writes aBuffer at specified location into the sink descriptor
00372 void CMMFExDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition)
00373         {
00374         WriteBufferL( aBuffer, aPosition, NULL );
00375         }
00376 
00377 // Gets the space available in the clip
00378 TInt64 CMMFExDescriptor::BytesFree() 
00379         {
00380         // get difference between length and maxlength
00381         TInt64 length = iDes->Length() ;
00382         TInt64 maxLength =  iDes->MaxLength() ;
00383         return( maxLength - length ) ;
00384         }
00385 
00386 // Gets the size of the clip
00387 TInt CMMFExDescriptor::Size() 
00388         {
00389         // Length (not max length) of descriptor
00390         TInt length = iDes->Length();
00391         return(length);
00392         }

Generated by  doxygen 1.6.2