1
mirror of https://github.com/mpv-player/mpv synced 2024-12-28 06:03:45 +01:00

vo_dxr2, ao_dxr2: drop dxr2 support

dxr2 support had been broken quite a while and nobody noticed. There
were finally commits to fix it in the svn repo, but rather than apply
those I'll just drop dxr2 support.
This commit is contained in:
Uoti Urpala 2011-01-31 04:30:08 +02:00
parent 6d534cd3cb
commit b138ca43ca
8 changed files with 1 additions and 1326 deletions

View File

@ -147,7 +147,7 @@ It works with X11, Xv, DGA, OpenGL, SVGAlib, fbdev, AAlib, libcaca, DirectFB,
Quartz, Mac OS X CoreVideo, but you can also use GGI, SDL (and all their drivers), Quartz, Mac OS X CoreVideo, but you can also use GGI, SDL (and all their drivers),
VESA (on every VESA-compatible card, even without X11), some low-level VESA (on every VESA-compatible card, even without X11), some low-level
card-specific drivers (for Matrox, 3dfx and ATI) and some hardware MPEG decoder card-specific drivers (for Matrox, 3dfx and ATI) and some hardware MPEG decoder
boards, such as the Siemens DVB, Hauppauge PVR (IVTV), DXR2 and DXR3/\:Hollywood+. boards, such as the Siemens DVB, Hauppauge PVR (IVTV) and DXR3/\:Hollywood+.
Most of them support software or hardware scaling, so you can enjoy movies in Most of them support software or hardware scaling, so you can enjoy movies in
fullscreen mode. fullscreen mode.
.PP .PP
@ -2889,10 +2889,6 @@ Set buffer size to <size> in samples (default: 2048).
.PD 1 .PD 1
. .
.TP .TP
.B dxr2 (also see \-dxr2) (DXR2 only)
Creative DXR2 specific output driver
.
.TP
.B ivtv (IVTV only) .B ivtv (IVTV only)
IVTV specific MPEG audio output driver. IVTV specific MPEG audio output driver.
Works with \-ac hwmpa only. Works with \-ac hwmpa only.
@ -2995,88 +2991,6 @@ Turns on direct rendering (not supported by all codecs and video outputs)
May cause OSD/SUB corruption! May cause OSD/SUB corruption!
. .
.TP .TP
.B \-dxr2 <option1:option2:...>
This option is used to control the dxr2 video output driver.
.RSs
.IPs ar-mode=<value>
aspect ratio mode (0 = normal, 1 = pan-and-scan, 2 = letterbox (default))
.IPs iec958-encoded
Set iec958 output mode to encoded.
.IPs iec958-decoded
Set iec958 output mode to decoded (default).
.IPs macrovision=<value>
macrovision mode (0 = off (default), 1 = agc, 2 = agc 2 colorstripe,
3 = agc 4 colorstripe)
.IPs "mute\ "
mute sound output
.IPs unmute
unmute sound output
.IPs ucode=<value>
path to the microcode
.RE
.RS
.sp 1
.I TV output
.RE
.RSs
.IPs 75ire
enable 7.5 IRE output mode
.IPs no75ire
disable 7.5 IRE output mode (default)
.IPs "bw\ \ \ "
b/w TV output
.IPs color
color TV output (default)
.IPs interlaced
interlaced TV output (default)
.IPs nointerlaced
disable interlaced TV output
.IPs norm=<value>
TV norm (ntsc (default), pal, pal60, palm, paln, palnc)
.IPs square-pixel
set pixel mode to square
.IPs ccir601-pixel
set pixel mode to ccir601
.RE
.RS
.sp 1
.I overlay
.RE
.RSs
.IPs cr-left=<0\-500>
Set the left cropping value (default: 50).
.IPs cr-right=<0\-500>
Set the right cropping value (default: 300).
.IPs cr-top=<0\-500>
Set the top cropping value (default: 0).
.IPs cr-bottom=<0\-500>
Set the bottom cropping value (default: 0).
.IPs ck-[r|g|b]=<0\-255>
Set the r(ed), g(reen) or b(lue) gain of the overlay color-key.
.IPs ck-[r|g|b]min=<0\-255>
minimum value for the respective color key
.IPs ck-[r|g|b]max=<0\-255>
maximum value for the respective color key
.IPs ignore-cache
Ignore cached overlay settings.
.IPs update-cache
Update cached overlay settings.
.IPs ol-osd
Enable overlay onscreen display.
.IPs nool-osd
Disable overlay onscreen display (default).
.IPs ol[h|w|x|y]-cor=<\-20\-20>
Adjust the overlay size (h,w) and position (x,y) in case it does not
match the window perfectly (default: 0).
.IPs overlay
Activate overlay (default).
.IPs nooverlay
Activate TV-out.
.IPs overlay-ratio=<1\-2500>
Tune the overlay (default: 1000).
.RE
.
.TP
.B \-fbmode <modename> (\-vo fbdev only) .B \-fbmode <modename> (\-vo fbdev only)
Change video mode to the one that is labeled as <modename> in Change video mode to the one that is labeled as <modename> in
/etc/\:fb.modes. /etc/\:fb.modes.
@ -4229,16 +4143,6 @@ Explicitly choose the device name to use (default: /dev/\:tdfx_vid).
.PD 1 .PD 1
. .
.TP .TP
.B dxr2 (also see \-dxr2) (DXR2 only)
Creative DXR2 specific video output driver.
.PD 0
.RSs
.IPs <vo_driver>
Output video subdriver to use as overlay (x11, xv).
.RE
.PD 1
.
.TP
.B dxr3 (DXR3 only) .B dxr3 (DXR3 only)
Sigma Designs em8300 MPEG decoder chip (Creative DXR3, Sigma Designs Sigma Designs em8300 MPEG decoder chip (Creative DXR3, Sigma Designs
Hollywood Plus) specific video output driver. Hollywood Plus) specific video output driver.

View File

@ -499,7 +499,6 @@ SRCS_MPLAYER-$(DGA) += libvo/vo_dga.c
SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c
SRCS_MPLAYER-$(DIRECTFB) += libvo/vo_directfb2.c libvo/vo_dfbmga.c SRCS_MPLAYER-$(DIRECTFB) += libvo/vo_directfb2.c libvo/vo_dfbmga.c
SRCS_MPLAYER-$(DIRECTX) += libao2/ao_dsound.c libvo/vo_directx.c SRCS_MPLAYER-$(DIRECTX) += libao2/ao_dsound.c libvo/vo_directx.c
SRCS_MPLAYER-$(DXR2) += libao2/ao_dxr2.c libvo/vo_dxr2.c
SRCS_MPLAYER-$(DXR3) += libvo/vo_dxr3.c SRCS_MPLAYER-$(DXR3) += libvo/vo_dxr3.c
SRCS_MPLAYER-$(ESD) += libao2/ao_esd.c SRCS_MPLAYER-$(ESD) += libao2/ao_esd.c
SRCS_MPLAYER-$(FBDEV) += libvo/vo_fbdev.c libvo/vo_fbdev2.c SRCS_MPLAYER-$(FBDEV) += libvo/vo_fbdev.c libvo/vo_fbdev2.c

