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

📄 sdl_dx5yuv.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id: SDL_dx5yuv.c,v 1.5 2002/03/06 11:23:08 slouken Exp $";#endif/* This is the DirectDraw implementation of YUV video overlays */#include <stdlib.h>#include <string.h>#include "SDL_error.h"#include "SDL_video.h"#include "SDL_dx5yuv_c.h"#include "SDL_yuvfuncs.h"#define USE_DIRECTX_OVERLAY/* The functions used to manipulate software video overlays */static struct private_yuvhwfuncs dx5_yuvfuncs = {	DX5_LockYUVOverlay,	DX5_UnlockYUVOverlay,	DX5_DisplayYUVOverlay,	DX5_FreeYUVOverlay};struct private_yuvhwdata {	LPDIRECTDRAWSURFACE3 surface;	/* These are just so we don't have to allocate them separately */	Uint16 pitches[3];	Uint8 *planes[3];};static LPDIRECTDRAWSURFACE3 CreateYUVSurface(_THIS,                                         int width, int height, Uint32 format){	HRESULT result;	LPDIRECTDRAWSURFACE  dd_surface1;	LPDIRECTDRAWSURFACE3 dd_surface3;	DDSURFACEDESC ddsd;	/* Set up the surface description */	memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT);	ddsd.dwWidth = width;	ddsd.dwHeight= height;#ifdef USE_DIRECTX_OVERLAY	ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY);#else	ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);#endif	ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);	ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;	ddsd.ddpfPixelFormat.dwFourCC = format;	/* Create the DirectDraw video surface */	result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL); 	if ( result != DD_OK ) {		SetDDerror("DirectDraw2::CreateSurface", result);		return(NULL);	}	result = IDirectDrawSurface_QueryInterface(dd_surface1,			&IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);	IDirectDrawSurface_Release(dd_surface1);	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface::QueryInterface", result);		return(NULL);	}	/* Make sure the surface format was set properly */	memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	result = IDirectDrawSurface3_Lock(dd_surface3, NULL,					  &ddsd, DDLOCK_NOSYSLOCK, NULL);	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::Lock", result);		IDirectDrawSurface_Release(dd_surface3);		return(NULL);	}	IDirectDrawSurface3_Unlock(dd_surface3, NULL);	if ( !(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||	      (ddsd.ddpfPixelFormat.dwFourCC != format) ) {		SDL_SetError("DDraw didn't use requested FourCC format");		IDirectDrawSurface_Release(dd_surface3);		return(NULL);	}	/* We're ready to go! */	return(dd_surface3);}#ifdef DEBUG_YUVstatic char *PrintFOURCC(Uint32 code){	static char buf[5];	buf[3] = code >> 24;	buf[2] = (code >> 16) & 0xFF;	buf[1] = (code >> 8) & 0xFF;	buf[0] = (code & 0xFF);	return(buf);}#endifSDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display){	SDL_Overlay *overlay;	struct private_yuvhwdata *hwdata;#ifdef DEBUG_YUV	DWORD numcodes;	DWORD *codes;	printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format));	IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL);	if ( numcodes ) {		DWORD i;		codes = malloc(numcodes*sizeof(*codes));		if ( codes ) {			IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes);			for ( i=0; i<numcodes; ++i ) {				fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i]));			}			free(codes);		}	} else {		fprintf(stderr, "No FOURCC codes supported\n");	}#endif	/* Create the overlay structure */	overlay = (SDL_Overlay *)malloc(sizeof *overlay);	if ( overlay == NULL ) {		SDL_OutOfMemory();		return(NULL);	}	memset(overlay, 0, (sizeof *overlay));	/* Fill in the basic members */	overlay->format = format;	overlay->w = width;	overlay->h = height;	/* Set up the YUV surface function structure */	overlay->hwfuncs = &dx5_yuvfuncs;	/* Create the pixel data and lookup tables */	hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata);	overlay->hwdata = hwdata;	if ( hwdata == NULL ) {		SDL_OutOfMemory();		SDL_FreeYUVOverlay(overlay);		return(NULL);	}	hwdata->surface = CreateYUVSurface(this, width, height, format);	if ( hwdata->surface == NULL ) {		SDL_FreeYUVOverlay(overlay);		return(NULL);	}	overlay->hw_overlay = 1;	/* Set up the plane pointers */	overlay->pitches = hwdata->pitches;	overlay->pixels = hwdata->planes;	switch (format) {	    case SDL_YV12_OVERLAY:	    case SDL_IYUV_OVERLAY:		overlay->planes = 3;		break;	    default:		overlay->planes = 1;		break;	}	/* We're all done.. */	return(overlay);}int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay){	HRESULT result;	LPDIRECTDRAWSURFACE3 surface;	DDSURFACEDESC ddsd;	surface = overlay->hwdata->surface;	memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	result = IDirectDrawSurface3_Lock(surface, NULL,					  &ddsd, DDLOCK_NOSYSLOCK, NULL);	if ( result == DDERR_SURFACELOST ) {		result = IDirectDrawSurface3_Restore(surface);		result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd, 					(DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);	}	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::Lock", result);		return(-1);	}	/* Find the pitch and offset values for the overlay */#if defined(NONAMELESSUNION)	overlay->pitches[0] = (Uint16)ddsd.u1.lPitch;#else	overlay->pitches[0] = (Uint16)ddsd.lPitch;#endif	overlay->pixels[0] = (Uint8 *)ddsd.lpSurface;	switch (overlay->format) {	    case SDL_YV12_OVERLAY:	    case SDL_IYUV_OVERLAY:		/* Add the two extra planes */		overlay->pitches[1] = overlay->pitches[0] / 2;		overlay->pitches[2] = overlay->pitches[0] / 2;	        overlay->pixels[1] = overlay->pixels[0] +		                     overlay->pitches[0] * overlay->h;	        overlay->pixels[2] = overlay->pixels[1] +		                     overlay->pitches[1] * overlay->h / 2;	        break;	    default:		/* Only one plane, no worries */		break;	}	return(0);}void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay){	LPDIRECTDRAWSURFACE3 surface;	surface = overlay->hwdata->surface;	IDirectDrawSurface3_Unlock(surface, NULL);}int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect){	HRESULT result;	LPDIRECTDRAWSURFACE3 surface;	RECT src, dst;	surface = overlay->hwdata->surface;	src.top = 0;	src.bottom = overlay->h;	src.left = 0;	src.right = overlay->w;	dst.top = SDL_bounds.top+dstrect->y;	dst.left = SDL_bounds.left+dstrect->x;	dst.bottom = dst.top+dstrect->h;	dst.right = dst.left+dstrect->w;#ifdef USE_DIRECTX_OVERLAY	result = IDirectDrawSurface3_UpdateOverlay(surface, &src,				SDL_primary, &dst, DDOVER_SHOW, NULL);	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::UpdateOverlay", result);		return(-1);	}#else	result = IDirectDrawSurface3_Blt(SDL_primary, &dst, surface, &src,							DDBLT_WAIT, NULL);	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::Blt", result);		return(-1);	}#endif	return(0);}void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay){	struct private_yuvhwdata *hwdata;	hwdata = overlay->hwdata;	if ( hwdata ) {		if ( hwdata->surface ) {			IDirectDrawSurface_Release(hwdata->surface);		}		free(hwdata);	}}

⌨️ 快捷键说明

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