/** Verify CMMFBuffer & CMMFDescriptorBuffer positioning * Use case: N/A * @test Req. under test REQ172.7.25 */ TVerdict CTestStep_MMF_BASECL_U_0009::DoTestStepL( void ) { TVerdict verdict = EPass; CMMFDataBuffer* descriptorBuffer = CMMFDataBuffer::NewL(KMMFTestBufferSize); //create descriptor buffer //check initial frame number is 0 if (descriptorBuffer->Position() != 0) verdict = EFail; //check setting a framenumber with no data size - This should keep the position to 0 //because there is no buffer size as yet! descriptorBuffer->SetPosition(KMMFTestPosition); if (descriptorBuffer->Position() != 0) verdict = EFail; //check set position descriptorBuffer->Data().SetLength((TInt)KMMFTestBufferLengthSize); descriptorBuffer->SetPosition(KMMFTestPosition); if (descriptorBuffer->Position() != KMMFTestPosition) verdict = EFail; //try positioning beyond the datalength - should set position to the data length ie buffer size descriptorBuffer->SetPosition(KMMFTestBufferLengthSize*2); if (descriptorBuffer->Position() != descriptorBuffer->BufferSize()) 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 ); }
//--------------------------------------------------------------------------- // 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 ); }
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 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 ); }