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

📄 mae1200.cpp

📁 AU1200嵌入式处理器媒体加速引擎(mae)的驱动
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// SDK\INC
#include <windows.h>

// DDK\INC
#include <ceddk.h>
#include <devload.h>
#include <ddkreg.h>

// OAK\INC
#include <nkintr.h>

// <BSP>\INC
#include <bceddk.h>

#include "stdafx.h"

// Use this define to discard (not display) frames later than threshold
//#define NO_SHOW_LATE 1
#define NO_SHOW_LATE_THRESHOLD 33  //msec

// KK - rev2 - Turn this flag on to debug FE register programming (reference pointers and related stuff)
//#define REG_DEBUG 1

// au1200 header files
#include "MAE1200.h"
#include "au1200_lcd.h"
#include "au1200.h"
#include "queue.h"
#include "mae_hal.h"
#include "mae_interface.h"
#include "mae_global.h"
#include "time64.h"

#include <Mmsystem.h>

#define MAE_THREAD_PRIORITY   40
//#define MAE_ROTATION_TEST

#define USE_STOPSTATE 1
//#define SLOW_SUBMITS_ON_PAUSE

static int gMaeInit=0;
static int nPriority = 21;
static  MAEhandler_t MAEhandler;
static au1xxxmae_ioctl_t *ioc;
static au1xxxmae_ioctl_t *lcd_ioc;
static HANDLE hEventYUVBufferAvailable;
static HANDLE g_hEventIoctlStart;
static HANDLE g_hEventIoctlComplete;
static AU1200_LCD lcd_info;

static BOOL gOpenFlag = FALSE;
static BOOL g_bSavedLcdRegisters = FALSE;
static int gOpenCounter = 0;
static BOOL g_bGotAudioPTS = FALSE;
static DWORD g_RegistryIgnorePTS = 0;
DWORD g_bFlushing = 0; /* flushing active */
int g_Speed=1;
static BOOL g_bLCDScanEnabled = FALSE;
static BOOL nFirstDisplayFrame = TRUE;
static DWORD g_FrameOutNum = 0;
HANDLE g_hEndOfStreamSemaphore = NULL;
extern "C" DWORD g_WaitForEOS;
DWORD nRequestDone = 0; /* is there an outstanding REQUESTed buffer */
extern "C" RECT g_RectPlayer;
extern "C" RECT g_RectScreen;

#ifdef YUV_DUMPS
#define INT_STATE_NONE            0
#define INT_STATE_FE_DONE         1
#define INT_STATE_BE_DONE         2
#define INT_STATE_BOTH_DONE       3

static int nFrameState = INT_STATE_NONE;
#endif

#define HANDLE_NON_STANDARD_DIVX_CERT_CLIPS

#define DISPLAY_THRESHOLD  3  // msec
#define WARNING_THRESHOLD 10000 // msec
#define RESYNC_MAX_THRESHOLD 10000 // msec
#define DISPLAY_MAX_WAIT     2000 // msec

#define MAE_BOTH_INT  0x80000000
#define MAE_FE_INT    0x200
#define MAE_BE_INT    0x10

#define MAE_STATE_NONE          0x00  /* no state - interrupts not started */
#define MAE_STATE_PAUSING       0x01  /* requesting a pause */
#define MAE_STATE_PAUSED        0x02  /* paused (at least one frame processed) */
#define MAE_STATE_PREROLL       0x04  /* preroll */
#define MAE_STATE_STARTING      0x08  /* start playing */
#define MAE_STATE_PLAYING       0x10  /* playing */
#define MAE_STATE_STOPPING      0x20  /* requesting a stop */
#define MAE_STATE_STOPPED       0x40  /* interrupt completed transition to stop */

#define IsBEStopped()  (g_BEState==MAE_STATE_NONE || g_BEState==MAE_STATE_STOPPED)

#define IsFEStopped()  (g_FEState==MAE_STATE_NONE || g_FEState==MAE_STATE_STOPPED)

/* IsRunning return success if MAE is in a state where it's queues are Active */
#define IsRunning()  (g_BEState&(MAE_STATE_PREROLL|MAE_STATE_STARTING|MAE_STATE_PLAYING))
#define IsPaused()  (g_BEState&(MAE_STATE_PAUSED))

static DWORD g_FEState=MAE_STATE_NONE;
static DWORD g_BEState=MAE_STATE_NONE;

ContextTime_t g_ContextTime;
MAE_MODE_STRUCT g_cur_mode;

/* enum/flag/string translation table entry (for debug) */
typedef struct EnumDesc_s {
  unsigned int uiEnum;
  TCHAR     *pszDesc;
} EnumDesc_t;
#define DECLARE_ENUM(_uiEnum, _szDesc) { _uiEnum, _szDesc }

#define RunStateStr(_eState)  sp_flagstostr(enumtabRunState, _eState)