View File

@ -47,8 +47,6 @@ extern int menu_fribidi_flip_commas;
extern char *unrar_executable; extern char *unrar_executable;
extern const m_option_t dxr2_opts[];
const m_option_t vd_conf[]={ const m_option_t vd_conf[]={
{"help", "Use MPlayer with an appropriate video file instead of live partners to avoid vd.\n", CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL}, {"help", "Use MPlayer with an appropriate video file instead of live partners to avoid vd.\n", CONF_TYPE_PRINT, CONF_NOCFG|CONF_GLOBAL, 0, 0, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL} {NULL, NULL, 0, 0, 0, 0, NULL}
@ -223,10 +221,6 @@ const m_option_t mplayer_opts[]={
{"zr*", vo_zr_parseoption, CONF_TYPE_FUNC_FULL, 0, 0, 0, &vo_zr_revertoption }, {"zr*", vo_zr_parseoption, CONF_TYPE_FUNC_FULL, 0, 0, 0, &vo_zr_revertoption },
#endif #endif
#ifdef CONFIG_DXR2
{"dxr2", &dxr2_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
#endif
//---------------------- mplayer-only options ------------------------ //---------------------- mplayer-only options ------------------------

25
configure vendored
View File

@ -400,7 +400,6 @@ Video output:
--enable-ggiwmh enable GGI libggiwmh extension [autodetect] --enable-ggiwmh enable GGI libggiwmh extension [autodetect]
--enable-direct3d enable Direct3D video output [autodetect] --enable-direct3d enable Direct3D video output [autodetect]
--enable-directx enable DirectX video output [autodetect] --enable-directx enable DirectX video output [autodetect]
--enable-dxr2 enable DXR2 video output [autodetect]
--enable-dxr3 enable DXR3/H+ video output [autodetect] --enable-dxr3 enable DXR3/H+ video output [autodetect]
--enable-ivtv enable IVTV TV-Out video output [autodetect] --enable-ivtv enable IVTV TV-Out video output [autodetect]
--enable-v4l2 enable V4L2 Decoder audio/video output [autodetect] --enable-v4l2 enable V4L2 Decoder audio/video output [autodetect]
@ -596,7 +595,6 @@ _svga=auto
_vesa=auto _vesa=auto
_fbdev=auto _fbdev=auto
_dvb=auto _dvb=auto
_dxr2=auto
_dxr3=auto _dxr3=auto
_ivtv=auto _ivtv=auto
_v4l2=auto _v4l2=auto
@ -935,8 +933,6 @@ for ac_option do
--disable-fbdev) _fbdev=no ;; --disable-fbdev) _fbdev=no ;;
--enable-dvb) _dvb=yes ;; --enable-dvb) _dvb=yes ;;
--disable-dvb) _dvb=no ;; --disable-dvb) _dvb=no ;;
--enable-dxr2) _dxr2=yes ;;
--disable-dxr2) _dxr2=no ;;
--enable-dxr3) _dxr3=yes ;; --enable-dxr3) _dxr3=yes ;;
--disable-dxr3) _dxr3=no ;; --disable-dxr3) _dxr3=no ;;
--enable-ivtv) _ivtv=yes ;; --enable-ivtv) _ivtv=yes ;;
@ -4782,25 +4778,6 @@ echores "$_directx"
fi #if win32; then fi #if win32; then
echocheck "DXR2"
if test "$_dxr2" = auto; then
_dxr2=no
for _inc_tmp in "" -I/usr/local/include/dxr2 -I/usr/include/dxr2; do
header_check dxr2ioctl.h $_inc_tmp && _dxr2=yes &&
extra_cflags="$extra_cflags $_inc_tmp" && break
done
fi
if test "$_dxr2" = yes; then
def_dxr2='#define CONFIG_DXR2 1'
aomodules="dxr2 $aomodules"
vomodules="dxr2 $vomodules"
else
def_dxr2='#undef CONFIG_DXR2'
noaomodules="dxr2 $noaomodules"
novomodules="dxr2 $novomodules"
fi
echores "$_dxr2"
echocheck "DXR3/H+" echocheck "DXR3/H+"
if test "$_dxr3" = auto ; then if test "$_dxr3" = auto ; then
_dxr3=no _dxr3=no
@ -6956,7 +6933,6 @@ DVDNAV = $_dvdnav
DVDNAV_INTERNAL = $dvdnav_internal DVDNAV_INTERNAL = $dvdnav_internal
DVDREAD = $_dvdread DVDREAD = $_dvdread
DVDREAD_INTERNAL = $_dvdread_internal DVDREAD_INTERNAL = $_dvdread_internal
DXR2 = $_dxr2
DXR3 = $_dxr3 DXR3 = $_dxr3
ESD = $_esd ESD = $_esd
FAAD = $_faad FAAD = $_faad
@ -7386,7 +7362,6 @@ $def_directfb
$def_directx $def_directx
$def_dvb $def_dvb
$def_dvbin $def_dvbin
$def_dxr2
$def_dxr3 $def_dxr3
$def_fbdev $def_fbdev
$def_ggi $def_ggi

View File

@ -1,221 +0,0 @@
/*
* DXR2 audio output driver
*
* 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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <inttypes.h>
#include <dxr2ioctl.h>
#include "config.h"
#include "mp_msg.h"
#include "libavutil/common.h"
#include "mpbswap.h"
#include "audio_out.h"
#include "audio_out_internal.h"
#include "libaf/af_format.h"
#include "libmpdemux/mpeg_packetizer.h"
static const ao_info_t info =
{
"DXR2 audio output",
"dxr2",
"Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
""
};
LIBAO_EXTERN(dxr2)
static int volume=19;
static int last_freq_id = -1;
extern int dxr2_fd;
// to set/get/query special features/parameters
static int control(int cmd,void *arg){
switch(cmd){
case AOCONTROL_GET_VOLUME:
if(dxr2_fd > 0) {
ao_control_vol_t* vol = (ao_control_vol_t*)arg;
vol->left = vol->right = volume * 19.0 / 100.0;
return CONTROL_OK;
}
return CONTROL_ERROR;
case AOCONTROL_SET_VOLUME:
if(dxr2_fd > 0) {
dxr2_oneArg_t v;
float diff;
ao_control_vol_t* vol = (ao_control_vol_t*)arg;
// We need this trick because the volume stepping is often too small
diff = ((vol->left+vol->right) / 2 - (volume*19.0/100.0)) * 19.0 / 100.0;
v.arg = volume + (diff > 0 ? ceil(diff) : floor(diff));
if(v.arg > 19) v.arg = 19;
if(v.arg < 0) v.arg = 0;
if(v.arg != volume) {
volume = v.arg;
if( ioctl(dxr2_fd,DXR2_IOC_SET_AUDIO_VOLUME,&v) < 0) {
mp_tmsg(MSGT_AO,MSGL_ERR,"[AO DXR2] Setting volume to %d failed.\n",volume);
return CONTROL_ERROR;
}
}
return CONTROL_OK;
}
return CONTROL_ERROR;
}
return CONTROL_UNKNOWN;
}
static int freq=0;
static int freq_id=0;
// open & setup audio device
// return: 1=success 0=fail
static int init(int rate,int channels,int format,int flags){
if(dxr2_fd <= 0)
return 0;
last_freq_id = -1;
ao_data.outburst=2048;
ao_data.samplerate=rate;
ao_data.channels=channels;
ao_data.buffersize=2048;
ao_data.bps=rate*4;
ao_data.format=format;
freq=rate;
switch(rate){
case 48000:
freq_id=DXR2_AUDIO_FREQ_48;
break;
case 96000:
freq_id=DXR2_AUDIO_FREQ_96;
break;
case 44100:
freq_id=DXR2_AUDIO_FREQ_441;
break;
case 32000:
freq_id=DXR2_AUDIO_FREQ_32;
break;
case 22050:
freq_id=DXR2_AUDIO_FREQ_2205;
break;
#ifdef DXR2_AUDIO_FREQ_24
// This is not yet in the dxr2 driver CVS
// you can get the patch at
// http://www.tdiedrich.de/~ranma/patches/dxr2.pcm1723.20020513
case 24000:
freq_id=DXR2_AUDIO_FREQ_24;
break;
case 64000:
freq_id=DXR2_AUDIO_FREQ_64;
break;
case 88200:
freq_id=DXR2_AUDIO_FREQ_882;
break;
#endif
default:
mp_tmsg(MSGT_AO,MSGL_ERR,"[AO DXR2] %d Hz not supported, try to resample.\n",rate);
return 0;
}
return 1;
}
// close audio device
static void uninit(int immed){
}
// stop playing and empty buffers (for seeking/pause)
static void reset(void){
}
// stop playing, keep buffers (for pause)
static void audio_pause(void)
{
// for now, just call reset();
reset();
}
// resume playing, after audio_pause()
static void audio_resume(void)
{
}
extern int vo_pts;
// return: how many bytes can be played without blocking
static int get_space(void){
float x=(float)(vo_pts-ao_data.pts)/90000.0;
int y;
if(x<=0) return 0;
y=freq*4*x;y/=ao_data.outburst;y*=ao_data.outburst;
if(y>32768) y=32768;
return y;
}
static void dxr2_send_lpcm_packet(unsigned char* data,int len,int id,unsigned int timestamp,int freq_id)
{
int write_dxr2(const unsigned char *data, int len);
if(dxr2_fd < 0) {
mp_msg(MSGT_AO,MSGL_ERR,"DXR2 fd is not valid\n");
return;
}
if(last_freq_id != freq_id) {
ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY, &freq_id);
last_freq_id = freq_id;
}
send_mpeg_lpcm_packet (data, len, id, timestamp, freq_id, write_dxr2);
}
// plays 'len' bytes of 'data'
// it should round it down to outburst*n
// return: number of bytes played
static int play(void* data,int len,int flags){
int write_dxr2(const unsigned char *data, int len);
// MPEG and AC3 don't work :-(
if(ao_data.format==AF_FORMAT_MPEG2)
send_mpeg_ps_packet (data, len, 0xC0, ao_data.pts, 2, write_dxr2);
else if(AF_FORMAT_IS_AC3(ao_data.format))
send_mpeg_ps_packet (data, len, 0x80, ao_data.pts, 2, write_dxr2);
else {
int i;
//unsigned short *s=data;
uint16_t *s=data;
#if !HAVE_BIGENDIAN
for(i=0;i<len/2;i++) s[i] = bswap_16(s[i]);
#endif
dxr2_send_lpcm_packet(data,len,0xA0,ao_data.pts-10000,freq_id);
}
return len;
}
// return: delay in seconds between first and last sample in buffer
static float get_delay(void){
return 0.0;
}

View File

@ -47,7 +47,6 @@ extern const ao_functions_t audio_out_win32;
extern const ao_functions_t audio_out_dsound; extern const ao_functions_t audio_out_dsound;
extern const ao_functions_t audio_out_kai; extern const ao_functions_t audio_out_kai;
extern const ao_functions_t audio_out_dart; extern const ao_functions_t audio_out_dart;
extern const ao_functions_t audio_out_dxr2;
extern const ao_functions_t audio_out_ivtv; extern const ao_functions_t audio_out_ivtv;
extern const ao_functions_t audio_out_v4l2; extern const ao_functions_t audio_out_v4l2;
extern const ao_functions_t audio_out_mpegpes; extern const ao_functions_t audio_out_mpegpes;
@ -110,9 +109,6 @@ const ao_functions_t* const audio_out_drivers[] =
&audio_out_openal, &audio_out_openal,
#endif #endif
&audio_out_mpegpes, &audio_out_mpegpes,
#ifdef CONFIG_DXR2
&audio_out_dxr2,
#endif
#ifdef CONFIG_IVTV #ifdef CONFIG_IVTV
&audio_out_ivtv, &audio_out_ivtv,
#endif #endif

View File

@ -109,7 +109,6 @@ extern struct vo_driver video_out_yuv4mpeg;
extern struct vo_driver video_out_direct3d; extern struct vo_driver video_out_direct3d;
extern struct vo_driver video_out_directx; extern struct vo_driver video_out_directx;
extern struct vo_driver video_out_kva; extern struct vo_driver video_out_kva;
extern struct vo_driver video_out_dxr2;
extern struct vo_driver video_out_dxr3; extern struct vo_driver video_out_dxr3;
extern struct vo_driver video_out_ivtv; extern struct vo_driver video_out_ivtv;
extern struct vo_driver video_out_v4l2; extern struct vo_driver video_out_v4l2;
@ -209,9 +208,6 @@ const struct vo_driver *video_out_drivers[] =
#ifdef CONFIG_CACA #ifdef CONFIG_CACA
&video_out_caca, &video_out_caca,
#endif #endif
#ifdef CONFIG_DXR2
&video_out_dxr2,
#endif
#ifdef CONFIG_DXR3 #ifdef CONFIG_DXR3
&video_out_dxr3, &video_out_dxr3,
#endif #endif

View File

@ -1,968 +0,0 @@
/*
* 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 "fastmemcpy.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include "config.h"
#include "video_out.h"
#include "video_out_internal.h"
#include "mp_msg.h"
#include "m_option.h"
#include "sub/sub.h"
#include "path.h"
#include "libmpdemux/mpeg_packetizer.h"
#include "x11_common.h"
#include <dxr2ioctl.h>
#include "aspect.h"
int dxr2_fd = -1;
static int movie_w,movie_h;
static int playing = 0;
// vo device used to blank the screen for the overlay init
static const struct vo_old_functions *sub_vo = NULL;
static const struct vo_info_s *sub_info;
static uint8_t* sub_img = NULL;
static int sub_x,sub_y,sub_w,sub_h;
static int sub_x_off,sub_y_off;
static int sub_config_count;
static int aspect;
static int sub_vo_win = 0;
static int use_ol = 1;
static int ol_ratio = 1000;
static char *norm = NULL;
static char *ucode = NULL;
static int ar_mode = DXR2_ASPECTRATIOMODE_LETTERBOX;
static int mv_mode = DXR2_MACROVISION_OFF;
static int _75ire_mode = DXR2_75IRE_OFF;
static int bw_mode = DXR2_BLACKWHITE_OFF;
static int interlaced_mode = DXR2_INTERLACED_ON;
static int pixel_mode = DXR2_PIXEL_CCIR601;
static int iec958_mode = DXR2_IEC958_DECODED;
static int mute_mode = DXR2_AUDIO_MUTE_OFF;
static int ignore_cache = 0;
static int update_cache = 0;
static int olw_cor = 0, olh_cor = 0,olx_cor = 0, oly_cor = 0;
static int ol_osd = 0;
static int ck_rmin = 0x40;
static int ck_rmax = 0xFF;
static int ck_r = 0xFF;
static int ck_gmin = 0x00;
static int ck_gmax = 0x20;
static int ck_g = 0;
static int ck_bmin = 0x40;
static int ck_bmax = 0xFF;
static int ck_b = 0xFF;
static int cr_left = 0, cr_right = 0;
static int cr_top = 55, cr_bot = 300;
const m_option_t dxr2_opts[] = {
{ "overlay", &use_ol, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "nooverlay", &use_ol, CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "overlay-ratio", &ol_ratio, CONF_TYPE_INT, CONF_RANGE, 1, 2500, NULL },
{ "ucode", &ucode, CONF_TYPE_STRING,0, 0, 0, NULL},
{ "norm", &norm, CONF_TYPE_STRING,0, 0, 0, NULL},
{ "ar-mode",&ar_mode, CONF_TYPE_INT, CONF_RANGE,0,2,NULL },
{ "macrovision",&mv_mode,CONF_TYPE_INT,CONF_RANGE,0,3, NULL },
{ "75ire",&_75ire_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "no75ire",&_75ire_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "bw",&bw_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "color",&bw_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "interlaced",&interlaced_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "nointerlaced",&interlaced_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "square-pixel",&pixel_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "ccir601-pixel",&pixel_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "iec958-encoded",&iec958_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "iec958-decoded",&iec958_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "mute", &mute_mode,CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "nomute",&mute_mode,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "ignore-cache",&ignore_cache,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "update-cache",&update_cache,CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "olh-cor", &olh_cor, CONF_TYPE_INT, CONF_RANGE, -20, 20, NULL},
{ "olw-cor", &olw_cor, CONF_TYPE_INT, CONF_RANGE, -20, 20, NULL},
{ "olx-cor", &olx_cor, CONF_TYPE_INT, CONF_RANGE, -20, 20, NULL},
{ "oly-cor", &oly_cor, CONF_TYPE_INT, CONF_RANGE, -20, 20, NULL},
{ "ol-osd", &ol_osd, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "nool-osd", &ol_osd, CONF_TYPE_FLAG, 0, 1, 0, NULL},
{ "ck-rmin", &ck_rmin, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-rmax", &ck_rmax, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-r", &ck_r, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-gmin", &ck_gmin, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-gmax", &ck_gmax, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-g", &ck_g, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-bmin", &ck_bmin, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-bmax", &ck_bmax, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "ck-b", &ck_b, CONF_TYPE_INT, CONF_RANGE, 0, 0xFF, NULL},
{ "cr-left", &cr_left, CONF_TYPE_INT, CONF_RANGE, 0, 500, NULL},
{ "cr-right", &cr_right, CONF_TYPE_INT, CONF_RANGE, 0, 500, NULL},
{ "cr-top", &cr_top, CONF_TYPE_INT, CONF_RANGE, 0, 500, NULL},
{ "cr-bot", &cr_bot, CONF_TYPE_INT, CONF_RANGE, 0, 500, NULL},
{ NULL,NULL, 0, 0, 0, 0, NULL}
};
static const vo_info_t info = {
"DXR2 video out",
"dxr2",
"Alban Bedel <albeu@free.fr> and Tobias Diedrich <ranma@gmx.at>",
""
};
const LIBVO_EXTERN (dxr2)
static char *ucodesearchpath[] = {
"/usr/local/lib/dxr2/dvd12.ux",
"/usr/lib/dxr2/dvd12.ux",
"/usr/src/dvd12.ux",
NULL,
};
#define BUF_SIZE 2048
static unsigned char dxr2buf[BUF_SIZE];
static unsigned int dxr2bufpos = 0;
int write_dxr2(const unsigned char *data, int len)
{
int w = 0;
if (dxr2_fd < 0)
{
mp_msg (MSGT_VO, MSGL_ERR, "DXR2 fd is not valid\n");
return 0;
}
while (len>0) if ((dxr2bufpos+len) <= BUF_SIZE) {
fast_memcpy(dxr2buf+dxr2bufpos, data, len);
dxr2bufpos+=len;
len=0;
} else {
int copylen=BUF_SIZE-dxr2bufpos;
if(copylen > 0) {
fast_memcpy(dxr2buf+dxr2bufpos, data, copylen);
dxr2bufpos += copylen;
data+=copylen;
len-=copylen;
}
w += write(dxr2_fd, dxr2buf, BUF_SIZE);
if(w < 0) {
mp_msg(MSGT_VO,MSGL_WARN,"DXR2 : write failed : %s \n",strerror(errno));
dxr2bufpos = 0;
break;
}
dxr2bufpos -= w;
if(dxr2bufpos)
memmove(dxr2buf,dxr2buf + w,dxr2bufpos);
}
return w;
}
static void flush_dxr2(void)
{
int w;
while (dxr2bufpos) {
w = write(dxr2_fd, dxr2buf, dxr2bufpos);
if(w < 0) {
mp_msg(MSGT_VO,MSGL_WARN,"DXR2 : write failed %s \n",strerror(errno));
dxr2bufpos = 0;
break;
}
dxr2bufpos -= w;
}
}
#define PACK_MAX_SIZE 2048
static unsigned char pack[PACK_MAX_SIZE];
static unsigned char mpg_eof[]={
0x00, 0x00, 0x01, 0xb9
};
static void dxr2_send_eof(void)
{
write_dxr2(mpg_eof, sizeof(mpg_eof));
}
void dxr2_send_sub_packet(unsigned char* data,int len,int id,unsigned int timestamp) {
int ptslen=5;
if(dxr2_fd < 0) {
mp_msg(MSGT_VO,MSGL_ERR,"DXR2 fd is not valid\n");
return;
}
if (((int) timestamp)<0)
timestamp=0;
mp_msg(MSGT_VO,MSGL_DBG2,"dxr2_send_sub_packet(timestamp=%d)\n", timestamp);
// startcode:
pack[0]=pack[1]=0;pack[2]=0x01;
// stream id
pack[3]=0xBD;
while(len>=4){
int payload_size= PACK_MAX_SIZE-(7+ptslen+3);
if(payload_size>len) payload_size= len;
pack[4]=(3+ptslen+1+payload_size)>>8;
pack[5]=(3+ptslen+1+payload_size)&255;
pack[6]=0x81;
if(ptslen){
int x;
pack[7]=0x80;
pack[8]=ptslen;
// presentation time stamp:
x=(0x02 << 4) | (((timestamp >> 30) & 0x07) << 1) | 1;
pack[9]=x;
x=((((timestamp >> 15) & 0x7fff) << 1) | 1);
pack[10]=x>>8; pack[11]=x&255;
x=((((timestamp) & 0x7fff) << 1) | 1);
pack[12]=x>>8; pack[13]=x&255;
} else {
pack[7]=0x00;
pack[8]=0x00;
}
pack[ptslen+9] = id;
write_dxr2(pack,7+ptslen+3);
write_dxr2(data,payload_size);
len -= payload_size;
data += payload_size;
ptslen = 0;
}
}
static int dxr2_set_vga_params(dxr2_vgaParams_t* vga,int detect) {
// Init the overlay, don't ask me how it work ;-)
dxr2_sixArg_t oc;
dxr2_oneArg_t om;
dxr2_twoArg_t win;
dxr2_fourArg_t crop;
crop.arg1= cr_left;
crop.arg2= cr_right;
crop.arg3 = cr_top;
crop.arg4 = cr_bot;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_CROPPING, &crop);
oc.arg1 = 0x40;
oc.arg2 = 0xff;
oc.arg3 = 0x40;
oc.arg4 = 0xff;
oc.arg5 = 0x40;
oc.arg6 = 0xff;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_COLOUR, &oc);
om.arg = ol_ratio;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_RATIO,&om);
win.arg1 = 100;
win.arg2 = 3;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);
win.arg1 = vo_screenwidth;
win.arg2 = vo_screenheight;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION,&win);
om.arg = 0;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_IN_DELAY,&om);
if(detect) {
// First we need a white screen
uint8_t* img = malloc(vo_screenwidth*vo_screenheight*3);
uint8_t* src[] = { img, NULL, NULL };
int stride[] = { vo_screenwidth * 3 , 0, 0 };
int cc = vo_config_count;
memset(img,255,vo_screenwidth*vo_screenheight*3);
vo_config_count = sub_config_count;
if(sub_vo->config(vo_screenwidth,vo_screenheight,vo_screenwidth,vo_screenheight,
VOFLAG_FULLSCREEN ,"DXR2 sub vo",IMGFMT_BGR24) != 0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] sub vo config failed => No overlay\n");
sub_vo->uninit();
sub_vo = NULL;
use_ol = 0;
vo_config_count = cc;
return 0;
}
sub_vo->draw_slice(src,stride,vo_screenwidth,vo_screenheight,0,0);
sub_vo->flip_page();
free(img);
sub_config_count++;
vo_config_count = cc;
om.arg = DXR2_OVERLAY_WINDOW_COLOUR_KEY;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_MODE,&om);
vga->xScreen = vo_screenwidth;
vga->yScreen = vo_screenheight;
vga->hOffWinKey = 100;
vga->vOffWinKey = 3;
ioctl(dxr2_fd, DXR2_IOC_CALCULATE_VGA_PARAMETERS, vga);
}
ioctl(dxr2_fd, DXR2_IOC_SET_VGA_PARAMETERS,vga);
return 1;
}
static int dxr2_save_vga_params(dxr2_vgaParams_t* vga,char* name) {
struct stat s;
char* p = get_path("dxr2_cache");
int p_len = strlen(p), name_len = strlen(name);
char cache_path[p_len + name_len + 2];
int ret;
FILE* fd;
if(stat(p,&s) !=0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] No vga cache dir found (%s)\n",strerror(errno));
if(errno == EACCES) {
free(p);
return 0;
}
// Try to create the dir
if(mkdir(p,S_IRWXU) != 0) {
mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Unable to create vga cache dir %s (%s)\n",p,strerror(errno));
free(p);
return 0;
}
}
sprintf(cache_path,"%s/%s",p,name);
free(p);
fd = fopen(cache_path,"w");
if(fd == NULL) {
mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Unable to open cache file %s for writing (%s)\n",cache_path,strerror(errno));
return 0;
}
ret = fprintf(fd,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
vga->hOffWinKey,
vga->vOffWinKey,
vga->xScreen,
vga->yScreen,
vga->hsyncPol,
vga->vsyncPol,
vga->blankStart,
vga->blankWidth,
vga->hOffset,
vga->vOffset,
vga->ratio,
olx_cor,
oly_cor,
olw_cor,
olh_cor);
fclose(fd);
return ret >= 11 ? 1 : 0;
}
static int dxr2_load_vga_params(dxr2_vgaParams_t* vga,char* name) {
char* p = get_path("dxr2_cache");
int p_len = strlen(p), name_len = strlen(name);
char cache_path[p_len + name_len + 2];
int ret;
int xc,yc,wc,hc;
FILE* fd;
sprintf(cache_path,"%s/%s",p,name);
free(p);
fd = fopen(cache_path,"r");
if(fd == NULL) {
mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Unable to open cache file %s for reading (%s)\n",cache_path,strerror(errno));
return 0;
}
ret = fscanf(fd, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
&vga->hOffWinKey,
&vga->vOffWinKey,
&vga->xScreen,
&vga->yScreen,
&vga->hsyncPol,
&vga->vsyncPol,
&vga->blankStart,
&vga->blankWidth,
&vga->hOffset,
&vga->vOffset,
&vga->ratio,
&xc,
&yc,
&wc,
&hc);
fclose(fd);
if(ret > 11 && !olx_cor) olx_cor = xc;
if(ret > 12 && !oly_cor) oly_cor = yc;
if(ret > 13 && !olw_cor) olw_cor = wc;
if(ret > 14 && !olh_cor) olh_cor = hc;
return ret >= 11 ? 1 : 0;
}
static int dxr2_setup_vga_params(void) {
const vo_info_t* vi = sub_info;
dxr2_vgaParams_t vga;
int loaded = dxr2_load_vga_params(&vga,(char*)vi->short_name);
if(!dxr2_set_vga_params(&vga,(update_cache || ignore_cache) ? 1 : !loaded ))
return 0;
if(!loaded || update_cache)
dxr2_save_vga_params(&vga,(char*)vi->short_name);
return 1;
}
static void dxr2_set_overlay_window(void) {
uint8_t* src[] = { sub_img, NULL, NULL };
int stride[] = { movie_w * 3 , 0, 0 };
dxr2_twoArg_t win;
int redisp = 0;
int cc = vo_config_count;
vo_config_count = sub_config_count;
sub_vo->draw_slice(src,stride,movie_w,movie_h,0,0);
sub_vo->flip_page();
vo_config_count = cc;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] setting overlay with correction x=%d y=%d w=%d h=%d\n",olx_cor,oly_cor, olw_cor,olh_cor);
// Sub vo isn't a windowed one, fill in the needed stuff
if(!sub_vo_win) {
if(vo_fs) {
vo_dwidth = vo_screenwidth;
vo_dheight = vo_screenheight;
vo_dx = vo_dy = 0;
} else {
vo_dwidth = movie_w;
vo_dheight = movie_h;
vo_dx = (vo_screenwidth - vo_dwidth) / 2;
vo_dy = (vo_screenheight - vo_dheight) / 2;
}
}
if(sub_w != vo_dwidth || sub_h != vo_dheight) {
int new_aspect = ((1<<16)*vo_dwidth + vo_dheight/2)/vo_dheight;
sub_w = vo_dwidth;
sub_h = vo_dheight;
if(new_aspect > aspect)
sub_w = (sub_h*aspect + (1<<15))>>16;
else
sub_h = ((sub_w<<16) + (aspect>>1)) /aspect;
sub_w += olw_cor;
sub_h += olh_cor;
sub_x_off = (vo_dwidth-sub_w) / 2;
sub_y_off = (vo_dheight-sub_h) / 2;
sub_x = -vo_dx; // Be sure to also replace the overlay
win.arg1 = sub_w;
win.arg2 = sub_h;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] set win size w=%d h=%d and offset x=%d y=%d \n",win.arg1,win.arg2,sub_x_off,sub_y_off);
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);
}
if(vo_dx != sub_x || vo_dy != sub_y) {
sub_x = vo_dx + olx_cor + sub_x_off;
sub_y = vo_dy + oly_cor + sub_y_off;
win.arg1 = (sub_x > 0 ? sub_x : 0);
win.arg2 = (sub_y > 0 ? sub_y : 0);
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] set pos x=%d y=%d \n",win.arg1,win.arg2);
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);
}
}
static int config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t flags, char *title, uint32_t format)
{
int arg;
dxr2_threeArg_t arg3;
if(dxr2_fd < 0) {
mp_msg(MSGT_VO,MSGL_ERR,"DXR2 fd is not valid\n");
return VO_ERROR;
}
if(playing) {
dxr2_send_eof();
flush_dxr2();
ioctl(dxr2_fd, DXR2_IOC_STOP, NULL);
playing = 0;
}
// Video stream setup
arg3.arg1 = DXR2_STREAM_VIDEO;
arg3.arg2 = 0;
ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);
if (vo_fps > 28)
arg3.arg1 = DXR2_SRC_VIDEO_FREQ_30;
else arg3.arg1 = DXR2_SRC_VIDEO_FREQ_25;
arg3.arg2 = s_width;
arg3.arg3 = s_height;
ioctl(dxr2_fd, DXR2_IOC_SET_SOURCE_VIDEO_FORMAT, &arg3);
arg = DXR2_BITSTREAM_TYPE_MPEG_VOB;
ioctl(dxr2_fd, DXR2_IOC_SET_BITSTREAM_TYPE, &arg);
// Aspect ratio
if (1.76 <= movie_aspect && movie_aspect <= 1.80) {
arg = DXR2_ASPECTRATIO_16_9;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] source aspect ratio 16:9\n");
} else {
arg = DXR2_ASPECTRATIO_4_3;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] source aspect ratio 4:3\n");
}
ioctl(dxr2_fd, DXR2_IOC_SET_SOURCE_ASPECT_RATIO, &arg);
if (1.76 <= monitor_aspect && monitor_aspect <=1.80) {
arg = DXR2_ASPECTRATIO_16_9;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] monitor aspect ratio 16:9\n");
} else {
arg = DXR2_ASPECTRATIO_4_3;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] monitor aspect ratio 4:3\n");
}
ioctl(dxr2_fd, DXR2_IOC_SET_OUTPUT_ASPECT_RATIO, &arg);
arg = ar_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_ASPECT_RATIO_MODE, &arg);
// TV setup
arg = mv_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_TV_MACROVISION_MODE, &arg);
arg = _75ire_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_TV_75IRE_MODE, &arg);
arg = bw_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_TV_BLACKWHITE_MODE, &arg);
arg = interlaced_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_TV_INTERLACED_MODE, &arg);
arg = pixel_mode;
ioctl(dxr2_fd, DXR2_IOC_SET_TV_PIXEL_MODE, &arg);
if (norm) {
if (strcmp(norm, "ntsc")==0)
arg = DXR2_OUTPUTFORMAT_NTSC;
else if (strcmp(norm, "pal")==0) {
if (vo_fps > 28) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] you want pal, but we play at 30 fps, selecting pal60 instead\n");
arg = DXR2_OUTPUTFORMAT_PAL_60;
norm="pal60";
} else arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;
} else if (strcmp(norm, "pal60")==0) {
if (vo_fps > 28)
arg = DXR2_OUTPUTFORMAT_PAL_60;
else {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] you want pal60, but we play at 25 fps, selecting pal instead\n");
arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;
norm="pal";
}
} else if (strcmp(norm, "palm")==0)
arg = DXR2_OUTPUTFORMAT_PAL_M;
else if (strcmp(norm, "paln")==0)
arg = DXR2_OUTPUTFORMAT_PAL_N;
else if (strcmp(norm, "palnc")==0)
arg = DXR2_OUTPUTFORMAT_PAL_Nc;
else {
mp_msg(MSGT_VO,MSGL_WARN,"[dxr2] invalid norm %s\n", norm);
mp_msg(MSGT_VO,MSGL_WARN,"Valid values are ntsc,pal,pal60,palm,paln,palnc\n");
mp_msg(MSGT_VO,MSGL_WARN,"Using ntsc\n");
norm="ntsc";
}
} else {
if (vo_fps > 28) {
arg = DXR2_OUTPUTFORMAT_NTSC;
norm="ntsc";
} else {
arg = DXR2_OUTPUTFORMAT_PAL_BDGHI;
norm="pal";
}
}
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] output norm set to %s\n", norm);
ioctl(dxr2_fd, DXR2_IOC_SET_TV_OUTPUT_FORMAT, &arg);
// Subtitles
arg = DXR2_SUBPICTURE_ON;
ioctl(dxr2_fd,DXR2_IOC_ENABLE_SUBPICTURE,&arg);
arg3.arg1 = DXR2_STREAM_SUBPICTURE;
arg3.arg2 = 0;
ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);
// Audio
arg = iec958_mode;
ioctl(dxr2_fd, DXR2_IOC_IEC958_OUTPUT_MODE, &arg);
arg = DXR2_AUDIO_WIDTH_16;
ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_DATA_WIDTH, &arg);
arg = DXR2_AUDIO_FREQ_48;
ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY, &arg);
arg3.arg1 = DXR2_STREAM_AUDIO_LPCM;
arg3.arg2 = 0;
ioctl(dxr2_fd, DXR2_IOC_SELECT_STREAM, &arg3);
arg = 19;
ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_VOLUME, &arg);
arg = mute_mode;
ioctl(dxr2_fd, DXR2_IOC_AUDIO_MUTE, &arg);
movie_w = width;
movie_h = height;
//vo_fs = flags & VOFLAG_FULLSCREEN ? 1 : 0;
// Overlay
while(use_ol) {
dxr2_twoArg_t win;
dxr2_oneArg_t om;
int cc = vo_config_count;
vo_config_count = sub_config_count;
// Load or detect the overlay stuff
if(!dxr2_setup_vga_params()) {
sub_vo->uninit();
sub_vo = NULL;
vo_config_count = cc;
break;
}
// Does the sub vo support the x11 stuff
// Fix me : test the other x11 vo's and enable them
if(strcmp(sub_info->short_name,"x11") == 0)
sub_vo_win = 1;
else
sub_vo_win = 0;
// No window and no osd => we don't need any subdriver
if(!sub_vo_win && !ol_osd) {
sub_vo->uninit();
sub_vo = NULL;
}
while(sub_vo) {
dxr2_sixArg_t oc;
int i,sub_flags = VOFLAG_SWSCALE | (flags & VOFLAG_FULLSCREEN);
if(sub_vo->config(width,height,width,height,sub_flags,
"MPlayer DXR2 render",IMGFMT_BGR24) != 0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] sub vo config failed => No X11 window\n");
sub_vo->uninit();
sub_vo = NULL;
break;
}
sub_config_count++;
// Feel free to try some other other color and report your results
oc.arg1 = ck_rmin;
oc.arg2 = ck_rmax;
oc.arg3 = ck_gmin;
oc.arg4 = ck_gmax;
oc.arg5 = ck_bmin;
oc.arg6 = ck_bmax;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_COLOUR, &oc);
om.arg = DXR2_OVERLAY_WINDOW_COLOUR_KEY;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_MODE,&om);
sub_img = malloc(width*height*3);
for(i = 0 ; i < width*height*3 ; i += 3) {
sub_img[i] = ck_b;
sub_img[i+1] = ck_g;
sub_img[i+2] = ck_r;
}
aspect = ((1<<16)*width + height/2)/height;
sub_w = sub_h = 0;
dxr2_set_overlay_window();
break;
}
vo_config_count = cc;
if(!sub_vo) { // Fallback on non windowed overlay
vo_fs = flags & VOFLAG_FULLSCREEN ? 1 : 0;
om.arg = DXR2_OVERLAY_WINDOW_KEY;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_MODE,&om);
win.arg1 = flags & VOFLAG_FULLSCREEN ? vo_screenwidth : width;
win.arg2 = flags & VOFLAG_FULLSCREEN ? vo_screenheight : height;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);
win.arg1 = (vo_screenwidth - win.arg1) / 2;
win.arg2 = (vo_screenheight - win.arg2) / 2;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);
}
break;
}
if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop);
// start playing
if(ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL) == 0) {
playing = 1;
return 0;
} else
return VO_ERROR;
}
static void clear_alpha(int x0,int y0, int w,int h) {
uint8_t* src[] = { sub_img , NULL, NULL };
int stride[] = { movie_w * 3, 0, 0 };
sub_vo->draw_slice(src,stride,w,h,x0,y0);
}
static void draw_osd(void)
{
if(sub_vo && ol_osd) {
vo_remove_text(movie_w,movie_h,clear_alpha);
sub_vo->draw_osd();
}
}
static int draw_frame(uint8_t * src[])
{
vo_mpegpes_t *p=(vo_mpegpes_t *)src[0];
if(p->id == 0x1E0) {// Video
send_mpeg_ps_packet (p->data, p->size, p->id,
p->timestamp ? p->timestamp : vo_pts, 2, write_dxr2);
} else if(p->id == 0x20) // Subtitles
dxr2_send_sub_packet(p->data, p->size, p->id, p->timestamp);
return 0;
}
static void flip_page (void)
{
if(sub_vo && ol_osd && vo_osd_changed_flag)
sub_vo->flip_page();
}
static int draw_slice( uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0 )
{
return 0;
}
static int query_format(uint32_t format)
{
if (format==IMGFMT_MPEGPES)
return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW|VFCAP_TIMER|VFCAP_SPU;
return 0;
}
static void uninit(void)
{
mp_msg(MSGT_VO,MSGL_DBG2, "VO: [dxr2] Uninitializing\n" );
if (dxr2_fd > 0) {
if(playing) {
dxr2_send_eof();
flush_dxr2();
playing = 0;
}
close(dxr2_fd);
dxr2_fd = -1;
}
free(sub_img);
sub_img = NULL;
if(sub_vo) {
int cc = vo_config_count;
vo_config_count = sub_config_count;
sub_vo->uninit();
sub_vo = NULL;
vo_config_count = cc;
}
}
static void check_events(void)
{
// I'd like to have this done in an x11 independent way
// It's because of this that we are limited to vo_x11 for windowed overlay :-(
#ifdef X11_FULLSCREEN
if(sub_vo && sub_vo_win) {
int e=vo_x11_check_events(mDisplay);
if ( !(e&VO_EVENT_RESIZE) && !(e&VO_EVENT_EXPOSE) ) return;
XSetBackground(mDisplay, vo_gc, 0);
XClearWindow(mDisplay, vo_window);
dxr2_set_overlay_window();
}
#endif
}
static int preinit(const char *arg) {
int uCodeFD = -1;
int uCodeSize;
dxr2_uCode_t* uCode;
dxr2_fourArg_t crop;
int n=0;
sub_vo = NULL;
sub_config_count = 0;
if(use_ol) {
if (arg) {
for(n = 0 ; video_out_drivers[n] != NULL ; n++) {
const vo_info_t* vi = video_out_drivers[n]->info;
if(!vi)
continue;
if(!video_out_drivers[n]->is_new && strcasecmp(arg,vi->short_name) == 0)
break;
}
sub_vo = video_out_drivers[n]->old_functions;
sub_info = video_out_drivers[n]->info;
} else {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] We need a sub driver to initialize the overlay\n");
use_ol = 0;
}
}
if(!sub_vo) {
if(use_ol)
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub driver '%s' not found => no overlay\n",arg);
use_ol = 0;
} else {
if(sub_vo->preinit(NULL) != 0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub vo %s preinit failed => no overlay\n",arg);
sub_vo = NULL;
use_ol = 0;
} else {
uint32_t fmt = IMGFMT_BGR24;
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] Sub vo %s initialized\n",arg);
if(sub_vo->control(VOCTRL_QUERY_FORMAT,&fmt) <= 0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] Sub vo %s doesn't support BGR24 => no overlay\n",arg);
sub_vo->uninit();
sub_vo = NULL;
use_ol = 0;
}
}
}
dxr2_fd = open( "/dev/dxr2", O_WRONLY);
if( dxr2_fd < 0 ) {
mp_msg(MSGT_VO,MSGL_V, "VO: [dxr2] Error opening /dev/dxr2 for writing!\n" );
return VO_ERROR;
}
if(ucode)
uCodeFD = open(ucode, O_RDONLY);
else for (n=0; ucodesearchpath[n] != NULL; n++) {
mp_msg(MSGT_VO,MSGL_V,"VO: [dxr2] Looking for microcode in %s... ",
ucodesearchpath[n]);
if ((uCodeFD = open(ucodesearchpath[n], O_RDONLY))>0) {
mp_msg(MSGT_VO,MSGL_V,"ok\n");
break;
} else {
mp_msg(MSGT_VO,MSGL_V,"failed (%s)\n", strerror(errno));
}
}
if (uCodeFD < 0) {
mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Could not open microcode\n");
return VO_ERROR;
}
uCodeSize = lseek(uCodeFD, 0, SEEK_END);
if ((uCode = malloc(uCodeSize + 4)) == NULL) {
mp_msg(MSGT_VO,MSGL_FATAL,"VO: [dxr2] Could not allocate memory for uCode: %s\n", strerror(errno));
return VO_ERROR;
}
lseek(uCodeFD, 0, SEEK_SET);
if (read(uCodeFD, uCode+4, uCodeSize) != uCodeSize) {
mp_msg(MSGT_VO,MSGL_ERR,"VO: [dxr2] Could not read uCode uCode: %s\n", strerror(errno));
return VO_ERROR;
}
close(uCodeFD);
uCode->uCodeLength = uCodeSize;
// upload ucode
ioctl(dxr2_fd, DXR2_IOC_INIT_ZIVADS, uCode);
// reset card
ioctl(dxr2_fd, DXR2_IOC_RESET, NULL);
playing = 0;
if(!use_ol) {
crop.arg1=0;
crop.arg2=0;
crop.arg3=0;
crop.arg4=0;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_CROPPING, &crop);
}
return 0;
}
static int control(uint32_t request, void *data)
{
switch (request) {
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
case VOCTRL_PAUSE:
ioctl(dxr2_fd,DXR2_IOC_PAUSE, NULL);
return VO_TRUE;
case VOCTRL_RESUME:
ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL);
return VO_TRUE;
case VOCTRL_RESET:
flush_dxr2();
ioctl(dxr2_fd, DXR2_IOC_PLAY, NULL);
return VO_TRUE;
case VOCTRL_ONTOP:
vo_x11_ontop();
return VO_TRUE;
case VOCTRL_FULLSCREEN:
if(!use_ol)
return VO_NOTIMPL;
else if(sub_vo) {
int r = sub_vo->control(VOCTRL_FULLSCREEN,0);
if(r == VO_TRUE && !sub_vo_win)
dxr2_set_overlay_window();
return r;
} else {
dxr2_twoArg_t win;
vo_fs = !vo_fs;
win.arg1 = vo_fs ? vo_screenwidth : movie_w;
win.arg2 = vo_fs ? vo_screenheight : movie_h;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_DIMENSION, &win);
win.arg1 = (vo_screenwidth - win.arg1) / 2;
win.arg2 = (vo_screenheight - win.arg2) / 2;
ioctl(dxr2_fd, DXR2_IOC_SET_OVERLAY_POSITION,&win);
return VO_TRUE;
}
case VOCTRL_SET_SPU_PALETTE: {
if(ioctl(dxr2_fd,DXR2_IOC_SET_SUBPICTURE_PALETTE,data) < 0) {
mp_msg(MSGT_VO,MSGL_WARN,"VO: [dxr2] SPU palette loading failed\n");
return VO_ERROR;
}
return VO_TRUE;
}
}
return VO_NOTIMPL;
}