Пример #1
0
// Helper function to create and zero fill a buffer of specified size
CMMFDataBuffer* CMMFRawFormatRead::CreateSourceBufferOfSizeL(TUint aSize)
	{
	//needs to create source buffer
	CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(aSize);
	buffer->Data().FillZ(aSize);
	return buffer;
	}
Пример #2
0
// -----------------------------------------------------------------------------
// CMccUlDataPath::BufferFilledL
// Databuffer filled callback
// -----------------------------------------------------------------------------
void CMccUlDataPath::BufferFilledL( CMMFBuffer* aBuffer )
    {
    // Has the datapath stopped running, if so were not interested in any
    // callbacks.
    if( EStreaming == State() )
        {
        if ( !aBuffer )
            {
            ChangeDataPathTransferState( EEndOfData );
            }
        else
            {
            // Sink buffer is with datapath, see if there is anything to send
            // to sink
	        IsBufferSupportedL( aBuffer );
	        aBuffer->SetStatus( EFull );
	        
	        if ( iSinkBuffer != aBuffer )
		        {
	            CMMFDataBuffer* desBuffer = static_cast<CMMFDataBuffer*>(iSinkBuffer);
		        if ( (TInt) aBuffer->BufferSize() > desBuffer->Data().MaxLength() )	
			        {
			        // if the buffer from source is too big, ignore it
			        // ask next one
                    __SUBCONTROLLER( "CMccUlDataPath::BufferFilledL, DATA IGNORED" )
                    __SUBCONTROLLER_INT1( "CMccUlDataPath::BufferFilledL, source", aBuffer->BufferSize() )
                    __SUBCONTROLLER_INT1( "CMccUlDataPath::BufferFilledL, dest", desBuffer->Data().MaxLength() )
			        iSinkBuffer->SetStatus( EAvailable );
			        aBuffer->SetStatus( EAvailable );
		            ChangeDataPathTransferState( ENeedSourceData );	
		            return;
			        }
			    else
				    {
				   	CopyBuffer( iSinkBuffer, aBuffer );
				    }
		        }
		    
		    if( !aBuffer->BufferSize() || aBuffer->LastBuffer() )
			    {
			    //ignore zero length buffer request for next buffer from AudioInput
		        iSinkBuffer->SetStatus( EAvailable );

		        ChangeDataPathTransferState( ENeedSourceData, ETrue );	
			    }
			else
				{
				ChangeDataPathTransferState( ESendDataToSink );	
				}
            }
        }
    else
        {
        User::Leave( KErrNotReady );
        }
    }
/** Verify CMMFDataBuffer buffer length setting
 * Use case: N/A
 * @test Req. under test REQ172.7.25
 */
TVerdict CTestStep_MMF_BASECL_U_0005::DoTestStepL( void )
	 {
	 TVerdict verdict = EPass;

	 CMMFDataBuffer* descriptorBuffer = CMMFDataBuffer::NewL(KMMFTestBufferSize); //create descriptor buffer

	 descriptorBuffer->Data().SetLength(KMMFTestBufferLengthSize);
	 if (descriptorBuffer->BufferSize() != KMMFTestBufferLengthSize) verdict = EFail;

	 delete descriptorBuffer;
	 return verdict;
	 }
/*
@see CMMFHwDevice::ThisHwBufferEmptied()
*/
TInt CMdfHwDeviceAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
	{
	if (iOutputBuffer->LastBuffer())
		{
		CMMFDataBuffer* buffer = static_cast <CMMFDataBuffer*> (iOutputBuffer);
		buffer->Data().SetLength(0);
		iHwDeviceObserver->EmptyThisHwBuffer(*iOutputBuffer);
		}
	else	
		{
		iCodecOutputPort->MopReadData(*iOutputBuffer);
		}
	return KErrNone;
	}
void UT_CAmrPayloadDecoder::UT_CAmrPayloadDecoder_DecodePayloadL(  )
    {
    CMMFDataBuffer* buf = CMMFDataBuffer::NewL( 50 );
    CleanupStack::PushL(buf);

    iDec->SetPayloadBuffer( buf->Data() );

    TUint32 ts(2);
    TUint32 tsInc( 5 );

	iDec->DecodePayload( ts, tsInc );
	CleanupStack::Pop(buf);
    delete buf;
    }
/** Verify CMMFBuffer timestamping
 * Use case: N/A
 * @test Req. under test REQ172.7.25
 */
TVerdict CTestStep_MMF_BASECL_U_0007::DoTestStepL( void )
	 {
	 TVerdict verdict = EPass;
	 const TInt KMMFTestTime = 1234567890;
	 CMMFDataBuffer* descriptorBuffer = CMMFDataBuffer::NewL(); //create descriptor buffer

	 //check that the initial time to play is 0
	 if (descriptorBuffer->TimeToPlay() != TTimeIntervalMicroSeconds(0)) verdict = EFail;

	 //assign a timestamp and check it is set correctly
	 descriptorBuffer->SetTimeToPlay(TTimeIntervalMicroSeconds(KMMFTestTime));
	 if (descriptorBuffer->TimeToPlay() != TTimeIntervalMicroSeconds(KMMFTestTime)) verdict = EFail;
 
	 delete descriptorBuffer;
	 return verdict;
	 }
/** Verify CMMFBuffer buffer stats
 * Use case: N/A
 * @test Req. under test REQ172.7.25
 */
TVerdict CTestStep_MMF_BASECL_U_0006::DoTestStepL( void )
	 {
	 TVerdict verdict = EPass;
	 CMMFDataBuffer* descriptorBuffer = CMMFDataBuffer::NewL(); //create descriptor buffer

	 //check that the buffer is initially available
	 if (descriptorBuffer->Status() != EAvailable) verdict = EFail;

	 //check we can write to the status - onlt try one option assume if one does the others do -since this
	 //is an enumeration this is a reasonable assumption
	 descriptorBuffer->SetStatus(EFull);
	 if (descriptorBuffer->Status() != EFull) verdict = EFail;

	 delete descriptorBuffer;
	 return verdict;
	 }
// ---------------------------------------------------------------------------
// CDTMFPayloadFormatWrite::DeliverPacketL
// Prepare the RTP packet header and deliver the packet to the datasink.
// ---------------------------------------------------------------------------
//
void CDTMFPayloadFormatWrite::DeliverPacketL( CMMFDataBuffer& aPayload, 
                                              TBool aMarkerBit )
    {
    DP_DTMF_WRITE4( 
        _L("CDTMFPayloadFormatWrite::DeliverPacketL - TSTAMP: %u, TDUR: %d, tick = %u"),
        TUint32( aPayload.TimeToPlay().Int64() ), iToneDuration, 
        User::NTickCount() );
    
    if ( KSignalOutbandDtmf == iGenerationMode )
        {
        // Set the marker bit if it is very first packet.
        if ( aMarkerBit )
            {
            iRtpSendHeader.iMarker = 1;
            }
        else
            {
            iRtpSendHeader.iMarker = 0;
            }
            
        // Construct RTP header.
        if ( EGenRedUsed == iCInfo.iAlgoUsed )
            {
            iRtpSendHeader.iPayloadType = iCInfo.iRedundantPayload;
            }
        else
            {
            iRtpSendHeader.iPayloadType = iCInfo.iPayloadType;
            }

        // Timestamp must be updated before coming here
        iRtpSendHeader.iTimestamp = TUint32( aPayload.TimeToPlay().Int64() );

        // Deliver the packet
        iRtpDataSink->EmptyBufferL( &aPayload, this,
            TMediaId( KUidMediaTypeAudio ), iRtpSendHeader );

        // Do not reset payload buffer because update packets
        // are send based on same buffer.
        }
    else
        {
        DP_DTMF_WRITE( _L("CDTMFPayloadFormatWrite::DeliverPacketL - INBAND TONE") );
        }
    }
/**
*
* PrintComparisonDataL
* @param aCodedData the coded data buffer
* @param aRefCodedData the reference coded data buffer
* 
*/
void CMMFDataGenerator::PrintComparisonDataL( CMMFDataBuffer& aCodedData, CMMFDataBuffer& aRefCodedData )
	{
	//[precondition reference coded data is equal in size or longer than coded data ]
	if( aRefCodedData.Data().Length() < aCodedData.Data().Length() )
		{
         //[coded data is longer than reference data]
	//	RDebug::Print(_L("Coded Data is longer than refernce data")); Commented under DEF105143
		User::Leave( KErrCorrupt );	 
		}

	TUint8* ptr1 = CONST_CAST(TUint8*, aCodedData.Data().Ptr());
	TUint8* ptr2 = CONST_CAST(TUint8*, aRefCodedData.Data().Ptr());
    TInt length = aCodedData.Data().Length();
	//[ now print the results for comparison ]
	for( TInt i = 0; i < length; i++ )
		{
        RDebug::Print( _L("difference: %d, coded: %d, RefCoded: %d"), (*ptr1-*ptr2), *ptr1++, *ptr2++ );
		} 
	}
void CPlayAudioFile::ReadNextBuffer(CMMFBuffer& aHwDataBuffer)
	{
	TBool finished = EFalse;
	TInt length = iSourceFile->Size();
	if (iSourceFilePos < length)
		{
		TInt size = length - iSourceFilePos;
		CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(&aHwDataBuffer);
		if (size > dataBuffer->Data().MaxLength())
			{
			size = dataBuffer->Data().MaxLength();
			}
		else
			{
			dataBuffer->SetLastBuffer(ETrue);
			finished = ETrue;
			}
		dataBuffer->Data().SetLength(size);
		Mem::Copy((TAny*)dataBuffer->Data().Ptr(), (TAny*)iSourceFile->Mid(iSourceFilePos).Ptr(), size);
		iSourceFilePos += size;
		}
	iHwDevice->ThisHwBufferFilled(aHwDataBuffer);
	if (finished)
		{
		SetState(EHwDeviceAllowToComplete);
		}
	}
Пример #11
0
/**
Fills the aBuffer with audio data depends on interleaved or not.
@param aBuffer
*/
void CAviReader::FillAudioBufferL(CMMFBuffer* aBuffer)
{
    if (!aBuffer)
    {
        User::Leave(KErrArgument);
    }
    iBufferFromDevSound = aBuffer;
    iAudioRequestMade = ETrue;
    if (iMainHeader.iFlags == KAVIF_ISINTERLEAVED)
    {
        //Here Audio and Video data are interleaved in the form of REc lists.
        if (!iReadRequestMade)
        {
            //Read request for REC list is not yet made. So read the REC list into the sourcebuffer.
            ReadNextFrameL(TUid::Null(), iSourcePos);
            iReadRequestMade = ETrue;
        }
        else if (iReadCompleted)
        {
            //audio frame is already read into the audio buffer
            //copy the data from the audio buffer to devsound buffer.
            CMMFDataBuffer* bufferFromSink = static_cast<CMMFDataBuffer*>(aBuffer);
            bufferFromSink->Data().Copy(iAudioBuffer->Data());
            ReadComplete();
        }
    }
    else
    {
        if (iAudioBuffer)
        {
            BufferFilledL(iAudioBuffer);
        }
        else
        {
            //non-interleaved
            ReadNextFrameL(KUidMediaTypeAudio, iAudioPos);
        }
    }
}
void UT_CG729PayloadFormatRead::UT_CG729PayloadFormatRead_DoBitUnPackingL()
    {
    if ( !iAlloc )
        {
        _LIT( KData, "dummy");
        TBool comfortNoise = EFalse;
        
        HBufC8* sourceBuf = HBufC8::NewL( 6 );  
        CleanupStack::PushL(sourceBuf);      
        TPtr8 ptr = sourceBuf->Des();
        ptr.Append( KData );         
        
        CMMFDataBuffer* destBuf = CMMFDataBuffer::NewL( KG729CodecDecBufSize );
        TDes8& buf = destBuf->Data();         // cleanup stackiin sourceBuf ainakin
        
        EUNIT_ASSERT_EQUALS( iRead->DoBitUnPacking( *sourceBuf, buf, comfortNoise ), KErrNone );
        buf.Zero();
        
        CleanupStack::Pop(sourceBuf); 
        
        delete destBuf;
        delete sourceBuf;        
        }
        
    else
        {
        _LIT( KData, "dummy");
        TBool comfortNoise = EFalse;
        HBufC8* sourceBuf = NULL;
        
        HBufC8* destBuf = HBufC8::NewL( 6 );        
        TPtr8 ptr = destBuf->Des();
        ptr.Append( KData );        
        
        EUNIT_ASSERT_EQUALS( iRead->DoBitUnPacking( *sourceBuf, ptr, comfortNoise ), KErrArgument );
        delete destBuf;        
        }    
    }
void UT_CDTMFPayloadFormatRead::UT_CDTMFPayloadFormatRead_BufferFilledLL()
    {
    TMccCodecInfoBuffer buf( iCodec );
    iRead->ConfigurePayloadFormatL( buf );
    iRead->FillSourceBufferL( );
    
    iHeaderInfo.iPayloadType = 102;
    iRead->iCInfo.iPayloadType = 102;
        
    CMMFDataBuffer* buffer = CMMFDataBuffer::NewL( KDTMFDefaultPayloadSize );
    CleanupStack::PushL( buffer );
    buffer->Data().FillZ( KDTMFDefaultPayloadSize );
    iRead->DataBufferFilledL( buffer, iHeaderInfo );
        
    CleanupStack::PopAndDestroy( buffer );
    
    buffer = NULL;
    buffer = CMMFDataBuffer::NewL( 0 );
    CleanupStack::PushL( buffer );
    iRead->DataBufferFilledL( buffer, iHeaderInfo );
    
    CleanupStack::PopAndDestroy( buffer );
    }
/**
*
* BuffersStatus
* @param source buffer containing the data to be coded
* @param destination buffer containing the coded data
* @return TBool EFalse indicates bad buffers
*
**/
TBool CMMFPcm16ToImaAdpcmCodec::BuffersStatus( const CMMFDataBuffer* source, const CMMFDataBuffer* destination )
	{
	TBool status = EFalse;
	
	//[ demand source and destination positions are zero ]
    CMMFDataBuffer* pDst = const_cast<CMMFDataBuffer*>( destination );
	if( source->Position() || destination->Position() )
		{
		return status;
		}
	
	//[ Have we got full buffers ]
	TInt sourceBuffers = source->Data().Length()/KSourceFrameSize;
	TInt destBuffers   = (pDst->Data().MaxLength())/KCodedFrameSize;
	
	if( sourceBuffers <= destBuffers )  // the sink can process the source
		{
		return ETrue;                       // note this precondition has been weakened in line with other codecs
		}                                   // such that it can process partially full buffers
	                                        // ie you can if you wish use larger buffers than needed and only partially
	                                        // fill them. We do however expect all the input to be processed.
	return status;
	}
/**
*
* ProcessBuffers
* @param aSource
* @param aDestination
* @param aResult 
* all we have to do is find out how many source frames there 
* are to process and process them
* finally returning process complete and fillin the status of the result
*
**/
void CMMFPcm16ToImaAdpcmCodec::ProcessBuffers(const CMMFDataBuffer& aSource, CMMFDataBuffer& aDestination, CMMFSwCodec::TCodecProcessResult& aResult )
	{
	//[ calculate how many full buffers are to be processed ]
    const TUint srcLen    = aSource.Data().Length();
    TInt numFullSrcFrames = srcLen/KSourceFrameSize;
    
	TUint8* pSrc = const_cast<TUint8*>(aSource.Data().Ptr());
	TUint8* pDst = const_cast<TUint8*>(aDestination.Data().Ptr());
    TInt dstBytesAdded = 0;
	// calculate number of pcm samples per source frame
	const TInt KSamplesPerFrame = KSourceFrameSize/(sizeof(TInt16)); 
	
	//[ convert all the buffers ]
	for( TInt count = 0; count < numFullSrcFrames; count++ )
		{
		i16PcmToImaAdpcm.Convert(pSrc, pDst, KSamplesPerFrame );				
		pSrc          += KSourceFrameSize;
		pDst          += KCodedFrameSize;
		dstBytesAdded += KCodedFrameSize;
		}
	aResult.iSrcBytesProcessed = numFullSrcFrames*KSourceFrameSize;
	aResult.iDstBytesAdded = dstBytesAdded;		
	aDestination.Data().SetLength( aResult.iDstBytesAdded);
	}
void UT_CG729PayloadFormatRead::UT_CG729PayloadFormatRead_BufferFilledLL(  )
    {
    TRtpRecvHeader test;
    test.iPayloadType = 13;
    
    if ( !iAlloc )
        {
        CMMFBuffer* buf = NULL;
        EUNIT_ASSERT_SPECIFIC_LEAVE( iRead->DataBufferFilledL( buf, test ), KErrArgument );
        CMMFDataBuffer* buffi = CMMFDataBuffer::NewL( 150 );      
        buf = buffi; 
        CleanupStack::PushL( buf );         
        iRtpDataSourceStub->FillBufferL( buf, iConsumer, KUidMediaTypeAudio );       
        EUNIT_ASSERT_NO_LEAVE( iRead->DataBufferFilledL( iRead->iSourceBuffer, test ) );

        buffi->Data().Append( _L("12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" ));
        EUNIT_ASSERT_NO_LEAVE( iRead->DataBufferFilledL( iRead->iSourceBuffer, test ) );
        CleanupStack::PopAndDestroy( buf );   
        }
    
    else
        {
        CMMFBuffer* buf = NULL;
        EUNIT_ASSERT_SPECIFIC_LEAVE( iRead->DataBufferFilledL( buf, test ), KErrArgument );
        CMMFDataBuffer* buffi = CMMFDataBuffer::NewL( 150 );      
        buf = buffi; 
        CleanupStack::PushL( buf );         
        iRtpDataSourceStub->FillBufferL( buf, iConsumer, KUidMediaTypeAudio );       
        EUNIT_ASSERT_NO_LEAVE( iRead->DataBufferFilledL( iRead->iSourceBuffer, test ) );

        buffi->Data().Append( _L("12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" ));
        EUNIT_ASSERT_NO_LEAVE( iRead->DataBufferFilledL( iRead->iSourceBuffer, test ) );
        CleanupStack::PopAndDestroy( buf );         
        }
    
    }
