--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommscontroller/mmccfilesourcesink/src/mccfilevideo.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,716 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+
+#include <e32std.h>
+#include <es_sock.h>
+#include <e32math.h>
+#include "mccfilevideo.h"
+#include "mmcccodecinformation.h"
+#include "mccperiodicrunner.h"
+#include "mccfilesourcelogs.h"
+#include "mccfilesourceimpl.h"
+#include "mccinternaldef.h"
+#include "mccresources.h"
+
+
+const TUint32 KMccFileSourceParameterSetsIntervalInMicroSeconds = 2000000;
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::NewL
+// -----------------------------------------------------------------------------
+//
+CMccFileVideo* CMccFileVideo::NewL(
+ CMccFileSourceImpl& aSource,
+ MMccResources* aMccResources,
+ TUint32 aEndpointId )
+ {
+ CMccFileVideo* self =
+ new (ELeave) CMccFileVideo( aSource, aMccResources, aEndpointId );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::ConstructL()
+ {
+ CMccFileSourceTypeBase::ConstructL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::CMccFileVideo
+// -----------------------------------------------------------------------------
+//
+CMccFileVideo::CMccFileVideo(
+ CMccFileSourceImpl& aSource, MMccResources* aMccResources, TUint32 aEndpointId )
+ : CMccFileSourceTypeBase ( aSource, KUidMediaTypeVideo ),
+ iMccResources( aMccResources ),
+ iEndpointId( aEndpointId ),
+ iBufferType ( CCMRMediaBuffer::EVideoH263 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::~CMccFileVideo
+// -----------------------------------------------------------------------------
+//
+CMccFileVideo::~CMccFileVideo()
+ {
+ delete iAVCNALUsBuffer;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::FillBufferL
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::FillBufferL(
+ CMMFBuffer* aBuffer,
+ MDataSink* aConsumer )
+ {
+ CMccFileSourceTypeBase::FillBufferL( aBuffer, aConsumer );
+
+ // There might be pending video frames, read the oldest one immediately
+ WriteBufferL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::ParseUpdateAudioDescriptions
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileVideo::ParseUpdateVideoDescriptions( MP4Handle aMP4Handle )
+ {
+ TBool containVideo = EFalse;
+ mp4_u32 timeScale = 0;
+ if ( MP4ParseRequestVideoDescription( aMP4Handle,
+ ( mp4_u32* ) &iLength, &iFrameRate, ( mp4_u32* ) &iType,
+ ( mp4_u32* ) &iWidth, ( mp4_u32* ) &iHeight,
+ ( mp4_u32* ) &timeScale )
+ == MP4_OK )
+ {
+ if ( iType == MP4_TYPE_H263_PROFILE_0 )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ParseUpdateVideoDescriptions \
+MP4_TYPE_H263_PROFILE_0" )
+
+ iBufferType = CCMRMediaBuffer::EVideoH263;
+ containVideo = ETrue;
+ iFourCC = TFourCC( KMccFourCCIdH263 );
+
+ TVideoClipProperties clipProperties;
+ MP4ParseGetVideoClipProperties( aMP4Handle, clipProperties );
+ iLevel = clipProperties.iH263Level;
+ }
+ else if ( iType == MP4_TYPE_MPEG4_VIDEO )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ParseUpdateVideoDescriptions \
+MP4_TYPE_MPEG4_VIDEO!" )
+
+ iBufferType = CCMRMediaBuffer::EVideoH263;
+ containVideo = ETrue;
+ iFourCC = TFourCC( KMccFourCCIdAVC );
+ }
+ else if ( IsAVC() )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::\
+ParseUpdateVideoDescriptions AVC!" )
+
+ iBufferType = CCMRMediaBuffer::EVideoH263;
+ containVideo = ETrue;
+ iFourCC = TFourCC( KMccFourCCIdAVC );
+ iIsFirstFrame = ETrue;
+ iInsertParameterSets = ETrue;
+ }
+ else if ( iType != MP4_TYPE_NONE )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::\
+ParseUpdateVideoDescriptions contains unsupported video" )
+ iFourCC = TFourCC( KMccFourCCUnsupported );
+ }
+ else
+ {
+ // NOP
+ }
+ }
+
+ return containVideo;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::IsAVC
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileVideo::IsAVC()
+ {
+ if ( ( iType == MP4_TYPE_AVC_PROFILE_BASELINE ) ||
+ ( iType == MP4_TYPE_AVC_PROFILE_MAIN ) ||
+ ( iType == MP4_TYPE_AVC_PROFILE_EXTENDED )
+ )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::DoSetPositionL
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::DoSetPositionL( TUint32 aPosition )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::DoSetPositionL" )
+
+ __ASSERT_ALWAYS( aPosition <= iLength, User::Leave( KErrArgument ) );
+ mp4_u32 audioPos = 0;
+ // if retrun value is MP4_OK, iPosition is updated
+ if ( MP4ParseSeek( iMP4Handle, ( mp4_u32 ) aPosition,
+ ( mp4_u32* )&audioPos, ( mp4_u32* ) &iPosition, MP4TRUE )
+ != MP4_OK )
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::Type
+// -----------------------------------------------------------------------------
+//
+CCMRMediaBuffer::TBufferType CMccFileVideo::Type()
+ {
+ return iBufferType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::GetFourCC
+// -----------------------------------------------------------------------------
+//
+TFourCC CMccFileVideo::GetFourCC()
+ {
+ return iFourCC;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::TickCallBack
+// -----------------------------------------------------------------------------
+//
+TCallBack CMccFileVideo::TickCallBack()
+ {
+ return TCallBack( TickVideoL, this );
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::GetConfigKeyL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMccFileVideo::GetConfigKeyL()
+ {
+ __ASSERT_ALWAYS( IsAVC(), User::Leave( KErrNotSupported ) );
+ HBufC8* configKey = NULL;
+ ExtractH264ParameterSetNALUsL( &configKey, ETrue );
+ return configKey;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::Position
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileVideo::Position()
+ {
+ return iPosition;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::DurationL
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileVideo::Duration()
+ {
+ return iLength;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::AudioBitRateL
+// -----------------------------------------------------------------------------
+//
+TUint32 CMccFileVideo::AudioBitRate()
+ {
+ return 0;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::VideoFrameSizeL
+// -----------------------------------------------------------------------------
+//
+TSize CMccFileVideo::VideoFrameSize()
+ {
+ TSize size;
+ size.iWidth = iWidth;
+ size. iHeight = iHeight;
+
+ return size;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::VideoFrameRateL
+// -----------------------------------------------------------------------------
+//
+TReal CMccFileVideo::VideoFrameRateL()
+ {
+ // Round to have zero decimals for clearness sake
+ TReal roundedFrameRate;
+ User::LeaveIfError( Math::Round( roundedFrameRate, iFrameRate, 0 ) );
+ return roundedFrameRate;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::StartTimerL
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::StartTimerL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::StartTimerL" )
+
+ if ( IsPaused() )
+ {
+ SetPaused( EFalse );
+
+ SetPositionL( iPosition, ETrue );
+ }
+ else
+ {
+ SetStartTime();
+ }
+
+ const TReal KMccSecondInMicroSeconds = 1000000;
+ TInt tickIntervalVideo = (TInt)KMccSecondInMicroSeconds;
+ if ( iFrameRate != 0 )
+ {
+ // Set interval for video
+ tickIntervalVideo = (TInt)( KMccSecondInMicroSeconds / iFrameRate );
+
+ // Increase tick rate 22%
+ const TReal KMccTickModifier = 0.78;
+ tickIntervalVideo =(TInt) (tickIntervalVideo * KMccTickModifier);
+ }
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileVideo::StartTimer (timer):",
+ tickIntervalVideo )
+
+ iTimerInterval = tickIntervalVideo;
+ iCorrectionInterval = iTimerInterval;
+
+ iPeriodicRunner->Start( tickIntervalVideo, TCallBack( TickVideoL, this ));
+
+ __FILESOURCE_CONTROLL( "CMccFileVideo::StartTimerL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::TickVideoL
+// -----------------------------------------------------------------------------
+//
+TInt CMccFileVideo::TickVideoL( TAny* aObject )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::TickVideoL" )
+
+ static_cast<CMccFileVideo*>(aObject)->ReadFrameL();
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::ReadFrameL
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::ReadFrameL()
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL" )
+
+
+ MP4Err retval = MP4ParseIsFrameAvailable( iMP4Handle, iType );
+
+ if ( retval != MP4_OK )
+ {
+ __FILESOURCE_CONTROLL_INT1( "CMccFileVideo::ReadFrameL, no video", retval )
+
+ SetPaused( ETrue );
+ TRAPD( positionErr, SetPositionL( 0 ) );
+ iSource.PauseVideoL( positionErr );
+ return;
+ }
+
+ // Read the size of next video frame
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL, reading frame" )
+
+ if ( MP4ParseNextFrameSize( iMP4Handle, iType,
+ ( mp4_u32* ) &iBufferSize ) != MP4_OK )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL, \
+MP4ParseNextFrameSize not Ok" )
+ return;
+ }
+
+ TInt aVCNALUsBufferLen = 0;
+ if ( IsAVC() && iIsFirstFrame )
+ {
+ delete iAVCNALUsBuffer;
+ iAVCNALUsBuffer = NULL;
+
+ ExtractH264ParameterSetNALUsL( &iAVCNALUsBuffer );
+ if( iAVCNALUsBuffer )
+ {
+ aVCNALUsBufferLen += iAVCNALUsBuffer->Length();
+ }
+ iIsFirstFrame = EFalse;
+ }
+
+ // Allocate a buffer big enough for the next video frame
+ __FILESOURCE_CONTROLL_INT1( "CMccFileVideo::ReadFrameL, reading frame, size", iBufferSize )
+ HBufC8* mediaBuffer = HBufC8::NewLC( iBufferSize + aVCNALUsBufferLen );
+ TPtr8 mediaSinkBuffer = mediaBuffer->Des();
+ mediaSinkBuffer.SetLength( iBufferSize + aVCNALUsBufferLen );
+ TUint8* ptrMediaBuffer = CONST_CAST(TUint8*, mediaBuffer->Ptr());
+
+ TBool keyFrame = EFalse;
+
+ TUint32 oldPosition = iPosition;
+ if ( MP4ParseReadVideoFrame( iMP4Handle,
+ ( mp4_u8* ) ptrMediaBuffer, ( mp4_u32 ) iBufferSize,
+ ( mp4_u32* ) &iFrameSize, ( mp4_u32* ) &iPosition,
+ ( mp4_bool* ) &keyFrame, NULL ) != MP4_OK )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL, reading frame, NOT OK" )
+ CleanupStack::PopAndDestroy( mediaBuffer );
+ }
+ else
+ {
+ __FILESOURCE_CONTROLL_INT1( "CMccFileVideo::ReadFrameL, reading frame, OK, position",
+ iPosition )
+
+ DoTimingCorrection( iPosition );
+
+ // Update read interval (how much position changes on each frame read)
+ iReadInterval = iPosition - oldPosition;
+
+ if ( IsAVC() )
+ {
+ MarkWithNALUDelimiters( iBufferSize, mediaSinkBuffer );
+ }
+
+ TTimeIntervalMicroSeconds timeStamp = GetTimeStamp();
+
+ CMccFrameItem* item = new (ELeave) CMccFrameItem();
+ item->iFrame = mediaBuffer;
+ CleanupStack::Pop( mediaBuffer );
+ CleanupStack::PushL( item );
+ item->iTimeStamp = timeStamp;
+ item->iKeyFrame = keyFrame;
+ iFrames.AppendL( item );
+ CleanupStack::Pop( item );
+
+ WriteBufferL();
+ }
+
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL, Time Check 2" )
+
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ReadFrameL, \
+writing buffer to sink complete" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::MarkWithNALUDelimiters()
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::MarkWithNALUDelimiters(
+ const TInt aAccessUnitSize, TDes8& aBuffer )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::MarkWithNALUDelimiters" )
+
+ TUint8* ptrByte = NULL;
+ TInt indx = 0;
+ TUint32 size;
+ const TUint32 size_field_len = 4;
+
+ do
+ {
+ ptrByte = const_cast<TUint8*> ( aBuffer.Mid( indx ).Ptr() ); // get starting point of NALU size
+ size = BigEndian::Get32(ptrByte); // get NALU size
+ aBuffer[indx+0] = 0x00;
+ aBuffer[indx+1] = 0x00;
+ aBuffer[indx+2] = 0x00;
+ aBuffer[indx+3] = 0x01;
+ indx = indx + size + size_field_len;
+
+ }while(indx < aAccessUnitSize);
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::ExtractH264ParameterSetNALUsL()
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::ExtractH264ParameterSetNALUsL(
+ HBufC8** aBufferOut,
+ TBool aSdpFormat )
+ {
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ExtractH264ParameterSetNALUsL" )
+
+ *aBufferOut = NULL;
+
+ HBufC8* buffer = NULL;
+ HBufC8* bufferOut = NULL;
+ TUint32 decspecinfosize;
+ TUint8* ptrByte;
+
+ // Query for size, buffer too small error is ok as we give zero length buffer
+ MP4Err retval = MP4ParseReadVideoDecoderSpecificInfo(
+ iMP4Handle, ( mp4_u8* ) NULL, 0, ( mp4_u32* ) &decspecinfosize );
+
+ if ( retval != MP4_OK && retval != MP4_BUFFER_TOO_SMALL )
+ {
+ User::Leave(KErrGeneral);
+ }
+
+ buffer = HBufC8::NewLC(decspecinfosize);
+ ptrByte = const_cast<TUint8*> ( buffer->Des().Ptr() );
+
+ if( MP4ParseReadVideoDecoderSpecificInfo( iMP4Handle,
+ ( mp4_u8* ) ptrByte,
+ ( mp4_u32 ) buffer->Des().MaxSize(),
+ ( mp4_u32* ) &decspecinfosize
+ ) != MP4_OK )
+ {
+ User::Leave(KErrGeneral);
+ }
+ else
+ {
+ buffer->Des().SetLength( decspecinfosize );
+ }
+
+ const TUint two = 2;
+ bufferOut = HBufC8::NewLC( buffer->Size() * two );
+ TPtr8 ptrBufferOut = bufferOut->Des();
+ TPtr8 ptrBuffer = buffer->Des();
+
+ // find NALUs in decoder info and put in buffer by marking with delimiters
+
+ TUint8 tmpByte;
+ TUint16 size16;
+ TInt indx = 5; // skip other info in the beginning
+ TInt numNALUs = 0;
+ TInt lp_indx;
+
+ // get number of seq. parameter set NALUs
+ tmpByte = ptrBuffer[indx++];
+ numNALUs = tmpByte & 0x1F; // get rid of reserved '111' bits
+
+ // extract seq. parameter set NALUs
+
+ for ( lp_indx = 0; lp_indx < numNALUs; lp_indx++ )
+ {
+ size16 = BigEndian::Get16( ptrBuffer.Mid( indx ).Ptr() );
+ indx += 2;
+
+ if ( aSdpFormat )
+ {
+ // TBD: take possibility of multiple nalus into account
+ HBufC8* base64Encoded =
+ MccConversionUtility::Base64EncodeLC( ptrBuffer.Mid( indx, size16 ) );
+ ptrBufferOut.Append( *base64Encoded );
+ CleanupStack::PopAndDestroy( base64Encoded );
+ }
+ else
+ {
+ // insert delimiter
+ tmpByte = 0x00;
+ ptrBufferOut.Append( &tmpByte, 1 );
+ ptrBufferOut.Append( &tmpByte, 1 );
+ ptrBufferOut.Append( &tmpByte, 1 );
+ tmpByte = 0x01;
+ ptrBufferOut.Append( &tmpByte, 1 );
+
+ ptrBufferOut.Append( ptrBuffer.Mid( indx, size16 ) );
+ }
+
+ indx += size16;
+ }
+
+ // get number of pic. parameter set NALUs
+ tmpByte = ptrBuffer[indx++];
+ numNALUs = tmpByte;
+
+ // extract pic. parameter set NALUs
+
+ for ( lp_indx = 0; lp_indx < numNALUs; lp_indx++ )
+ {
+ size16 = BigEndian::Get16( ptrBuffer.Mid( indx ).Ptr() );
+ indx += 2;
+
+ if ( aSdpFormat )
+ {
+ // TBD: take possibility of multiple nalus into account
+ _LIT8( KMccFileSinkNaluSeparator, "," );
+ ptrBufferOut.Append( KMccFileSinkNaluSeparator );
+ HBufC8* base64Encoded =
+ MccConversionUtility::Base64EncodeLC( ptrBuffer.Mid( indx, size16 ) );
+ ptrBufferOut.Append( *base64Encoded );
+ CleanupStack::PopAndDestroy( base64Encoded );
+ }
+ else
+ {
+ // insert delimiter
+ tmpByte = 0x00;
+ ptrBufferOut.Append( &tmpByte, 1 );
+ ptrBufferOut.Append( &tmpByte, 1 );
+ ptrBufferOut.Append( &tmpByte, 1 );
+ tmpByte = 0x01;
+ ptrBufferOut.Append( &tmpByte, 1 );
+
+ ptrBufferOut.Append( ptrBuffer.Mid( indx, size16 ) );
+ }
+
+ indx += size16;
+ }
+
+ CleanupStack::Pop( bufferOut );
+ CleanupStack::PopAndDestroy( buffer );
+
+ *aBufferOut = bufferOut;
+
+ __FILESOURCE_CONTROLL( "CMccFileVideo::ExtractH264ParameterSetNALUsL, exit" )
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::InsertParameterSetNALUs
+// -----------------------------------------------------------------------------
+//
+TBool CMccFileVideo::InsertParameterSetNALUs()
+ {
+ TBool insertParameterSets( iInsertParameterSets );
+ if ( insertParameterSets )
+ {
+ iInsertParameterSets = EFalse;
+ iInsertParameterSetsTime.HomeTime();
+ }
+ else
+ {
+ TTime currentTime;
+ currentTime.HomeTime();
+ if ( currentTime.MicroSecondsFrom( iInsertParameterSetsTime ).Int64() >
+ KMccFileSourceParameterSetsIntervalInMicroSeconds )
+ {
+ // Enough time elapsed from previous parameter set NALUs,
+ // insert them at next round.
+ iInsertParameterSets = ETrue;
+ }
+ }
+ return insertParameterSets;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::GetTimeStamp
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalMicroSeconds CMccFileVideo::GetTimeStamp()
+ {
+ TInt64 position = iPosition + iPositionModifier;
+ TUint32 position2 = ( position < 0 ) ? 0 : (TUint32)position;
+ TTimeIntervalMicroSeconds timeStamp =
+ TTimeIntervalMicroSeconds ( (TInt64) position2 * KMccMicroToMilliConst );
+
+ __FILESOURCE_CONTROLL_INT1( "CMccFileVideo::GetTimeStamp timestamp (without clock frequency):",
+ timeStamp.Int64() )
+ return timeStamp;
+ }
+
+// -----------------------------------------------------------------------------
+// CMccFileVideo::WriteBufferL
+// If AVC NALUS buffer exists, it is passed always before keyframe and it uses
+// timestamp of that frame. It is also passed always at beginning even if first
+// frame wouldn't be keyframe.
+// -----------------------------------------------------------------------------
+//
+void CMccFileVideo::WriteBufferL()
+ {
+ __FILESOURCE_CONTROLL("CMccFileVideo::WriteBufferL")
+
+ if ( iFrames.Count() && iConsumer && iConsumerBuffer )
+ {
+ TBool removeCurrentFrame( ETrue );
+
+ CMMFDataBuffer* buf = static_cast<CMMFDataBuffer*>(iConsumerBuffer);
+
+ CMccFrameItem* item = iFrames[0];
+ HBufC8* videoFrame = item->iFrame;
+
+ if ( iAVCNALUsBuffer && InsertParameterSetNALUs() )
+ {
+ videoFrame = iAVCNALUsBuffer;
+ removeCurrentFrame = EFalse;
+ }
+
+ if ( buf->Data().MaxLength() >= videoFrame->Des().Length() )
+ {
+ buf->Data().Delete( 0, buf->BufferSize() );
+
+ buf->Data().Append( *videoFrame );
+
+ iConsumerBuffer->SetTimeToPlay(item->iTimeStamp);
+ iConsumerBuffer->SetLastBuffer(EFalse);
+ iConsumerBuffer->SetFrameNumber( iSequenceNum );
+
+ if ( removeCurrentFrame )
+ {
+ if ( iMccResources && item->iKeyFrame )
+ {
+ iMccResources->StoreKeyFrameInfoL( iEndpointId, *iConsumerBuffer );
+ }
+
+ delete item;
+ iFrames.Remove(0);
+ }
+
+ videoFrame = NULL;
+
+ iConsumer->BufferFilledL( iConsumerBuffer );
+ iConsumer = NULL;
+ iConsumerBuffer = NULL;
+ iSequenceNum++;
+ __FILESOURCE_CONTROLL("CMccFileVideo::WriteBufferL, done")
+ }
+ else
+ {
+ __FILESOURCE_CONTROLL("CMccFileVideo::WriteBufferL, drop frame")
+ delete iFrames[0];
+ iFrames.Remove(0);
+ videoFrame = NULL;
+ }
+ }
+ else
+ {
+ __FILESOURCE_CONTROLL("CMccFileVideo::WriteBufferL, writing ignored")
+ }
+ }
+
+