// 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; }
// ----------------------------------------------------------------------------- // 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); } }
/** 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 ); }
/** 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 ); }