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

📄 decoder.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************
 * Name         : decoder.c
 * Title        : M24VA video decode acceleration API
 * Author       : Dave Bartlett
 * Created      : 23/04/02
 *
 * Copyright   : 2003 by Imagination Technologies. All rights reserved.
 *             : No part of this software, either material or conceptual 
 *             : may be copied or distributed, transmitted, transcribed,
 *             : stored in a retrieval system or translated into any 
 *             : human or computer language in any form by any means,
 *             : electronic, mechanical, manual or other-wise, or 
 *             : disclosed to third parties without the express written
 *             : permission of Imagination Technologies Limited, Unit 8,
 *             : HomePark Industrial Estate, King's Langley, Hertfordshire,
 *             : WD4 8LZ, U.K.
 *
 * Description  : M24VA video decode acceleration API (Marathon)
 *
 * Platform     : 
 *

 Version	 	: $Revision: 1.38 $

 Modifications	:

 $Log: decoder.c $

  --- Revision Logs Removed --- 

  --- Revision Logs Removed --- 

  --- Revision Logs Removed --- 
 
 */

/***************************************************** Configuration options */

#ifdef DEBUG
	#define DEBUG_MODE
#endif

/*****************************************************************************/

#include <windows.h>
#include <ddraw.h>

#include <Pkfuncs.h>
#include <drvescape.h>

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "img_defs.h"
#include "services.h"
#include "syscommon.h"

/********************************************************* IMG include files */

#include "pvrapi.h"

#include "pvrvadd.h"

#include "m24vahw.h"
#include "decdisp.h"

#include "mbx13ddef.h"
#include <ceddk.h>

/*****************************************************************************/

#ifdef DEBUG_MODE
	#define M24VA_PDUMP(arg)			if(g_eScriptMode != M24VA_NoScript) M24VA_SimScriptLog arg
	#define DEBUG_MODE_ONLY(x)	x
#else
	#define M24VA_PDUMP(arg)
	#define DEBUG_MODE_ONLY(x)
#endif

#define M24VA_READREG(reg)				M24VA_ReadReg(reg)
#define M24VA_WRITEREG(reg,val,suf)		M24VA_WriteReg(reg, val)

#define M24VA_FRAMEFREE(p)				FrameFree(p)
#define M24VA_FRAMEALLOCATE(w,h,f)		FrameAllocate(w, h, f)

#define SP_WRITE_MASK                    (2*1024/4 - 1);

/********************************************************** Internal defines */

typedef enum 
{	M24VA_NoScript,		/* Do not generate script */
	M24VA_LogAccesses,	/* Use h/w log, in script, accesses */
} SCRIPT_MODE;

typedef struct _M24VA_SP_
{
	IMG_UINT32					*pui32SlavePortLinAddr;		/* Pointer to SP */
	IMG_UINT32					iu32SPFree;					/* Free space in SP fifo's*/

    IMG_UINT32					*pSPBufferBase;				/* Slave Port Write Buffer Base */
	IMG_UINT32					*pSPBuffer;					/* Next usable location in Buffer */
	IMG_UINT32					*pSPFlushThreshold;	

	IMG_UINT32					ui32SPAddOn;
	
#ifdef DEBUG_MODE
	IMG_UINT32					ui32AccessCount;
	IMG_UINT32					ui32Polls;
	IMG_UINT32					ui32Trys;
	IMG_UINT32					ui32Overflows;
#endif

} M24VA_SP;

/********************************************* M24VA state control structure */

/* The driver buffers up cmds and residual data internally before writing to the hardware.
 * The size of these buffer must be less than the size of the hardware FIFOs for the 
 * algorithm to work.  The sizes are in 32 bit wrords.
 */
#define	M24VA_SW_CMD_FIFO_SIZE			(0x1f)	
#define	M24VA_SW_IDCT_FIFO_SIZE			(0x3f)	
#define	M24VA_SW_IZZ_FIFO_SIZE			(0x1f)	