static EnumDesc_t enumtabRunState[] = {
  DECLARE_ENUM(MAE_STATE_NONE, TEXT("NONE")),
  DECLARE_ENUM(MAE_STATE_PAUSING, TEXT("PAUSING")),
  DECLARE_ENUM(MAE_STATE_PAUSED, TEXT("PAUSED")),
  DECLARE_ENUM(MAE_STATE_PREROLL, TEXT("PREROLL")),
  DECLARE_ENUM(MAE_STATE_STARTING, TEXT("STARTING")),
  DECLARE_ENUM(MAE_STATE_PLAYING, TEXT("PLAYING")),
  DECLARE_ENUM(MAE_STATE_STOPPING, TEXT("STOPPING")),
  DECLARE_ENUM(MAE_STATE_STOPPED, TEXT("STOPPED")),
  DECLARE_ENUM(MAE_STATE_NONE, TEXT("NONE")),
  DECLARE_ENUM(0xFFFFFFFF, TEXT("Unknown"))
};

static TCHAR szFrameType[3][12] =
{
  {TEXT("I Frame")},
  {TEXT("P Frame")},
  {TEXT("B Frame")}
};

unsigned long PowerMgmtThread();
void wake_decoder(void);
void wake_fe(void);
void enable_overlay(DWORD uiPlane);
void disable_overlay(DWORD uiPlane);
void save_lcd_registers();
void restore_lcd_registers();
void clear_lcd_pipeline(void);
void enable_lcd_scan(void);
void disable_lcd_scan(void);
void halt_mae(void);
void flush_mae(int);
void flush_maeq(void);
void flush_rgbq(void);
PMAEQ_T new_besw(void);
#ifndef USE_IOCTL_THREAD
void write_system_time_clock(ContextTime_t *ContextTime);
#else
void write_system_time_clock(ContextTime_t ContextTime);
#endif
unsigned long display_frame();
extern "C" void print_registers();
void do_display() ;

extern "C" ULONG getPRId(void);
extern "C" ULONG getconfig1(void);

// #define DISPLAY_FPS 1
// #define SEND_FPS_TO_CLIENT 1
// #define WaitForSingleObject(x, y) MGDWaitForSingleObject((x), (y), __FILE__, __LINE__)
// #define MGD_WAIT_LIMIT 10000

#ifdef DISPLAY_FPS
unsigned long g_totaltime,g_totalframes;
long g_frame_cnt;
DWORD endtime,starttime;
#endif

#ifdef SEND_FPS_TO_CLIENT
static HANDLE hFile = NULL;
static HANDLE hMapFile = NULL;
static LPVOID lpBuffer = NULL;
static float fMaxFPS = -1.0f;
static float fMinFPS = 100000.0f;
#endif

#ifdef WaitForSingleObject
inline DWORD MGDWaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds, char *File, int line)
{
  DWORD rv = WAIT_TIMEOUT;

  if (dwMilliseconds == INFINITE)
  {
    // We will not be doing infinite waits because they suck

    while(rv == WAIT_TIMEOUT)
    {
      rv = WaitForSingleObject(hHandle, MGD_WAIT_LIMIT);
      if (rv == WAIT_TIMEOUT)
      {
        // this is our shortcircuited infinite wait path
        printf("Infinite loop found at %s:%d\n", File, line);
      }
    }

  }
  else 
  {
    rv = WaitForSingleObject(hHandle, dwMilliseconds);
  }
  return ( rv );
}

#endif

int sp_strcat(TCHAR *pdst, const TCHAR *psrc)
{
  int count=0;
  /* find the end of destination string */
  while (*pdst)
  {
    pdst++;
    count++;
  }
  /* append psrc->pdst */
  while (*psrc)
  {
    *pdst=*psrc;
    pdst++;
    psrc++;
    count++;
  }
  *pdst=0;
  return count;
}

/*
** sp_flagstostr()
**   Convert flags to a string (note: this also uses enum tables).
*/
TCHAR *sp_flagstostr(EnumDesc_t *pEnumTable, unsigned int uiFlags)
{
  static TCHAR pszTmpStr[2][128]={TEXT("")};
  static uiTmpStrIndex=0;  /* allows nested calls to return different string pointers */
  TCHAR *pszStr;
  EnumDesc_t *pEnumEntry=NULL;
  unsigned int uiPos;
  unsigned int uiFlagCount=0;
  pszStr=pszTmpStr[uiTmpStrIndex];
  uiTmpStrIndex=(uiTmpStrIndex+1)%2; /* bump temp str pointer */
  pszStr[0]=0;
  if (pEnumTable)
  {
    for (uiPos=0; pEnumTable[uiPos].uiEnum!=0xFFFFFFFF; uiPos++)
      if (pEnumTable[uiPos].uiEnum &&
          (pEnumTable[uiPos].uiEnum&uiFlags)==pEnumTable[uiPos].uiEnum)
      {
        pEnumEntry=pEnumTable+uiPos;
        /* found matching flag */
        if (uiFlagCount)
          sp_strcat(pszStr, TEXT("|")); /* seperator */
        sp_strcat(pszStr, pEnumEntry->pszDesc);
        uiFlagCount++;
      }
    if (!uiFlagCount) /* no flags matched, search for exact match (handles NONE values) */
      for (uiPos=0; pEnumTable[uiPos].uiEnum!=0xFFFFFFFF; uiPos++)
        if (pEnumTable[uiPos].uiEnum==uiFlags)
        {
          pEnumEntry=pEnumTable+uiPos;
          /* found matching flag */
          if (uiFlagCount)
            sp_strcat(pszStr, TEXT("|")); /* seperator */
          sp_strcat(pszStr, pEnumEntry->pszDesc);
          uiFlagCount++;
        }
  }

  if (!uiFlagCount) /* no matching flags in table */
  {
    /* Return enum in form of: "0x12345678" */
    //pszStr[0]='0';
    //pszStr[1]='x';
    //sp_uitoah(uiFlags, pszStr+2, 0);
    //pszStr[10]=0;
  }
  return pszStr;
}


void change_FEstate(unsigned int eNewState)
{
  if (g_FEState!=eNewState)
  {
    DPRINTF(MSG_STATE, (TEXT("mae: FEstate %s -> %s\n"),
        RunStateStr(g_FEState), RunStateStr(eNewState)));

    if (eNewState==MAE_STATE_NONE || eNewState==MAE_STATE_STOPPED)
    {
      /* disable lcd interrupt in stopped states */
      disable_lcd_scan();
    }
    else if ((eNewState&(MAE_STATE_PREROLL|MAE_STATE_STARTING|MAE_STATE_PLAYING|MAE_STATE_PAUSING|MAE_STATE_PAUSED))!=0)
    {
      /* enable lcd interrupt on any non-stopped states */
      enable_lcd_scan();
    }
    g_FEState = eNewState; /* change state */
    if (g_FEState!=MAE_STATE_NONE && g_FEState!=MAE_STATE_STOPPED) /* FE not in stopped state, so mae_int should be active */
    {
      /* signal mae_interrupt to pick up state change */
      wake_fe();
      wake_decoder();
    }
    else if ((g_FEState==MAE_STATE_NONE || g_FEState==MAE_STATE_STOPPED) &&
             (g_BEState==MAE_STATE_NONE || g_BEState==MAE_STATE_STOPPED))  /* both FE and BE are stopped */
    {
      halt_mae();
    }
  }
}

void change_BEstate(unsigned int eNewState)
{
  if (g_BEState!=eNewState)
  {
    DPRINTF(MSG_STATE, (TEXT("mae: BEstate %s -> %s\n"),
        RunStateStr(g_BEState), RunStateStr(eNewState)));

    /* handle special event on state changes */
    if (eNewState==MAE_STATE_NONE || eNewState==MAE_STATE_STOPPING || eNewState==MAE_STATE_STOPPED)
    {
      disable_overlay(MAE_PLANE);
    }
    else if ((eNewState&(MAE_STATE_PLAYING))!=0)
    {
      if (!g_bFlushing) /* during Flushing ignore state changes - don't change overlay state */
        enable_overlay(MAE_PLANE);
    }
    if (eNewState==MAE_STATE_NONE || eNewState==MAE_STATE_STOPPED)
      g_FrameOutNum = 0;
    g_BEState = eNewState; /* change state */
    if (g_FEState!=MAE_STATE_NONE && g_FEState!=MAE_STATE_STOPPED) /* FE not in stopped state, so mae_int should be active */
    {
      /* signal mae_interrupt to pick up state change */
      wake_fe();
    }
    else if ((g_FEState==MAE_STATE_NONE || g_FEState==MAE_STATE_STOPPED) &&
             (g_BEState==MAE_STATE_NONE || g_BEState==MAE_STATE_STOPPED))  /* both FE abd BE are stopped */
    {
      halt_mae();
    }
  }
}

int isFEstate(unsigned int eStateFlags)
{
  return ((g_FEState&eStateFlags)!=0 || g_FEState==eStateFlags);
}

int isBEstate(unsigned int eStateFlags)
{
  return ((g_BEState&eStateFlags)!=0 || g_BEState==eStateFlags);
}

int waitfor_FEstate(unsigned int eStateFlags, unsigned int uiTimeOut)
{
  unsigned int uiTotalWait=0;
  int bStateMatched=0;
  while (g_FEState!=MAE_STATE_NONE)
  {
    if ((g_FEState&eStateFlags)!=0 || g_FEState==eStateFlags)
    {
      bStateMatched=1;
      break;
    }
    DPRINTF(MSG_STATE, (TEXT("waitfor_FEstate(%s) current=%s\n"),
      RunStateStr(eStateFlags), RunStateStr(g_FEState)));
    if (uiTimeOut && uiTotalWait>=uiTimeOut)
      break; /* timeout reached */
    Sleep(50);
    uiTotalWait+=50;
  }
  DPRINTF(MSG_STATE, (TEXT("waitfor_FEstate(%s) done: current=%s time=%d\n"),
    RunStateStr(eStateFlags), RunStateStr(g_FEState), uiTotalWait));
  return bStateMatched;
}

int waitfor_BEstate(unsigned int eStateFlags, unsigned int uiTimeOut)
{
  unsigned int uiTotalWait=0;
  int bStateMatched=0;
  while (g_bLCDScanEnabled)
  {
    if ((g_BEState&eStateFlags)!=0 || g_BEState==eStateFlags)

⌨️ 快捷键说明

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