⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoderengine.cpp

📁 symbian上的yuv视频文件处理程序 可对yuv的每一帧数据进行读取 处理 显示
💻 CPP
字号:
/*
 * DecoderEngine.cpp
 *
 * The MPEG4 Codec for Symbian Project
 *
 * Copyright (c) 2005-2008 for Cyansoft Studio (www.cyansoft.com.cn).
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Cyansoft$
 * 
 */
#include "DecoderEngine.h"
#include <eikenv.h>
#include "DirectDraw.h"
#include "mpg4dec.h"
#include "yuv2rgb.h"
#include "scale.h"

CDecoderEngine::CDecoderEngine() : 
CActive( CActive::EPriorityStandard )
	{
	
	}

CDecoderEngine* CDecoderEngine::NewL( CDirectDraw* aDDraw )
	{
	CDecoderEngine* self = CDecoderEngine::NewLC( aDDraw );
	CleanupStack::Pop( self );
	return self;
	}

CDecoderEngine* CDecoderEngine::NewLC( CDirectDraw* aDDraw )
	{
	CDecoderEngine* self = new ( ELeave ) CDecoderEngine();
	CleanupStack::PushL( self );
	self->ConstructL( aDDraw );
	return self;
	}

void CDecoderEngine::ConstructL( CDirectDraw* aDDraw )
	{
	CActiveScheduler::Add( this );
	
	iDDraw = aDDraw;
	User::LeaveIfNull( iDDraw );
	iPause = EFalse;
	iStop = EFalse;
	}

CDecoderEngine::~CDecoderEngine()
	{
	Cancel();
	StopL( ETrue );
	}

TInt CDecoderEngine::CreateL( TFileName aFileToOpen, TUint32 aWidth, TUint32 aHeight, TUint32 aBytesPixel, CYuv2Rgb* aYuv2Rgb, CScale* aScale, HBufC8* aInputbuf, TUint32 aInputSize, HBufC8* aYuvbuf, TUint32 aYuvSize, HBufC8* aRgbbuf, CMPEG4Decoder* aDecoder )
	{
	User::LeaveIfNull( aYuv2Rgb );
	User::LeaveIfNull( aScale );
	User::LeaveIfNull( aInputbuf );
	User::LeaveIfNull( aYuvbuf );
	User::LeaveIfNull( aRgbbuf );
	User::LeaveIfNull( aDecoder );
	
	iFileToOpen = aFileToOpen;
	iWidth = aWidth;
	iHeight = aHeight;
	iBytesPixel = aBytesPixel;
	iYuv2Rgb = aYuv2Rgb;
	iScale = aScale;
	iInputbuf = aInputbuf;
	iYuvbuf = aYuvbuf;
	iRgbbuf = aRgbbuf;
	iDecoder = aDecoder;
	iInputSize = aInputSize;
	iYuvSize = aYuvSize;
	
	iFileSize = 0;
	iReadSize = 0;
	
	return 0;
	}

void CDecoderEngine::StartL()
	{
	iFsSession = new (ELeave) RFs;
	// Connects a client process to the fileserver
	User::LeaveIfError( iFsSession->Connect() );
	iFile = new (ELeave) RFile;
	// Open file where the stream is
	User::LeaveIfError( iFile->Open(*iFsSession, iFileToOpen, EFileStream | EFileRead | EFileShareReadersOnly) );
	User::LeaveIfError( iFile->Size( iFileSize ) );
	
	if( iFileSize > iInputSize )
		iReadSize = iInputSize;
	else
		iReadSize = iFileSize;
	
	iInputStreamFile = new (ELeave) RFileReadStream( *iFile );
	
	iFrames = 0;
	iTotalTime = iDecodeTime = iYuv2rgbTime = iScaleTime = 0;
	
	SetActive();
	TRequestStatus* status;
	status = &iStatus;
	User::RequestComplete( status, KErrNone );
	}

void CDecoderEngine::PauseL( TBool fPause )
	{
	iPause = fPause;
	}

void CDecoderEngine::StopL( TBool fIgnoreReport )
	{
	if(iInputStreamFile)
		{
		iInputStreamFile->Close();
		delete iInputStreamFile;
		iInputStreamFile = NULL;
		}
	
	if(iFile)
		{
		iFile->Close();
		delete iFile;
		iFile = NULL;
		}
	
	if(iFsSession)
		{
		iFsSession->Close();
		delete iFsSession;
		iFsSession = NULL;		
		}
	
	if( iTotalTime > 0 && !fIgnoreReport )
		{
		_LIT( KMsgTitle, "Benchmark Report" );
		_LIT( KMsgFps, "Play:    %u fps\nDecode:  %u fps\nYuv2rgb: %u fps\nScale:    %u fps\n" );	
		TBuf<256> msg;
		
		msg.Format(KMsgFps, (iFrames * 1000 * 1000)/iTotalTime, 				
				iDecodeTime > 0 ? (iFrames * 1000 * 1000)/iDecodeTime : 0, 
				iYuv2rgbTime > 0 ? (iFrames * 1000 * 1000)/iYuv2rgbTime : 0,
				iScaleTime > 0 ? (iFrames * 1000 * 1000)/iScaleTime : 0 );
		
		CEikonEnv::Static()->InfoWinL( KMsgTitle, msg );
		}
	
	iTotalTime = iDecodeTime = iYuv2rgbTime = iScaleTime = 0;
	}

TInt CDecoderEngine::DecodeL()
	{
	if( iPause )return 0;
	
	if(iFileSize > iReadSize)
		iFileSize -= iReadSize;
	else if(iFileSize > 0)
		{
		iReadSize = iFileSize;
		iFileSize = 0;
		}
	else
		{
		return -1;
		}
	
	iInputStreamFile->ReadL( ( TUint8* )iInputbuf->Ptr(), iReadSize );
	
	TTime aStart, aStop, aDecStop;
	TTimeIntervalMicroSeconds aTi;
	aStart.HomeTime();
	
	if( 0 == iDecoder->DecodeL( iInputbuf->Ptr(), iReadSize, iYuvbuf->Ptr(), iYuvSize ) )
		{
		do
			{
			aDecStop.HomeTime();
			DrawFrameL();
			aStop.HomeTime();
			aTi = aStop.MicroSecondsFrom( aStart );
			iTotalTime += aTi.Int64();
			aTi = aDecStop.MicroSecondsFrom( aStart );
			iDecodeTime += aTi.Int64();
			iFrames ++;
			
			aStart.HomeTime();
			}
		while( 0 == iDecoder->DecodeL( NULL, 0, iYuvbuf->Ptr(), iYuvSize ) );
		}
	
	return iFileSize;
	}

void CDecoderEngine::DrawFrameL()
	{
	TUint8* rgb;
	TUint8* y;
	TUint8* u;
	TUint8* v;
	
	y = ( TUint8* )iYuvbuf->Ptr();
	u = y + ( iWidth * iHeight );
	v = u + ( iWidth * iHeight >> 2 );
	
	rgb = iDDraw->BeginDraw();
	if( rgb )
		{
		TTime aStart, aStop;
		TTimeIntervalMicroSeconds aTi;
		
		aStart.HomeTime();
		iYuv2Rgb->ConvertL( ( TUint8* )iRgbbuf->Ptr(), y, u, v, iWidth, iHeight, 
				iWidth * iBytesPixel, iWidth, iWidth>>1 );
		aStop.HomeTime();
		aTi = aStop.MicroSecondsFrom( aStart );
		iYuv2rgbTime += aTi.Int64();
		
		aStart.HomeTime();
		iScale->ConvertL( iRgbbuf->Ptr(), rgb );
		aStop.HomeTime();
		aTi = aStop.MicroSecondsFrom( aStart );
		iScaleTime += aTi.Int64();
		
		iDDraw->EndDraw();
		}
	}

void CDecoderEngine::Restart( RDirectScreenAccess::TTerminationReasons aReason )
	{
	iPause = EFalse;
	}

void CDecoderEngine::AbortNow( RDirectScreenAccess::TTerminationReasons aReason )
	{
	iPause = ETrue;
	}

void CDecoderEngine::DoCancel()
	{
	iPause = ETrue;
	}

void CDecoderEngine::RunL()
	{
	if( !iStop )
		{
		if( DecodeL() < 0 )
			{
			StopL( EFalse );
			iStop = ETrue;
			}
		else
			{
			SetActive();
			TRequestStatus* status;
			status = &iStatus;
			User::RequestComplete( status, KErrNone );
			}		
		}
	}

/* End of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -