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

📄 mae1200.cpp

📁 AU1200嵌入式处理器媒体加速引擎(mae)的驱动
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  
  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 + -