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

📄 maimpeg2dec.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* <LIC_AMD_STD> * Copyright (c) 2005 Advanced Micro Devices, Inc. *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *  * The full GNU General Public License is included in this distribution in the * file called COPYING * </LIC_AMD_STD>  *//* <CTL_AMD_STD> * </CTL_AMD_STD>  *//* <DOC_AMD_STD>  @doc MAI   @module maimpeg2dec.c -  Media Accelerator Interface, MPEG2 video decoder   MAI video wrapper file. Contains wrapper interface for MPEG2 video decoder to MAI * </DOC_AMD_STD>  */#include "mai_osal.h"#if defined(MAI_OS_WINDOWS)typedef unsigned short uint16_t;typedef signed short int16_t;typedef unsigned char uint8_t;typedef signed char int8_t;typedef signed __int64 int64_t;typedef unsigned __int64 uint64_t;typedef unsigned int uint32_t;typedef signed int int32_t;#else#include <inttypes.h>#endif#include <memory.h> /* for memset */#include "mai_component.h"#include "mai_param.h" /* for Get/SetParam */#include "mpeg2.h" /* libmpeg2 public header for APIs */#include "mai_compbase.h"#ifdef MAE_HW#include "mae_interface.h"#endifextern void setup_mae_driver(void *pvParamVideoAccel);/* enable display (non-MAE) */#if !defined(NO_DISPLAY)#if defined(MAI_OS_WINXP)#define VREND_SUPPORT#elif defined(MAI_OS_LINUX) && !defined(MAE_HW)#define VREND_SUPPORT#ifdef MAI_OS_WINCE#undef VREND_SUPPORT#endif /* MAI_OS_WINCE */#endif#endif/* send PTS to decoder on GOP boundary only *//* #define SETPTS_ON_GOP_ONLY */#ifdef VREND_SUPPORT#include "util_render.h"#endif#ifdef TRACE_BUILD#define ERRORPRINTF(_args_)        MAIOSDebugPrint _args_#define APIPRINTF(_args_)          MAIOSDebugPrint _args_#define DPRINTF(_args_)          /*  MAIOSDebugPrint _args_ */#define DPRINTF2(_args_)         /*  MAIOSDebugPrint _args_ */#define SYNCPRINTF(_args_)         MAIOSDebugPrint _args_#else#define ERRORPRINTF(_args_)     /* MAIOSDebugPrint _args_ */#define APIPRINTF(_args_)       /* MAIOSDebugPrint _args_ */#define DPRINTF(_args_)         /* MAIOSDebugPrint _args_ */#define DPRINTF2(_args_)        /* MAIOSDebugPrint _args_ */#define SYNCPRINTF(_args_)      /* MAIOSDebugPrint _args_ */#endif#if !defined(MAI_OS_LINUX)#define SYNC_SKIPPING_SUPPORT /* enable frame skipping if sync is falling behind */#endif#ifdef MAI_OS_WINCE//WinCE we use a single buffer so having we don't need to alloc so many#define DEFAULT_INBUFSIZE  32*1024#define DEFAULT_INBUFCOUNT 32#else#define DEFAULT_INBUFSIZE  16*1024#define DEFAULT_INBUFCOUNT 128#endif#define OUTPUT_MODE_NONE       0  /* output not sent anywhere */#define OUTPUT_MODE_VREND      1  /* output sent directly to video output */#define OUTPUT_MODE_OUTPUTPIN  2  /* output sent to output pin *//* Our component's private processor variables are stored here */typedef struct ProcessorInfo_s {  mpeg2dec_t        *m_pDecoder;  unsigned int       m_eOutputMode;  unsigned int       m_uiFrameCount;  unsigned int       m_uiOutputFrameCount;  unsigned int       m_uiErrorCount;  MAIOSCritSec_t     m_hCSDecode;  unsigned long      m_uiDisplayOnOff;  unsigned int       m_bVideoOpen;  unsigned char     *m_pVideoBuffer[3];  m_bool             m_bFirstInput;  MAITimeStamp_t     m_tDecodePTS; /* PTS of last frame decoded */  MAITimeStamp_t     m_tInputPTS; /* PTS of last packet on input */  MAICompBuffer_t   *m_pOutBufferInfo;  MAISpeed_e         m_CurrentSpeed;  MAISpeed_e         m_NextSpeed;  unsigned int       m_uiCurrentDecodeMode;  unsigned int       m_uiNextDecodeMode;  unsigned int       m_uiFramesOutInMode; /* how many frames output since mode changed */  unsigned int       m_uiSyncSkippingThreshold; /* threshold in millisecs to start skipping frames */  unsigned int       m_uiSyncSkippingThresholdI; /* threshold in millisecs to start skipping to I-frames */  m_bool             m_bCheckSync;  unsigned int       m_uiFramesSinceCheckSync;} ProcessorInfo_t;/* Function prototypes*/static void update_speed(ProcessorInfo_t *pPInfo, int bForceUpdate);#if 0/* obsolete - kept here to verify that compbase covers all information reported */static void _InBufferPoolStateCB(MAICompBufferPool_t hBufferPool, MAIBufState_e ePoolState, void *pUserData){  MAICompHandle_t hThisComp = (MAICompHandle_t)pUserData;  /* This reports to us if BufferPool becomes: MAI_BUFSTATE_FILLED or MAI_BUFSTATE_EMPTY */  DPRINTF((M_TEXT("MPV2: _InBufferPoolStateCB() ePoolState=%d\n"), ePoolState));  if (g_pfProgressCB && (g_uiProgressSelectFlags & MAI_PROGRESS_BUFFER)!=0)  {    MAIProgressBuffer_t ProgressInfo;    unsigned int uiMaxBufs;    unsigned int uiMaxBufSize;    unsigned int uiBufsFilled;    unsigned int uiDataFilled;    MAICompBufferPoolGetStatus(hBufferPool, &uiMaxBufs, &uiMaxBufSize, &uiBufsFilled, &uiDataFilled);    /* setup progress info fields */    memset(&ProgressInfo, 0, sizeof(MAIProgressBuffer_t));    ProgressInfo.uiFlags=MAI_PROGRESSFLAG_TIMESTAMP;    ProgressInfo.hComp=hThisComp;    ProgressInfo.tCurrentTime = g_tLastPTS;    ProgressInfo.eBufferUnitType=MAI_UNIT_BYTES;    ProgressInfo.uiBufferAvail=(uiMaxBufs-uiBufsFilled)*uiMaxBufSize;    ProgressInfo.uiBufferUsed=uiDataFilled;    ProgressInfo.uiTotalBufferCount=uiMaxBufs;    ProgressInfo.uiUsedBufferCount=uiBufsFilled;    /* make progress call */    g_pfProgressCB(hThisComp, MAI_PROGRESS_BUFFER, &ProgressInfo, sizeof(ProgressInfo));    DPRINTF((M_TEXT("MPV2: _InBufferPoolStateCB() g_pfProgressCB done\n")));  }}#endif#define SETSKIPMODE(_pinfo, _skipframes)     mpeg2_setskipmode(_pinfo->m_pDecoder, _skipframes)#define GETSKIPMODE(_pinfo)                  mpeg2_getskipmode(_pinfo->m_pDecoder)#define SETDECODEMODE(_pinfo, _mode, _speed) mpeg2_setmode(_pinfo->m_pDecoder, (mpeg2_decode_mode_t)_mode, _speed)#define GETDECODEMODE(_pinfo)                mpeg2_getmode(_pinfo->m_pDecoder)static void update_speed(ProcessorInfo_t *pPInfo, int bForceUpdate){  unsigned int uiNewPlayRate=pPInfo->m_NextSpeed&MAI_SPEED_RATEMASK;  if ((pPInfo->m_NextSpeed!=MAI_SPEED_UNSPECIFIED && pPInfo->m_CurrentSpeed!=pPInfo->m_NextSpeed)        || pPInfo->m_uiCurrentDecodeMode!=pPInfo->m_uiNextDecodeMode)     bForceUpdate=1;  if (bForceUpdate && pPInfo->m_pDecoder)  {    MAISpeed_e NextSpeed=(pPInfo->m_NextSpeed==MAI_SPEED_UNSPECIFIED)?pPInfo->m_CurrentSpeed:pPInfo->m_NextSpeed;    APIPRINTF((M_TEXT("MPV2: update_speed() NextSpeed=0x%X NextMode=%d\n"),                pPInfo->m_NextSpeed, pPInfo->m_uiNextDecodeMode));    if (NextSpeed!=MAI_SPEED_UNSPECIFIED &&        pPInfo->m_CurrentSpeed!=pPInfo->m_NextSpeed && pPInfo->m_uiCurrentDecodeMode==pPInfo->m_uiNextDecodeMode)    {      /* Speed is changing, and there has been no request to change decode mode, */      /*   so just translate the new speed to the decode mode */      APIPRINTF((M_TEXT("MPV2: update_speed() 0x%X->0x%X\n"),                 pPInfo->m_CurrentSpeed, pPInfo->m_NextSpeed));      if ((NextSpeed&MAI_SPEED_REVERSEFLAG)!=0)        pPInfo->m_uiNextDecodeMode=DECODE_I_ONLY;      else if (uiNewPlayRate>MAI_SPEED_4X)        pPInfo->m_uiNextDecodeMode=DECODE_I_ONLY;      else if (uiNewPlayRate>=MAI_SPEED_2X)        pPInfo->m_uiNextDecodeMode=DECODE_IP_ONLY;      else        pPInfo->m_uiNextDecodeMode=DECODE_NORMAL;    }    /* set mode in decoder */    APIPRINTF((M_TEXT("MPV2: update_speed() mpeg2_setmode(mode=%d, speed=0x%X)\n"), pPInfo->m_uiNextDecodeMode, pPInfo->m_NextSpeed));    if (pPInfo->m_NextSpeed!=pPInfo->m_CurrentSpeed)    {      APIPRINTF((M_TEXT("MPV2: update_speed() mpeg2_setmode(mode=%d, speed=0x%X) playback direction change\n"), pPInfo->m_uiNextDecodeMode, pPInfo->m_NextSpeed));      mpeg2_setdiscontinuity(pPInfo->m_pDecoder, 1);    }    SETDECODEMODE(pPInfo, pPInfo->m_uiNextDecodeMode, NextSpeed);    pPInfo->m_uiCurrentDecodeMode=pPInfo->m_uiNextDecodeMode; /* remember mode */    pPInfo->m_CurrentSpeed=NextSpeed;        }}#ifdef SYNC_SKIPPING_SUPPORTstatic void check_sync(ProcessorInfo_t *pPInfo, MAIParamClock_t *pClock){  mpeg_time_t tCurrent=0;  SYNCPRINTF((M_TEXT("MPV2:check_sync() CurrentSpeed=0x%08X\n"), pPInfo->m_CurrentSpeed));  pPInfo->m_bCheckSync=M_TRUE;  pPInfo->m_uiFramesSinceCheckSync=0; /* track how frequently check_sync is called */  mpeg2_gettimestamp (pPInfo->m_pDecoder, &tCurrent);  if ((pClock->uiFlags&MAI_CLOCK_FLAG_SYNCTHRESHOLD)!=0)  {    pPInfo->m_uiSyncSkippingThreshold=pClock->uiParam1;    pPInfo->m_uiSyncSkippingThresholdI=pClock->uiParam1*6;    /* check for resonable I frame skipping thresholds */    if (pPInfo->m_uiSyncSkippingThresholdI>800)      pPInfo->m_uiSyncSkippingThresholdI=800;    else if (pPInfo->m_uiSyncSkippingThresholdI<150)      pPInfo->m_uiSyncSkippingThresholdI=150;  }  if (pPInfo->m_CurrentSpeed==MAI_SPEED_NORMAL)  {    if ((pClock->uiFlags&MAI_CLOCK_FLAG_CURRENTTIME)!=0)    {      int iTimeDiff=(int)(MAITIME_LO32(pClock->tCurrentTime)-MAITIME_LO32(tCurrent));      SYNCPRINTF((M_TEXT("MPV2:check_sync() DecodePTS=%d TimeDiff=%d Threshold=%d PlayDecodeMode=%d FInMode=%d\n"),                   MAITIME_LO32(tCurrent), iTimeDiff, pPInfo->m_uiSyncSkippingThreshold,                   pPInfo->m_uiCurrentDecodeMode, pPInfo->m_uiFramesOutInMode));      if (pPInfo->m_uiFramesOutInMode>=1) /* have we decoded some frames in the current decode mode? */      {        int iSkipMoreOrLess=0; /* <0==less skipping, 0==leave mode, >0==more skipping */        unsigned int eCurrentMode=GETDECODEMODE(pPInfo);        unsigned int uiSkipMode = 1;        if (eCurrentMode == DECODE_I_ONLY)          uiSkipMode = GETSKIPMODE(pPInfo);        /* determine if we should increase or decrease skipping based on thresholds */        if (iTimeDiff>(int)pPInfo->m_uiSyncSkippingThreshold)        {          /* video is falling behind - we'll gracefully adjust skipping mode as needed */          if (eCurrentMode == DECODE_NORMAL)            iSkipMoreOrLess=1;          else if (iTimeDiff>(int)pPInfo->m_uiSyncSkippingThresholdI)          {            if (eCurrentMode == DECODE_IP_ONLY)            {              /* increase skipping from IP mode only */              if (pPInfo->m_uiFramesOutInMode>15) /* help smooth transitions, we've processed several frames in this mode */                iSkipMoreOrLess=1;            }            /* I_ONLY */            else if (tCurrent>0 /* ensure we don't skip too much at preroll (negative timestamps) */                && uiSkipMode<=4) /* limit highest practical skipping to every 8 frames */            {              if (pPInfo->m_uiFramesOutInMode>30) /* help smooth transitions, we've processed several frames in this mode */                iSkipMoreOrLess=1;            }          }          else if (eCurrentMode == DECODE_I_ONLY)            iSkipMoreOrLess=-1; /* reduce I-frame skipping */        }        else if (iTimeDiff<0) /* video is catching up */        {          if (eCurrentMode != DECODE_NORMAL)          {            if (iTimeDiff<-200)              iSkipMoreOrLess=-2; /* reduce skipping faster */            else if (eCurrentMode == DECODE_I_ONLY)              iSkipMoreOrLess=-1; /* reduce skipping one mode */          }        }        if (iSkipMoreOrLess) /* we need to increase or decrease skipping mode */        {          SYNCPRINTF((M_TEXT("MPV2:check_sync() MoreLess=%d CurrentMode=%d Diff=%d Thresh=%d FInMode=%d Skip=%d\n"),                     iSkipMoreOrLess, eCurrentMode, iTimeDiff, pPInfo->m_uiSyncSkippingThreshold,                     pPInfo->m_uiFramesOutInMode, uiSkipMode));          if (iSkipMoreOrLess>0)          {            /* bump up the skipping mode to maintain sync */            if (eCurrentMode == DECODE_NORMAL)            {              SYNCPRINTF((M_TEXT("MPV2:check_sync() IP-frames\n")));              SETDECODEMODE(pPInfo, DECODE_IP_ONLY, pPInfo->m_CurrentSpeed);              pPInfo->m_uiFramesOutInMode=0;            }            else if (eCurrentMode == DECODE_IP_ONLY)            {              SYNCPRINTF((M_TEXT("MPV2:check_sync() I-Frames skipmode 1\n")));              SETDECODEMODE(pPInfo, DECODE_I_ONLY, pPInfo->m_CurrentSpeed);              SETSKIPMODE(pPInfo, 1);              pPInfo->m_uiFramesOutInMode=0;            }            else if (eCurrentMode == DECODE_I_ONLY)            {              /* already in I Frame only decode mode, bump up I-frame skipping */              unsigned int uiNewSkipMode=uiSkipMode+1;              SYNCPRINTF((M_TEXT("MPV2:check_sync() I-Frames: increase skipping %d->%d\n"),                    uiSkipMode, uiNewSkipMode));              SETSKIPMODE(pPInfo, uiNewSkipMode);              pPInfo->m_uiFramesOutInMode=0;            }          }          else if (iSkipMoreOrLess<0) /* reduce skipping */          {            /* bump down the skipping mode (we're catching up) */            if (eCurrentMode == DECODE_I_ONLY && ((int)uiSkipMode + iSkipMoreOrLess)>0)            {              /* I-Frame only skipping mode */                          unsigned int uiNewSkipMode=uiSkipMode;              if (iSkipMoreOrLess==-1) /* step down I-frame only skipping */                uiNewSkipMode=uiSkipMode-1;              else if (iSkipMoreOrLess<-1) /* step down quicker */                uiNewSkipMode=uiSkipMode/2;              if (uiNewSkipMode==0)                uiNewSkipMode=1;              SYNCPRINTF((M_TEXT("MPV2:check_sync() I-Frames: reduce skipping %d->%d\n"),                         uiSkipMode, uiNewSkipMode));              SETSKIPMODE(pPInfo, uiNewSkipMode);            }            else if (eCurrentMode == DECODE_I_ONLY && iSkipMoreOrLess==-1)            {              /* go from I mode to IP mode */              SYNCPRINTF((M_TEXT("MPV2:check_sync() IP-frames\n")));              SETSKIPMODE(pPInfo, 1);              SETDECODEMODE(pPInfo, DECODE_IP_ONLY, pPInfo->m_CurrentSpeed);            }            else            {              /* go back to normal mode */              SYNCPRINTF((M_TEXT("MPV2:check_sync() Play NORMAL\n")));              SETDECODEMODE(pPInfo, DECODE_NORMAL, pPInfo->m_CurrentSpeed);            }            pPInfo->m_uiFramesOutInMode=0;          }        } /* if (iSkipMoreOrLess) */      }    }  }}#endif /* SYNC_SKIPPING_SUPPORT */MAIStatus_e _newformat(MAICompHandle_t hComp){  ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp);  MAIStatus_e eStatus = MAI_STATUS_OK;  int szY, szUV;                                                const mpeg2_info_t *pInfo;

⌨️ 快捷键说明

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