diff options
Diffstat (limited to 'libvo/vo_dxr3.c')
-rw-r--r-- | libvo/vo_dxr3.c | 1321 |
1 files changed, 0 insertions, 1321 deletions
diff --git a/libvo/vo_dxr3.c b/libvo/vo_dxr3.c deleted file mode 100644 index 8f7b471306..0000000000 --- a/libvo/vo_dxr3.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * DXR3/H+ video output - * - * Copyright (C) 2002-2003 David Holm <david@realityrift.com> - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <linux/em8300.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/select.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <stdio.h> -#include <time.h> -#include <math.h> - -#include "config.h" -#include "mp_msg.h" -#include "fastmemcpy.h" - -#include "video_out.h" -#include "video_out_internal.h" -#include "aspect.h" -#include "spuenc.h" -#include "sub/sub.h" -#ifdef CONFIG_X11 -#include "x11_common.h" -#endif -#include "libavutil/avstring.h" - -#define SPU_SUPPORT - -static const vo_info_t info = -{ - "DXR3/H+ video out", - "dxr3", - "David Holm <dholm@iname.com>", - "" -}; -const 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 - - -/* 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 CONFIG_X11 -#define KEY_COLOR 0x80a040 -static 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_SET_SPU_PALETTE: - if (ioctl(fd_spu, EM8300_IOCTL_SPU_SETPALETTE, data) < 0) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to load new SPU palette!\n"); - return VO_ERROR; - } - return VO_TRUE; -#ifdef CONFIG_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_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); - } - } - return VO_TRUE; - case VOCTRL_PAUSE: - if (dxr3_prebuf) { - ioval = EM8300_PLAYMODE_PAUSED; - if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); - } - } - 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: - { - em8300_bcs_t bcs; - struct voctrl_set_equalizer_args *args = data; - - if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) - return VO_FALSE; - if (!strcasecmp(args->name, "brightness")) - bcs.brightness = (args->value+100)*5; - else if (!strcasecmp(args->name, "contrast")) - bcs.contrast = (args->value+100)*5; - else if (!strcasecmp(args->name, "saturation")) - bcs.saturation = (args->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: - { - em8300_bcs_t bcs; - struct voctrl_get_equalizer_args *args = data; - - if (ioctl(fd_control, EM8300_IOCTL_GETBCS, &bcs) < 0) - return VO_FALSE; - - if (!strcasecmp(args->name, "brightness")) - *args->valueptr = (bcs.brightness/5)-100; - else if (!strcasecmp(args->name, "contrast")) - *args->valueptr = (bcs.contrast/5)-100; - else if (!strcasecmp(args->name, "saturation")) - *args->valueptr = (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; - - /* 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_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set subpicture mode!\n"); - 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_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set playmode!\n"); - } - - /* Start em8300 prebuffering and sync engine */ - reg.microcode_register = 1; - reg.reg = 0; - reg.val = MVCOMMAND_SYNC; - ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®); - - /* 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_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to get TV norm!\n"); - 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_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Auto-selected TV norm by framerate: "); - 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) { - ioval = EM8300_VIDEOMODE_NTSC; - } else { - ioval = EM8300_VIDEOMODE_PAL; - } - - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Auto-selected TV norm by framerate: "); - ioval == EM8300_VIDEOMODE_NTSC ? mp_msg(MSGT_VO,MSGL_INFO, "NTSC") : mp_msg(MSGT_VO,MSGL_INFO, "PAL"); - printf(".\n"); - } - - if (old_vmode != ioval) { - if (ioctl(fd_control, EM8300_IOCTL_SET_VIDEOMODE, &ioval) < 0) { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to set TV norm!\n"); - } - } - } - - - /* libavcodec requires a width and height that is x|16 */ - aspect_save_orig(width, height); - aspect_save_prescale(d_width, d_height); - ioctl(fd_control, EM8300_IOCTL_GET_VIDEOMODE, &ioval); - if (ioval == EM8300_VIDEOMODE_NTSC) { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting up for NTSC.\n"); - aspect_save_screenres(352, 240); - } else { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting up for PAL/SECAM.\n"); - aspect_save_screenres(352, 288); - } - aspect(&s_width, &s_height, A_ZOOM); - s_width -= s_width % 16; - s_height -= s_height % 16; - - /* Try to figure out whether to use widescreen output or not */ - /* Anamorphic widescreen modes makes this a pain in the ass */ - tmp1 = abs(d_height - ((d_width / 4) * 3)); - tmp2 = abs(d_height - (int) (d_width / 2.35)); - if (tmp1 < tmp2) { - ioval = EM8300_ASPECTRATIO_4_3; - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting aspect ratio to 4:3.\n"); - } else { - ioval = EM8300_ASPECTRATIO_16_9; - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Setting aspect ratio to 16:9.\n"); - } - ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval); - -#ifdef SPU_SUPPORT -#ifdef CONFIG_FREETYPE - if (ioval == EM8300_ASPECTRATIO_16_9) { - s_width *= d_height*1.78/s_height*(d_width*1.0/d_height)/2.35; - } else { - s_width *= 0.84; - } - //printf("VO: [dxr3] sw/sh:dw/dh ->%i,%i,%i,%i\n",s_width,s_height,d_width,d_height); -#else - s_width*=2; - s_height*=2; -#endif - - osdpicbuf = calloc( 1,s_width * s_height); - if (osdpicbuf == NULL) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); - return -1; - } - spued = malloc(sizeof(encodedata)); - if (spued == NULL) { - free( osdpicbuf ); - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); - return -1; - } - spubuf = malloc(sizeof(encodedata)); - if (spubuf == NULL) { - free( osdpicbuf ); - free( spued ); - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] out of memory\n"); - return -1; - } - osd_w = s_width; - osd_h = s_height; - osdpicbuf_w = s_width; - osdpicbuf_h = s_height; - - spubuf->count=0; - pixbuf_encode_rle( 0,0,osdpicbuf_w,osdpicbuf_h - 1,osdpicbuf,osdpicbuf_w,spubuf ); - -#endif - -#ifdef CONFIG_X11 - if (dxr3_overlay) { - XVisualInfo vinfo; - XSetWindowAttributes xswa; - XSizeHints hint; - unsigned long xswamask; - Colormap cmap; - XColor key_color; - Window junkwindow; - Screen *scr; - int depth, red_shift, red_prec, green_shift, green_prec, blue_shift, blue_prec, acq_color; - em8300_overlay_screen_t ovlscr; - em8300_attribute_t ovlattr; - - vo_dx = (vo_screenwidth - d_width) / 2; - vo_dy = (vo_screenheight - d_height) / 2; - vo_dwidth = d_width; - vo_dheight = d_height; - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &xwin_attribs); - depth = xwin_attribs.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { - depth = 24; - } - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); - vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, - d_width, d_height, flags, - CopyFromParent, "Viewing Window", title); - xswa.background_pixel = KEY_COLOR; - xswa.border_pixel = 0; - xswamask = CWBackPixel | CWBorderPixel; - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); - - /* Start setting up overlay */ - XGetWindowAttributes(mDisplay, mRootWin, &xwin_attribs); - overlay_set_screen(overlay_data, xwin_attribs.width, xwin_attribs.height, xwin_attribs.depth); - overlay_read_state(overlay_data, NULL); - - /* Allocate keycolor */ - cmap = vo_x11_create_colormap(&vinfo); - calculate_cvals(vinfo.red_mask, &red_shift, &red_prec); - calculate_cvals(vinfo.green_mask, &green_shift, &green_prec); - calculate_cvals(vinfo.blue_mask, &blue_shift, &blue_prec); - - key_color.red = ((KEY_COLOR >> 16) & 0xff) * 256; - key_color.green = ((KEY_COLOR >> 8) & 0xff) * 256; - key_color.blue = (KEY_COLOR & 0xff) * 256; - key_color.pixel = (((key_color.red >> (16 - red_prec)) << red_shift) + - ((key_color.green >> (16 - green_prec)) << green_shift) + - ((key_color.blue >> (16 - blue_prec)) << blue_shift)); - key_color.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(mDisplay, cmap, &key_color)) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to allocate keycolor!\n"); - return -1; - } - - acq_color = ((key_color.red / 256) << 16) | ((key_color.green / 256) << 8) | key_color.blue; - if (key_color.pixel != KEY_COLOR) { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Unable to allocate exact keycolor, using closest match (0x%lx).\n", key_color.pixel); - } - - /* Set keycolor and activate overlay */ - XSetWindowBackground(mDisplay, vo_window, key_color.pixel); - XClearWindow(mDisplay, vo_window); - overlay_set_keycolor(overlay_data, key_color.pixel); - overlay_set_mode(overlay_data, EM8300_OVERLAY_MODE_OVERLAY); - overlay_set_mode(overlay_data, EM8300_OVERLAY_MODE_RECTANGLE); - } -#endif - - return 0; -} - -static void draw_alpha(int x, int y, int w, int h, unsigned char* src, unsigned char *srca, int srcstride) -{ -#ifdef SPU_SUPPORT - unsigned char *buf = &osdpicbuf[(y * osdpicbuf_w) + x]; - int by = 0; - register int lx, ly; - register int stride = 0; - - for (ly = 0; ly < h - 1; ly++) - { - for(lx = 0; lx < w; lx++ ) - if ( ( srca[stride + lx] )&&( src[stride + lx] >= 128 ) ) buf[by + lx] = 3; - by+=osdpicbuf_w; - stride+=srcstride; - } - pixbuf_encode_rle(x, y, osdpicbuf_w, osdpicbuf_h - 1, osdpicbuf, osdpicbuf_w, spued); -#endif -} - -extern mp_osd_obj_t* vo_osd_list; - -static void draw_osd(void) -{ -#ifdef SPU_SUPPORT - static int cleared = 0; - int changed = 0; - - if ((disposd % 15) == 0) - { - { - mp_osd_obj_t* obj = vo_osd_list; - vo_update_osd( osd_w,osd_h ); - while( obj ) - { - if ( obj->flags & OSDFLAG_VISIBLE ) { changed=1; break; } - obj=obj->next; - } - } - if ( changed ) - { - vo_draw_text(osd_w, osd_h, draw_alpha); - memset(osdpicbuf, 0, s_width * s_height); - cleared=0; - } - else - { - if ( !cleared ) - { - spued->count=spubuf->count; - fast_memcpy( spued->data,spubuf->data,DATASIZE ); - cleared=1; - } - } - - - /* could stand some check here to see if the subpic hasn't changed - * as if it hasn't and we re-send it it will "blink" as the last one - * is turned off, and the new one (same one) is turned on - */ -/* Subpics are not stable yet =( - expect lockups if you enable */ - write(fd_spu, spued->data, spued->count); - } - disposd++; -#endif -} - - -static int draw_frame(uint8_t * src[]) -{ - vo_mpegpes_t *p = (vo_mpegpes_t *) src[0]; - -#ifdef SPU_SUPPORT - if (p->id == 0x20) { - write(fd_spu, p->data, p->size); - } else -#endif - write(fd_video, p->data, p->size); - return 0; -} - -static void flip_page(void) -{ -#ifdef CONFIG_X11 - if (dxr3_overlay) { - int event = vo_x11_check_events(mDisplay); - if (event & VO_EVENT_RESIZE) { - Window junkwindow; - XGetWindowAttributes(mDisplay, vo_window, &xwin_attribs); - XTranslateCoordinates(mDisplay, vo_window, mRootWin, -xwin_attribs.border_width, -xwin_attribs.border_width, &xwin_attribs.x, &xwin_attribs.y, &junkwindow); - overlay_set_window(overlay_data, xwin_attribs.x, xwin_attribs.y, xwin_attribs.width, xwin_attribs.height); - } - if (event & VO_EVENT_EXPOSE) { - Window junkwindow; - XSetWindowBackground(mDisplay, vo_window, KEY_COLOR); - XClearWindow(mDisplay, vo_window); - XGetWindowAttributes(mDisplay, vo_window, &xwin_attribs); - XTranslateCoordinates(mDisplay, vo_window, mRootWin, -xwin_attribs.border_width, -xwin_attribs.border_width, &xwin_attribs.x, &xwin_attribs.y, &junkwindow); - overlay_set_window(overlay_data, xwin_attribs.x, xwin_attribs.y, xwin_attribs.width, xwin_attribs.height); - } - } -#endif - - if (dxr3_newsync) { - ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval); - ioval <<= 1; - if (vo_pts == 0) { - ioval = 0; - ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval); - pts_offset = 0; - } else if ((vo_pts - pts_offset) < (ioval - 7200) || (vo_pts - pts_offset) > (ioval + 7200)) { - ioval = (vo_pts + pts_offset) >> 1; - ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval); - ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval); - pts_offset = vo_pts - (ioval << 1); - if (pts_offset < 0) { - pts_offset = 0; - } - } - ioval = vo_pts + pts_offset; - ioctl(fd_video, EM8300_IOCTL_SPU_SETPTS, &ioval); - ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &ioval); - prev_pts = vo_pts; - } else if (dxr3_prebuf) { - ioctl(fd_spu, EM8300_IOCTL_SPU_SETPTS, &vo_pts); - ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts); - } -} - -static int draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0) -{ - return -1; -} - -static void uninit(void) -{ - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Uninitializing.\n"); -#ifdef CONFIG_X11 - if (dxr3_overlay) { - overlay_set_mode(overlay_data, EM8300_OVERLAY_MODE_OFF); - overlay_release(overlay_data); - - vo_x11_uninit(); - } -#endif - if (old_vmode != -1) { - if (ioctl(fd_control, EM8300_IOCTL_SET_VIDEOMODE, &old_vmode) < 0) { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed restoring TV norm!\n"); - } - } - - if (fd_video != -1) { - close(fd_video); - } - if (fd_spu != -1) { - close(fd_spu); - } - if (fd_control != -1) { - close(fd_control); - } -#ifdef SPU_SUPPORT - free(osdpicbuf); - free(spued); -#endif -} - -static void check_events(void) -{ -} - -static int preinit(const char *arg) -{ - char devname[MAX_STR_SIZE]; - int fdflags = O_WRONLY; - - /* Parse commandline */ - while (arg) { - if (!strncmp("prebuf", arg, 6) && !dxr3_prebuf) { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Enabling prebuffering.\n"); - dxr3_prebuf = 1; - } else if (!strncmp("sync", arg, 4) && !dxr3_newsync) { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Using new sync engine.\n"); - dxr3_newsync = 1; - } else if (!strncmp("overlay", arg, 7) && !dxr3_overlay) { -#ifdef CONFIG_X11 - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Using overlay.\n"); - dxr3_overlay = 1; -#else - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error: Overlay requires compiling with X11 libs/headers installed.\n"); -#endif - } else if (!strncmp("norm=", arg, 5)) { - arg += 5; - // dxr3_norm is 0 (-> don't change norm) by default - // but maybe someone changes this in the future - - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Will set TV norm to: "); - - if (*arg == '5') { - dxr3_norm = 5; - mp_msg(MSGT_VO,MSGL_INFO, "NTSC"); - } else if (*arg == '4') { - dxr3_norm = 4; - mp_msg(MSGT_VO,MSGL_INFO, "PAL-60"); - } else if (*arg == '3') { - dxr3_norm = 3; - mp_msg(MSGT_VO,MSGL_INFO, "PAL"); - } else if (*arg == '2') { - dxr3_norm = 2; - mp_tmsg(MSGT_VO,MSGL_INFO, "auto-adjust to movie framerate (PAL/PAL-60)"); - } else if (*arg == '1') { - dxr3_norm = 1; - mp_tmsg(MSGT_VO,MSGL_INFO, "auto-adjust to movie framerate (PAL/NTSC)"); - } else if (*arg == '0') { - dxr3_norm = 0; - mp_tmsg(MSGT_VO,MSGL_INFO, "Use current norm."); - } else { - dxr3_norm = 0; - mp_tmsg(MSGT_VO,MSGL_INFO, "Unknown norm supplied. Use current norm."); - } - - mp_msg(MSGT_VO,MSGL_INFO, ".\n"); - } else if (arg[0] == '0' || arg[0] == '1' || arg[0] == '2' || arg[0] == '3') { - dxr3_device_num = arg[0]; - } - - arg = strchr(arg, ':'); - if (arg) { - arg++; - } - } - - - /* Open the control interface */ - sprintf(devname, "/dev/em8300-%d", dxr3_device_num); - fd_control = open(devname, fdflags); - if (fd_control < 1) { - /* Fall back to old naming scheme */ - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300 instead.\n", devname); - sprintf(devname, "/dev/em8300"); - fd_control = open(devname, fdflags); - if (fd_control < 1) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300 for writing as well!\nBailing out.\n"); - return -1; - } - } else { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); - } - - /* Open the video interface */ - sprintf(devname, "/dev/em8300_mv-%d", dxr3_device_num); - fd_video = open(devname, fdflags); - if (fd_video < 0) { - /* Fall back to old naming scheme */ - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_mv instead.\n", devname); - sprintf(devname, "/dev/em8300_mv"); - fd_video = open(devname, fdflags); - if (fd_video < 0) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300_mv for writing as well!\nBailing out.\n"); - uninit(); - return -1; - } - } else { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); - } - strcpy(fdv_name, devname); - - /* Open the subpicture interface */ - sprintf(devname, "/dev/em8300_sp-%d", dxr3_device_num); - fd_spu = open(devname, fdflags); - if (fd_spu < 0) { - /* Fall back to old naming scheme */ - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_sp instead.\n", devname); - sprintf(devname, "/dev/em8300_sp"); - fd_spu = open(devname, fdflags); - if (fd_spu < 0) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Error opening /dev/em8300_sp for writing as well!\nBailing out.\n"); - uninit(); - return -1; - } - } else { - mp_tmsg(MSGT_VO,MSGL_INFO, "[VO_DXR3] Opened: %s.\n", devname); - } - strcpy(fds_name, devname); - -#ifdef CONFIG_X11 - if (dxr3_overlay) { - - /* Fucked up hack needed to enable overlay. - * Will be removed as soon as I figure out - * how to make it work like it should - */ - Display *dpy; - overlay_t *ov; - XWindowAttributes attribs; - - dpy = XOpenDisplay(NULL); - if (!dpy) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to open display during overlay hack setup!\n"); - return -1; - } - XGetWindowAttributes(dpy, RootWindow(dpy, DefaultScreen(dpy)), &attribs); - ov = overlay_init(fd_control); - overlay_set_screen(ov, attribs.width, attribs.height, PlanesOfScreen(ScreenOfDisplay(dpy, 0))); - overlay_read_state(ov, NULL); - overlay_set_keycolor(ov, KEY_COLOR); - overlay_set_mode(ov, EM8300_OVERLAY_MODE_OVERLAY); - overlay_set_mode(ov, EM8300_OVERLAY_MODE_RECTANGLE); - overlay_release(ov); - XCloseDisplay(dpy); - /* End of fucked up hack */ - - /* Initialize overlay and X11 */ - overlay_data = overlay_init(fd_control); - if (!vo_init()) { - mp_tmsg(MSGT_VO,MSGL_ERR, "[VO_DXR3] Unable to init X11!\n"); - return -1; - } - } -#endif - - if (dxr3_newsync) { - ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval); - pts_offset = vo_pts - (ioval << 1); - if (pts_offset < 0) { - pts_offset = 0; - } - } - - return 0; -} - -/* Begin overlay.c */ -static int update_parameters(overlay_t *o) -{ - overlay_set_attribute(o, EM9010_ATTRIBUTE_XOFFSET, o->xoffset); - overlay_set_attribute(o, EM9010_ATTRIBUTE_YOFFSET, o->yoffset); - overlay_set_attribute(o, EM9010_ATTRIBUTE_XCORR, o->xcorr); - overlay_set_attribute(o, EM9010_ATTRIBUTE_STABILITY, o->stability); - overlay_set_attribute(o, EM9010_ATTRIBUTE_JITTER, o->jitter); - return 0; -} - -static int overlay_set_attribute(overlay_t *o, int attribute, int value) -{ - em8300_attribute_t attr; - - attr.attribute = attribute; - attr.value = value; - if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)==-1) - { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay attribute.\n"); - return -1; - } - - return 0; -} - -static overlay_t *overlay_init(int dev) -{ - overlay_t *o; - - o = malloc(sizeof(overlay_t)); - - if(!o) - return NULL; - - memset(o,0,sizeof(overlay_t)); - - o->dev = dev; - o->xres = 1280; o->yres=1024; o->xcorr=1000; - o->color_interval=10; - - return o; -} - -static int overlay_release(overlay_t *o) -{ - free(o); - return 0; -} -#define TYPE_INT 1 -#define TYPE_XINT 2 -#define TYPE_COEFF 3 -#define TYPE_FLOAT 4 - -struct lut_entry { - char *name; - int type; - void *ptr; -}; - -static struct lut_entry *new_lookuptable(overlay_t *o) -{ - struct lut_entry m[] = { - {"xoffset", TYPE_INT, &o->xoffset}, - {"yoffset", TYPE_INT, &o->yoffset}, - {"xcorr", TYPE_INT, &o->xcorr}, - {"jitter", TYPE_INT, &o->jitter}, - {"stability", TYPE_INT, &o->stability}, - {"keycolor", TYPE_XINT, &o->keycolor}, - {"colcal_upper", TYPE_COEFF, &o->colcal_upper[0]}, - {"colcal_lower", TYPE_COEFF, &o->colcal_lower[0]}, - {"color_interval", TYPE_FLOAT, &o->color_interval}, - {0,0,0} - },*p; - - p = malloc(sizeof(m)); - memcpy(p,m,sizeof(m)); - return p; -} - -static int lookup_parameter(overlay_t *o, struct lut_entry *lut, char *name, void **ptr, int *type) { - int i; - - for(i=0; lut[i].name; i++) { - if(!strcmp(name,lut[i].name)) { - *ptr = lut[i].ptr; - *type = lut[i].type; - return 1; - } - } - return 0; -} - -static int overlay_read_state(overlay_t *o, char *p) -{ - char *a,*tok; - char path[128],fname[128],tmp[128],line[256]; - FILE *fp; - struct lut_entry *lut; - void *ptr; - int type; - int j; - - if(!p) { - av_strlcpy(fname, getenv("HOME"), sizeof( fname )); - av_strlcat(fname,"/.overlay", sizeof( fname )); - } else - av_strlcpy(fname, p, sizeof( fname )); - - sprintf(tmp,"/res_%dx%dx%d",o->xres,o->yres,o->depth); - av_strlcat(fname, tmp, sizeof( fname )); - - if(!(fp=fopen(fname,"r"))) - return -1; - - lut = new_lookuptable(o); - - while(!feof(fp)) { - if(!fgets(line,256,fp)) - break; - tok=strtok(line," "); - if(lookup_parameter(o,lut,tok,&ptr,&type)) { - tok=strtok(NULL," "); - switch(type) { - case TYPE_INT: - sscanf(tok,"%d",(int *)ptr); - break; - case TYPE_XINT: - sscanf(tok,"%x",(int *)ptr); - break; - case TYPE_FLOAT: - sscanf(tok,"%f",(float *)ptr); - break; - case TYPE_COEFF: - for(j=0;j<3;j++) { - sscanf(tok,"%f",&((struct coeff *)ptr)[j].k); - tok=strtok(NULL," "); - sscanf(tok,"%f",&((struct coeff *)ptr)[j].m); - tok=strtok(NULL," "); - } - break; - } - - } - } - - update_parameters(o); - - free(lut); - fclose(fp); - return 0; -} - -static void overlay_update_params(overlay_t *o) { - update_parameters(o); -} - -static int overlay_write_state(overlay_t *o, char *p) -{ - char *a; - char path[128],fname[128],tmp[128]; - FILE *fp; - char line[256],*tok; - struct lut_entry *lut; - int i,j; - - if(!p) { - av_strlcpy(fname, getenv("HOME"), sizeof( fname )); - av_strlcat(fname,"/.overlay", sizeof( fname )); - } else - av_strlcpy(fname, p, sizeof( fname )); - - if(access(fname, W_OK|X_OK|R_OK)) { - if(mkdir(fname,0766)) - return -1; - } - - sprintf(tmp,"/res_%dx%dx%d",o->xres,o->yres,o->depth); - av_strlcat(fname, tmp, sizeof( fname )); - - if(!(fp=fopen(fname,"w"))) - return -1; - - lut = new_lookuptable(o); - - for(i=0; lut[i].name; i++) { - fprintf(fp,"%s ",lut[i].name); - switch(lut[i].type) { - case TYPE_INT: - fprintf(fp,"%d\n",*(int *)lut[i].ptr); - break; - case TYPE_XINT: - fprintf(fp,"%06x\n",*(int *)lut[i].ptr); - break; - case TYPE_FLOAT: - fprintf(fp,"%f\n",*(float *)lut[i].ptr); - break; - case TYPE_COEFF: - for(j=0;j<3;j++) - fprintf(fp,"%f %f ",((struct coeff *)lut[i].ptr)[j].k, - ((struct coeff *)lut[i].ptr)[j].m); - fprintf(fp,"\n"); - break; - } - } - - fclose(fp); - return 0; -} - -static int overlay_set_screen(overlay_t *o, int xres, int yres, int depth) -{ - em8300_overlay_screen_t scr; - - o->xres = xres; - o->yres = yres; - o->depth = depth; - - scr.xsize = xres; - scr.ysize = yres; - - if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr)==-1) - { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay screen!\nExiting.\n"); - return -1; - } - return 0; -} - -static int overlay_set_mode(overlay_t *o, int mode) -{ - if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETMODE, &mode)==-1) { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed enabling overlay!\nExiting.\n"); - return -1; - } - return 0; -} - -static int overlay_set_window(overlay_t *o, int xpos,int ypos,int width,int height) -{ - em8300_overlay_window_t win; - win.xpos = xpos; - win.ypos = ypos; - win.width = width; - win.height = height; - - if (ioctl(o->dev, EM8300_IOCTL_OVERLAY_SETWINDOW, &win)==-1) - { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed resizing overlay window!\n"); - return -1; - } - return 0; -} - -static int overlay_set_bcs(overlay_t *o, int brightness, int contrast, int saturation) -{ - em8300_bcs_t bcs; - bcs.brightness = brightness; - bcs.contrast = contrast; - bcs.saturation = saturation; - - if (ioctl(o->dev, EM8300_IOCTL_GETBCS, &bcs)==-1) - { - mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_DXR3] Failed setting overlay bcs!\n"); - return -1; - } - return 0; -} - -static int col_interp(float x, struct coeff c) -{ - float y; - y = x*c.k + c.m; - if(y > 255) - y = 255; - if(y < 0) - y = 0; - return rint(y); -} - -static int overlay_set_keycolor(overlay_t *o, int color) { - int r = (color & 0xff0000) >> 16; - int g = (color & 0x00ff00) >> 8; - int b = (color & 0x0000ff); - float ru,gu,bu; - float rl,gl,bl; - int upper,lower; - - ru = r+o->color_interval; - gu = g+o->color_interval; - bu |