// -----------------------------------------------------------------------------
// CG711PayloadFormatRead::FillSinkBuffer
// Fill SinkBuffer.
// -----------------------------------------------------------------------------
//
void CG711PayloadFormatRead::FillSinkBufferL()
{
    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBuffer()" );

    CMMFDataBuffer* curFrameBuffer = NULL;
    if ( EBufferOne == iCurrentBuffer )
    {
        curFrameBuffer = iFrameBufferOne;
    }
    else
    {
        curFrameBuffer = iFrameBufferTwo;
    }

    TDes8& curFrameData( curFrameBuffer->Data() );
    curFrameData.SetLength( KVoIPHeaderLength );

    // Put next frame decoded from RTP payload to the framebuffer
    iBufferToReadExists = GetNextFrame( curFrameData );

    // G.711 Gwc expects 2 bytes for dtx-decision
    if ( iCnFrame )
    {
        DP_G711_READ( "CG711PayloadFormatRead::FillSinkBufferL add dtx-header" );

        curFrameData[0] = KVoIPCNFrame;
        curFrameData[1] = 0;
    }
    else
    {
        DP_G711_READ( "CG711PayloadFormatRead::FillSinkBufferL add voice-header" );

        curFrameData[0] = KVoIPAudioFrame;
        curFrameData[1] = 0;
    }

    curFrameBuffer->SetFrameNumber( iRecvHeader.iTimestamp + ( ( iFrameIndex - 1 )
                                    * TUint( iCInfo.iHwFrameTime * KDefaultSampleRateInkHz ) ) );

    DP_G711_READ2( "CG711PayloadFormatRead::FillSinkBuffer - FRAMENUM: %u",
                   curFrameBuffer->FrameNumber() );

    const TInt dataLen( ( iCInfo.iHwFrameTime * KBitsPerByte )
                        + KVoIPHeaderLength );
    curFrameData.SetLength( dataLen );
    curFrameBuffer->SetStatus( EFull );

    DP_G711_READ2( "CG711PayloadFormatRead: Filled framebuffer with buf. size: %d",
                   curFrameBuffer->BufferSize() );

    iStateMachine->ChangeState( EEmptyDataToSink );

    DP_G711_READ( "CG711PayloadFormatRead::FillSinkBuffer - DONE" );
}
/** Verify CMMFBuffer buffer framenumbers
 * Use case: N/A
 * @test Req. under test REQ172.7.25
 */
TVerdict CTestStep_MMF_BASECL_U_0008::DoTestStepL( void )
	 {
	 TVerdict verdict = EPass;

	 CMMFDataBuffer* descriptorBuffer = CMMFDataBuffer::NewL(); //create descriptor buffer

	 //check initial frame number is 0
	 if (descriptorBuffer->FrameNumber() != 0) verdict = EFail;
 
	 //check setting a framenumber
	 descriptorBuffer->SetFrameNumber(KMMFTestFrameNumber);
	 if (descriptorBuffer->FrameNumber() != KMMFTestFrameNumber) verdict = EFail;

	 //check incrementing the framenumber
	 descriptorBuffer->NextFrame();
	 if (descriptorBuffer->FrameNumber() != (KMMFTestFrameNumber+1)) verdict = EFail;

	 delete descriptorBuffer;

	 return verdict;
	 }
