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;c0) { 
		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;cbase[0]+c*FrameWidth),FrameWidth); 
			} 
 
			for (c=0;cbase[2]+c*FrameWidth/2),FrameWidth/2); 
			} 
  
			for (c=0;cbase[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; 
}