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

📄 decode.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * decode.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec 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. * * mpeg2dec 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 */#include "config.h"// $PP#include <stdio.h>#include <string.h>	/* memcmp/memset, try to remove */#include <stdlib.h>#include <string.h>#ifdef MAE_HW#include "inttypes.h"#endif#include "mpeg2.h"#include "attributes.h"#include "mpeg2_internal.h"#ifdef MAE_HW#include "mae_pass_thru.h"#include "MAE_Global.h"#include "defines.h"#include "mai_types.h" /* for MAITimeStamp_t, m_s64 */#include "mae_interface.h"#ifdef USE_CMODELIF#include "cmodelif.h"#endif#include "sliceMAE.h"#include "driverif.h"#endif /* MAE_HW */#if !defined(UNDER_CE) && defined(MAE_RENDERER)    #include "mae_renderer.h"#endif#ifdef TRACE_BUILD#include "mai_osal.h"/* enable these TIME printfs to assist in timestamp/PTS debugging */#define DPRINTF(_args_)   /* MAIOSDebugPrint _args_ */#define DPRINTF2(_args_)  /* MAIOSDebugPrint _args_ */#define APIPRINTF(_args_)   MAIOSDebugPrint _args_ #define GETPRINTF(_args_)   MAIOSDebugPrint _args_ #define PUTPRINTF(_args_)   MAIOSDebugPrint _args_ #else#define DPRINTF(_args_)#define DPRINTF2(_args_)#define APIPRINTF(_args_)#define GETPRINTF(_args_)#define PUTPRINTF(_args_)#endif#if defined(MAE_HW)wrap_context *pWrapContext = NULL;#ifndef UNDER_CE /* Linux */extern uint32 g_flushMAE;#endif#endifextern unsigned char ucMarkFrameSet;extern unsigned char ucMarkFieldSet;#ifdef MAE_HWextern header_words local_header;#endif#if defined(MAE_HW) && !defined(USE_CMODELIF)extern int nDMVUpdate1, nDMVUpdate2;extern int prog_frame; // KK - rev2#endifstatic int mpeg2_accels = 0;#define BUFFER_SIZE (1194 * 1024)const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec){  return &(mpeg2dec->info);}static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes){  uint8_t * current;  uint32_t shift;  uint8_t * limit;  uint8_t byte;    if (!bytes)    return 0;    current = mpeg2dec->buf_start;  shift = mpeg2dec->shift;  limit = current + bytes;    do {    byte = *current++;    if (shift == 0x00000100) {      int skipped;            mpeg2dec->shift = 0xffffff00;      skipped = current - mpeg2dec->buf_start;      mpeg2dec->buf_start = current;      return skipped;    }    shift = (shift | byte) << 8;  } while (current < limit);    mpeg2dec->shift = shift;  mpeg2dec->buf_start = current;  return 0;}static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes){  uint8_t * current;  uint32_t shift;  uint8_t * chunk_ptr;  uint8_t * limit;  uint8_t byte;    if (!bytes)    return 0;    current = mpeg2dec->buf_start;  shift = mpeg2dec->shift;  chunk_ptr = mpeg2dec->chunk_ptr;  limit = current + bytes;    do {    byte = *current++;    if (shift == 0x00000100) {      int copied;            mpeg2dec->shift = 0xffffff00;      mpeg2dec->chunk_ptr = chunk_ptr + 1;      copied = current - mpeg2dec->buf_start;      mpeg2dec->buf_start = current;      return copied;    }    shift = (shift | byte) << 8;    *chunk_ptr++ = byte;  } while (current < limit);    mpeg2dec->shift = shift;  mpeg2dec->buf_start = current;  return 0;}void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end){  unsigned int bufsize=(int)(end-start);  DPRINTF2((M_TEXT("mpeg2_buffer() size=%d Data=%02X %02X %02X %02X ...\n"),    bufsize, start[0], start[1], start[2], start[3]));#if 0 /* enable for debug start codes in buffer */  {    unsigned int i;    for (i=0; i<(bufsize-3); i++)    {      if (start[i]==0x00 && start[i+1]==0x00 && start[i+2]==0x01)      {        DPRINTF((M_TEXT("mpeg2_buffer() code=0x%02X @ %d\n"), start[i+3], i));      }    }  }#endif    mpeg2dec->buf_start = start;  mpeg2dec->buf_end = end;}int mpeg2_getpos (mpeg2dec_t * mpeg2dec){  return mpeg2dec->buf_end - mpeg2dec->buf_start;}static inline mpeg2_state_t seek_chunk (mpeg2dec_t * mpeg2dec){  int size, skipped;    size = mpeg2dec->buf_end - mpeg2dec->buf_start;  skipped = skip_chunk (mpeg2dec, size);  if (!skipped) {    mpeg2dec->bytes_since_tag += size;    return STATE_BUFFER;  }  mpeg2dec->bytes_since_tag += skipped;  mpeg2dec->code = mpeg2dec->buf_start[-1];  return (mpeg2_state_t)-1;}mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec){  while (mpeg2dec->code != 0xb3 &&         ((mpeg2dec->code != 0xb7 && mpeg2dec->code != 0xb8 &&           mpeg2dec->code) || mpeg2dec->sequence.width == (unsigned)-1))  {    if (seek_chunk (mpeg2dec) == STATE_BUFFER)    {      DPRINTF((M_TEXT("mpeg2_seek_header() no code found (last code=0x%02X) seq_width=%d\n"),            mpeg2dec->code, mpeg2dec->sequence.width));      return STATE_BUFFER;    }  }  mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;  mpeg2dec->user_data_len = 0;  DPRINTF((M_TEXT("mpeg2_seek_header() code=0x%02X\n"), mpeg2dec->code));  return (mpeg2dec->code ? mpeg2_parse_header (mpeg2dec) :            mpeg2_header_picture_start (mpeg2dec));}static void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec){  /* HWG - discontinuity handling logic */  DPRINTF((M_TEXT("mpeg2_discontinuity() old: CurrentPTS=%d TempNum=%d GopCount=%d\n"),      (int)mpeg2dec->decoder.tCurrentPTS, mpeg2dec->decoder.uiTemporalNum, mpeg2dec->decoder.uiGOPCount));#if defined(MAE_HW)  if (pWrapContext)  {    PUTPRINTF((M_TEXT("mpeg2_discontinuity() Dummy submit\n")));    pWrapContext->dummysubmit = 1;    WrapSubmitMBs();    pWrapContext = NULL;    mpeg2dec->decoder.ulOkToSubmit = 0;    mpeg2dec->decoder.ulSubmitCalled=1;  }#ifndef UNDER_CE /* Linux */  /* Note: Under Linux the mae-driver is signaled to flush when next WrapGetContext() is called.      It would be preferred to add the pWrapContext->nFlushMAE like under WinCE. */  PUTPRINTF((M_TEXT("mpeg2_discontinuity() bFlushing=1\n")));  mpeg2dec->decoder.bFlushing=1;#endif#endif    DPRINTF((M_TEXT("mpeg2_discontinuity() reset parser\n")));  mpeg2dec->num_tags = 0;  mpeg2dec->shift = 0xffffff00;  if (mpeg2dec->sequence.width == (unsigned)-1)  {    DPRINTF((M_TEXT("mpeg2_discontinuity() no sequence header\n")));    /* sequence header unknown */    mpeg2dec->code = 0xb4;    mpeg2dec->state = STATE_INVALID;  }  else  {    DPRINTF((M_TEXT("mpeg2_discontinuity() still have sequence header\n")));    mpeg2dec->code = 0xb8;  // 0xb8 = seq header    mpeg2dec->state = STATE_GOP;  }  mpeg2dec->action = mpeg2_seek_header;  mpeg2dec->first = 1;  mpeg2dec->first_decode_slice = 1;  mpeg2dec->nb_decode_slices = 0xb0 - 1;    mpeg2dec->decoder.uiWaitForIFrame = 1;  mpeg2dec->decoder.uiOkToDecode = 0;    mpeg2dec->decoder.tCurrentPTS =    mpeg2dec->decoder.uiTemporalOffset =    mpeg2dec->decoder.uiTemporalNum = 0;    mpeg2dec->decoder.uiGOPCount = 0;  mpeg2dec->decoder.uiMaxTemporal=0;    mpeg2dec->decoder.tPTSLastSync = 0;  mpeg2dec->decoder.bSyncedPTS = 0;  mpeg2dec->decoder.iTemporalAtSyncPTS = 0;  mpeg2dec->decoder.uiFramesSincePTSSync = 0;  mpeg2dec->decoder.uiGOPsSincePTSSync = 0;  mpeg2dec->decoder.uiIFramesProcessed = 0;  mpeg2dec->decoder.uiPFramesProcessed = 0;  mpeg2dec->decoder.uiBFramesProcessed = 0;    if (mpeg2dec->decoder.uiFramesSinceNewPTS)  {    mpeg2dec->decoder.tNewPTS = 0;    mpeg2dec->decoder.iTemporalAtNewPTS = 0;    mpeg2dec->decoder.uiFramesSinceNewPTS = 0;    DPRINTF((M_TEXT("mpeg2_discontinuity() reseting NewPTS, old: tNewPTS=%d iTemporalAtNewPTS=%d\n"),      (int)mpeg2dec->decoder.tNewPTS, mpeg2dec->decoder.iTemporalAtNewPTS));  }  }#define RECEIVED(code,state) (((state) << 8) + (code))mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec){  mpeg2_decoder_t * const decoder = &mpeg2dec->decoder;  int size_buffer, size_chunk, copied;  mpeg2_picture_t * picture = &(mpeg2dec->new_picture); // KK  APIPRINTF((M_TEXT("mpeg2_parse() state=%d decmode=%d ctype=%d ulSubmitCalled=%d OKDecode=%d bDiscon=%d\n"),    mpeg2dec->state, decoder->uiDecodeMode, decoder->coding_type, decoder->ulSubmitCalled,    decoder->uiOkToDecode, decoder->bDiscon));    mpeg2dec->info.uiFrameSent = 0;#if defined(MAE_HW)#ifdef UNDER_CE  if (decoder->bFlushing && decoder->ulSubmitCalled)  {    GETPRINTF((M_TEXT("mpeg2_parse() WrapGetContext(0)\n")));    pWrapContext = WrapGetContext (0);    if (pWrapContext)    {      PUTPRINTF((M_TEXT("mpeg2_parse() nFlushMAE=1\n")));      pWrapContext->nFlushMAE = 1;      decoder->bFlushing = 0;      PUTPRINTF((M_TEXT("mpeg2_parse() WrapSubmitMBs() Flush\n")));      WrapSubmitMBs();      pWrapContext = NULL;    }  }#else /* Linux */  /* Linux - Driver (mae_interface) flushes via global variable g_flushMAE  **  The mae-driver is signaled to flush when next GetContext() is called.  **  It would be preferred to add the pWrapContext->nFlushMAE like under WinCE.  */  if (decoder->bFlushing)  {    GETPRINTF((M_TEXT("mpeg2_parse() WrapGetContext(0)\n")));    PUTPRINTF((M_TEXT("mpeg2_parse() g_flushMAE=1\n")));    g_flushMAE=1;    if (decoder->ulSubmitCalled || !pWrapContext)      pWrapContext = WrapGetContext (0);    if (pWrapContext)    {      decoder->bFlushing = 0;      pWrapContext->dummysubmit = 1;      PUTPRINTF((M_TEXT("mpeg2_parse() WrapSubmitMBs() Flush\n")));      WrapSubmitMBs();      pWrapContext = NULL;      decoder->ulSubmitCalled=1;    }  }#endif#endif    if (!decoder->bFlushing && decoder->bDiscon)  {    /* HWG - safe time to do Discontinuity handling */    DPRINTF((M_TEXT("mpeg2_parse() mpeg2_discontinuity\n")));    mpeg2_discontinuity(mpeg2dec);    decoder->bDiscon=0;  }    if (mpeg2dec->action)  {    mpeg2_state_t state;        state = mpeg2dec->action (mpeg2dec);    DPRINTF2((M_TEXT("mpeg2_parse() state=%d\n"), state));        //$PP    // If we decide to q macroblocks to the mae h/w on a field by field basis    // then uncomment the following code block    // this detects when the end of the slices for one field occur and q those MBs#if 0    if (mpeg2dec->state == STATE_PICTURE_2ND)    {      if ( mpeg2dec->decoder.bUseMAE && decoder->ulOkToSubmit )      {        decoder->ulSubmitCalled = 1;        WrapSubmitMBs();        decoder->ulOkToSubmit = 0;        if ( decoder->bUseMAE && (decoder->bDumpFinal || decoder->bDumpFiles) )          WriteFrame (&mpeg2dec->decoder, DUMP, (mpeg2dec->decoder.picture_structure == FRAME_PICTURE ? 0 : 1));      }    }#endif        if ((int)state >= 0)      return state;  }  #if defined(MAE_HW) && !defined(USE_MAI_RENDERER)

⌨️ 快捷键说明

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