typedef struct _M24VA_STATE_
{
	IMG_UINT32				*pui32DeviceResource;
	IMG_UINT32				ui32CurrentProcessID;
	M24VA_SP				sIDCTSlavePort;
	M24VA_SP				sCMDSlavePort;

	IMG_BOOL				bHardwareInUse;
	HDC						hdcDriver;

	IMG_HANDLE				hServices;
	PVRSRV_DEV_DATA			sM24VADevData;
	PVRSRV_HW_INFO			sHWInfo;

	IMG_UINT32				aui32CMDWriteBuffer[M24VA_SW_CMD_FIFO_SIZE*2];

	M24VA_SP				sIZZSlavePort;
	IMG_UINT32				aui32IZZWriteBuffer[M24VA_SW_IZZ_FIFO_SIZE*2];

	IMG_UINT32					*pRegisters;

	/* Frame dimensions's */
	IMG_UINT32	ui32Width;
	IMG_UINT32	ui32Height;

	IMG_BOOL	bDummyImageWriteSent;
	IMG_BOOL	bFCInProgress;

#ifdef DEBUG_MODE
	/* Access stats */
	IMG_UINT32 ui32RegAccessCount;

	IMG_UINT32 ui32FlushCount;
	IMG_UINT32 ui32InterruptPolls;
	IMG_UINT32 ui32InterruptTrys;
	IMG_UINT32 ui32InterruptOverflows;

#endif

} M24VA_STATE;

/************************************************* Internal global variables */

static M24VA_STATE		g_M24VAState	= { FALSE };
static SCRIPT_MODE		g_eScriptMode	= M24VA_NoScript;
extern PVRSRV_SYNC_INFO	*gpsLastSyncObject;

#ifdef DEBUG_MODE
/* Log file details */	
static 	char	g_szLogFileName[1024];
static  FILE*	g_pfLogFile;
#endif

/********************************************** Internal function prototypes */

static DWORD M24VA_ReadReg(DWORD dwAddr);
static void M24VA_WriteReg(DWORD dwAddr, DWORD dwData);

static M24VAError FrameFree(PINT_SM_HANDLE pSurface);
static PINT_SM_HANDLE FrameAllocate(DWORD dwWidth, DWORD dwHeight, 
									M24VA_SURF_FORMAT eFormat);


void UpdateSPFreeCounters();
static void AcquireMPEG();
static void ReleaseMPEG();

/*********************** Internal inline functions, slaveport buffered writes */

/*****************************************************************************
 FUNCTION	: AcquireMPEG
    
 PURPOSE	: Acquire MPEG mutex to prevent power state transitions.

 PARAMETERS	: 
			  
 RETURNS	: nothing

 Notes		: 
*****************************************************************************/
static void AcquireMPEG()
{
	IMG_UINT32		ui32Result;
	IMG_UINT32		ui32Count = 0;
	IMG_UINT32		ui32Ms = 0;

	while (ui32Result = InterlockedTestExchange(g_M24VAState.pui32DeviceResource, 0, g_M24VAState.ui32CurrentProcessID))
	{
			Sleep(ui32Ms);
			/*
				we have to handle thread starvation and block this thread
				if we fail to acquire the lock after some number of tries
			*/
			if(ui32Count++ == 100)
			{
				ui32Ms = 1;
			}
	}	
	
	/* Verify that mutex has been acquired. */
	assert(ui32Result == 0);

#ifdef DEBUG
	if(ui32Result != 0)
	{
		OutputDebugString(TEXT("HostAcquireMutex: failed\n"));
	}
#endif

}

/*****************************************************************************
 FUNCTION	: ReleaseMPEG
    
 PURPOSE	: Release MPEG mutex to allow power state transitions.

 PARAMETERS	: 
			  
 RETURNS	: nothing

 Notes		: 
*****************************************************************************/
static void ReleaseMPEG()
{
	PVRSRV_ERROR eError = PVRSRV_OK;

	if (*g_M24VAState.pui32DeviceResource == g_M24VAState.ui32CurrentProcessID)
	{
		*g_M24VAState.pui32DeviceResource = 0;
	}
#ifdef DEBUG
	else
	{
		/* Process does not have permission to release mutex. */
		OutputDebugString(TEXT("HostReleaseMutex: Mutex is not locked with expected value\n"));
		assert(0);
	}
#endif
}

/*****************************************************************************
 FUNCTION	: M24VA_SPBufferFlush
    
 PURPOSE	: Flush slave port

 PARAMETERS	: 
			  
 RETURNS	: nothing

 Notes		: 
*****************************************************************************/

M24VAError M24VA_SPBufferFlush(M24VA_SP	*psSlavePort)
{
#ifndef INIFINTELY_FAST_HW
	int				iPolls, iTrys;
	IMG_UINT32		ui32DataToWrite;

	M24VAError  eRtn = M24VAError_OK;

	/************************************* Ensure space in slave port FIFO's */

	assert((psSlavePort->pSPBufferBase != NULL));

	/* Verify that pSPBuffer points to a legal location within slave port write buffer. */
	assert(((psSlavePort->pSPBuffer <= psSlavePort->pSPFlushThreshold) && (psSlavePort->pSPBuffer >= psSlavePort->pSPBufferBase)));

	ui32DataToWrite = psSlavePort->pSPBuffer - psSlavePort->pSPBufferBase;

	/* Verify that ui32DataToWrite and iu32SPFree values are correct for the CMD buffer 
	and IZZ buffer (IDCT buffer is not in use). */
	assert(((ui32DataToWrite >= 0) && (ui32DataToWrite <= (M24VA_SW_CMD_FIFO_SIZE * 2))));
	assert(((psSlavePort->iu32SPFree >= 0) && (psSlavePort->iu32SPFree <= (M24VA_SW_CMD_FIFO_SIZE * 2))));

	if(psSlavePort->iu32SPFree < ui32DataToWrite)
	{
		for(iTrys = 10; iTrys; iTrys --)
		{
			for(iPolls = 100; iPolls; iPolls--)
			{
				DEBUG_MODE_ONLY(psSlavePort->ui32Polls++);
				UpdateSPFreeCounters();

				if(psSlavePort->iu32SPFree >= ui32DataToWrite) goto HaveSpace;
			}

			DEBUG_MODE_ONLY(psSlavePort->ui32Trys++);
			Sleep(1);
		}

		/* Error Slaveport overflow, cmd lost */
		DEBUG_MODE_ONLY(psSlavePort->ui32Overflows++);

		/* Timeout condition should not occur. */
		assert(0);
		return(M24VAError_WriteTimedOut);
	}

HaveSpace:
#endif

	/************************************************************ Write data */

	DEBUG_MODE_ONLY(psSlavePort->ui32AccessCount+=ui32DataToWrite);

	{
		IMG_UINT32	*pui32Source	= psSlavePort->pSPBufferBase;
		IMG_UINT32	*pui32Dest		= psSlavePort->pui32SlavePortLinAddr + psSlavePort->ui32SPAddOn; 

		psSlavePort->ui32SPAddOn = (psSlavePort->ui32SPAddOn + ui32DataToWrite) & SP_WRITE_MASK;

		psSlavePort->iu32SPFree -= ui32DataToWrite;

		while(ui32DataToWrite--)
		{
#ifdef INIFINTELY_FAST_HW
			IMG_UINT32 iu32Dummy = *pui32Source++;
#else
			M24VA_PDUMP(("WRW :SP:%08X %08X\n", psSlavePort->pSPBufferBase, *pui32Source));

			*pui32Dest++ = *pui32Source++;
#endif // INIFINTELY_FAST_HW
		}

		psSlavePort->pSPBuffer = psSlavePort->pSPBufferBase; 
	}

	return(eRtn);
}

/*****************************************************************************
 FUNCTION	: M24VA_IZZ_SPBufferWrite
    
 PURPOSE	: Buffered write to the IZZ slaveport

 PARAMETERS	: 
			  
 RETURNS	: nothing

 Notes		: 
*****************************************************************************/

__inline static M24VAError M24VA_IZZ_SPBufferWrite(IMG_UINT32	*pui23SPData, 
												  IMG_UINT32	ui32DataSize)
{
	M24VAError  eRtn = M24VAError_OK;
	register IMG_UINT32	*pui32Buffer		= g_M24VAState.sIZZSlavePort.pSPBuffer;
	register IMG_UINT32	*pui32Threshold		= g_M24VAState.sIZZSlavePort.pSPFlushThreshold;


	/* Transfer Data to Buffer, assumes alway one free location in buffer */
	while(ui32DataSize--)
	{
		*pui32Buffer++ = *pui23SPData++;

		if(pui32Buffer >= pui32Threshold)
		{	
			g_M24VAState.sIZZSlavePort.pSPBuffer = pui32Buffer;

			AcquireMPEG();

			M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);

			eRtn = M24VA_SPBufferFlush(&g_M24VAState.sIZZSlavePort);

			ReleaseMPEG();

			pui32Buffer		= g_M24VAState.sIZZSlavePort.pSPBuffer;
		}
	}

	g_M24VAState.sIZZSlavePort.pSPBuffer = pui32Buffer;


	return(eRtn);
}