// --------------------------------------------------------------------------
//  From class CMMFCodec.
//  This function is used to encode the given source and fill the destination
//  buffer with the encode data.
//  The buffers can be of any size.  Since the buffers can be of any size
//  there is no guarantee that all the source buffer can be processed to fill
//  the destination buffer or that the all the source buffer may be processed
//  before the destination is full.  Therefore the ProcessL needs to return a
//  TCodecProcessResult returing the number of source bytes processed and the
//  number of destination bytes processed along with a process result code
//  defined thus:
//  - EProcessComplete: the codec processed all the source data into the
//    sink buffer
//  - EProcessIncomplete: the codec filled sink buffer before all the source
//    buffer
//    was processed
//  - EDstNotFilled: the codec processed the source buffer but the sink
//    buffer was not filled
//  - EEndOfData: the codec detected the end data - all source data is
//    processed but sink may not be full
//  - EProcessError: the codec process error condition
//
//  The ProcessL should start processing the source buffer from the iPosition
//  data member of the source data and start filling the destination buffer
//  from its iPosition.
//  -------------------------------------------------------------------------
//
TCodecProcessResult CAriAacLCEncMmfCodec::ProcessL( const CMMFBuffer& aSrc,
                                                        CMMFBuffer& aDst )
    {
    PRINT_ENTRY;

    // total decoded bytes added to the dst buffer
    TInt totalDstBytesAdded = 0;
    // total src bytes added to the internal src buffer
    TInt totalSrcBytesCopied = 0;
    TInt internalInputBufferLen = 0;
    // temporary variable to use for copying the sorce or destination data
    TInt numberOfBytesCopied;


    /**
    * Process the dst buffer, update the dstBufferPos and check
    * whether dst buffer is NULL or not.
    */
    CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>( &aDst );
    const TInt dstMaxLen = dst->Data().MaxLength();
    TUint8* dstPtr = const_cast<TUint8*>( dst->Data().Ptr() );
    TInt dstBufferPos = dst->Position();

    /**
    * Process the src buffer, update srcbuffer length, position and
    * flag for last frame. check whether src buffer is NULL or not
    * and check src buffer contains any data
    */
    const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>( &aSrc );
    TUint8* srcPtr = const_cast <TUint8*>( src->Data().Ptr() );
    TInt srcBufferLen = src->Data().Length();
    TInt srcBufferPos = src->Position();
    TBool lastFrame = src->LastBuffer();

    PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d",srcBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d",dstBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d",
            iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d",
                iInternalInputBufferResidueLen ) );

    TInt srcBufferRemainingBytes = 0;
    srcBufferRemainingBytes = srcBufferLen - srcBufferPos -
                                                        totalSrcBytesCopied;
    TInt totRemainingSrc = srcBufferRemainingBytes +
                                            iInternalInputBufferResidueLen;
    if ( ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos == 0 )
            && ( totRemainingSrc < iSrclenToProcess ) && ( lastFrame ) )
        {
        totalSrcBytesCopied = 0;
        iInternalOutputBufferResidueLen = 0;
        iInternalInputBufferResidueLen = 0;
        iInternalOutputBufferPos = 0;
        PRINT_EXIT;
        return Result( TCodecProcessResult::EEndOfData,
                    totalSrcBytesCopied, totalDstBytesAdded );
        }

    /**
    * if any destination bytes from internal destination buffer is not
    * given to the dst buffer from the previous call, give it to the
    * dst buffer. After this block, it ensures that no bytes are remaining
    * in the internal destination buffer.
    */
    if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
        {
        numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );

        if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )

            {
            PRINT_EXIT;
            return Result( TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
            }
        else
            {
            if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 ) &&
                                    ( iInternalInputBufferResidueLen == 0 ) )
                {
                totalSrcBytesCopied = 0;
                iInternalOutputBufferResidueLen = 0;
                iInternalInputBufferResidueLen = 0;
                iInternalOutputBufferPos = 0;
                PRINT_EXIT;
                return Result( TCodecProcessResult::EEndOfData,
                            totalSrcBytesCopied, totalDstBytesAdded );
                }
            iInternalOutputBufferPos = 0;
            iInternalOutputBufferResidueLen = 0;
            }
        }
    TInt dstBufferRemainingBytes = 0;
    dstBufferRemainingBytes = dstMaxLen - dstBufferPos - totalDstBytesAdded;
    if ( dstBufferRemainingBytes == 0 )
        {
        PRINT_EXIT;
        return Result( TCodecProcessResult::EProcessIncomplete,
                                totalSrcBytesCopied, totalDstBytesAdded );
        }




    //generate header for ADIF and Raw encoded formats
    if ( !iHeaderGenerated )
        {
        if ( ( iParam.iOutputFormat == EFormatADIF ) ||
                                    ( iParam.iOutputFormat == EFormatRaw ) )
            {
            TInt retval = KErrNone;
            TInt headerLen = KMinDstLen;
            retval = iCodec->GetHeader( iInternalOutputBuffer,headerLen );

            /**
            * Fill Destination Buffer
            */

            iInternalOutputBufferResidueLen = headerLen;
            numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
            dstBufferRemainingBytes -= numberOfBytesCopied;

            iHeaderGenerated = ETrue;
            if ( ( iInternalOutputBufferResidueLen -
                            iInternalOutputBufferPos > 0 ) ||
                                            dstBufferRemainingBytes == 0 )
                {
                totalSrcBytesCopied = 0;
                PRINT_EXIT;
                return Result(
                            TCodecProcessResult::EProcessIncomplete,
                            totalSrcBytesCopied, totalDstBytesAdded );
                }
            }
        else
            {
            iHeaderGenerated = ETrue;
            }
        }

    TInt newSrcCopied = 0;
    /**
    * copy the src buffer data into the internal buffer till internal buffer
    * holds minimum bytes to process i.e KMinBytesInput. After this block, it
    * ensures that internal source buffer holds KMinBytesInput.
    * if it is a last frame, treat remaining residual buffer as internal
    * buffer.
    */
    if ( ( iSrclenToProcess - iInternalInputBufferResidueLen > 0 ) &&
                                        ( srcBufferLen - srcBufferPos > 0 ) )
        {
        numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
        newSrcCopied = numberOfBytesCopied;
        }

    if ( iSrclenToProcess > iInternalInputBufferResidueLen )
        {
        if ( !lastFrame )
            {
            PRINT_EXIT;
            return Result( TCodecProcessResult::EDstNotFilled,
                   srcBufferLen - srcBufferPos, totalDstBytesAdded );
            }
        else
            {
            totalSrcBytesCopied = 0;
            iInternalOutputBufferResidueLen = 0;
            iInternalInputBufferResidueLen = 0;
            iInternalOutputBufferPos = 0;
            PRINT_EXIT;
            return Result( TCodecProcessResult::EEndOfData,
                        totalSrcBytesCopied, totalDstBytesAdded );
            }
        }

    srcBufferRemainingBytes = srcBufferLen - srcBufferPos -
                                                        totalSrcBytesCopied;

    if ( lastFrame && ( ( iSrclenToProcess > iInternalInputBufferResidueLen )
            && ( iSrclenToProcess > srcBufferRemainingBytes ) )
            && ( iInternalOutputBufferResidueLen -
                                        iInternalOutputBufferPos == 0 ) )
        {
        totalSrcBytesCopied = 0;
        iInternalOutputBufferResidueLen = 0;
        iInternalInputBufferResidueLen = 0;
        iInternalOutputBufferPos = 0;
        PRINT_EXIT;
        return Result( TCodecProcessResult::EEndOfData,
                                    totalSrcBytesCopied, totalDstBytesAdded );
        }


    if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos == 0 )
        {
        iInternalOutputBufferResidueLen = 0;
        iInternalOutputBufferPos = 0;
        }
    /**
     * process the src buffer till destination buffer or source buffer or
     * both buffers are exhausted.
     */
    do
        {

        srcBufferRemainingBytes = srcBufferLen - srcBufferPos -
                                                        totalSrcBytesCopied;
        dstBufferRemainingBytes = dstMaxLen - dstBufferPos -
                                                        totalDstBytesAdded;
        TInt internalInputBufferPos = 0;

        /**
        * initialize the variables like srcUsed and dstLen accordingly.
        * call Encode.
        */
        TInt srcUsed = iSrclenToProcess;
        TInt dstLen  = KMinDstLen;
        TInt16* tempIn = NULL;
        tempIn = ( TInt16* ) ( ( iInternalInputBuffer +
                                                internalInputBufferPos ) );
        TInt error = iCodec->Encode( tempIn, srcUsed, iInternalOutputBuffer,
                                                                    dstLen );
        if ( error != KErrNone )
            {
            iInternalInputBufferResidueLen = 0;
            totalSrcBytesCopied = srcBufferLen;
            PRINT_ERR( error );
            return Result(
                    TCodecProcessResult::EProcessError,
                    totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos );
            }

        /**
         * Fill Destination Buffer
         */
        PRINT_MSG( LEVEL_HIGH, ( "dstLen: %d",dstLen ) );
        iInternalOutputBufferResidueLen = dstLen;
        numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
        dstBufferRemainingBytes -= numberOfBytesCopied;

        /***
        * Fill Source Buffer if FillBuffer flag is true
        */
        internalInputBufferPos += srcUsed ;
        ShiftData( internalInputBufferPos, 0 );

        if ( iFillBuffer )
            {
            numberOfBytesCopied = CopyFromSrcBuffer( src,
                                                        totalSrcBytesCopied );
            srcBufferRemainingBytes -= numberOfBytesCopied;
            }

        /***
        * check four conditions if else for src and if else for dst
        */
        // src has available bytes
        TInt totSrcUsed = 0;
        if ( ( iSrclenToProcess > srcBufferRemainingBytes ) &&
                    ( iSrclenToProcess > iInternalInputBufferResidueLen ) &&
                                                    ( lastFrame ) )
            {
            iInternalOutputBufferResidueLen = 0;
            iInternalInputBufferResidueLen = 0;
            iInternalOutputBufferPos = 0;
            PRINT_EXIT;
            return Result( TCodecProcessResult::EEndOfData,
                    totalSrcBytesCopied, totalDstBytesAdded );
            }

        if ( srcBufferRemainingBytes > 0 || iInternalInputBufferResidueLen >=
                                                            iSrclenToProcess )
            {
            if ( dstBufferRemainingBytes > 0 )
                {
                if ( !iFillBuffer )
                    {
                    totSrcUsed = srcBufferPos + srcUsed;
                    totalSrcBytesCopied = newSrcCopied;
                    PRINT_EXIT;
                    return Result(
                            TCodecProcessResult::EProcessIncomplete,
                            totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
            else
                {
                PRINT_EXIT;
                return Result(
                            TCodecProcessResult::EProcessIncomplete,
                            totalSrcBytesCopied, totalDstBytesAdded );
                }

            }
        else
            {
            if ( dstBufferRemainingBytes > 0 )
                {
                if ( lastFrame )
                    {
                    if ( iInternalInputBufferResidueLen >= iSrclenToProcess )
                        {
                        if ( !iFillBuffer )
                            {
                            totSrcUsed = srcBufferPos + srcUsed;
                            totalSrcBytesCopied = newSrcCopied;
                            PRINT_EXIT;
                            return Result(
                                    TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                            }
                        }
                    else
                        {
                        iInternalOutputBufferResidueLen = 0;
                        iInternalInputBufferResidueLen = 0;
                        iInternalOutputBufferPos = 0;
                        PRINT_EXIT;
                        return Result( TCodecProcessResult::EEndOfData,
                                totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    }
                else
                    {
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EDstNotFilled,
                                totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
            else
                {
                if ( iInternalOutputBufferResidueLen -
                                                iInternalOutputBufferPos > 0 )
                    {
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                    }
                else
                    {
                    if( lastFrame && (iInternalInputBufferResidueLen == 0 ) )

                        {
                        iInternalOutputBufferResidueLen = 0;
                        iInternalInputBufferResidueLen = 0;
                        iInternalOutputBufferPos = 0;
                        PRINT_EXIT;
                        return Result( TCodecProcessResult::EEndOfData,
                                totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    else
                        {
                        PRINT_EXIT;
                        return Result(
                               TCodecProcessResult::EProcessComplete,
                               totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    }
                }
            }
        }while ( 1 );
    }
Пример #20
0
/**
Fills the buffer with audio/Video data and informs the observer
@param aBuffer
*/
void CAviReader::BufferFilledL(CMMFBuffer* aBuffer)
{
    if (!aBuffer)
    {
        User::Leave(KErrArgument);
    }
    if (aBuffer == iVideoBuffer)
    {
        //callback for video read when the file is not interleaved(No REC lists)
        iBufferFromDevVideo->iData.Copy(iVideoBuffer->Data());
        iObserver.VideoBufferFilled(iBufferFromDevVideo);
    }
    else if (aBuffer == iAudioBuffer)
    {
        //callback for audio read when the file is not interleaved(No REC lists)
        CMMFDataBuffer* bufferFromSink = static_cast<CMMFDataBuffer*>(iBufferFromDevSound);

        TInt sinkBufLen = bufferFromSink->Data().MaxSize();
        TInt audBufLen = iAudioBuffer->Data().Length();

        if (sinkBufLen < audBufLen)
        {
            bufferFromSink->Data().Copy(iAudioBuffer->Data().Ptr(), sinkBufLen);
            CMMFDescriptorBuffer* tempBuffer = CMMFDescriptorBuffer::NewL(audBufLen - sinkBufLen);
            tempBuffer->Data().Copy(iAudioBuffer->Data().Mid(sinkBufLen));
            delete iAudioBuffer;
            iAudioBuffer = tempBuffer;
        }
        else
        {
            // DEF113319 - call SetLastBuffer when sending last audio chunk
            TInt position = 0;
            position = (iMainHeader.iFlags == KAVIF_ISINTERLEAVED) ? iSourcePos : iAudioPos;
            if(!IsAudioDataAvailableL(position))
            {
                bufferFromSink->SetLastBuffer(ETrue);
                SetMediaEOS(KUidMediaTypeAudio);
            }

            bufferFromSink->Data().Copy(iAudioBuffer->Data());
            delete iAudioBuffer;
            iAudioBuffer = NULL;
        }
        iObserver.AudioBufferFilled();
    }
    else if (aBuffer == iSourceBuffer)//callback for REC list
    {
        //callback for REC list read. We need to extract video and audio chunks from the sourcebuffer
        TUint8* rawform = &(iSourceBuffer->Data()[0]);
        TInt desPos = 0; //position in descriptor

        //Now we should be pointing to audio or video chunks
        TInt bufLen = iSourceBuffer->Data().Length();
        if(bufLen < 4)
        {
            User::Leave(KErrCorrupt);
        }
        rawform += 4; //skip the fourcc of REC
        desPos += 4; //byte count corresponding to where rawform points to

        if (bufLen - desPos < 8)
        {
            //if the buffer is not long enough to accomodate - chunk id and size leave
            User::Leave(KErrCorrupt);
        }

        for (TUint8 i=0; i < iMainHeader.iStreams; i++)//we expect only 2 streams at the moment
        {
            if (desPos == bufLen) //caution check for the necessity of the block
            {
                //Sometimes we only have one stream in this list. No more data to read
                break;
            }

            if (bufLen - desPos < 8 && i== 1)
            {
                //if the buffer is not long enough to accomodate - chunk id and size leave
                break;
            }

            TUint32 dwChunkId = Read32(rawform);
            rawform += 4; //Skip chunkId
            desPos += 4;
            TBool bAudioId = EFalse;
            TBool bVideoId = EFalse;
            switch (dwChunkId)	//identify chunk
            {
            case KRiffChunkName00db:
            case KRiffChunkName00dc:
            case KRiffChunkName01db:
            case KRiffChunkName01dc:
                bVideoId = ETrue;
                break;
            case KRiffChunkName00wb:
            case KRiffChunkName01wb:
                bAudioId = ETrue;
                break;
            default:
                User::Leave(KErrCorrupt);
            }

            if (!bAudioId && !bVideoId)
            {
                //we are supposed to get audio or video stream here. if anything else, we return KErrCorrupt
                User::Leave(KErrCorrupt);
            }
            TUint32 dwChunkSz = Read32(rawform);
            if (dwChunkSz > bufLen - desPos)
            {
                User::Leave(KErrCorrupt); //caution - check
            }
            rawform += 4; //Skip chunkSize
            desPos += 4;
            TPtr8 temp = iSourceBuffer->Data().MidTPtr(desPos, dwChunkSz);
            if (bVideoId)// video
            {
                if (iVideoRequestMade)
                {
                    //if video request is already made we can copy the data directly into the devvideo buffer
                    //instead of iVideoBuffer
                    iBufferFromDevVideo->iData.Copy(temp);
                }
                else
                {
                    //DevVideo request is not made. So copy the data into video buffer
                    delete iVideoBuffer;
                    iVideoBuffer = NULL;
                    iVideoBuffer = CMMFDescriptorBuffer::NewL(dwChunkSz);
                    iVideoBuffer->Data().Copy(temp);
                }
            }
            else if (bAudioId)//audio
            {
                if (iAudioRequestMade)
                {
                    //if audio request is already made, copy the data into devsound buffer
                    CMMFDataBuffer* bufferFromSink = static_cast<CMMFDataBuffer*>(iBufferFromDevSound);
                    bufferFromSink->Data().Copy(temp);
                }
                else
                {
                    //DevSound request is not made. copy the audio chunk into audio buffer
                    delete iAudioBuffer;
                    iAudioBuffer = NULL;
                    iAudioBuffer = CMMFDescriptorBuffer::NewL(dwChunkSz);
                    iAudioBuffer->Data().Copy(temp);
                }
            }
            rawform	+= dwChunkSz;//Skip video/audio chunk
            desPos += dwChunkSz;
        }
        iReadCompleted = ETrue;//REC list is read
        // we send the bufferfilled callbacks after both audio and video requests are made.
        ReadComplete();
    }
    else
    {
        User::Leave(KErrCorrupt);
    }
}
// ---------------------------------------------------------------------------
//  From class CMMFCodec.
//  This function is used to decode the given source and fill the destination
//  buffer with the decode data.
//  The buffers can be of any size.  Since the buffers can be of any size
//  there is no guarantee that all the source buffer can be processed to fill
//  the destination buffer or that the all the source buffer may be processed
//  before the destination is full.  Therefore the ProcessL needs to return a
//  TCodecProcessResult returing the number of source bytes processed and the
//  number of destination bytes processed along with a process result code
//  defined thus:
//  - EProcessComplete: the codec processed all the source data into the sink
//    buffer
//  - EProcessIncomplete: the codec filled sink buffer before all the source
//    buffer was processed
//  - EDstNotFilled: the codec processed the source buffer but the sink buffer
//    was not filled
//  - EEndOfData: the codec detected the end data - all source data in
//    processed but sink may not be full
//  - EProcessError: the codec process error condition
//
//  The ProcessL should start processing the source buffer from the iPosition
//  data member of the source data and start filling the destination buffer
//  from its iPosition.
//  --------------------------------------------------------------------------
//
TCodecProcessResult CAriHeAacDecMmfCodec::ProcessL( const CMMFBuffer& aSrc,
                                                CMMFBuffer& aDst )
    {
    PRINT_ENTRY;

    if ( !iConfigured )
        {
        PRINT_ERR( "Decoder not yet configured" );
        User::Leave( KErrNotReady );
        }
    // total decoded bytes added to the dst buffer
    TInt totalDstBytesAdded = 0;
    // total src bytes added to the internal src buffer
    TInt totalSrcBytesCopied = 0;
    // temporary variable to use for copying the sorce or destination data
    TInt numberOfBytesCopied = 0;
    TInt dstBufferRemainingBytes = 0;

    /**
     * Process the dst buffer, update the dstBufferPos and check
     * whether dst buffer is NULL or not.
     */
    CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>( &aDst );
    const TInt dstMaxLen = dst->Data().MaxLength();
    TUint8* dstPtr = const_cast<TUint8*>( dst->Data().Ptr() );
    TInt dstBufferPos = dst->Position();

    /**
     * Process the src buffer, update srcbuffer length, position and
     * flag for last frame. check whether src buffer is NULL or not
     * and check src buffer contains any data
     */
    const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>( &aSrc );
    TUint8* srcPtr = const_cast<TUint8*>( src->Data().Ptr() );
    TInt srcBufferLen = src->Data().Length();
    TInt srcBufferPos = src->Position();
    TBool lastFrame = src->LastBuffer();

    PRINT_MSG( LEVEL_HIGH, ( "Src Buffer Pos: %d", srcBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Dst Buffer Pos: %d", dstBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Residue in internal output buffer: %d",
           iInternalOutputBufferResidueLen - iInternalOutputBufferPos ) );
    PRINT_MSG( LEVEL_HIGH, ( "Residue in internal input buffer: %d",
                                      iInternalInputBufferResidueLen ) );
    /**
     * if any destination bytes from internal destination buffer is not
     * given to the dst buffer from the previous call, give it to the
     * dst buffer. After this block, it ensures that no bytes are remaining
     * in the internal destination buffer.
     */
    if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
        {
        numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );

        if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
            {
            PRINT_EXIT;
            return Result( TCodecProcessResult::EProcessIncomplete,
                            totalSrcBytesCopied, totalDstBytesAdded );
            }
        else
            {
            //Decode NULL frame to handle error concealment
            if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&&
            ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) )
                {
                dstBufferRemainingBytes = dstMaxLen - dstBufferPos -
                                                    totalDstBytesAdded;
                if ( dstBufferRemainingBytes == 0 )
                    {
                    iInternalOutputBufferPos = 0;
                    iInternalOutputBufferResidueLen = 0;
                    totalSrcBytesCopied = 0;
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                     }

                TInt dstLen  = iOutFrameSize;
                DecodeLastFrame(dstLen);
                iInternalOutputBufferResidueLen = dstLen;

                numberOfBytesCopied =
                                CopyToDstBuffer( dst, totalDstBytesAdded );
                totalDstBytesAdded += numberOfBytesCopied;
                dstBufferRemainingBytes -= numberOfBytesCopied;

                if ( ( iInternalOutputBufferResidueLen -
                    iInternalOutputBufferPos == 0 ) && iLastFrameDecoded )
                    {
                    totalSrcBytesCopied = 0;
                    iInternalOutputBufferResidueLen = 0;
                    iInternalInputBufferResidueLen = 0;
                    iInternalOutputBufferPos = 0;
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EEndOfData,
                                totalSrcBytesCopied, totalDstBytesAdded );
                    }
                else
                    {
                    totalSrcBytesCopied = 0;
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
            iInternalOutputBufferPos = 0;
            iInternalOutputBufferResidueLen = 0;
            }
        }
    else
        {
        if ( lastFrame && ( srcBufferLen - srcBufferPos == 0 )&&
            ( iInternalInputBufferResidueLen == 0 && !iLastFrameDecoded ) )
            {
            TInt dstLen  = iOutFrameSize;
            DecodeLastFrame(dstLen);
            iInternalOutputBufferResidueLen = dstLen;

            numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
            totalDstBytesAdded += numberOfBytesCopied;
            dstBufferRemainingBytes -= numberOfBytesCopied;

            if ( ( iInternalOutputBufferResidueLen -
                    iInternalOutputBufferPos == 0 ) && iLastFrameDecoded )
                {
                totalSrcBytesCopied = 0;
                iInternalOutputBufferResidueLen = 0;
                iInternalInputBufferResidueLen = 0;
                iInternalOutputBufferPos = 0;
                PRINT_EXIT;
                return Result( TCodecProcessResult::EEndOfData,
                            totalSrcBytesCopied, totalDstBytesAdded );
                }
            else
                {
                totalSrcBytesCopied = 0;
                PRINT_EXIT;
                return Result( TCodecProcessResult::EProcessIncomplete,
                                totalSrcBytesCopied, totalDstBytesAdded );
                }
            }
        }

    /**
     * copy the src buffer data into the internal buffer till internal buffer
     * holds minimum bytes to process i.e KMinBytesInput. After this block,
     * it ensures that internal source buffer holds KMinBytesInput.
     * if it is a last frame, treat remaining residual buffer as internal
     * buffer.
     */
    if ( ( KMinBytesInput - iInternalInputBufferResidueLen > 0 ) &&
                                ( srcBufferLen - srcBufferPos > 0 ) )
        {
        numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
        }

    /**
     * update the internal buffer length.
     */
    if ( ( KMinBytesInput > iInternalInputBufferResidueLen ) &&
                                                        ( !lastFrame ) )
        {
        PRINT_EXIT;
        return Result( TCodecProcessResult::EDstNotFilled,
                srcBufferLen - srcBufferPos, totalDstBytesAdded );
        }

    if ( iLastFrameDecoded && iInternalInputBufferResidueLen == 0 &&
                                    iInternalOutputBufferResidueLen == 0 )
        {
        totalSrcBytesCopied = 0;
        iInternalOutputBufferResidueLen = 0;
        iInternalInputBufferResidueLen = 0;
        iInternalOutputBufferPos = 0;
        PRINT_EXIT;
        return Result( TCodecProcessResult::EEndOfData,
                    totalSrcBytesCopied, totalDstBytesAdded );
        }

    /**
     * process the src buffer till destination buffer or source buffer or
     * both buffers are exhausted.
     */
    do
        {
        TInt srcBufferRemainingBytes = srcBufferLen - srcBufferPos -
                                                        totalSrcBytesCopied;
        dstBufferRemainingBytes = dstMaxLen - dstBufferPos -
                                                        totalDstBytesAdded;
        TInt internalInputBufferPos = 0;

        /**
         * initialize the variables like iSrcUsed and dstLen accordingly.
         * call Decode.
         */
        iSrcUsed = iInternalInputBufferResidueLen - internalInputBufferPos;
        TInt dstLen  = iOutFrameSize;

        TInt error = iCodec->Decode(
                            &iInternalInputBuffer[internalInputBufferPos],
                                iSrcUsed, iInternalOutputBuffer, dstLen );
        if ( error != 0 )
            {
            iInternalInputBufferResidueLen = 0;
            totalSrcBytesCopied = srcBufferLen;
            PRINT_ERR( error );
            return Result(
                    TCodecProcessResult::EProcessError,
                    totalSrcBytesCopied, totalDstBytesAdded + dstBufferPos);
            }
        iFrameNum++;
        PRINT_MSG( LEVEL_HIGH, ( "Frame: %d", iFrameNum ) );
        PRINT_MSG( LEVEL_HIGH, ( "iSrcUsed: %d", iSrcUsed ) );
        PRINT_MSG( LEVEL_HIGH, ( "dstLen: %d", dstLen ) );

        /**
         * Fill Destination Buffer
         */
        iInternalOutputBufferResidueLen = dstLen;
        numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
        dstBufferRemainingBytes -= numberOfBytesCopied;

        /**
         * Fill Source Buffer
         */
        internalInputBufferPos += iSrcUsed ;
        ShiftData( internalInputBufferPos, 0 );
        numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
        srcBufferRemainingBytes -= numberOfBytesCopied;

        /**
         * check four conditions if else for src and if else for dst
         */
        /**
         * src has available bytes
         */
        if ( srcBufferRemainingBytes > 0  ||
                iInternalInputBufferResidueLen >= KMinBytesInput )
            {
            if ( dstBufferRemainingBytes == 0 )
                {
                PRINT_EXIT;
                return Result(
                        TCodecProcessResult::EProcessIncomplete,
                        totalSrcBytesCopied, totalDstBytesAdded );
                }
            }
        else
            {
            // dst buffer has availabe space for decoded bytes
            if ( dstBufferRemainingBytes > 0 )
                {
                if ( lastFrame )
                    {
                    if ( iInternalInputBufferResidueLen == 0 )
                        {
                        TInt dstLen  = iOutFrameSize;
                        DecodeLastFrame(dstLen);
                        iInternalOutputBufferResidueLen = dstLen;

                        numberOfBytesCopied =
                                CopyToDstBuffer( dst, totalDstBytesAdded );
                        totalDstBytesAdded += numberOfBytesCopied;
                        dstBufferRemainingBytes -= numberOfBytesCopied;

                        if ( ( iInternalOutputBufferResidueLen -
                                iInternalOutputBufferPos == 0 ) &&
                                iLastFrameDecoded )
                            {
                            totalSrcBytesCopied = 0;
                            iInternalOutputBufferResidueLen = 0;
                            iInternalInputBufferResidueLen = 0;
                            iInternalOutputBufferPos = 0;
                            PRINT_EXIT;
                            return Result( TCodecProcessResult::EEndOfData,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                            }
                        else
                            {
                            totalSrcBytesCopied = 0;
                            PRINT_EXIT;
                            return Result(
                                    TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                            }
                        }
                    }
                else
                    {
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EDstNotFilled,
                            totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
            else
                {
                if ( iInternalOutputBufferResidueLen -
                                            iInternalOutputBufferPos > 0 )
                    {
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                    }
                else
                    {
                    if ( lastFrame )
                        {
                        PRINT_EXIT;
                        return Result(
                                    TCodecProcessResult::EProcessIncomplete,
                                    totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    else
                        {
                        PRINT_EXIT;
                        return Result(
                                TCodecProcessResult::EProcessComplete,
                                totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    }
                }
            }
        }while ( 1 );
    }
TCodecProcessResult CAriMp3DecMmfCodec::ProcessL( const CMMFBuffer& aSrc,
        CMMFBuffer& aDst )
{
    PRINT_ENTRY;
    // total decoded bytes added to the dst buffer
    TInt totalDstBytesAdded = 0;
    // total src bytes added to the internal src buffer
    TInt totalSrcBytesCopied = 0;
    // temporary variable to use for copying the sorce or destination data
    TInt numberOfBytesCopied;
    // Flag for finding valid sync
    TBool syncFound = EFalse;

    /**
    * Process the dst buffer, update the dstBufferPos and check
    * whether dst buffer is NULL or not.
    */
    CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>( &aDst );

    const TInt dstMaxLen = dst->Data().MaxLength();
    TUint8* dstPtr = const_cast<TUint8*>( dst->Data().Ptr() );
    TInt dstBufferPos = dst->Position();

    /**
    * Process the src buffer, update srcbuffer length, position and
    * flag for last frame. check whether src buffer is NULL or not
    * and check src buffer contains any data
    */
    const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>( &aSrc );

    TUint8* srcPtr = const_cast <TUint8*>( src->Data().Ptr() );
    TInt srcBufferLen = src->Data().Length();
    TInt srcBufferPos = src->Position();
    TBool lastFrame = src->LastBuffer();

    if ( srcBufferLen == 0 && iInternalInputBufferResidueLen == 0 )
    {
        PRINT_ERR( "source buffer length is zero" );
        User::Leave( KErrArgument );
    }

    /**
    * if any destination bytes from internal destination buffer is not
    * given to the dst buffer from the previous call, give it to the
    * dst buffer. After this block, it ensures that no bytes are remaining
    * in the internal destination buffer.
    */
    if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
    {
        numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );

        if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
        {
            PRINT_EXIT;
            return Result( TCodecProcessResult::EProcessIncomplete,
                           totalSrcBytesCopied, totalDstBytesAdded );
        }
        else
        {
            if ( ( lastFrame ) && ( srcBufferLen - srcBufferPos == 0 )&&
                    ( iInternalInputBufferResidueLen == 0 ) )
            {
                iInternalOutputBufferResidueLen = 0;
                iInternalInputBufferResidueLen = 0;
                iInternalOutputBufferPos = 0;
                PRINT_EXIT;
                return Result( TCodecProcessResult::EEndOfData,
                               totalSrcBytesCopied, totalDstBytesAdded );
            }
            iInternalOutputBufferPos = 0;
            iInternalOutputBufferResidueLen = 0;
        }
    }

    /**
    * copy the src buffer data into the internal buffer till internal buffer
    * holds minimum bytes to process i.e KMinBytesInput. After this block, it
    * ensures that internal source buffer holds KMinBytesInput.
    * if it is a last frame, treat remaining residual buffer as internal
    * buffer.
    */
    if ( ( KMinBytesInput - iInternalInputBufferResidueLen > 0 )
            && ( srcBufferLen - srcBufferPos > 0 ) )
    {
        numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
    }

    if ( ( KMinBytesInput > iInternalInputBufferResidueLen )
            && ( !lastFrame ) )
    {
        PRINT_EXIT;
        return Result( TCodecProcessResult::EDstNotFilled,
                       srcBufferLen - srcBufferPos, totalDstBytesAdded );
    }

    /**
    * process the src buffer till destination buffer or source buffer
    * or both buffers are exhausted.
    */
    do
    {
        /**
        * call seeksync to find the valid fram start offset i.e syncpos.
        * update internal buffer position to that offset position if it is
        * success.if it is failed then there is no valid frame start in
        * the available buffer. Go for new src buffer. all bytes present
        * in the internal buffer are discarded.
        */
        TInt syncpos;
        TInt srcBufferRemainingBytes = srcBufferLen
                                       - srcBufferPos
                                       - totalSrcBytesCopied;
        TInt dstBufferRemainingBytes = dstMaxLen
                                       - dstBufferPos
                                       - totalDstBytesAdded;
        TInt internalInputBufferPos = 0;

        if ( KErrNone != iCodec->SeekSync(
                    &iInternalInputBuffer[internalInputBufferPos],
                    ( iInternalInputBufferResidueLen - internalInputBufferPos ),
                    syncpos ) )
        {
            TCodecProcessResult result = GetNewData( src, totalSrcBytesCopied,
                                         totalDstBytesAdded );

            if ( result.iStatus == TCodecProcessResult::EDstNotFilled ||
                    result.iStatus == TCodecProcessResult::EEndOfData )
            {
                return result;
            }
        }
        else
        {
            syncFound = ETrue;
            internalInputBufferPos += syncpos;
        }
        /**
        * call GetFrameInfo to find whether valid frame is present in the
        * availabel buffer.if it is success and framelength is 0 then
        * there is no valid frame is present,  discard the present buffer
        * till sync position and add new buffer.
        */
        if ( syncFound )
        {
            TInt frameLen;
            TMp3FrameInfo frameInfo;
            if ( KErrNone != iCodec->GetFrameInfo(
                        &iInternalInputBuffer[internalInputBufferPos],
                        ( iInternalInputBufferResidueLen - internalInputBufferPos ),
                        frameLen, frameInfo ) )
            {
                PRINT_ERR( "Decoder Getframeinfo failed" );
                User::Leave( KErrGeneral );
            }
            if ( frameLen == 0 )
            {
                TCodecProcessResult result = GetNewData( src,
                                             totalSrcBytesCopied, totalDstBytesAdded );

                if ( result.iStatus == TCodecProcessResult::EDstNotFilled ||
                        result.iStatus == TCodecProcessResult::EEndOfData )
                {
                    return result;
                }
            }

            /**
            * if the buffer has less than framelen then fill the internal
            * sorce buffer with KMinBytesInput bytes.
            */
            if ( frameLen   > ( iInternalInputBufferResidueLen
                                - internalInputBufferPos ) )
            {
                if( lastFrame )
                {
                    iInternalInputBufferResidueLen = 0;
                    iInternalOutputBufferResidueLen = 0;
                    iInternalOutputBufferPos = 0;
                    PRINT_EXIT;
                    return Result(
                               TCodecProcessResult::EEndOfData,
                               totalSrcBytesCopied, totalDstBytesAdded );
                }

                ShiftData( internalInputBufferPos, 0 );
                numberOfBytesCopied = CopyFromSrcBuffer( src,
                                      totalSrcBytesCopied );
                internalInputBufferPos = 0;

                if ( iInternalInputBufferResidueLen < KMinBytesInput )
                {
                    PRINT_EXIT;
                    return Result(
                               TCodecProcessResult::EDstNotFilled,
                               totalSrcBytesCopied, totalDstBytesAdded );
                }
            }

            /**
            * initialize the variables like srcUsed and dstLen accordingly.
            * call Decode.
            */

            TInt srcUsed = iInternalInputBufferResidueLen
                           - internalInputBufferPos;
            TInt dstLen  = iOutFrameSize;

            TInt error = iCodec->Decode(
                             &iInternalInputBuffer[internalInputBufferPos],
                             srcUsed, iInternalOutputBuffer, dstLen );

            if ( KErrNone != error )
            {
                iInternalInputBufferResidueLen = 0;
                PRINT_ERR( error );
                return Result(
                           TCodecProcessResult::EProcessError,
                           totalSrcBytesCopied, totalDstBytesAdded );
            }

            /**
            * Fill Destination Buffer
            */

            iInternalOutputBufferResidueLen = dstLen;
            numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
            dstBufferRemainingBytes -= numberOfBytesCopied;

            /***
            * Fill Sorce Buffer
            */

            internalInputBufferPos += srcUsed ;
            ShiftData( internalInputBufferPos, 0 );
            numberOfBytesCopied = CopyFromSrcBuffer( src,
                                  totalSrcBytesCopied );
            srcBufferRemainingBytes -= numberOfBytesCopied;
            internalInputBufferPos = 0;

            /***
            * check four conditions if else for src and if else for dst
            */

            // src buffer has available bytes to decode
            if ( srcBufferRemainingBytes > 0 )
            {
                if ( dstBufferRemainingBytes == 0 )
                {
                    PRINT_EXIT;
                    return Result( TCodecProcessResult::EProcessIncomplete,
                                   totalSrcBytesCopied, totalDstBytesAdded );
                }
            }

            else
            {
                // dst buffer has availabe space for decoded bytes
                if ( dstBufferRemainingBytes > 0 )
                {
                    // last frame of the input stream
                    if ( lastFrame )
                    {
                        if ( iInternalInputBufferResidueLen == 0 )
                        {
                            PRINT_EXIT;
                            return Result( TCodecProcessResult::EEndOfData,
                                           totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    }
                    else
                    {
                        PRINT_EXIT;
                        return Result( TCodecProcessResult::EDstNotFilled,
                                       totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
                else
                {
                    /**
                     *internal output buffer has decoded bytes which is not
                     *given to dst buffer.
                     */
                    if ( iInternalOutputBufferResidueLen
                            - iInternalOutputBufferPos > 0 )
                    {
                        PRINT_EXIT;
                        return Result(
                                   TCodecProcessResult::EProcessIncomplete,
                                   totalSrcBytesCopied, totalDstBytesAdded );
                    }
                    // last frame of the input stream
                    else if ( lastFrame )
                    {
                        // if internal buffer has available bytes to decode
                        if ( iInternalInputBufferResidueLen > 0 )
                        {
                            PRINT_EXIT;
                            return Result(
                                       TCodecProcessResult::EProcessIncomplete,
                                       totalSrcBytesCopied, totalDstBytesAdded );
                        }
                        else
                        {
                            iInternalInputBufferResidueLen = 0;
                            PRINT_EXIT;
                            return Result(
                                       TCodecProcessResult::EEndOfData,
                                       totalSrcBytesCopied, totalDstBytesAdded );
                        }
                    }
                    else
                    {
                        PRINT_EXIT;
                        return Result(
                                   TCodecProcessResult::EProcessComplete,
                                   totalSrcBytesCopied, totalDstBytesAdded );
                    }
                }
            }
        }
    } while ( 1 );
}
//---------------------------------------------------------------------------
// From class CMMFCodec.
// This function is used to decode the given source and fill the destination
// buffer with the decode data.
// The buffers can be of any size.  Since the buffers can be of any size there
// is no guarantee that all the source buffer can be processed to fill the
// destination buffer or that the all the source buffer may be processed
// before the destination is full.  Therefore the ProcessL needs to return a
// TCodecProcessResult returing the number of source bytes processed and the
// number of destination bytes processed along with a process result code
// defined thus:
// - EProcessComplete: the codec processed all the source data into the sink
//	 buffer
// - EProcessIncomplete: the codec filled sink buffer before all the source
//   buffer was processed
// - EDstNotFilled: the codec processed the source buffer but the sink buffer
//   was not filled
// - EEndOfData: the codec detected the end data - all source data in
//   processed but sink may not be full
// - EProcessError: the codec process error condition
//
// The ProcessL should start processing the source buffer from the iPosition
// data member of the source data and start filling the destination buffer
// from its iPosition.
//---------------------------------------------------------------------------
//
TCodecProcessResult CAriAmrNbDecMmfCodec::ProcessL( const CMMFBuffer& aSrc,
													CMMFBuffer& aDst )
    {
	PRINT_ENTRY;
	// total decoded bytes added to the dst buffer
	TInt totalDstBytesAdded = 0;
	// total src bytes added to the internal src buffer
	TInt totalSrcBytesCopied = 0;
	// temporary variable to use for copying the sorce or destination data
	TInt numberOfBytesCopied;
	// Flag for finding valid sync
	TBool syncFound = EFalse;

	/**
	* Process the dst buffer, update the dstBufferPos and check
	* whether dst buffer is NULL or not.
	*/
	CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>( &aDst );

	const TInt dstMaxLen = dst->Data().MaxLength();
	TUint8* dstPtr = const_cast<TUint8*>( dst->Data().Ptr() );
	TInt dstBufferPos = dst->Position();

	/**
	* Process the src buffer, update srcbuffer length, position and
	* flag for last frame. check whether src buffer is NULL or not
	* and check src buffer contains any data
	*/
	const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>( &aSrc );

	TUint8* srcPtr = const_cast <TUint8*>( src->Data().Ptr() );
	TInt srcBufferLen = src->Data().Length();
	TInt srcBufferPos = src->Position();
	TBool lastFrame = src->LastBuffer();

	if ( srcBufferLen == 0 && iInternalInputBufferResidueLen == 0 )
		{
		PRINT_ERR( "source buffer length is zero" );
		User::Leave( KErrArgument );
		}

	/**
	* if any destination bytes from internal destination buffer is not
	* given to the dst buffer from the previous call, give it to the
	* dst buffer. After this block, it ensures that no bytes are remaining
	* in the internal destination buffer.
	*/
	if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
		{
		numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );

		if ( iInternalOutputBufferResidueLen - iInternalOutputBufferPos > 0 )
			{
			PRINT_EXIT;
			return Result( TCodecProcessResult::EProcessIncomplete,
							totalSrcBytesCopied, totalDstBytesAdded );
			}
		else
			{
			if ( ( lastFrame ) && ( srcBufferLen - srcBufferPos == 0 )&&
								( iInternalInputBufferResidueLen == 0 ) )
				{
				iInternalOutputBufferResidueLen = 0;
				iInternalInputBufferResidueLen = 0;
				iInternalOutputBufferPos = 0;
				PRINT_EXIT;
				return Result( TCodecProcessResult::EEndOfData,
								totalSrcBytesCopied, totalDstBytesAdded );
				}
			iInternalOutputBufferPos = 0;
			iInternalOutputBufferResidueLen = 0;
			}
		}

	/**
	* copy the src buffer data into the internal buffer till internal buffer
	* holds minimum bytes to process i.e KMinBytesInput. After this block, it
	* ensures that internal source buffer holds KMinBytesInput.
	* if it is a last frame, treat remaining residual buffer as internal
	* buffer.
	*/
	if ( ( KAMRNBMinOutBufLength - iInternalInputBufferResidueLen > 0 )
							&& ( srcBufferLen - srcBufferPos > 0 ) )
		{
		numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
		}

	if ( ( KAMRNBMinOutBufLength > iInternalInputBufferResidueLen )
														&& ( !lastFrame ) )
		{
		PRINT_EXIT;
		return Result( TCodecProcessResult::EDstNotFilled,
						srcBufferLen - srcBufferPos, totalDstBytesAdded );
		}

	/**
	* process the src buffer till destination buffer or source buffer
	* or both buffers are exhausted.
	*/
	do
	{
		TInt srcBufferRemainingBytes = srcBufferLen
									  - srcBufferPos
									  - totalSrcBytesCopied;
		TInt dstBufferRemainingBytes = dstMaxLen
									   - dstBufferPos
									   - totalDstBytesAdded;
		TInt internalInputBufferPos = 0;


		/**
		* initialize the variables like srcUsed and dstLen accordingly.
		* call Decode.
		*/

		TInt srcUsed = iInternalInputBufferResidueLen
						- internalInputBufferPos;
		TInt dstLen  = KAMRNBMinOutBufLength;

		TInt error =
		iCodec->Decode( &iInternalInputBuffer[internalInputBufferPos],
						srcUsed, ( TInt* )iInternalOutputBuffer, dstLen );

		if ( KErrNone != error )
			{
			iInternalInputBufferResidueLen = 0;
			PRINT_ERR( "Amr Nb Decoder decodes fails" );
			return Result(
					TCodecProcessResult::EProcessError,
					totalSrcBytesCopied, totalDstBytesAdded );
			}

		/**
		* Fill Destination Buffer
		*/

		iInternalOutputBufferResidueLen = dstLen;
		numberOfBytesCopied = CopyToDstBuffer( dst, totalDstBytesAdded );
		dstBufferRemainingBytes -= numberOfBytesCopied;

		/***
		* Fill Sorce Buffer
		*/

		internalInputBufferPos += srcUsed ;
		ShiftData( internalInputBufferPos, 0 );
		numberOfBytesCopied = CopyFromSrcBuffer( src, totalSrcBytesCopied );
		srcBufferRemainingBytes -= numberOfBytesCopied;
		internalInputBufferPos = 0;

		/***
		* check four conditions if else for src and if else for dst
		*/

		// src buffer has available bytes to decode
		if ( srcBufferRemainingBytes > 0 )
			{
			if ( dstBufferRemainingBytes == 0 )
				{
				PRINT_EXIT;
				return Result( TCodecProcessResult::EProcessIncomplete,
						totalSrcBytesCopied, totalDstBytesAdded );
				}
			}

		else
			{
			// dst buffer has availabe space for decoded bytes
			if ( dstBufferRemainingBytes > 0 )
				{
				// last frame of the input stream
				if ( lastFrame )
					{
					if ( iInternalInputBufferResidueLen == 0 )
						{
						PRINT_EXIT;
						return Result( TCodecProcessResult::EEndOfData,
								totalSrcBytesCopied, totalDstBytesAdded );
						}
					}
				else
					{
					PRINT_EXIT;
					return Result( TCodecProcessResult::EDstNotFilled,
							totalSrcBytesCopied, totalDstBytesAdded );
					}
				}
			else
				{
				/**
				 *internal output buffer has decoded bytes which is not
				 *given to dst buffer.
				 */
				if ( iInternalOutputBufferResidueLen
									- iInternalOutputBufferPos > 0 )
					{
					PRINT_EXIT;
					return Result( TCodecProcessResult::EProcessIncomplete,
									totalSrcBytesCopied, totalDstBytesAdded );
					}
				// last frame of the input stream
				else if ( lastFrame )
					{
					// if internal buffer has available bytes to decode
					if ( iInternalInputBufferResidueLen > 0 )
						{
						PRINT_EXIT;
						return Result(
								TCodecProcessResult::EProcessIncomplete,
								totalSrcBytesCopied, totalDstBytesAdded );
						}
					else
						{
						iInternalInputBufferResidueLen = 0;
						PRINT_EXIT;
						return Result( TCodecProcessResult::EEndOfData,
									totalSrcBytesCopied, totalDstBytesAdded );
						}
					}
				else
					{
					PRINT_EXIT;
					return Result( TCodecProcessResult::EProcessComplete,
									totalSrcBytesCopied, totalDstBytesAdded );
					}
				}
			}
	}while ( 1 );
		}