vo_dxr3.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,483 行 · 第 1/3 页

C
1,483
字号
/* * vo_dxr3.c - DXR3/H+ video out * * Copyright (C) 2002-2003 David Holm <david@realityrift.com> * *//* ChangeLog added 2002-01-10 * 2003-11-28: *  Added a patch from Anders Rune Jensen to support the latest em8300 CVS *  changes. * * 2003-02-19: *  Yet another patch from Tamas Kohegyi to fix subpic placement. * * 2003-01-12: *  Added patch from Tamas Kohegyi to fix subpic placement with freetype. * * 2003-01-02: *  Added patch from Jens Axboe that makes vo_dxr3 return to previous TV norm *   after quiting. *  Added patch from Thomas Jarosch that fixed a lot of textual ouput *   errors. * * 2002-12-24: (Hohoho) *  Added patch from Thomas Jarosch <tomj@simonv.com> which adds support *   for setting the TV norm by movie framerate. * * 2002-11-03: *  Cleaned up syncing code and renamed setup variables so *   they can be accessed from the GUI. * * 2002-11-02: *  Added native overlay support, activate with :overlay *   you have to run dxr3view to modify settings (or manually *   edit the files in ~/.overlay. * * 2002-10-29: *  Added new sync-engine, activate with :sync option. *  Greatly improved commandline parser. *  Replaced :noprebuf with :prebuf and made noprebuf the default. * * 2002-10-28: *  Fixed multicard bug on athlons * * 2002-07-18: *  Disabled spuenc support, this is still not stable enough =( * * 2002-07-05: *  Removed lavc and fame encoder to be compatible with new libvo style. *  Added graphic equalizer support. * * 2002-04-15: *  The spuenc code isn't 100% stable yet, therefore I'm disabling *  it due to the upcoming stable release. * * 2002-04-03: *  Carl George added spuenc support * * 2002-03-26: *  XorA added an option parser and support for selecting encoder *  codec. We thank him again. * * 2002-03-25: *  A couple of bugfixes by XorA * * 2002-03-23: *  Thanks to Marcel Hild <hild@b4mad.net> the jitter-bug experienced *  with some videos have been fixed, many thanks goes to him. * * 2002-03-16: *  Fixed problems with fame, it gives a better picture than avcodec, *  but is slightly slower. Most notably the wobbling effect is gone *  with fame. * * 2002-03-13: *  Preliminary fame support added (it breaks after seeking, why?) * * 2002-02-18: *  Fixed sync problems when pausing video (while using prebuffering) * * 2002-02-16: *  Fixed bug which would case invalid output when using :noprebuf *  Removed equalization code, it caused problems on slow systems * * 2002-02-13: *  Using the swscaler instead of the old hand coded shit. (Checkout man mplayer and search for sws ;). *  Using aspect function to setup a proper mpeg1, no more hassling with odd resolutions or GOP-sizes, *  this would only create jitter on some vids! *  The swscaler sometimes exits with sig8 on mpegs, I don't know why yet (just use -vc mpegpes in this *  case, and report to me if you have any avi's etc which does this...) * * 2002-02-09: *  Thanks to the new control() method I have finally been able to enable the em8300 prebuffering. *  This should speed up playback on all systems, the vout cpu usage should rocket since I will be hogging *  the pci bus. Not to worry though, since frames are prebuffered it should be able to take a few blows *  if you start doing other stuff simultaneously. * * 2002-02-03: *  Removal of libmp1e, libavcodec has finally become faster (and it's code is helluva lot cleaner) * * 2002-02-02: *  Cleaned out some old code which might have slowed down writes * * 2002-01-17: *  Testrelease of new sync engine (using previously undocumented feature of em8300). * * 2002-01-15: *  Preliminary subpic support with -vc mpegpes and dvd's *  Device interfaces tries the new naming scheme by default (even though most users probably still use the old one) * * 2002-01-10: *  I rehauled the entire codebase. I have now changed to *  Kernighan & Ritchie codingstyle, please mail me if you  *  find any inconcistencies. */ #include <linux/em8300.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/select.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <fcntl.h>#include <mplaylib.h>#include <time.h>#include <math.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#ifdef HAVE_MALLOC_H#include <uclib.h>#endif#include "fastmemcpy.h"#include "video_out.h"#include "video_out_internal.h"#include "aspect.h"#include "spuenc.h"#include "sub.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#endif#ifdef HAVE_X11#include "x11_common.h"#endif#include "libavutil/avstring.h"#define SPU_SUPPORTstatic vo_info_t info = {	"DXR3/H+ video out",	"dxr3",	"David Holm <dholm@iname.com>",	""};LIBVO_EXTERN (dxr3)/* Resolutions and positions */static int v_width, v_height;static int s_width, s_height;static int osd_w, osd_h;static int img_format;/* Configuration values * Don't declare these static, they  * should be accessible from the gui. */int dxr3_prebuf = 0;int dxr3_newsync = 0;int dxr3_overlay = 0;int dxr3_device_num = 0;int dxr3_norm = 0;#define MAX_STR_SIZE 80 /* length for the static strings  *//* File descriptors */static int fd_control = -1;static int fd_video = -1;static int fd_spu = -1;static char fdv_name[MAX_STR_SIZE];static char fds_name[MAX_STR_SIZE];#ifdef SPU_SUPPORT/* on screen display/subpics */static char *osdpicbuf;static int osdpicbuf_w;static int osdpicbuf_h;static int disposd;static encodedata *spued;static encodedata *spubuf;#endif#undef memcpy#define memcpy uc_memcpy/* Static variable used in ioctl's */static int ioval;static int prev_pts;static int pts_offset;static int old_vmode = -1;/* Begin overlay.h *//*  Simple analog overlay API for DXR3/H+ linux driver.  Henrik Johansson*//* Pattern drawing callback used by the calibration functions.   The function is expected to:     Clear the entire screen.     Fill the screen with color bgcol (0xRRGGBB)     Draw a rectangle at (xpos,ypos) of size (width,height) in fgcol (0xRRGGBB)*/typedef int (*pattern_drawer_cb)(int fgcol, int bgcol,			     int xpos, int ypos, int width, int height, void *arg);struct coeff {    float k,m;};typedef struct {    int dev;    int xres, yres,depth;    int xoffset,yoffset,xcorr;    int jitter;    int stability;    int keycolor;    struct coeff colcal_upper[3];    struct coeff colcal_lower[3];    float color_interval;    pattern_drawer_cb draw_pattern;    void *dp_arg;} overlay_t;static overlay_t *overlay_init(int dev);static int overlay_release(overlay_t *);static int overlay_read_state(overlay_t *o, char *path);static int overlay_write_state(overlay_t *o, char *path);static int overlay_set_screen(overlay_t *o, int xres, int yres, int depth);static int overlay_set_mode(overlay_t *o, int mode);static int overlay_set_attribute(overlay_t *o, int attribute, int val);static int overlay_set_keycolor(overlay_t *o, int color);static int overlay_set_window(overlay_t *o, int xpos,int ypos,int width,int height);static int overlay_set_bcs(overlay_t *o, int brightness, int contrast, int saturation);static int overlay_autocalibrate(overlay_t *o, pattern_drawer_cb pd, void *arg);static void overlay_update_params(overlay_t *o);static int overlay_signalmode(overlay_t *o, int mode);/* End overlay.h */#ifdef HAVE_X11#define KEY_COLOR 0x80a040static XWindowAttributes xwin_attribs;static overlay_t *overlay_data;#endif/* Functions for working with the em8300's internal clock *//* End of internal clock functions */static int control(uint32_t request, void *data, ...){	switch (request) {	case VOCTRL_GUISUPPORT:		return VO_TRUE;	case VOCTRL_GUI_NOWINDOW:		if (dxr3_overlay) {			return VO_FALSE;		}		return VO_TRUE;	case VOCTRL_SET_SPU_PALETTE:		if (ioctl(fd_spu, EM8300_IOCTL_SPU_SETPALETTE, data) < 0) {			mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_DXR3_UnableToLoadNewSPUPalette);			return VO_ERROR;		}		return VO_TRUE;#ifdef HAVE_X11	case VOCTRL_ONTOP:		vo_x11_ontop();		return VO_TRUE;	case VOCTRL_FULLSCREEN:		if (dxr3_overlay) {			vo_x11_fullscreen();			overlay_signalmode(overlay_data,			  vo_fs ? EM8300_OVERLAY_SIGNAL_ONLY :			    EM8300_OVERLAY_SIGNAL_WITH_VGA);			return VO_TRUE;		}		return VO_FALSE;#endif	case VOCTRL_RESUME:		if (dxr3_newsync) {			ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval);			pts_offset = vo_pts - (ioval << 1);			if (pts_offset < 0) {				pts_offset = 0;			}		}				if (dxr3_prebuf) {			ioval = EM8300_PLAYMODE_PLAY;			if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {				mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode);			}		}		return VO_TRUE;	case VOCTRL_PAUSE:		if (dxr3_prebuf) {			ioval = EM8300_PLAYMODE_PAUSED;			if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {				mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode);			}		}		return VO_TRUE;	case VOCTRL_RESET:		if (dxr3_prebuf) {			close(fd_video);			fd_video = open(fdv_name, O_WRONLY);			close(fd_spu);			fd_spu = open(fds_name, O_WRONLY);			fsync(fd_video);			fsync(fd_spu);		}		return VO_TRUE;	case VOCTRL_QUERY_FORMAT:	    {		uint32_t flag = 0;		if (*((uint32_t*)data) != IMGFMT_MPEGPES)		    return 0;		flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_SPU;		if (dxr3_prebuf)		    flag |= VFCAP_TIMER;		return flag;	    }	case VOCTRL_SET_EQUALIZER:	    {		va_list ap;		int value;		em8300_bcs_t bcs;				va_start(ap, data);		value = va_arg(ap, int);		va_end(ap);		if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0)		    return VO_FALSE;		if (!strcasecmp(data, "brightness"))		    bcs.brightness = (value+100)*5;		else if (!strcasecmp(data, "contrast"))		    bcs.contrast = (value+100)*5;		else if (!strcasecmp(data, "saturation"))		    bcs.saturation = (value+100)*5;		else return VO_FALSE;        		if (ioctl(fd_control, EM8300_IOCTL_SETBCS, &bcs) < 0)		    return VO_FALSE;		return VO_TRUE;	    }	case VOCTRL_GET_EQUALIZER:	    {		va_list ap;		int *value;		em8300_bcs_t bcs;				va_start(ap, data);		value = va_arg(ap, int*);		va_end(ap);		if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0)		    return VO_FALSE;				if (!strcasecmp(data, "brightness"))		    *value = (bcs.brightness/5)-100;		else if (!strcasecmp(data, "contrast"))		    *value = (bcs.contrast/5)-100;		else if (!strcasecmp(data, "saturation"))		    *value = (bcs.saturation/5)-100;		else return VO_FALSE;        		return VO_TRUE;	    }	}	return VO_NOTIMPL;}void calculate_cvals(unsigned long mask, int *shift, int *prec){	/* Calculate shift and precision */	(*shift) = 0;	(*prec) = 0;		while (!(mask & 0x1)) {		(*shift)++;		mask >>= 1;	}		while (mask & 0x1) {		(*prec)++;		mask >>= 1;	}}static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format){	int tmp1, tmp2, size;	em8300_register_t reg;	extern float monitor_aspect;	/* Softzoom turned on, downscale */	/* This activates the subpicture processor, you can safely disable this and still send */	/* broken subpics to the em8300, if it's enabled and you send broken subpics you will end */	/* up in a lockup */	ioval = EM8300_SPUMODE_ON;	if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) {		mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetSubpictureMode);		uninit();		return -1;	}	/* Set the playmode to play (just in case another app has set it to something else) */	ioval = EM8300_PLAYMODE_PLAY;	if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {		mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToSetPlaymode);	}		/* Start em8300 prebuffering and sync engine */	reg.microcode_register = 1;	reg.reg = 0;	reg.val = MVCOMMAND_SYNC;	ioctl(fd_control, EM8300_IOCTL_WRITEREG, &reg);	/* Clean buffer by syncing it */	ioval = EM8300_SUBDEVICE_VIDEO;	ioctl(fd_control, EM8300_IOCTL_FLUSH, &ioval);	ioval = EM8300_SUBDEVICE_AUDIO;	ioctl(fd_control, EM8300_IOCTL_FLUSH, &ioval);	/* Sync the video device to make sure the buffers are empty	 * and set the playback speed to normal. Also reset the	 * em8300 internal clock.	 */	fsync(fd_video);	ioval = 0x900;	ioctl(fd_control, EM8300_IOCTL_SCR_SETSPEED, &ioval);	/* Store some variables statically that we need later in another scope */	img_format = format;	v_width = width;	v_height = height;	/* Set monitor_aspect to avoid jitter */	monitor_aspect = (float) width / (float) height;	if (ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &old_vmode) < 0) {		mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_DXR3_UnableToGetTVNorm);		old_vmode = -1;	}		/* adjust TV norm */	if (dxr3_norm != 0) {	    if (dxr3_norm == 5) {			ioval = EM8300_VIDEOMODE_NTSC;	    } else if (dxr3_norm == 4) {			ioval = EM8300_VIDEOMODE_PAL60;	    } else if (dxr3_norm == 3) {			ioval = EM8300_VIDEOMODE_PAL;	    } else if (dxr3_norm == 2) {			if (vo_fps > 28) {			    ioval = EM8300_VIDEOMODE_PAL60;			} else {			    ioval = EM8300_VIDEOMODE_PAL;			}						mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_DXR3_AutoSelectedTVNormByFrameRate);			ioval == EM8300_VIDEOMODE_PAL60 ? mp_msg(MSGT_VO,MSGL_INFO, "PAL-60") : mp_msg(MSGT_VO,MSGL_INFO, "PAL");			printf(".\n"); 		} else {			if (vo_fps > 28) {

⌨️ 快捷键说明

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