/******************************************************** External functions */

/*****************************************************************************
 FUNCTION	: M24VA_Initialise
    
 PURPOSE	: Initialise m24va interface, acquire hardware

 PARAMETERS	: ui32Param - implemention specific parameter
			  
 RETURNS	: M24VAError

 Notes		: Map M24VA hardware into our address space
*****************************************************************************/

M24VAError PVRAPI M24VA_Initialise(IMG_PVOID pvParam)
{
	UNREFERENCED_PARAMETER(pvParam);

	if(g_M24VAState.bHardwareInUse)
	{
		return(M24VAError_HardwareNotAvailable);
	}

	memset(&g_M24VAState, 0, sizeof(g_M24VAState));

	g_M24VAState.bHardwareInUse	= TRUE;


	/****************************************************** Acquire hardware */

	{
		DRVESC_M24VA_ACQUIRE_PARAMS	sM24VAAcquire;

		if(!g_M24VAState.hdcDriver)
		{
			g_M24VAState.hdcDriver				= GetWindowDC(NULL);
		}

		sM24VAAcquire.dwAcquire		= TRUE;
		sM24VAAcquire.dwProcessID	= GetCurrentProcessId();

		if(ExtEscape(g_M24VAState.hdcDriver, DRVESC_M24VA_ACQUIRE, 0, NULL,  
					 sizeof(sM24VAAcquire), (LPSTR)&sM24VAAcquire) < 0)
		{
			g_M24VAState.bHardwareInUse	= FALSE;

			ReleaseDC(NULL, g_M24VAState.hdcDriver);
			return(M24VAError_HardwareNotAvailable);
		}
	}

	/* Connect to services acquire device */
	PVRSRVConnect(NULL, &g_M24VAState.hServices);

	if(PVRSRVAcquireDeviceData(g_M24VAState.hServices, 0, &g_M24VAState.sM24VADevData, PVRSRV_DEVICE_TYPE_M24VA) != PVRSRV_OK)
	{
		PVRSRVDisconnect(g_M24VAState.hServices);
		g_M24VAState.hServices = NULL;

		M24VA_Deinitialise();
		return(M24VAError_HardwareNotAvailable);
	}

	if(PVRSRVConnectMPEGApplication(&g_M24VAState.sM24VADevData, IMG_TRUE))
	{
		PVRSRVDisconnect(g_M24VAState.hServices);
		g_M24VAState.hServices = NULL;

		M24VA_Deinitialise();
		return(M24VAError_HardwareNotAvailable);
	}

	if(PVRSRVGetHWInfo(&g_M24VAState.sM24VADevData, &g_M24VAState.sHWInfo) != PVRSRV_OK)
	{
		PVRSRVReleaseDeviceData(&g_M24VAState.sM24VADevData);
		PVRSRVDisconnect(g_M24VAState.hServices);
		g_M24VAState.hServices = NULL;

		M24VA_Deinitialise();

		return(M24VAError_HardwareNotAvailable);
	}

	g_M24VAState.pRegisters		= g_M24VAState.sHWInfo.pvRegsBase;

	g_M24VAState.sCMDSlavePort.pui32SlavePortLinAddr = g_M24VAState.sHWInfo.sDeviceSpecific.sM24VA.pvSPCmd;
	g_M24VAState.sCMDSlavePort.pSPBufferBase		 = g_M24VAState.aui32CMDWriteBuffer;
	g_M24VAState.sCMDSlavePort.pSPBuffer			 = g_M24VAState.aui32CMDWriteBuffer;
	g_M24VAState.sCMDSlavePort.pSPFlushThreshold	 = &g_M24VAState.aui32CMDWriteBuffer[M24VA_SW_CMD_FIFO_SIZE];
	g_M24VAState.sCMDSlavePort.ui32SPAddOn			 = 0;


⌨️ 快捷键说明

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