examples/Multimedia/MmfExSinkSource/Mmfdes.cpp

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

Generated by  doxygen 1.6.2