免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1104 | 回复: 0
打印 上一主题 下一主题

xvid解码 SDL显示 源程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-14 00:13 |只看该作者 |倒序浏览
#include
#include
#include
#include
#include
#include
#include "xvid.h"
#define USE_PNM 1
#define USE_TGA 0
static int SHXDIM = 0;//display size
static int SHYDIM = 0;
static int XDIM = 352;//real size
static int YDIM = 288;
static int ARG_SAVEDECOUTPUT = 0;
static int ARG_SAVEMPEGSTREAM = 0;
static char *ARG_INPUTFILE = NULL;
static int CSP = XVID_CSP_I420;
static int BPP = 1;
static int FORMAT = USE_PNM;
static char filepath[256] = "./";
static void *dec_handle = NULL;
#define BUFFER_SIZE (2*1024*1024)
static const int display_buffer_bytes = 0;
static SDL_Surface *screen;
static SDL_Overlay *overlay;
static SDL_Rect rect;
static double msecond();
static int dec_init(int use_assembler, int debug_level);
static int dec_main(unsigned char *istream,
     unsigned char *ostream,
     int istream_size,
     xvid_dec_stats_t *xvid_dec_stats);
static int dec_stop();
static void usage();
static int write_image(char *prefix, unsigned char *image);
static int write_pnm(char *filename, unsigned char *image);
static int write_tga(char *filename, unsigned char *image);
const char * type2str(int type)
{
    if (type==XVID_TYPE_IVOP)
        return "I";
    if (type==XVID_TYPE_PVOP)
        return "P";
    if (type==XVID_TYPE_BVOP)
        return "B";
    return "S";
}
static void init_SDL()
{
    if (SDL_Init (SDL_INIT_VIDEO) flags & SDL_HWSURFACE)
    {
        fprintf(stderr,"Can't get hardware surface\n");
        exit(3);
    }
    SDL_WM_SetCaption ("SDL MultiMedia Application", NULL);      
    overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
    if (!overlay)
    {
        fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
        exit(4);
    }   
    //show the overlay status
    printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
           overlay->hw_overlay?"hardware":"software",
           overlay->format==SDL_YV12_OVERLAY?"YV12":
           overlay->format==SDL_IYUV_OVERLAY?"IYUV":
           overlay->format==SDL_YUY2_OVERLAY?"YUY2":
           overlay->format==SDL_UYVY_OVERLAY?"UYVY":
           overlay->format==SDL_YVYU_OVERLAY?"YVYU":
           "Unknown");
    rect.x=0;
    rect.y=0;
    rect.w=SHXDIM;
    rect.h=SHYDIM;
}
int main(int argc, char *argv[])
{
SDL_Event event;
uint32_t lastftick;
unsigned char *mp4_buffer = NULL;
unsigned char *mp4_ptr    = NULL;
unsigned char *out_buffer = NULL;
int useful_bytes;
xvid_dec_stats_t xvid_dec_stats;

double totaldectime;
  
long totalsize;
int status;
int fps = 25;
    int fpsdelay;
int paused=0;
    int resized=0;  
int use_assembler = 1;
int debug_level = 0;
  
char filename[256];
  
FILE *in_file;
int filenr;
int i;
for (i=1; i
/* PNM/PGM format can't handle 16/32 bit data */
if (BPP != 1 && BPP != 3 && FORMAT == USE_PNM) {
  FORMAT = USE_TGA;
}
/* Memory for encoded mp4 stream */
mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
if (!mp4_buffer)
  goto free_all_memory;
out_buffer = (unsigned char *)malloc(XDIM*YDIM*3/2);
if (!out_buffer)
  goto free_all_memory;
/******************************************************************************
*        INIT SDL
*******************************************************************************/        
    init_SDL();   
        
/*****************************************************************************
*        XviD PART  Start
****************************************************************************/
status = dec_init(use_assembler, debug_level);
if (status) {
  fprintf(stderr,
    "Decore INIT problem, return value %d\n", status);
  goto release_all;
}        
/*****************************************************************************
*                          Main loop
****************************************************************************/
/* Fill the buffer ,create 2M buffer*/
useful_bytes = fread(mp4_buffer, 1, BUFFER_SIZE, in_file);
totaldectime = 0;
totalsize = 0;
filenr = 0;
mp4_ptr = mp4_buffer;
    uint8_t  *outy,*outu,*outv,*op[3];
int y;
    /* set the start frame */
    i=0;
    fpsdelay=1000/fps;
lastftick=SDL_GetTicks();
do
{  
  int used_bytes = 0;
  double dectime;
  while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_VIDEORESIZE:
                     screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
                     rect.w=event.resize.w;
                     rect.h=event.resize.h;
                     if (paused)
                     {
                         resized=1;
                     }
                     break;
                case SDL_KEYDOWN:
                     if (event.key.keysym.sym == SDLK_SPACE)
                     {
                         paused=!paused;
                         break;
                     }
                     if (event.key.keysym.sym != SDLK_ESCAPE)
                     {
          goto release_all;
                     }
                case SDL_QUIT:
                     goto release_all;
            }
        }
  /*
  * If the buffer is half empty or there are no more bytes in it
  * then fill it.
  */
  if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2)
  {
            int already_in_buffer = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
      /* Move data if needed */
      if (already_in_buffer > 0)
                memcpy(mp4_buffer, mp4_ptr, already_in_buffer);
      /* Update mp4_ptr */
      mp4_ptr = mp4_buffer;
      /* read new data */
      if(feof(in_file))
            break;
            useful_bytes += fread(mp4_buffer + already_in_buffer,
             1, BUFFER_SIZE - already_in_buffer,
               in_file);
        }
  if ((!paused)||(resized))
  {
         if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
         {
             lastftick=SDL_GetTicks();
    /* This loop is needed to handle VOL/NVOP reading */
    do{
        /* Decode frame */
              dectime = msecond();   
              used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats);
              dectime = msecond() - dectime;
     if(xvid_dec_stats.type==XVID_TYPE_VOL
         && (xvid_dec_stats.data.vol.width != XDIM
             ||xvid_dec_stats.data.vol.height != YDIM))
         {
       //reallocate bigger out frame
      free(out_buffer);
      XDIM = xvid_dec_stats.data.vol.width;
       YDIM = xvid_dec_stats.data.vol.height;
       out_buffer = (unsigned char *) malloc(XDIM*YDIM*3/2);         
       if (!out_buffer)
              goto free_all_memory;
                     
       //reallocate bigger yuv overlay
                        
          SDL_FreeYUVOverlay(overlay);
             overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
             if (!overlay)
             {
                  fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
               exit(4);
                         }     
                     
       }        
     /* Update buffer pointers */
     if(used_bytes > 0) {
         mp4_ptr += used_bytes;
      useful_bytes -= used_bytes;
      /* Total size */
      totalsize += used_bytes;
     }
                }while (xvid_dec_stats.type  0);
    /* Check if there is a negative number of useful bytes left in buffer
     * This means we went too far */
          if(useful_bytes h && yh;y++)
    {
        op[0]=overlay->pixels[0]+overlay->pitches[0]*y;
     op[1]=overlay->pixels[1]+overlay->pitches[1]*(y/2);
     op[2]=overlay->pixels[2]+overlay->pitches[2]*(y/2);   
     memcpy(op[0],outy+y*XDIM,XDIM);
     if(y%2 == 0)
     {
             memcpy(op[1],outu+XDIM/2*y/2,XDIM/2);
       memcpy(op[2],outv+XDIM/2*y/2,XDIM/2);   
           }
    }
          SDL_UnlockYUVOverlay(overlay);
          SDL_UnlockSurface(screen);        
          SDL_DisplayYUVOverlay(overlay, &rect);
    /* Save output frame if required */
    if (ARG_SAVEDECOUTPUT) {
        sprintf(filename, "%sdec%05d", filepath, filenr);
     if(write_image(filename, out_buffer)) {
        fprintf(stderr,
      "Error writing decoded frame %s\n",
      filename);
     }
                }
                filenr++;
                if (resized)
                    resized = 0;
             }
          }
          SDL_Delay(10);
} while (useful_bytes>0 || !feof(in_file));
useful_bytes = 0; /* Empty buffer */
/*****************************************************************************
*     Flush decoder buffers
****************************************************************************/
do {
  /* Fake vars */
  int used_bytes;
  double dectime;
        do {
      dectime = msecond();
      used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats);
      dectime = msecond() - dectime;
        } while(used_bytes>=0 && xvid_dec_stats.type
        if (used_bytes
  /* Updated data - Count only usefull decode time */
  totaldectime += dectime;
  /* Prints some decoding stats */
  if (!display_buffer_bytes) {
   printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n",
     filenr, type2str(xvid_dec_stats.type), dectime, used_bytes);
  }
  /* Save output frame if required */
  if (ARG_SAVEDECOUTPUT) {
   sprintf(filename, "%sdec%05d", filepath, filenr);
   if(write_image(filename, out_buffer)) {
    fprintf(stderr,
      "Error writing decoded frame %s\n",
      filename);
   }
  }
  filenr++;
}while(1);
/*****************************************************************************
*     Calculate totals and averages for output, print results
****************************************************************************/
if (filenr>0) {
  totalsize    /= filenr;
  totaldectime /= filenr;
  printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n",
      totaldectime, 1000/totaldectime, (int)totalsize);
}else{
  printf("Nothing was decoded!\n");
}
  
/*****************************************************************************
*      XviD PART  Stop
****************************************************************************/
release_all:
    SDL_FreeYUVOverlay(overlay);         
   if (dec_handle) {
    status = dec_stop();
  if (status)   
   fprintf(stderr, "decore RELEASE problem return value %d\n", status);
}
free_all_memory:
    free(out_buffer);
free(mp4_buffer);
return 0;
}
/*****************************************************************************
*               Usage function
****************************************************************************/
static void usage()
{
fprintf(stderr, "Usage : xvid_decraw [OPTIONS]\n");
fprintf(stderr, "Options :\n");
fprintf(stderr, " -asm           : use assembly optimizations (default=disabled)\n");
fprintf(stderr, " -i string      : input filename (default=stdin)\n");
fprintf(stderr, " -d             : save decoder output\n");
fprintf(stderr, " -f format      : choose output file format (tga, pnm, pgm)\n");
fprintf(stderr, " -w width       : init window width\n");
fprintf(stderr, " -h height      : init window height\n");
fprintf(stderr, " -help          : This help message\n");
fprintf(stderr, " (* means default)\n");
}
/* return the current time in milli seconds */
static double
msecond()
{
clock_t clk;
clk = clock();
return(clk * 1000 / CLOCKS_PER_SEC);
}
        
static int write_image(char *prefix, unsigned char *image)
{
char filename[1024];
char *ext;
int ret;
if (FORMAT == USE_PNM && BPP == 1) {
  ext = "pgm";
} else if (FORMAT == USE_PNM && BPP == 3) {
  ext = "pnm";
} else if (FORMAT == USE_TGA) {
  ext = "tga";
} else {
  fprintf(stderr, "Bug: should not reach this path code -- please report to
xvid-devel@xvid.org
with command line options used");
  exit(-1);
}
sprintf(filename, "%s.%s", prefix, ext);
if (FORMAT == USE_PNM) {
  ret = write_pnm(filename, image);
} else {
  ret = write_tga(filename, image);
}
return(ret);
}
static int write_tga(char *filename, unsigned char *image)
{
FILE * f;
char hdr[18];
f = fopen(filename, "wb");
if ( f == NULL) {
  return -1;
}
hdr[0]  = 0; /* ID length */
hdr[1]  = 0; /* Color map type */
hdr[2]  = (BPP>1)?2:3; /* Uncompressed true color (2) or greymap (3) */
hdr[3]  = 0; /* Color map specification (not used) */
hdr[4]  = 0; /* Color map specification (not used) */
hdr[5]  = 0; /* Color map specification (not used) */
hdr[6]  = 0; /* Color map specification (not used) */
hdr[7]  = 0; /* Color map specification (not used) */
hdr[8]  = 0; /* LSB X origin */
hdr[9]  = 0; /* MSB X origin */
hdr[10] = 0; /* LSB Y origin */
hdr[11] = 0; /* MSB Y origin */
hdr[12] = (XDIM>>0)&0xff; /* LSB Width */
hdr[13] = (XDIM>>8)&0xff; /* MSB Width */
if (BPP > 1) {
  hdr[14] = (YDIM>>0)&0xff; /* LSB Height */
  hdr[15] = (YDIM>>8)&0xff; /* MSB Height */
} else {
  hdr[14] = ((YDIM*3)>>1)&0xff; /* LSB Height */
  hdr[15] = ((YDIM*3)>>9)&0xff; /* MSB Height */
}
hdr[16] = BPP*8;
hdr[17] = 0x00 | (1
/* write first plane */
fwrite(image, 1, XDIM*YDIM*BPP, f);
/* Write Y and V planes for YUV formats */
if (BPP == 1) {
  int i;
  /* Write the two chrominance planes */
  for (i=0; i
/* Close the file */
fclose(f);
return(0);
}
static int write_pnm(char *filename, unsigned char *image)
{
FILE * f;
f = fopen(filename, "wb");
if ( f == NULL) {
  return -1;
}
if (BPP == 1) {
  int i;
  fprintf(f, "P5\n#xvid\n%i %i\n255\n", XDIM, YDIM*3/2);
  fwrite(image, 1, XDIM*YDIM, f);
  for (i=0; i
fclose(f);
return 0;
}
/*****************************************************************************
* Routines for decoding: init decoder, use, and stop decoder
****************************************************************************/
/* init decoder before first run */
static int
dec_init(int use_assembler, int debug_level)
{
int ret;
xvid_gbl_init_t   xvid_gbl_init;
xvid_dec_create_t xvid_dec_create;
/* Reset the structure with zeros */
memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init_t));
memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t));
/*------------------------------------------------------------------------
  * XviD core initialization
  *----------------------------------------------------------------------*/
/* Version */
xvid_gbl_init.version = XVID_VERSION;
/* Assembly setting */
if(use_assembler)
     xvid_gbl_init.cpu_flags = 0;
else
  xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
xvid_gbl_init.debug = debug_level;
xvid_global(NULL, 0, &xvid_gbl_init, NULL);
/*------------------------------------------------------------------------
  * XviD encoder initialization
  *----------------------------------------------------------------------*/
/* Version */
xvid_dec_create.version = XVID_VERSION;
/*
  * Image dimensions -- set to 0, xvidcore will resize when ever it is
  * needed
  */
xvid_dec_create.width = 0;
xvid_dec_create.height = 0;
ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL);
dec_handle = xvid_dec_create.handle;
return(ret);
}
/* decode one frame  */
static int
dec_main(unsigned char *istream,
   unsigned char *ostream,
   int istream_size,
   xvid_dec_stats_t *xvid_dec_stats)
{
int ret;
xvid_dec_frame_t xvid_dec_frame;
/* Reset all structures */
memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t));
memset(xvid_dec_stats, 0, sizeof(xvid_dec_stats_t));
/* Set version */
xvid_dec_frame.version = XVID_VERSION;
xvid_dec_stats->version = XVID_VERSION;
/* No general flags to set */
xvid_dec_frame.general          = 0;
/* Input stream */
xvid_dec_frame.bitstream        = istream;
xvid_dec_frame.length           = istream_size;
/* Output frame structure */
xvid_dec_frame.output.plane[0]  = ostream;
xvid_dec_frame.output.stride[0] = XDIM*BPP;
xvid_dec_frame.output.csp = CSP;
ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats);
return(ret);
}
/* close decoder to release resources */
static int
dec_stop()
{
int ret;
ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);
return(ret);
}
本文来自CSDN博客,转载请标明出处:
http://blog.csdn.net/dog0138/archive/2007/03/15/1530779.aspx


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/99873/showart_2069830.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP