www.pudn.com > mpeg2win-0.4-source.zip > video_out_pgm.c
/* * video_out_pgm.c * Copyright (C) 1999-2001 Aaron Holtzman* * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * 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" #include #include #include #include #include #include #include "../mpg123/fifo.h" #include "video_out.h" #include "video_out_internal.h" typedef struct pgm_instance_s { vo_instance_t vo; int prediction_index; vo_frame_t * frame_ptr[3]; vo_frame_t frame[3]; int width; int height; int framenum; char header[1024]; char filename[128]; } pgm_instance_t; static LPDIRECTDRAW pDirectDraw; static LPDIRECTDRAWSURFACE pDirectDrawSurface,pPrimarySurface; static DDCAPS ddcaps,ddcapseml; static char LUT_U[256]; static char LUT_V[256]; static void memLUTU (unsigned char * memout,unsigned char *memin, int bytecount) { int c; for (c=0;c 0) { Sleep (TicksToWait); } afree=audiohead-audiotail; if (afree<0) afree+=AUDIOBUFSIZE; vfree=videohead-videotail; if (vfree<0) vfree+=VIDEOBUFSIZE; if (DebugPrint) printf ("audio : %d bytes, video : %d bytes, ticks : %d/%d ,waited : %d MS\n",afree,vfree,ElapsedTicks,SyncFrames*40,TicksToWait); SyncFrames+=1; if (TicksToWait>-40) // if we're more then 1 frame too late, drop frame ! { rect.left=0; rect.right=FrameWidth-1; rect.top=0; rect.bottom=FrameHeight-1; outrect=VideoRect; hResult = IDirectDrawSurface_Lock(pDirectDrawSurface,NULL/*&rect*/,&SurfaceDesc,DDLOCK_WRITEONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL); if (hResult==0) { for (c=0;c base[0]+c*FrameWidth),FrameWidth); } for (c=0;c base[2]+c*FrameWidth/2),FrameWidth/2); } for (c=0;c base[1]+c*FrameWidth/2),FrameWidth/2); } } hResult=IDirectDrawSurface_UpdateOverlay(pDirectDrawSurface, &rect, pPrimarySurface, &outrect, DDOVER_SHOW , NULL); hResult = IDirectDrawSurface_Unlock(pDirectDrawSurface,NULL); } else { printf ("dropped frame !"); } } int load_luts () { int c; FILE *LUTfile; LUTfile=fopen ("LUT.dat","rt"); for (c=0;c<256;c++) { fscanf (LUTfile,"%d %d",&LUT_V[c],&LUT_U[c]); } fclose (LUTfile); } static int internal_setup (vo_instance_t * _instance, int width, int height, void (* draw_frame) (vo_frame_t *)) { pgm_instance_t * instance; instance = (pgm_instance_t *) _instance; instance->vo.close = libvo_common_free_frames; instance->vo.get_frame = libvo_common_get_frame; instance->width = width; instance->height = height; sprintf (instance->header, "P5\n\n%d %d\n255\n", width, height * 3 / 2); return libvo_common_alloc_frames ((vo_instance_t *) instance, width, height, sizeof (vo_frame_t), NULL, NULL, draw_frame); } static void pgm_draw_frame (vo_frame_t * frame) { pgm_instance_t * instance; FILE * file; instance = (pgm_instance_t *) frame->instance; if (++(instance->framenum) < 0) return; sprintf (instance->filename, "%d.pgm", instance->framenum); // file = fopen (instance->filename, "wb"); if (!file) return; internal_draw_frame (instance, file, frame); // fclose (file); } static int pgm_setup (vo_instance_t * instance, int width, int height) { return internal_setup (instance, width, height, pgm_draw_frame); } vo_instance_t * vo_pgm_open (void) { pgm_instance_t * instance; int hResult; static DDSURFACEDESC ddsd; SyncFrames=0; load_luts(); SetCursorPos (1024,768); hResult = DirectDrawCreate(NULL, &pDirectDraw, NULL); hResult=hResult&0xffff; printf ("Creating DirectDraw Object : %d\n",hResult); hResult = IDirectDraw_SetCooperativeLevel(pDirectDraw,GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); hResult=hResult&0xffff; printf ("Setting Cooperative Level : %d\n",hResult); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hResult = IDirectDraw_CreateSurface( pDirectDraw, &ddsd, &pPrimarySurface, NULL ); printf ("Creating primary sUrface : %d\n",hResult); if (hResult!=0) { printf ("Error creating surface, can't create primary !\n"); return NULL; } /* Set up the surface description */ memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); ddsd.dwWidth=SurWidth; FrameWidth=SurWidth; ddsd.dwHeight=SurHeight; FrameHeight=SurHeight; printf ("Display Size : %d x %d\n",SurWidth,SurHeight); ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY); ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2'); hResult=hResult&0xffff; hResult = IDirectDraw_CreateSurface(pDirectDraw,&ddsd,&pDirectDrawSurface,NULL); hResult=hResult&0xffff; printf ("Creating Surface : %d\n",hResult); if (hResult!=0) { printf ("Error creating surface, either the video-card doesnt support YV12 YUV planes, or the video-size is too large\n"); return NULL; } instance = malloc (sizeof (pgm_instance_t)); if (instance == NULL) return NULL; instance->vo.setup = pgm_setup; instance->framenum = -2; return (vo_instance_t *) instance; } static void pgmpipe_draw_frame (vo_frame_t * frame) { pgm_instance_t * instance; instance = (pgm_instance_t *)frame->instance; if (++(instance->framenum) >= 0) internal_draw_frame (instance, 0, frame); //! } static int pgmpipe_setup (vo_instance_t * instance, int width, int height) { return internal_setup (instance, width, height, pgmpipe_draw_frame); } vo_instance_t * vo_pgmpipe_open (void) { pgm_instance_t * instance; instance = malloc (sizeof (pgm_instance_t)); if (instance == NULL) return NULL; instance->vo.setup = pgmpipe_setup; instance->framenum = -2; return (vo_instance_t *) instance; } static void md5_draw_frame (vo_frame_t * frame) { pgm_instance_t * instance; char buf[100]; instance = (pgm_instance_t *) frame->instance; pgm_draw_frame (frame); if (instance->framenum < 0) return; sprintf (buf, "md5sum -b %s", instance->filename); system (buf); remove (instance->filename); } static int md5_setup (vo_instance_t * instance, int width, int height) { return internal_setup (instance, width, height, md5_draw_frame); } vo_instance_t * vo_md5_open (void) { pgm_instance_t * instance; instance = malloc (sizeof (pgm_instance_t)); if (instance == NULL) return NULL; instance->vo.setup = md5_setup; instance->framenum = -2; return (vo_instance_t *) instance; }