📄 mae1200.cpp
字号:
MAEhandler.hInterruptThread_LCD = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)lcd_interruptThread,
(PVOID)(AU1200_LCD_INT ),
0,
NULL);
if(MAEhandler.hInterruptThread_LCD == NULL)
{
RPRINTF(MSG_ERROR, (TEXT("CreateThread failed for AU1200_LCD_INT\n")));
return 1;
}
MAEhandler.hPowerMgmtThread = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)PowerMgmtThread,
(PVOID)(NULL ),
0,
NULL);
if(MAEhandler.hPowerMgmtThread == NULL)
{
RPRINTF(MSG_ERROR, (TEXT("CreateThread failed for hPowerMgmtThread\n")));
return 1;
}
#if USE_IOCTL_THREAD
MAEhandler.hInterruptThread_IOCTL = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)IoctlThread,
(PVOID)(NULL ),
0,
NULL);
if(MAEhandler.hInterruptThread_IOCTL == NULL)
{
RPRINTF(MSG_ERROR, (TEXT("CreateThread failed for IoctlThread\n")));
return 1;
}
#endif
return 0;
}
void DisableInterrupts()
{
// disable all interrupts from 1200
teardown_interrupts();
// un-register the interrupts with OS
InterruptDisable(MAEhandler.IRQL_MAE);
InterruptDisable(MAEhandler.IRQL_LCD);
// close all handles
CloseHandle(MAEhandler.hInterruptEvent_MAE);
CloseHandle(MAEhandler.hInterruptEvent_LCD);
CloseHandle(hEventYUVBufferAvailable);
CloseHandle(g_hEndOfStreamSemaphore);
CloseHandle(MAEhandler.hInterruptThread_MAE);
CloseHandle(MAEhandler.hInterruptThread_LCD);
CloseHandle(MAEhandler.hInterruptThread_IOCTL);
}
void InitGlobals()
{
DPRINTF(MSG_FUNCTION|MSG_TIME, (TEXT("mae: InitGlobals()\n")));
gblYUVBuffer = NULL;
gblYUVq = NULL;
gblDataq = NULL;
lcd = (AU1200_LCD *)AU1200_LCD_ADDR;
MAE_FREEZE = 1<<4;
DISABLE_FE = 1<<8;
ENABLE_FE = 1;
ENABLE_BE = 1<<1;
MAE_RUNNING = 1<<16;
ENABLE_LCD = 1<<2;
ENABLE_DISCARD = 1<<3;
this_pts =0;
prev_tnum = 0;
nIgnorePTS = 0;
g_bLCDScanEnabled = 0;
f_ptr = 0;
b_ptr = 0;
previous_pts = 0;
my_fe_armed = FALSE;
my_be_armed = FALSE;
rgb_scan = NULL;
rgb_holdfree = NULL;
display_addr = NULL;
gblBEOnly = 0;
gDecoderSleeping = FALSE;
g_FrameOutNum = 0;
}
// kickstart_hw sets global gIntrnum to look for that interrupt
unsigned long mae_interruptThread(PVOID pvData)
{
unsigned long dwWaitResult = 0;
long irq = AU1200_MAE_FE_INT;
int intnum=0;
int lIntrnum =0,rvalue;
static unsigned int xsize=0, ysize=0, sizechange=0;
HANDLE lIntrEvent;
DPRINTF(MSG_FUNCTION, (TEXT("mae_interruptThread Entry \n")));
CeSetThreadPriority(GetCurrentThread(),MAE_THREAD_PRIORITY);
Sleep(10);
gIntrEvent = MAEhandler.hInterruptEvent_MAE;
gIntrnum = MAEhandler.IRQL_MAE;
intnum = MAEhandler.IRQL_MAE;
if (xsize != pmms->video_out_linesize)
{
xsize = pmms->video_out_linesize;
sizechange=1;
}
if (ysize != pmms->video_out_height)
{
ysize = pmms->video_out_height;
sizechange=1;
}
if (sizechange)
{
sizechange=0;
DPRINTF(MSG_FUNCTION, (TEXT("New size detected: %dx%d\n"), pmms->video_out_linesize, pmms->video_out_height));
}
while (!g_bDone ) // loop till driver close is called or an error happens
{
DPRINTF(0, (TEXT("Interrupt thread waiting: gIntrnum %x gIntrEvent %x\n"), gIntrnum, gIntrEvent));
EnterCS(g_CriticalSection);
lIntrnum = gIntrnum;
lIntrEvent = gIntrEvent;
LeaveCS(g_CriticalSection);
if(lIntrEvent != 0)
{
dwWaitResult = WaitForSingleObject(lIntrEvent,INFINITE);
} else
{
Sleep(2);
continue;
}
//DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread received interrupt from line %d\n"),gIntrnum));
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
EnterCS(g_CriticalSection);
rvalue = mae_interrupt_handler(irq);
if( rvalue != 1 ) {
InterruptDone(intnum);
DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread: Processed lIntrnum %x\n"),lIntrnum));
}
LeaveCS(g_CriticalSection);
break;
case WAIT_OBJECT_0 + 1:
DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread exit normally: dwWaitResult %x, lIntrEvent %x, lIntrnum %x!!!\n"),dwWaitResult,lIntrEvent,lIntrnum));
g_bDone = TRUE;
break;
default:
DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread exit abnormally: dwWaitResult %x, lIntrEvent %x, lIntrnum %x!!!\n"),dwWaitResult,lIntrEvent,lIntrnum));
g_bDone = TRUE;
break;
}
}
MAEhandler.hInterruptThread_MAE = NULL;
DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread: Done \n")));
return 0;
}
unsigned long lcd_interruptThread(PVOID pvData)
{
unsigned long dwWaitResult = 0;
long irq = AU1200_LCD_INT;//(long)pvData;
int intnum=0,rvalue;
DPRINTF(MSG_FUNCTION, (TEXT("lcd_interruptThread Entry \n")));
CeSetThreadPriority(GetCurrentThread(),MAE_THREAD_PRIORITY);//THREAD_PRIORITY_ABOVE_NORMAL);
Sleep(10);
while (!g_bDone ) // loop till driver close is called or an error happens
{
dwWaitResult = WaitForSingleObject(MAEhandler.hInterruptEvent_LCD,INFINITE);
intnum = MAEhandler.IRQL_LCD;
//DPRINTF(MSG_INTERRUPT, (TEXT("lcd_interruptThread received interrupt \n")));
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
//DPRINTF(MSG_INTERRUPT, (TEXT("mae_interruptThread enter dwWaitResult=%x!!!\n"),dwWaitResult));
EnterCS(g_CriticalSection);
rvalue = lcd_interrupt_handler();
if( rvalue != 1 )
InterruptDone(intnum);
LeaveCS(g_CriticalSection);
break;
case WAIT_OBJECT_0 + 1:
DPRINTF(MSG_INTERRUPT, (TEXT("lcd_interruptThread exit normally %x!!!\n"),dwWaitResult));
g_bDone = TRUE;
break;
default:
DPRINTF(MSG_INTERRUPT, (TEXT("lcd_interruptThread exit abnormally %x!!!\n"),dwWaitResult));
g_bDone = TRUE;
break;
}
Sleep(3);
}
DPRINTF(MSG_INTERRUPT, (TEXT("lcd_interruptThread: Done \n")));
MAEhandler.hInterruptThread_LCD = NULL;
return 0;
}
unsigned long PowerMgmtThread()
{
unsigned long dwWaitResult = 0;
DPRINTF(MSG_FUNCTION, (TEXT("PowerMgmtThread Entry \n")));
CeSetThreadPriority(GetCurrentThread(),MAE_THREAD_PRIORITY);
Sleep(10);
while (!g_bDone ) // loop till driver close is called or an error happens
{
dwWaitResult = WaitForSingleObject(MAEhandler.hPowerMgmtEvent,INFINITE);
DPRINTF(MSG_POWER, (TEXT("PowerMgmtThread: Received PowerUp Event\n")));
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
EnterCS(g_CriticalSection);
DPRINTF(MSG_POWER, (TEXT("PowerMgmtThread: Trying to restore MAE and LCD state\n")));
setup_interrupts();
//We need to reinitialize the back end and LCD registers.
program_static_be_registers();
enable_overlay(MAE_PLANE);
restore_lcd_registers();
enable_lcd_scan();
wake_decoder();
LeaveCS(g_CriticalSection);
break;
case WAIT_OBJECT_0 + 1:
DPRINTF(MSG_INTERRUPT, (TEXT("PowerMgmtThread exit normally %x!!!\n"),dwWaitResult));
g_bDone = TRUE;
break;
default:
DPRINTF(MSG_INTERRUPT, (TEXT("PowerMgmtThread exit abnormally %x!!!\n"),dwWaitResult));
g_bDone = TRUE;
break;
}
Sleep(3);
}
DPRINTF(MSG_INTERRUPT, (TEXT("PowerMgmtThread: Done \n")));
MAEhandler.hPowerMgmtThread = NULL;
return 0;
}
VOID MAE_PowerUp(HANDLE pHandle)
{
DPRINTF(MSG_POWER, (TEXT("==> MAE Power Up\n")));
// Turn on the clocks to the back end.
au_writel(MAEBE_CTLENABLE_EN, MAEBE_CTLENABLE);
CeSetPowerOnEvent(MAEhandler.hPowerMgmtEvent);
DPRINTF(MSG_POWER, (TEXT("<== MAE Power Up\n")));
}
VOID MAE_PowerDown(HANDLE pHandle)
{
if (!gMaeInit)
return;
DPRINTF(MSG_POWER, (TEXT("==> MAE Power Down\n")));
mask_interrupts(gbl_mask | (1 << AU1200_LCD_INT));
au_writel(MAEFE_INTSTAT_DONE, MAEFE_INTSTAT);
au_writel(MAEBE_INTSTAT_DONE, MAEBE_INTSTAT);
au_writel(LCD_INTSTATUS_SS, LCD_INTSTATUS);
// shut off the clocks to the back end
au_writel(0, MAEBE_CTLENABLE);
disable_lcd_scan();
flush_mae(1);
clear_lcd_pipeline();
save_lcd_registers();
DPRINTF(MSG_POWER, (TEXT("<== MAE Power Down\n")));
}
BOOL MAE_IOControl(HANDLE pHandle,
DWORD dwCode, LPVOID pBufIn,
DWORD dwLenIn, LPVOID pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
unsigned long status;
unsigned long pyuvbuf=NULL;
ioc = (au1xxxmae_ioctl_t *)pBufIn;
status = 0;
switch ( dwCode )
{
case AU1XXXMAE_INIT:
{
DPRINTF(MSG_IOCTL|MSG_STATE, (TEXT("MAE_Ioctl INIT: fe=%s be=%s\n"),
RunStateStr(g_FEState), RunStateStr(g_BEState)));
if (!gMaeInit)
{
gMaeInit=1;
DPRINTF(MSG_IOCTL|MSG_STATE|MSG_TIME, (TEXT("MAE_Ioctl INIT uninitialized driver\n")));
(ioc->ksegbase) = gMaePhysBaseAddress;
(ioc->addrpmms) = (unsigned long)pmms;
init_mae_structs();
// HWG - initialize video dimensions from current LCD setting
pmms->video_out_linesize = (((lcd->screen) >> 8) & 0x7FF) + 1;
pmms->video_out_height = (((lcd->screen) >> 19) & 0x7FF) + 1;
g_RectScreen.top = 0;
g_RectScreen.left = 0;
g_RectScreen.bottom = (((lcd->screen) >> 8) & 0x7FF) + 1;
g_RectScreen.right = (((lcd->screen) >> 19) & 0x7FF) + 1;
}
else
{
DPRINTF(MSG_IOCTL|MSG_STATE|MSG_TIME, (TEXT("MAE_Ioctl REINIT driver\n")));
halt_mae();
flush_mae(1);
init_mae_structs();
}
if (isBEstate(MAE_STATE_NONE))
{
/* if run state hasn't yet been determined, set the defualt state (paused or playing???) */
DPRINTF(MSG_IOCTL|MSG_STATE|MSG_TIME, (TEXT("MAE_Ioctl INIT: Default run states\n")));
if (!isBEstate(MAE_STATE_PAUSED))
change_BEstate(MAE_STATE_PAUSING);
change_FEstate(MAE_STATE_STARTING);
}
DPRINTF(MSG_IOCTL|MSG_STATE, (TEXT("MAE_Ioctl INIT: done fe=%s be=%s\n"),
RunStateStr(g_FEState), RunStateStr(g_BEState)));
}
break;
case AU1XXXMAE_UNINIT:
{
// code move to Close()
DPRINTF(MSG_IOCTL, (TEXT("MAE_Ioctl MAE UNINIT IOCTL...\n")));
}
break;
case AU1XXXMAE_SETMODE:
{
DPRINTF(MSG_IOCTL, (TEXT("MAE_Ioctl MAE SETMODE IOCTL (deprecated, do not use)\n")));
}
break;
//SCB FOR NEW VIDEO RENDERER-DRIVEN FF/REW
case AU1XXXMAE_SETMODE2:
{
PMAE_MODE_STRUCT pcur_mode;
DWORD mask;
pcur_mode = (PMAE_MODE_STRUCT)pBufIn;
DPRINTF(MSG_TIME, (TEXT("MAE_Ioctl MAE SETMODE2 mode %d, speed 0x%x\n"),
pcur_mode->operating_mode, pcur_mode->playback_speed));
mask = mask_interrupts(gbl_mask | (1 << AU1200_LCD_INT));
g_Speed = pcur_mode->playback_speed;
pmms->playback_speed = pcur_mode->playback_speed;
pmms->operating_mode = pcur_mode->operating_mode;
//pmms->pipeline_be_delay = IPB_BE_DELAY;
//pmms->pipeline_discard_delay = IPB_DISCARD_DELAY;
//nIgnorePTS = 0;
unmask_interrupts(mask);
}
break;
case AU1XXXMAE_SETPLAYERRECT:
{
RECT *rect;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -