package depends on it because of the icon and menu entry.
* Added an intf_WarnHexDump() function to do raw hexadecimal dumps of
memory areas. For debugging purposes or for real men, as you wish.
* Lots of tidying in dvd_ioctl.c, a few comments added.
* Better error handling in the subpicture decoder.
* Tidied video_spu.c. More to come later.
* Fixed subtitle displaying. Will soon work in overlay mode as well.
clean:
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(STD_PLUGIN_OBJ)
rm -f plugins/*/*.o src/*/*.o lib/*.so
- rm -f vlc @ALIASES@
+ rm -f vlc kvlc gvlc
distclean: clean
rm -f src/*/*.o plugins/*/*.o **/*~ *.log
Package: vlc
Architecture: any
-Depends: ${shlibs:Depends}, vlc-gnome
-Suggests: vlc-sdl, vlc-esd
+Depends: ${shlibs:Depends}, vlc-gtk
+Suggests: vlc-sdl, vlc-esd, vlc-gnome
Description: the free MPEG and DVD player VideoLAN Client
VideoLAN is a free MPEG, MPEG2 and DVD software solution.
.
Package: vlc-gnome
Architecture: any
-Depends: vlc (= ${Source-Version}), ${shlibs:Depends}
+Depends: vlc (= ${Source-Version}), vlc-gtk (= ${Source-Version}), ${shlibs:Depends}
Description: Gnome plugin for the VideoLAN Client
VideoLAN is a free MPEG, MPEG2 and DVD software solution.
.
This plugin adds a Gnome interface to the VideoLAN Client.
+Package: vlc-gtk
+Architecture: any
+Depends: vlc (= ${Source-Version}), ${shlibs:Depends}
+Description: Gtk+ plugin for the VideoLAN Client
+ VideoLAN is a free MPEG, MPEG2 and DVD software solution.
+ .
+ This plugin adds a Gtk+ interface to the VideoLAN Client.
+
Package: vlc-esd
Architecture: any
Depends: vlc (= ${Source-Version}), ${shlibs:Depends}
./configure --prefix=/usr \
--mandir=\$${prefix}/share/man \
--infodir=\$${prefix}/share/info \
- --enable-gnome --enable-fb --with-glide --with-ggi \
- --with-sdl --enable-esd --enable-alsa --disable-ppro ; \
+ --enable-gnome --enable-gtk --enable-fb --with-glide \
+ --with-ggi --with-sdl --enable-esd --enable-alsa \
+ --disable-ppro ; \
else \
./configure --prefix=/usr \
--mandir=\$${prefix}/share/man \
--infodir=\$${prefix}/share/info \
- --enable-gnome --enable-fb --with-ggi \
+ --enable-gnome --enable-gtk --enable-fb --with-ggi \
--with-sdl --enable-esd --enable-alsa; \
fi
DESTDIR=`pwd`/debian/vlc/ $(MAKE) install prefix=/usr
# make symlinks for packages
- for alias in ggi gnome glide esd sdl alsa ; do \
+ for alias in ggi gtk gnome glide esd sdl alsa ; do \
mkdir -p debian/vlc-$$alias/usr/share/doc/ ; \
ln -s vlc debian/vlc-$$alias/usr/share/doc/vlc-$$alias ; \
mkdir -p debian/vlc-$$alias/usr/lib/videolan/vlc/ ; \
debian/vlc-$$alias/usr/lib/videolan/vlc/ ; \
done
- mkdir -p debian/vlc-gnome/usr/bin/
- mv debian/vlc/usr/bin/gvlc debian/vlc-gnome/usr/bin/
- mkdir -p debian/vlc-gnome/usr/share/videolan/
+ mkdir -p debian/vlc-gtk/usr/bin/
+ mv debian/vlc/usr/bin/gvlc debian/vlc-gtk/usr/bin/
+ mkdir -p debian/vlc-gtk/usr/share/videolan/
mv debian/vlc/usr/share/videolan/gvlc.png \
- debian/vlc-gnome/usr/share/videolan/
- mkdir -p debian/vlc-gnome/usr/share/man/man1/
- ln -s vlc.1.gz debian/vlc-gnome/usr/share/man/man1/gvlc.1.gz
+ debian/vlc-gtk/usr/share/videolan/
+ mkdir -p debian/vlc-gtk/usr/share/man/man1/
+ ln -s vlc.1.gz debian/vlc-gtk/usr/share/man/man1/gvlc.1.gz
# Build architecture-independent files here.
binary-indep: build install
# dh_installpam
# dh_installinit
dh_installcron
- dh_installmanpages -Nvlc-gnome -Nvlc-ggi -Nvlc-glide -Nvlc-esd -Nvlc-sdl -Nvlc-alsa
+ dh_installmanpages -Nvlc-gnome -Nvlc-gtk -Nvlc-ggi -Nvlc-glide -Nvlc-esd -Nvlc-sdl -Nvlc-alsa
dh_installinfo
# dh_undocumented
- dh_installchangelogs -Nvlc-gnome -Nvlc-ggi -Nvlc-glide -Nvlc-esd -Nvlc-sdl -Nvlc-alsa
+ dh_installchangelogs -Nvlc-gnome -Nvlc-gtk -Nvlc-ggi -Nvlc-glide -Nvlc-esd -Nvlc-sdl -Nvlc-alsa
dh_link
dh_strip
dh_compress
+++ /dev/null
-?package(vlc-gnome):command="/usr/bin/gvlc" hotkey="V" needs="X11" \
- section="Apps/Viewers" title="Gnome VideoLAN Client" \
- icon="/usr/share/videolan/gvlc.png"
--- /dev/null
+?package(vlc-gtk):command="/usr/bin/gvlc" hotkey="V" needs="X11" \
+ section="Apps/Viewers" title="Gnome/Gtk VideoLAN Client" \
+ icon="/usr/share/videolan/gvlc.png"
This package was debianized by Samuel Hocevar <sam@zoy.org> on
Mon, 13 Mar 2000 02:21:45 +0100.
-It was downloaded from ftp://ftp.videolan.org/pub/videolan/
+It was taken from the CVS tree. See http://www.videolan.org/cvs.html
Upstream Author(s): The VideoLAN Team <videolan@videolan.org>
-VideoLAN is Copyright 1996, 1997, 1998, 1999, 2000 The VideoLAN Team
+VideoLAN is Copyright 1996, 1997, 1998, 1999, 2000, 2001 The VideoLAN Team
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
void intf_MsgImm ( char *psz_format, ... );
void intf_ErrMsgImm ( char *psz_format, ... );
void intf_WarnMsgImm ( int i_level, char *psz_format, ... );
+void intf_WarnHexDump ( int i_level, void *p_data, int i_size );
+
+++ /dev/null
-/*****************************************************************************
- * video_graphics.h: pictures manipulation primitives
- * Includes function to compose, convert and display pictures, and also basic
- * functions to copy pictures data or descriptors.
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors: Vincent Seguin <seguin@via.ecp.fr>
- *
- * This program 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Requires:
- * "config.h"
- * "common.h"
- * "mtime.h"
- * "video.h"
- *****************************************************************************/
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-
-
* intf_beos.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: intf_beos.cpp,v 1.10 2001/02/20 07:49:12 sam Exp $
+ * $Id: intf_beos.cpp,v 1.11 2001/02/26 12:16:28 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
#include "main.h"
}
-#include "beos_window.h"
+#include "window.h"
/*****************************************************************************
* intf_sys_t: description and status of FB interface
#include "video.h"
#include "video_output.h"
-#include "interface.h" /* XXX maybe to remove if beos_window.h is splitted */
+#include "interface.h" /* XXX maybe to remove if window.h is splitted */
#include "intf_msg.h"
#include "main.h"
}
-#include "beos_window.h"
+#include "window.h"
#define WIDTH 128
#define HEIGHT 64
/*****************************************************************************
- * beos_window.h: beos window class prototype
+ * window.h: BeOS window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
- * Jean-Marc Dressler
+ * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* dvd_ioctl.c: DVD ioctl replacement function
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ioctl.c,v 1.1 2001/02/20 07:49:12 sam Exp $
+ * $Id: dvd_ioctl.c,v 1.2 2001/02/26 12:16:28 sam Exp $
*
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org>
#include "dvd_ioctl.h"
/*****************************************************************************
- * Local prototypes
+ * Local prototypes - BeOS specific
*****************************************************************************/
#if defined( SYS_BEOS )
-static int dvd_do_auth ( int i_fd, dvd_authinfo *p_authinfo );
-static int dvd_read_struct ( int i_fd, dvd_struct *p_dvd );
-static int dvd_read_physical ( int i_fd, dvd_struct *p_dvd );
-static int dvd_read_copyright ( int i_fd, dvd_struct *p_dvd );
-static int dvd_read_disckey ( int i_fd, dvd_struct *p_dvd );
-static int dvd_read_bca ( int i_fd, dvd_struct *p_dvd );
-static int dvd_read_manufact ( int i_fd, dvd_struct *p_dvd );
-static int communicate_with_dvd ( int i_fd,
- struct cdrom_generic_command *p_cgc );
-static void init_cdrom_command ( struct cdrom_generic_command *p_cgc,
- void *buf, int i_len, int i_type );
-static void setup_report_key ( struct cdrom_generic_command *p_cgc,
- unsigned i_agid, unsigned i_type );
-static void setup_send_key ( struct cdrom_generic_command *p_cgc,
- unsigned i_agid, unsigned i_type );
+static int ReadData ( int i_fd, dvd_struct *p_dvd );
+static int ReadCopyright ( int i_fd, dvd_struct *p_dvd );
+static int ReadKey ( int i_fd, dvd_struct *p_dvd );
+static int ReadBCA ( int i_fd, dvd_struct *p_dvd );
+static int ReadManufacturer ( int i_fd, dvd_struct *p_dvd );
+
+static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
+ void *buf, int i_len, int i_type );
+static void InitReadCommand ( struct cdrom_generic_command *p_cgc,
+ unsigned i_agid, unsigned i_type );
+static void InitWriteCommand ( struct cdrom_generic_command *p_cgc,
+ unsigned i_agid, unsigned i_type );
+
+static int SendCommand ( int i_fd, struct cdrom_generic_command *p_cgc );
#endif
/*****************************************************************************
return( ioctl( i_fd, i_op, p_arg ) );
#elif defined( SYS_BEOS )
- switch ( i_op )
- {
- case DVD_AUTH:
- return dvd_do_auth( i_fd, (dvd_authinfo *)p_arg );
- case DVD_READ_STRUCT:
- return dvd_read_struct( i_fd, (dvd_struct *)p_arg );
-
- default:
- intf_ErrMsg( "css error: unknown command 0x%x", i_op );
- return -1;
- }
-#else
+ int i_ret;
+ unsigned char buf[20];
- return -1;
-#endif
-}
+ struct cdrom_generic_command p_cgc;
-#if defined( SYS_BEOS )
+ dvd_struct *p_dvd = (dvd_struct *)p_arg;
+ dvd_authinfo *p_authinfo = (dvd_authinfo *)p_arg;
-/*****************************************************************************
- * setup_report_key
- *****************************************************************************/
-static void setup_report_key( struct cdrom_generic_command *p_cgc,
- unsigned i_agid, unsigned i_type )
-{
- p_cgc->cmd[0] = GPCMD_REPORT_KEY;
- p_cgc->cmd[10] = i_type | (i_agid << 6);
-
- switch( i_type )
+ switch ( i_op )
{
- case 0:
- case 8:
- case 5:
- p_cgc->buflen = 8;
- break;
+ case DVD_AUTH: /* Request type is "authentication" */
+ {
+ memset( buf, 0, sizeof( buf ) );
+ InitGenericCommand( &p_cgc, buf, 0, CGC_DATA_READ );
- case 1:
- p_cgc->buflen = 16;
- break;
+ switch( p_authinfo->type )
+ {
+ case DVD_LU_SEND_AGID: /* LU data send */
- case 2:
- case 4:
- p_cgc->buflen = 12;
- break;
- }
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_AGID" );
- p_cgc->cmd[9] = p_cgc->buflen;
- p_cgc->data_direction = CGC_DATA_READ;
-}
+ InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0 );
-/*****************************************************************************
- * setup_send_key
- *****************************************************************************/
-static void setup_send_key( struct cdrom_generic_command *p_cgc,
- unsigned i_agid, unsigned i_type )
-{
- p_cgc->cmd[0] = GPCMD_SEND_KEY;
- p_cgc->cmd[10] = i_type | (i_agid << 6);
+ i_ret = SendCommand( i_fd, &p_cgc );
- switch( i_type )
- {
- case 1:
- p_cgc->buflen = 16;
- break;
+ p_authinfo->lsa.agid = buf[7] >> 6;
- case 3:
- p_cgc->buflen = 12;
- break;
+ return i_ret;
- case 6:
- p_cgc->buflen = 8;
- break;
- }
+ case DVD_LU_SEND_KEY1:
- p_cgc->cmd[9] = p_cgc->buflen;
- p_cgc->data_direction = CGC_DATA_WRITE;
-}
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY1" );
-/*****************************************************************************
- * init_cdrom_command
- *****************************************************************************/
-static void init_cdrom_command( struct cdrom_generic_command *p_cgc,
- void *buf, int i_len, int i_type )
-{
- memset( p_cgc, 0, sizeof(struct cdrom_generic_command) );
+ InitReadCommand( &p_cgc, p_authinfo->lsk.agid, 2 );
- if (buf)
- {
- memset( buf, 0, i_len );
- }
+ i_ret = SendCommand( i_fd, &p_cgc );
- p_cgc->buffer = (char *) buf;
- p_cgc->buflen = i_len;
- p_cgc->data_direction = i_type;
- p_cgc->timeout = 255;
-}
+ /* Copy the key */
+ memcpy( p_authinfo->lsk.key, &buf[4], sizeof(dvd_key) );
-/* DVD handling */
+ return i_ret;
-/*****************************************************************************
- * dvd_do_auth
- *****************************************************************************/
-static int dvd_do_auth( int i_fd, dvd_authinfo *p_authinfo )
-{
- int i_ret;
- unsigned char buf[20];
- struct cdrom_generic_command p_cgc;
+ case DVD_LU_SEND_CHALLENGE:
-#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
-#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
-#if 0
- struct rpc_state_t rpc_state;
-#endif
+ InitReadCommand( &p_cgc, p_authinfo->lsc.agid, 1 );
- memset( buf, 0, sizeof(buf) );
- init_cdrom_command( &p_cgc, buf, 0, CGC_DATA_READ );
+ i_ret = SendCommand( i_fd, &p_cgc );
- switch (p_authinfo->type)
- {
- /* LU data send */
- case DVD_LU_SEND_AGID:
+ /* Copy the challenge */
+ memcpy( p_authinfo->lsc.chal, &buf[4],
+ sizeof(dvd_challenge) );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_AGID" );
+ return i_ret;
- setup_report_key(&p_cgc, p_authinfo->lsa.agid, 0);
+ case DVD_LU_SEND_TITLE_KEY: /* Post-auth key */
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_TITLE_KEY" );
- p_authinfo->lsa.agid = buf[7] >> 6;
- /* Returning data, let host change state */
+ InitReadCommand( &p_cgc, p_authinfo->lstk.agid, 4 );
- break;
+ p_cgc.cmd[5] = p_authinfo->lstk.lba;
+ p_cgc.cmd[4] = p_authinfo->lstk.lba >> 8;
+ p_cgc.cmd[3] = p_authinfo->lstk.lba >> 16;
+ p_cgc.cmd[2] = p_authinfo->lstk.lba >> 24;
- case DVD_LU_SEND_KEY1:
+ i_ret = SendCommand( i_fd, &p_cgc );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_KEY1" );
+ p_authinfo->lstk.cpm = (buf[4] >> 7) & 1;
+ p_authinfo->lstk.cp_sec = (buf[4] >> 6) & 1;
+ p_authinfo->lstk.cgms = (buf[4] >> 4) & 3;
- setup_report_key(&p_cgc, p_authinfo->lsk.agid, 2);
+ /* Copy the key */
+ memcpy( p_authinfo->lstk.title_key, &buf[5],
+ sizeof(dvd_key) );
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ return i_ret;
- copy_key(p_authinfo->lsk.key, &buf[4]);
- /* Returning data, let host change state */
+ case DVD_LU_SEND_ASF:
- break;
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_ASF" );
- case DVD_LU_SEND_CHALLENGE:
+ InitReadCommand( &p_cgc, p_authinfo->lsasf.agid, 5 );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_CHALLENGE" );
+ i_ret = SendCommand( i_fd, &p_cgc );
- setup_report_key(&p_cgc, p_authinfo->lsc.agid, 1);
+ p_authinfo->lsasf.asf = buf[7] & 1;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
-
- copy_chal(p_authinfo->lsc.chal, &buf[4]);
- /* Returning data, let host change state */
+ return i_ret;
- break;
+ case DVD_HOST_SEND_CHALLENGE: /* LU data receive */
- /* Post-auth key */
- case DVD_LU_SEND_TITLE_KEY:
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_TITLE_KEY" );
+ InitWriteCommand( &p_cgc, p_authinfo->hsc.agid, 1 );
+ buf[1] = 0xe;
- setup_report_key(&p_cgc, p_authinfo->lstk.agid, 4);
- p_cgc.cmd[5] = p_authinfo->lstk.lba;
- p_cgc.cmd[4] = p_authinfo->lstk.lba >> 8;
- p_cgc.cmd[3] = p_authinfo->lstk.lba >> 16;
- p_cgc.cmd[2] = p_authinfo->lstk.lba >> 24;
-
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
-
- p_authinfo->lstk.cpm = (buf[4] >> 7) & 1;
- p_authinfo->lstk.cp_sec = (buf[4] >> 6) & 1;
- p_authinfo->lstk.cgms = (buf[4] >> 4) & 3;
- copy_key(p_authinfo->lstk.title_key, &buf[5]);
- /* Returning data, let host change state */
-
- break;
+ /* Copy the challenge */
+ memcpy( &buf[4], p_authinfo->hsc.chal,
+ sizeof(dvd_challenge) );
- case DVD_LU_SEND_ASF:
+ if( (i_ret = SendCommand(i_fd, &p_cgc)) )
+ {
+ return i_ret;
+ }
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_ASF" );
+ p_authinfo->type = DVD_LU_SEND_KEY1;
- setup_report_key(&p_cgc, p_authinfo->lsasf.agid, 5);
+ return 0;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ case DVD_HOST_SEND_KEY2:
- p_authinfo->lsasf.asf = buf[7] & 1;
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY2" );
- break;
+ InitWriteCommand( &p_cgc, p_authinfo->hsk.agid, 3 );
+ buf[1] = 0xa;
- /* LU data receive (LU changes state) */
- case DVD_HOST_SEND_CHALLENGE:
+ /* Copy the key */
+ memcpy( &buf[4], p_authinfo->hsk.key, sizeof(dvd_key) );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_CHALLENGE" );
+ if( (i_ret = SendCommand(i_fd, &p_cgc)) )
+ {
+ p_authinfo->type = DVD_AUTH_FAILURE;
+ return i_ret;
+ }
- setup_send_key(&p_cgc, p_authinfo->hsc.agid, 1);
- buf[1] = 0xe;
- copy_chal(&buf[4], p_authinfo->hsc.chal);
+ p_authinfo->type = DVD_AUTH_ESTABLISHED;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ return 0;
- p_authinfo->type = DVD_LU_SEND_KEY1;
+ case DVD_INVALIDATE_AGID: /* Misc */
- break;
+ intf_WarnMsg( 2, "css DoAuth: DVD_INVALIDATE_AGID" );
- case DVD_HOST_SEND_KEY2:
+ InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0x3f );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_KEY2" );
+ return SendCommand( i_fd, &p_cgc );
- setup_send_key(&p_cgc, p_authinfo->hsk.agid, 3);
- buf[1] = 0xa;
- copy_key(&buf[4], p_authinfo->hsk.key);
+ case DVD_LU_SEND_RPC_STATE: /* Get region settings */
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- p_authinfo->type = DVD_AUTH_FAILURE;
- return i_ret;
- }
- p_authinfo->type = DVD_AUTH_ESTABLISHED;
+ intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_RPC_STATE "
+ "(unimplemented)" );
- break;
+ #if 0
+ p_dvdetup_report_key( &p_cgc, 0, 8 );
+ memset( &rpc_state, 0, sizeof(rpc_state_t) );
+ p_cgc.buffer = (char *) &rpc_state;
- /* Misc */
- case DVD_INVALIDATE_AGID:
+ if( (i_ret = SendCommand(i_fd, &p_cgc)) )
+ {
+ return i_ret;
+ }
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_INVALIDATE_AGID" );
+ p_authinfo->lrpcs.type = rpc_state.type_code;
+ p_authinfo->lrpcs.vra = rpc_state.vra;
+ p_authinfo->lrpcs.ucca = rpc_state.ucca;
+ p_authinfo->lrpcs.region_mask = rpc_state.region_mask;
+ p_authinfo->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
+ #endif
- setup_report_key(&p_cgc, p_authinfo->lsa.agid, 0x3f);
+ return 0;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ case DVD_HOST_SEND_RPC_STATE: /* Set region settings */
- break;
+ intf_WarnMsg( 2, "css DoAuth: DVD_HOST_SEND_RPC_STATE" );
- /* Get region settings */
- case DVD_LU_SEND_RPC_STATE:
+ InitWriteCommand( &p_cgc, 0, 6 );
+ buf[1] = 6;
+ buf[4] = p_authinfo->hrpcs.pdrc;
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_LU_SEND_RPC_STATE "
- "(unimplemented)" );
+ return SendCommand( i_fd, &p_cgc );
-#if 0
- p_dvdetup_report_key(&p_cgc, 0, 8);
- memset(&rpc_state, 0, sizeof(rpc_state_t));
- p_cgc.buffer = (char *) &rpc_state;
+ default:
+ intf_ErrMsg( "css DoAuth: invalid DVD key ioctl" );
+ return -1;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
}
+ }
- p_authinfo->lrpcs.type = rpc_state.type_code;
- p_authinfo->lrpcs.vra = rpc_state.vra;
- p_authinfo->lrpcs.ucca = rpc_state.ucca;
- p_authinfo->lrpcs.region_mask = rpc_state.region_mask;
- p_authinfo->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
-#endif
+ case DVD_READ_STRUCT: /* Request type is "read structure" */
+ {
+ switch( p_dvd->type )
+ {
+ case DVD_STRUCT_PHYSICAL:
- break;
+ intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_PHYSICAL" );
- /* Set region settings */
- case DVD_HOST_SEND_RPC_STATE:
+ return ReadData( i_fd, p_dvd );
- intf_WarnMsg( 2, "css dvd_do_auth: DVD_HOST_SEND_RPC_STATE" );
+ case DVD_STRUCT_COPYRIGHT:
- setup_send_key(&p_cgc, 0, 6);
- buf[1] = 6;
- buf[4] = p_authinfo->hrpcs.pdrc;
+ intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_COPYRIGHT" );
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &p_cgc)))
- {
- return i_ret;
- }
+ return ReadCopyright( i_fd, p_dvd );
- break;
+ case DVD_STRUCT_DISCKEY:
- default:
- intf_ErrMsg( "css dvd_do_auth: invalid DVD key ioctl" );
- return -1;
+ intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_DISCKEY" );
- }
+ return ReadKey( i_fd, p_dvd );
- return 0;
-}
+ case DVD_STRUCT_BCA:
-/*****************************************************************************
- * dvd_read_struct
- *****************************************************************************/
-static int dvd_read_struct( int i_fd, dvd_struct *p_dvd )
-{
- switch (p_dvd->type)
- {
- case DVD_STRUCT_PHYSICAL:
-
- intf_WarnMsg( 2, "css dvd_read_struct: DVD_STRUCT_PHYSICAL" );
- return dvd_read_physical(i_fd, p_dvd);
-
- case DVD_STRUCT_COPYRIGHT:
-
- intf_WarnMsg( 2, "css dvd_read_struct: DVD_STRUCT_COPYRIGHT" );
- return dvd_read_copyright(i_fd, p_dvd);
+ intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_BCA" );
- case DVD_STRUCT_DISCKEY:
+ return ReadBCA( i_fd, p_dvd );
- intf_WarnMsg( 2, "css dvd_read_struct: DVD_STRUCT_DISCKEY" );
- return dvd_read_disckey(i_fd, p_dvd);
+ case DVD_STRUCT_MANUFACT:
- case DVD_STRUCT_BCA:
+ intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_MANUFACT" );
- intf_WarnMsg( 2, "css dvd_read_struct: DVD_STRUCT_BCA" );
- return dvd_read_bca(i_fd, p_dvd);
+ return ReadManufacturer( i_fd, p_dvd );
- case DVD_STRUCT_MANUFACT:
+ default:
+ intf_WarnMsg( 2, "css ReadStruct: invalid request (%d)",
+ p_dvd->type );
- intf_WarnMsg( 2, "css dvd_read_struct: DVD_STRUCT_MANUFACT" );
- return dvd_read_manufact(i_fd, p_dvd);
+ return -1;
+ }
+ }
- default:
- intf_WarnMsg( 2, "css dvd_read_struct: invalid request (%d)",
- p_dvd->type );
+ default: /* Unknown request type */
+ {
+ intf_ErrMsg( "css error: unknown command 0x%x", i_op );
return -1;
+ }
}
+#else
+
+ return -1;
+#endif
}
+/* Local prototypes */
+
+#if defined( SYS_BEOS )
/*****************************************************************************
- * dvd_read_physical
+ * ReadData: Get data structure information from the DVD.
*****************************************************************************/
-static int dvd_read_physical( int i_fd, dvd_struct *p_dvd )
+static int ReadData( int i_fd, dvd_struct *p_dvd )
{
int i_ret, i;
u_char buf[4 + 4 * 20], *base;
struct dvd_layer *layer;
struct cdrom_generic_command cgc;
- init_cdrom_command( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+ InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[6] = p_dvd->physical.layer_num;
cgc.cmd[7] = p_dvd->type;
cgc.cmd[9] = cgc.buflen & 0xff;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &cgc)))
+ if( (i_ret = SendCommand(i_fd, &cgc)) )
{
return i_ret;
}
}
/*****************************************************************************
- * dvd_read_copyright
+ * ReadCopyright: get copyright information from the DVD.
*****************************************************************************/
-static int dvd_read_copyright( int i_fd, dvd_struct *p_dvd )
+static int ReadCopyright( int i_fd, dvd_struct *p_dvd )
{
int i_ret;
u_char buf[8];
struct cdrom_generic_command cgc;
- init_cdrom_command( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+ InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[6] = p_dvd->copyright.layer_num;
cgc.cmd[8] = cgc.buflen >> 8;
cgc.cmd[9] = cgc.buflen & 0xff;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if( (i_ret = communicate_with_dvd(i_fd, &cgc)) )
+ if( (i_ret = SendCommand(i_fd, &cgc)) )
{
return i_ret;
}
}
/*****************************************************************************
- * dvd_read_disckey
+ * ReadKey: get a key from the DVD.
*****************************************************************************/
-static int dvd_read_disckey( int i_fd, dvd_struct *p_dvd )
+static int ReadKey( int i_fd, dvd_struct *p_dvd )
{
int i_ret, size;
u_char *buf;
return -ENOMEM;
}
#endif
- buf = (u_char *) malloc(size);
+ buf = (u_char *) malloc( size );
+
+ InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
- init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[7] = p_dvd->type;
cgc.cmd[8] = size >> 8;
cgc.cmd[9] = size & 0xff;
cgc.cmd[10] = p_dvd->disckey.agid << 6;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if( !(i_ret = communicate_with_dvd(i_fd, &cgc)) )
+ if( !(i_ret = SendCommand(i_fd, &cgc)) )
{
memcpy( p_dvd->disckey.value, &buf[4], sizeof(p_dvd->disckey.value) );
}
}
/*****************************************************************************
- * dvd_read_bca
+ * ReadBCA: read the Burst Cutting Area of a DVD.
+ *****************************************************************************
+ * The BCA is a special part of the DVD which is used to burn additional
+ * data after it has been manufactured. DIVX is an exemple.
*****************************************************************************/
-static int dvd_read_bca( int i_fd, dvd_struct *p_dvd )
+static int ReadBCA( int i_fd, dvd_struct *p_dvd )
{
int i_ret;
u_char buf[4 + 188];
struct cdrom_generic_command cgc;
- init_cdrom_command( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+ InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[7] = p_dvd->type;
cgc.cmd[9] = cgc.buflen = 0xff;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if( (i_ret = communicate_with_dvd(i_fd, &cgc)) )
+ if( (i_ret = SendCommand(i_fd, &cgc)) )
{
return i_ret;
}
p_dvd->bca.len = buf[0] << 8 | buf[1];
if( p_dvd->bca.len < 12 || p_dvd->bca.len > 188 )
{
- intf_ErrMsg("css error: invalid BCA length (%d)", p_dvd->bca.len );
+ intf_ErrMsg( "css error: invalid BCA length (%d)", p_dvd->bca.len );
return -1;
}
}
/*****************************************************************************
- * dvd_read_manufact
+ * ReadManufacturer: get manufacturer information from the DVD.
*****************************************************************************/
-static int dvd_read_manufact( int i_fd, dvd_struct *p_dvd )
+static int ReadManufacturer( int i_fd, dvd_struct *p_dvd )
{
int i_ret = 0, size;
u_char *buf;
struct cdrom_generic_command cgc;
- size = sizeof(p_dvd->manufact.value) + 4;
+ size = sizeof( p_dvd->manufact.value ) + 4;
#if 0
if( (buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL )
#endif
buf = (u_char *) malloc(size);
- init_cdrom_command( &cgc, buf, size, CGC_DATA_READ );
+ InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
+
cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
cgc.cmd[7] = p_dvd->type;
cgc.cmd[8] = size >> 8;
cgc.cmd[9] = size & 0xff;
- /* handle uniform packets for scsi type devices (scsi,atapi) */
- if ((i_ret = communicate_with_dvd(i_fd, &cgc)))
+ if( (i_ret = SendCommand(i_fd, &cgc)) )
{
return i_ret;
}
p_dvd->manufact.len = buf[0] << 8 | buf[1];
if( p_dvd->manufact.len < 0 || p_dvd->manufact.len > 2048 )
{
- intf_ErrMsg( "css error: invalid manufacturer info length "
- "(%d)\n", p_dvd->bca.len );
+ intf_ErrMsg( "css error: invalid manufacturer info length (%d)",
+ p_dvd->bca.len );
i_ret = -1;
}
else
}
/*****************************************************************************
- * communicate_with_dvd
+ * InitGenericCommand: initialize a CGC structure
+ *****************************************************************************
+ * This function initializes a CDRom Generic Command structure for
+ * future use, either a read command or a write command.
*****************************************************************************/
-static int communicate_with_dvd( int i_fd,
- struct cdrom_generic_command *p_cgc )
+static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
+ void *buf, int i_len, int i_type )
{
+ memset( p_cgc, 0, sizeof( struct cdrom_generic_command ) );
+
+ if( buf != NULL )
+ {
+ memset( buf, 0, i_len );
+ }
+
+ p_cgc->buffer = ( char * )buf;
+ p_cgc->buflen = i_len;
+ p_cgc->data_direction = i_type;
+ p_cgc->timeout = 255;
+}
+
+/*****************************************************************************
+ * InitReadCommand: fill a CGC structure for reading purposes.
+ *****************************************************************************
+ * This function fills a CDRom Generic Command for a command which will
+ * read data from the DVD.
+ *****************************************************************************/
+static void InitReadCommand( struct cdrom_generic_command *p_cgc,
+ unsigned i_agid, unsigned i_type )
+{
+ p_cgc->cmd[0] = GPCMD_REPORT_KEY;
+ p_cgc->cmd[10] = i_type | (i_agid << 6);
+
+ /* FIXME: check what i_type means */
+ switch( i_type )
+ {
+ case 0:
+ case 8:
+ case 5:
+ p_cgc->buflen = 8;
+ break;
+
+ case 1:
+ p_cgc->buflen = 16;
+ break;
+
+ case 2:
+ case 4:
+ p_cgc->buflen = 12;
+ break;
+ }
+
+ p_cgc->cmd[9] = p_cgc->buflen;
+ p_cgc->data_direction = CGC_DATA_READ;
+}
+
+/*****************************************************************************
+ * InitWriteCommand: fill a CGC structure for writing purposes.
+ *****************************************************************************
+ * This function fills a CDRom Generic Command for a command which will
+ * send data to the DVD.
+ *****************************************************************************/
+static void InitWriteCommand( struct cdrom_generic_command *p_cgc,
+ unsigned i_agid, unsigned i_type )
+{
+ p_cgc->cmd[0] = GPCMD_SEND_KEY;
+ p_cgc->cmd[10] = i_type | (i_agid << 6);
+
+ /* FIXME: check what i_type means */
+ switch( i_type )
+ {
+ case 1:
+ p_cgc->buflen = 16;
+ break;
+
+ case 3:
+ p_cgc->buflen = 12;
+ break;
+
+ case 6:
+ p_cgc->buflen = 8;
+ break;
+ }
+
+ p_cgc->cmd[9] = p_cgc->buflen;
+ p_cgc->data_direction = CGC_DATA_WRITE;
+}
+
+/*****************************************************************************
+ * SendCommand: send a raw device command to the DVD drive.
+ *****************************************************************************
+ * This is the most important part of the ioctl emulation, the place where
+ * data is really sent to the DVD.
+ *****************************************************************************/
+static int SendCommand( int i_fd, struct cdrom_generic_command *p_cgc )
+{
+ int i;
+
raw_device_command rdc;
memset( &rdc, 0, sizeof( rdc ) );
}
rdc.command_length = 12;
- rdc.command[0] = p_cgc->cmd[0];
- rdc.command[1] = p_cgc->cmd[1];
- rdc.command[2] = p_cgc->cmd[2];
- rdc.command[3] = p_cgc->cmd[3];
- rdc.command[4] = p_cgc->cmd[4];
- rdc.command[5] = p_cgc->cmd[5];
- rdc.command[6] = p_cgc->cmd[6];
- rdc.command[7] = p_cgc->cmd[7];
- rdc.command[8] = p_cgc->cmd[8];
- rdc.command[9] = p_cgc->cmd[9];
- rdc.command[10] = p_cgc->cmd[10];
- rdc.command[11] = p_cgc->cmd[11];
- rdc.command[12] = p_cgc->cmd[12];
+
+ /* FIXME: check if this _really_ should go up to [12] */
+ for( i = 0 ; i < 13 ; i++ )
+ {
+ rdc.command[i] = p_cgc->cmd[i];
+ }
return ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
}
-
#endif
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.20 2001/02/22 08:59:54 stef Exp $
+ * $Id: input_dvd.c,v 1.21 2001/02/26 12:16:28 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
/* FIXME: We consider here that one title is one title set
* it is not true !!! */
- intf_WarnMsg( 2, "DVD: Number of titles: %d\n",
+ intf_WarnMsg( 2, "DVD: Number of titles: %d",
p_method->ifo.vmg.mat.i_tts_nb );
#define area p_input->stream.pp_areas
GtkWidget *vbox3;
GtkWidget *label14;
GtkWidget *label18;
- GtkWidget *hbox1;
- GtkWidget *label15;
+ GtkWidget *frame1;
GtkWidget *label16;
GtkWidget *label17;
GtkWidget *dialog_action_area;
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (label18);
gtk_box_pack_start (GTK_BOX (vbox3), label18, FALSE, FALSE, 0);
+ gtk_label_set_justify (GTK_LABEL (label18), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_padding (GTK_MISC (label18), 0, 5);
- hbox1 = gtk_hbox_new (FALSE, 0);
- gtk_widget_ref (hbox1);
- gtk_object_set_data_full (GTK_OBJECT (intf_about), "hbox1", hbox1,
+ frame1 = gtk_frame_new (_("Authors"));
+ gtk_widget_ref (frame1);
+ gtk_object_set_data_full (GTK_OBJECT (intf_about), "frame1", frame1,
(GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show (hbox1);
- gtk_box_pack_start (GTK_BOX (vbox3), hbox1, FALSE, FALSE, 0);
-
- label15 = gtk_label_new (_("Authors:"));
- gtk_widget_ref (label15);
- gtk_object_set_data_full (GTK_OBJECT (intf_about), "label15", label15,
- (GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show (label15);
- gtk_box_pack_start (GTK_BOX (hbox1), label15, FALSE, FALSE, 0);
- gtk_label_set_justify (GTK_LABEL (label15), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (label15), 0.5, 1.67638e-08);
- gtk_misc_set_padding (GTK_MISC (label15), 0, 10);
+ gtk_widget_show (frame1);
+ gtk_box_pack_start (GTK_BOX (vbox3), frame1, FALSE, FALSE, 0);
label16 = gtk_label_new (_("Régis Duchesne <regis@via.ecp.fr>\nMichel Lespinasse <walken@zoy.org>\nOlivier Pomel <pomel@via.ecp.fr>\nPierre Baillet <oct@zoy.org>\nJean-Philippe Grimaldi <jeanphi@via.ecp.fr>\nAndres Krapf <dae@via.ecp.fr>\nChristophe Massiot <massiot@via.ecp.fr>\nVincent Seguin <seguin@via.ecp.fr>\nBenoit Steiner <benny@via.ecp.fr>\nArnaud de Bossoreille de Ribou <bozo@via.ecp.fr>\nJean-Marc Dressler <polux@via.ecp.fr>\nGaël Hendryckx <jimmy@via.ecp.fr>\nSamuel Hocevar <sam@zoy.org>\nBrieuc Jeunhomme <bbp@via.ecp.fr>\nMichel Kaempf <maxx@via.ecp.fr>\nStéphane Borel <stef@via.ecp.fr>\nRenaud Dartus <reno@via.ecp.fr>\nHenri Fallon <henri@via.ecp.fr>"));
gtk_widget_ref (label16);
gtk_object_set_data_full (GTK_OBJECT (intf_about), "label16", label16,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (label16);
- gtk_box_pack_start (GTK_BOX (hbox1), label16, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame1), label16);
gtk_label_set_justify (GTK_LABEL (label16), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment (GTK_MISC (label16), 0.5, 0);
- gtk_misc_set_padding (GTK_MISC (label16), 10, 10);
+ gtk_misc_set_padding (GTK_MISC (label16), 5, 5);
label17 = gtk_label_new (_("This is the VideoLAN client, a DVD and MPEG player. It can play MPEG and MPEG 2 files from a file or from a network source."));
gtk_widget_ref (label17);
gtk_object_set_data_full (GTK_OBJECT (intf_about), "label17", label17,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (label17);
- gtk_box_pack_start (GTK_BOX (vbox3), label17, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox3), label17, FALSE, FALSE, 0);
gtk_label_set_justify (GTK_LABEL (label17), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (label17), TRUE);
gtk_misc_set_padding (GTK_MISC (label17), 0, 5);
<class>GtkLabel</class>
<name>label18</name>
<label>(C) 1996, 1997, 1998, 1999, 2000, 2001 - the VideoLAN Team</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
+ <justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
- <ypad>0</ypad>
+ <ypad>5</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
</widget>
<widget>
- <class>GtkHBox</class>
- <name>hbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
+ <class>GtkFrame</class>
+ <name>frame1</name>
+ <label>Authors</label>
+ <label_xalign>0</label_xalign>
+ <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
- <widget>
- <class>GtkLabel</class>
- <name>label15</name>
- <label>Authors:</label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>1.67638e-08</yalign>
- <xpad>0</xpad>
- <ypad>10</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
<widget>
<class>GtkLabel</class>
<name>label16</name>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0</yalign>
- <xpad>10</xpad>
- <ypad>10</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
+ <xpad>5</xpad>
+ <ypad>5</ypad>
</widget>
</widget>
<child>
<padding>0</padding>
<expand>False</expand>
- <fill>True</fill>
+ <fill>False</fill>
</child>
</widget>
</widget>
}
#endif
+/*****************************************************************************
+ * intf_WarnHexDump : print a hexadecimal dump of a memory area
+ *****************************************************************************
+ * This is convenient for debugging purposes.
+ *****************************************************************************/
+void intf_WarnHexDump( int i_level, void *p_data, int i_size )
+{
+ int i_index = 0;
+ int i_subindex;
+ char p_string[75];
+ u8 *p_area = (u8 *)p_data;
+
+ intf_WarnMsg( i_level, "hexdump: dumping %i bytes at address %p",
+ i_size, p_data );
+
+ while( i_index < i_size )
+ {
+ i_subindex = 0;
+
+ while( ( i_subindex < 24 ) && ( i_index + i_subindex < i_size ) )
+ {
+ sprintf( p_string + 3 * i_subindex, "%.2x ",
+ p_area[ i_index + i_subindex ] );
+
+ i_subindex++;
+ }
+
+ /* -1 here is safe because we know we printed at least one */
+ p_string[ 3 * i_subindex - 1 ] = '\0';
+ intf_WarnMsg( i_level, "0x%.4x: %s", i_index, p_string );
+
+ i_index += 24;
+ }
+
+ intf_WarnMsg( i_level, "hexdump: %i bytes dumped", i_size );
+}
+
/*****************************************************************************
* intf_FlushMsg (ok ?)
*****************************************************************************
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "mtime.h"
#include "intf_msg.h"
-#include "debug.h" /* ASSERT */
#include "stream_control.h"
#include "input_ext-dec.h"
#include "spu_decoder.h"
-/*
+/*****************************************************************************
* Local prototypes
- */
-static int InitThread ( spudec_thread_t *p_spudec );
-static void RunThread ( spudec_thread_t *p_spudec );
-static void ErrorThread ( spudec_thread_t *p_spudec );
-static void EndThread ( spudec_thread_t *p_spudec );
+ *****************************************************************************/
+static int InitThread ( spudec_thread_t * );
+static void RunThread ( spudec_thread_t * );
+static void ErrorThread ( spudec_thread_t * );
+static void EndThread ( spudec_thread_t * );
+
+static int SyncPacket ( spudec_thread_t * );
+static void ParsePacket ( spudec_thread_t * );
+static int ParseRLE ( spudec_thread_t *, subpicture_t * );
+static int ParseControlSequences( spudec_thread_t *, subpicture_t * );
/*****************************************************************************
* spudec_CreateThread: create a spu decoder thread
{
spudec_thread_t * p_spudec;
- intf_DbgMsg("spudec debug: creating spu decoder thread");
-
/* Allocate the memory needed to store the thread's structure */
p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) );
if ( vlc_thread_create(&p_spudec->thread_id, "spu decoder",
(vlc_thread_func_t)RunThread, (void *)p_spudec) )
{
- intf_ErrMsg("spudec error: can't spawn spu decoder thread");
+ intf_ErrMsg( "spudec error: can't spawn spu decoder thread" );
free( p_spudec );
return( 0 );
}
- intf_DbgMsg("spudec debug: spu decoder thread (%p) created", p_spudec);
return( p_spudec->thread_id );
}
*****************************************************************************/
static int InitThread( spudec_thread_t *p_spudec )
{
- intf_DbgMsg("spudec debug: initializing spu decoder thread %p", p_spudec);
-
p_spudec->p_config->decoder_config.pf_init_bit_stream(
&p_spudec->bit_stream,
p_spudec->p_config->decoder_config.p_decoder_fifo );
/* Mark thread as running and return */
- intf_DbgMsg( "spudec debug: InitThread(%p) succeeded", p_spudec );
return( 0 );
}
*****************************************************************************/
static void RunThread( spudec_thread_t *p_spudec )
{
- intf_DbgMsg("spudec debug: running spu decoder thread (%p) (pid == %i)",
- p_spudec, getpid());
+ intf_WarnMsg( 1, "spudec: spu decoder thread %i spawned", getpid() );
/*
* Initialize thread and free configuration
*/
while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) )
{
- int i_packet_size;
- int i_rle_size;
- int i_index, i_next;
- boolean_t b_valid;
- subpicture_t * p_spu = NULL;
-
- /* wait for the next SPU ID.
- * XXX: We trash 0xff bytes since they probably come from
- * an incomplete previous packet */
- do
- {
- i_packet_size = GetBits( &p_spudec->bit_stream, 8 );
- }
- while( i_packet_size == 0xff );
-
- if( p_spudec->p_fifo->b_die )
- {
- break;
- }
-
- /* the total size - should equal the sum of the
- * PES packet size that form the SPU packet */
- i_packet_size = i_packet_size << 8
- | GetBits( &p_spudec->bit_stream, 8 );
-
- /* the RLE stuff size */
- i_rle_size = GetBits( &p_spudec->bit_stream, 16 );
-
- /* if the values we got aren't too strange, decode the data */
- if( i_rle_size < i_packet_size )
- {
- /* allocate the subpicture.
- * FIXME: we should check if the allocation failed */
- p_spu = vout_CreateSubPicture( p_spudec->p_vout,
- DVD_SUBPICTURE, i_rle_size );
- /* get display time */
- p_spu->begin_date = p_spu->end_date
- = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
-
- /* get RLE data, skip 4 bytes for the first two read offsets */
- GetChunk( &p_spudec->bit_stream, p_spu->p_data,
- i_rle_size - 4 );
-
- if( p_spudec->p_fifo->b_die )
- {
- break;
- }
-
- /* continue parsing after the RLE part */
- i_index = i_rle_size;
-
- /* assume packet is valid */
- b_valid = 1;
-
- /* getting the control part */
- do
- {
- unsigned char i_cmd;
- u16 i_date;
-
- /* Get the sequence date */
- i_date = GetBits( &p_spudec->bit_stream, 16 );
-
- /* Next offset */
- i_next = GetBits( &p_spudec->bit_stream, 16 );
-
- i_index += 4;
-
- do
- {
- i_cmd = GetBits( &p_spudec->bit_stream, 8 );
- i_index++;
-
- switch( i_cmd )
- {
- case SPU_CMD_FORCE_DISPLAY:
- /* 00 (force displaying) */
- break;
- /* FIXME: here we have to calculate dates. It's
- * around i_date * 12000 but I don't know
- * how much exactly.
- */
- case SPU_CMD_START_DISPLAY:
- /* 01 (start displaying) */
- p_spu->begin_date += ( i_date * 12000 );
- break;
- case SPU_CMD_STOP_DISPLAY:
- /* 02 (stop displaying) */
- p_spu->end_date += ( i_date * 12000 );
- break;
- case SPU_CMD_SET_PALETTE:
- /* 03xxxx (palette) - trashed */
- RemoveBits( &p_spudec->bit_stream, 16 );
- i_index += 2;
- break;
- case SPU_CMD_SET_ALPHACHANNEL:
- /* 04xxxx (alpha channel) - trashed */
- RemoveBits( &p_spudec->bit_stream, 16 );
- i_index += 2;
- break;
- case SPU_CMD_SET_COORDINATES:
- /* 05xxxyyyxxxyyy (coordinates) */
- p_spu->i_x =
- GetBits( &p_spudec->bit_stream, 12 );
-
- p_spu->i_width = p_spu->i_x -
- GetBits( &p_spudec->bit_stream, 12 ) + 1;
-
- p_spu->i_y =
- GetBits( &p_spudec->bit_stream, 12 );
-
- p_spu->i_height = p_spu->i_y -
- GetBits( &p_spudec->bit_stream, 12 ) + 1;
-
- i_index += 6;
- break;
- case SPU_CMD_SET_OFFSETS:
- /* 06xxxxyyyy (byte offsets) */
- p_spu->type.spu.i_offset[0] =
- GetBits( &p_spudec->bit_stream, 16 ) - 4;
- p_spu->type.spu.i_offset[1] =
- GetBits( &p_spudec->bit_stream, 16 ) - 4;
- i_index += 4;
- break;
- case SPU_CMD_END:
- /* ff (end) */
- break;
- default:
- /* ?? (unknown command) */
- intf_ErrMsg( "spudec: unknown command 0x%.2x",
- i_cmd );
- b_valid = 0;
- break;
- }
- }
- while( b_valid && ( i_cmd != SPU_CMD_END ) );
- }
- while( b_valid && ( i_index == i_next ) );
-
- if( b_valid )
- {
- /* SPU is finished - we can tell the video output
- * to display it */
- vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
- }
- else
- {
- vout_DestroySubPicture( p_spudec->p_vout, p_spu );
- }
- }
- else
+ if( !SyncPacket( p_spudec ) )
{
- /* Unexpected PES packet - trash it */
- intf_ErrMsg( "spudec: trying to recover from bad packet" );
- vlc_mutex_lock( &p_spudec->p_fifo->data_lock );
- p_spudec->p_fifo->pf_delete_pes( p_spudec->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_spudec->p_fifo) );
- DECODER_FIFO_INCSTART( *p_spudec->p_fifo );
- vlc_mutex_unlock( &p_spudec->p_fifo->data_lock );
+ ParsePacket( p_spudec );
}
}
}
/* End of thread */
+ intf_WarnMsg( 1, "spudec: destroying spu decoder thread %i", getpid() );
EndThread( p_spudec );
}
}
/* Waiting for the input thread to put new PES packets in the fifo */
- vlc_cond_wait( &p_spudec->p_fifo->data_wait, &p_spudec->p_fifo->data_lock );
+ vlc_cond_wait( &p_spudec->p_fifo->data_wait,
+ &p_spudec->p_fifo->data_lock );
}
/* We can release the lock before leaving */
*****************************************************************************/
static void EndThread( spudec_thread_t *p_spudec )
{
- intf_DbgMsg( "spudec debug: destroying spu decoder thread %p", p_spudec );
free( p_spudec->p_config );
free( p_spudec );
- intf_DbgMsg( "spudec debug: spu decoder thread %p destroyed", p_spudec);
+}
+
+/*****************************************************************************
+ * SyncPacket: get in sync with the stream
+ *****************************************************************************
+ * This function makes a few sanity checks and returns 0 if it looks like we
+ * are at the beginning of a subpicture packet.
+ *****************************************************************************/
+static int SyncPacket( spudec_thread_t *p_spudec )
+{
+ /* Re-align the buffer on an 8-bit boundary */
+ RealignBits( &p_spudec->bit_stream );
+
+ /* The total SPU packet size, often bigger than a PS packet */
+ p_spudec->i_spu_size = GetBits( &p_spudec->bit_stream, 16 );
+
+ /* The RLE stuff size */
+ p_spudec->i_rle_size = GetBits( &p_spudec->bit_stream, 16 );
+
+ /* If the values we got are a bit strange, skip packet */
+ if( p_spudec->i_rle_size >= p_spudec->i_spu_size )
+ {
+ return( 1 );
+ }
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ParsePacket: parse an SPU packet and send it to the video output
+ *****************************************************************************
+ * This function parses the SPU packet and, if valid, sends it to the
+ * video output.
+ *****************************************************************************/
+static void ParsePacket( spudec_thread_t *p_spudec )
+{
+ subpicture_t * p_spu;
+
+ /* Allocate the subpicture internal data. */
+ p_spu = vout_CreateSubPicture( p_spudec->p_vout, DVD_SUBPICTURE,
+ p_spudec->i_rle_size );
+
+ if( p_spu == NULL )
+ {
+ return;
+ }
+
+ /* Get display time */
+ p_spu->begin_date = p_spu->end_date
+ = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
+
+ if( ParseRLE( p_spudec, p_spu ) )
+ {
+ /* There was a parse error, delete the subpicture */
+ vout_DestroySubPicture( p_spudec->p_vout, p_spu );
+ return;
+ }
+
+ /* Dump the subtitle info */
+ intf_WarnHexDump( 0, p_spu->p_data, p_spudec->i_rle_size - 4 );
+
+ /* Getting the control part */
+ if( ParseControlSequences( p_spudec, p_spu ) )
+ {
+ /* There was a parse error, delete the subpicture */
+ vout_DestroySubPicture( p_spudec->p_vout, p_spu );
+ return;
+ }
+
+ intf_WarnMsg( 1, "spudec: got a valid %ix%i subtitle at (%i,%i), "
+ "RLE offsets: 0x%x 0x%x",
+ p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y,
+ p_spu->type.spu.i_offset[0], p_spu->type.spu.i_offset[1] );
+
+ /* SPU is finished - we can tell the video output to display it */
+ vout_DisplaySubPicture( p_spudec->p_vout, p_spu );
+}
+
+/*****************************************************************************
+ * ParseRLE: parse the RLE part of the subtitle
+ *****************************************************************************
+ * This part parses the subtitle graphical data and stores it in a more
+ * convenient structure for later decoding. For more information on the
+ * subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
+ * TODO: pre-parse the RLE stuff here.
+ *****************************************************************************/
+static int ParseRLE( spudec_thread_t *p_spudec, subpicture_t * p_spu )
+{
+ /* Get RLE data, skip 4 bytes for the first two read offsets */
+ GetChunk( &p_spudec->bit_stream, p_spu->p_data, p_spudec->i_rle_size - 4 );
+
+ if( p_spudec->p_fifo->b_die )
+ {
+ return( 1 );
+ }
+
+ return( 0 );
+}
+
+ /*****************************************************************************
+ * ParseControlSequences: parse all SPU control sequences
+ *****************************************************************************
+ * This is the most important part in SPU decoding. We get dates, palette
+ * information, coordinates, and so on. For more information on the
+ * subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
+ *****************************************************************************/
+static int ParseControlSequences( spudec_thread_t *p_spudec,
+ subpicture_t * p_spu )
+{
+ int i_index = p_spudec->i_rle_size;
+ int i_next_index = 0, i_prev_index;
+
+ int i_date;
+ u8 i_command;
+
+ do
+ {
+ /* Get the control sequence date */
+ i_date = GetBits( &p_spudec->bit_stream, 16 );
+
+ /* Next offset */
+ i_prev_index = i_next_index;
+ i_next_index = GetBits( &p_spudec->bit_stream, 16 );
+
+ /* Current offset */
+ i_index += 4;
+
+ do
+ {
+ i_command = GetBits( &p_spudec->bit_stream, 8 );
+ i_index++;
+
+ switch( i_command )
+ {
+ case SPU_CMD_FORCE_DISPLAY:
+
+ /* 00 (force displaying) */
+
+ break;
+
+ /* FIXME: here we have to calculate dates. It's around
+ * i_date * 12000 but I don't know how much exactly. */
+ case SPU_CMD_START_DISPLAY:
+
+ /* 01 (start displaying) */
+ p_spu->begin_date += ( i_date * 12000 );
+
+ break;
+
+ case SPU_CMD_STOP_DISPLAY:
+
+ /* 02 (stop displaying) */
+ p_spu->end_date += ( i_date * 12000 );
+
+ break;
+
+ case SPU_CMD_SET_PALETTE:
+
+ /* 03xxxx (palette) - trashed */
+ RemoveBits( &p_spudec->bit_stream, 16 );
+ i_index += 2;
+
+ break;
+
+ case SPU_CMD_SET_ALPHACHANNEL:
+
+ /* 04xxxx (alpha channel) - trashed */
+ RemoveBits( &p_spudec->bit_stream, 16 );
+ i_index += 2;
+
+ break;
+
+ case SPU_CMD_SET_COORDINATES:
+
+ /* 05xxxyyyxxxyyy (coordinates) */
+ p_spu->i_x = GetBits( &p_spudec->bit_stream, 12 );
+ p_spu->i_width = GetBits( &p_spudec->bit_stream, 12 )
+ - p_spu->i_x + 1;
+
+ p_spu->i_y = GetBits( &p_spudec->bit_stream, 12 );
+ p_spu->i_height = GetBits( &p_spudec->bit_stream, 12 )
+ - p_spu->i_y + 1;
+
+ i_index += 6;
+
+ break;
+
+ case SPU_CMD_SET_OFFSETS:
+
+ /* 06xxxxyyyy (byte offsets) */
+ p_spu->type.spu.i_offset[0] =
+ GetBits( &p_spudec->bit_stream, 16 ) - 4;
+
+ p_spu->type.spu.i_offset[1] =
+ GetBits( &p_spudec->bit_stream, 16 ) - 4;
+
+ i_index += 4;
+
+ break;
+
+ case SPU_CMD_END:
+
+ /* ff (end) */
+
+ break;
+
+ default:
+
+ /* ?? (unknown command) */
+ intf_ErrMsg( "spudec error: unknown command 0x%.2x",
+ i_command );
+ return( 1 );
+ }
+
+ } while( i_command != SPU_CMD_END );
+
+ } while( i_index == i_next_index );
+
+ /* Check that the last index matches the previous one */
+ if( i_next_index != i_prev_index )
+ {
+ intf_ErrMsg( "spudec error: index mismatch (0x%.4x != 0x%.4x)",
+ i_next_index, i_prev_index );
+ return( 1 );
+ }
+
+ if( i_index > p_spudec->i_spu_size )
+ {
+ intf_ErrMsg( "spudec error: uh-oh, we went too far (0x%.4x > 0x%.4x)",
+ i_index, p_spudec->i_spu_size );
+ return( 1 );
+ }
+
+ /* Get rid of padding bytes */
+ switch( p_spudec->i_spu_size - i_index )
+ {
+ case 1:
+
+ RemoveBits( &p_spudec->bit_stream, 8 );
+ i_index++;
+
+ case 0:
+
+ /* Zero or one padding byte, quite usual */
+
+ break;
+
+ default:
+
+ /* More than one padding byte - this is very strange, but
+ * we can deal with it */
+ intf_WarnMsg( 2, "spudec warning: %i padding bytes",
+ p_spudec->i_spu_size - i_index );
+
+ while( i_index < p_spudec->i_spu_size )
+ {
+ RemoveBits( &p_spudec->bit_stream, 8 );
+ i_index++;
+ }
+
+ break;
+ }
+
+ /* Successfully parsed ! */
+ return( 0 );
}
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
vout_thread_t * p_vout; /* needed to create the spu objects */
+ /*
+ * Private properties
+ */
+ int i_spu_size; /* size of current SPU packet */
+ int i_rle_size; /* size of the RLE part */
+ subpicture_t * p_spu;
+
} spudec_thread_t;
/*****************************************************************************
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/*****************************************************************************
- * video_spu.h : DVD subpicture units functions
+ * video_spu.c : DVD subpicture units functions
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
- * Samuel "Sam" Hocevar <sam@via.ecp.fr>
- * Henri Fallon <henri@via.ecp.fr>
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ * Henri Fallon <henri@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "intf_msg.h"
-typedef struct vout_spu_s
-{
- int i_id;
- byte_t *p_data;
-
- /* drawing coordinates inside the spu */
- int i_x;
- int i_y;
- /* target size */
- int i_width;
- int i_height;
-
-} vout_spu_t;
+/* FIXME: fake palette - the real one has to be sought in the .IFO */
+static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
-static int NewLine ( vout_spu_t *p_vspu, int *i_id );
-
-/* i = get_nibble(); */
-#define GET_NIBBLE( i ) \
- if( b_aligned ) \
- { \
- i_next = *p_from[i_id]; \
- p_from[ i_id ]++; \
- b_aligned = 0; \
- i = i_next >> 4; \
- } \
- else \
- { \
- b_aligned = 1; \
- i = i_next & 0xf; \
+static __inline__ u8 GetNibble( u8 *p_source, int *pi_index )
+{
+ if( *pi_index & 0x1 )
+ {
+ return( p_source[(*pi_index)++ >> 1] & 0xf );
}
-
-/* i = j + get_nibble(); */
-#define ADD_NIBBLE( i, j ) \
- if( b_aligned ) \
- { \
- i_next = *p_from[i_id]; \
- p_from[ i_id ]++; \
- b_aligned = 0; \
- i = (j) + (i_next >> 4); \
- } \
- else \
- { \
- b_aligned = 1; \
- i = (j) + (i_next & 0xf); \
+ else
+ {
+ return( p_source[(*pi_index)++ >> 1] >> 4 );
}
+}
/*****************************************************************************
- * vout_RenderSPU: draws an SPU on a picture
+ * vout_RenderSPU: draw an SPU on a picture
*****************************************************************************
*
*****************************************************************************/
-void vout_RenderSPU( vout_buffer_t *p_buffer, subpicture_t *p_subpic,
+void vout_RenderSPU( vout_buffer_t *p_buffer, subpicture_t *p_spu,
int i_bytes_per_pixel, int i_bytes_per_line )
{
int i_code = 0x00;
- int i_next = 0;
int i_id = 0;
int i_color;
+ /* SPU size */
+ int i_width = p_spu->i_width;
+ int i_height = p_spu->i_height;
+
+ /* Drawing coordinates inside the SPU */
+ int i_x = 0, i_y = 0;
+
/* FIXME: we need a way to get this information from the stream */
#define TARGET_WIDTH 720
#define TARGET_HEIGHT 576
- int i_x_scale = ( p_buffer->i_pic_width << 6 ) / TARGET_WIDTH;
- int i_y_scale = ( p_buffer->i_pic_height << 6 ) / TARGET_HEIGHT;
+ int i_xscale = ( p_buffer->i_pic_width << 6 ) / TARGET_WIDTH;
+ int i_yscale = ( p_buffer->i_pic_height << 6 ) / TARGET_HEIGHT;
- /* FIXME: fake palette - the real one has to be sought in the .IFO */
- static int p_palette[4] = { 0x0000, 0xffff, 0x5555, 0x8888 };
+ u8 *p_source = p_spu->p_data;
+ u8 *p_dest;
+ int pi_index[2];
- boolean_t b_aligned = 1;
- byte_t *p_from[2];
- vout_spu_t vspu;
+ pi_index[0] = ( p_spu->type.spu.i_offset[0] - 2 ) << 1;
+ pi_index[1] = ( p_spu->type.spu.i_offset[1] - 2 ) << 1;
- p_from[1] = p_subpic->p_data + p_subpic->type.spu.i_offset[1];
- p_from[0] = p_subpic->p_data + p_subpic->type.spu.i_offset[0];
+ p_dest = p_buffer->p_data
+ /* add the picture coordinates and the SPU coordinates */
+ + ( p_buffer->i_pic_x + ((p_spu->i_x * i_xscale) >> 6))
+ * i_bytes_per_pixel
+ + ( p_buffer->i_pic_y + ((p_spu->i_y * i_yscale) >> 6))
+ * i_bytes_per_line;
- vspu.i_x = 0;
- vspu.i_y = 0;
- vspu.i_width = TARGET_WIDTH;
- vspu.i_height = TARGET_HEIGHT;
- vspu.p_data = p_buffer->p_data
- /* add the picture coordinates and the SPU coordinates */
- + ( p_buffer->i_pic_x + ((p_subpic->i_x * i_x_scale) >> 6))
- * i_bytes_per_pixel
- + ( p_buffer->i_pic_y + ((p_subpic->i_y * i_y_scale) >> 6))
- * i_bytes_per_line;
-
- /* Do we need scaling ?
- * This is mostly dupliucate code except a few lines.
- * This test was put out of the loop to avoid testing it
- * each time.
- */
- if ( i_y_scale >= (1 << 6) )
+ while( pi_index[0] >> 1 < p_spu->type.spu.i_offset[1] )
{
- while( p_from[0] < (byte_t *)p_subpic->p_data
- + p_subpic->type.spu.i_offset[1] )
+ i_code = GetNibble( p_source, pi_index + i_id );
+
+ if( i_code >= 0x04 )
{
- GET_NIBBLE( i_code );
-
- if( i_code >= 0x04 )
- {
- found_code_with_scale:
-
- if( ((i_code >> 2) + vspu.i_x + vspu.i_y * vspu.i_width)
- > vspu.i_height * vspu.i_width )
- {
- intf_DbgMsg ( "video_spu: invalid draw request ! %d %d",
- i_code >> 2, vspu.i_height * vspu.i_width
- - ( (i_code >> 2) + vspu.i_x
- + vspu.i_y * vspu.i_width ) );
- return;
- }
- else
- {
- if( (i_color = i_code & 0x3) )
- {
- u8 *p_target = &vspu.p_data[
- i_bytes_per_pixel * ((vspu.i_x * i_x_scale) >> 6)
- + i_bytes_per_line * ((vspu.i_y * i_y_scale) >> 6) ];
-
- memset( p_target, p_palette[i_color],
- ((((i_code - 1) * i_x_scale) >> 8) + 1)
- * i_bytes_per_pixel );
-
- /* here we need some horizontal scaling (unlikely )
- * we only scale up to 2x, someone watching a DVD
- * with more than 2x zoom must be braindead */
- p_target += i_bytes_per_line;
-
- memset( p_target, p_palette[i_color],
- ((((i_code - 1) * i_x_scale) >> 8) + 1)
- * i_bytes_per_pixel );
- }
- vspu.i_x += i_code >> 2;
- }
-
- if( vspu.i_x >= vspu.i_width )
- {
- /* byte-align the stream */
- b_aligned = 1;
- /* finish the line */
- NewLine( &vspu, &i_id );
- }
- continue;
- }
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x10 ) /* 00 11 xx cc */
- goto found_code_with_scale; /* 00 01 xx cc */
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x040 ) /* 00 00 11 xx xx cc */
- goto found_code_with_scale; /* 00 00 01 xx xx cc */
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x0100 ) /* 00 00 00 11 xx xx xx cc */
- goto found_code_with_scale; /* 00 00 00 01 xx xx xx cc */
-
- /* if the 14 first bits are 0, then it's a newline */
- if( i_code <= 0x0003 )
+ found_code:
+
+ if( ((i_code >> 2) + i_x + i_y * i_width) > i_height * i_width )
{
- if( NewLine( &vspu, &i_id ) < 0 )
- return;
-
- if( !b_aligned )
- b_aligned = 1;
+ intf_DbgMsg ( "video_spu: invalid draw request ! %d %d",
+ i_code >> 2, i_height * i_width
+ - ( (i_code >> 2) + i_x + i_y * i_width ) );
+ return;
}
else
{
- /* we have a boo boo ! */
- intf_DbgMsg( "video_spu: unknown code 0x%x "
- "(dest %x side %x, x=%d, y=%d)",
- i_code, p_from[i_id], i_id, vspu.i_x, vspu.i_y );
- if( NewLine( &vspu, &i_id ) < 0 )
- return;
- continue;
- }
- }
- }
- else
- {
- while( p_from[0] < (byte_t *)p_subpic->p_data
- + p_subpic->type.spu.i_offset[1] )
- {
- GET_NIBBLE( i_code );
-
- if( i_code >= 0x04 )
- {
- found_code:
-
- if( ((i_code >> 2) + vspu.i_x + vspu.i_y * vspu.i_width)
- > vspu.i_height * vspu.i_width )
+ if( (i_color = i_code & 0x3) )
{
- intf_DbgMsg ( "video_spu: invalid draw request ! %d %d",
- i_code >> 2, vspu.i_height * vspu.i_width
- - ( (i_code >> 2) + vspu.i_x
- + vspu.i_y * vspu.i_width ) );
- return;
+ u8 *p_target = p_dest
+ + i_bytes_per_pixel * ((i_x * i_xscale) >> 6)
+ + i_bytes_per_line * ((i_y * i_yscale) >> 6);
+
+ memset( p_target, p_palette[i_color],
+ ((((i_code >> 2) * i_xscale) >> 6) + 1)
+ * i_bytes_per_pixel );
}
- else
+ i_x += i_code >> 2;
+ }
+
+ if( i_x >= i_width )
+ {
+ /* byte-align the stream */
+ if( pi_index[i_id] & 0x1 )
{
- if( (i_color = i_code & 0x3) )
- {
- u8 *p_target = &vspu.p_data[
- i_bytes_per_pixel * ((vspu.i_x * i_x_scale) >> 6)
- + i_bytes_per_line * ((vspu.i_y * i_y_scale) >> 6) ];
-
- memset( p_target, p_palette[i_color],
- ((((i_code - 1) * i_x_scale) >> 8) + 1)
- * i_bytes_per_pixel );
- }
- vspu.i_x += i_code >> 2;
+ pi_index[i_id]++;
}
-
- if( vspu.i_x >= vspu.i_width )
+
+ i_id = ~i_id & 0x1;
+
+ i_y++;
+ i_x = 0;
+
+ if( i_width <= i_y )
{
- /* byte-align the stream */
- b_aligned = 1;
- /* finish the line */
- NewLine( &vspu, &i_id );
+ return;
}
- continue;
}
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x10 ) /* 00 11 xx cc */
- goto found_code; /* 00 01 xx cc */
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x040 ) /* 00 00 11 xx xx cc */
- goto found_code; /* 00 00 01 xx xx cc */
-
- ADD_NIBBLE( i_code, (i_code << 4) );
- if( i_code >= 0x0100 ) /* 00 00 00 11 xx xx xx cc */
- goto found_code; /* 00 00 00 01 xx xx xx cc */
-
- /* if the 14 first bits are 0, then it's a newline */
- if( i_code <= 0x0003 )
+ continue;
+ }
+
+ i_code = ( i_code << 4 ) + GetNibble( p_source, pi_index + i_id );
+
+ if( i_code >= 0x10 ) /* 00 11 xx cc */
+ {
+ goto found_code; /* 00 01 xx cc */
+ }
+
+ i_code = ( i_code << 4 ) + GetNibble( p_source, pi_index + i_id );
+ if( i_code >= 0x040 ) /* 00 00 11 xx xx cc */
+ {
+ goto found_code; /* 00 00 01 xx xx cc */
+ }
+
+ i_code = ( i_code << 4 ) + GetNibble( p_source, pi_index + i_id );
+ if( i_code >= 0x0100 ) /* 00 00 00 11 xx xx xx cc */
+ {
+ goto found_code; /* 00 00 00 01 xx xx xx cc */
+ }
+
+ if( i_code & ~0x0003 )
+ {
+ /* we have a boo boo ! */
+ intf_ErrMsg( "video_spu: unknown code 0x%x "
+ "(dest %x side %x, x=%d, y=%d)",
+ i_code, p_source, i_id, i_x, i_y );
+ return;
+ }
+ else
+ {
+ /* if the 14 first bits are 0, then it's a new line */
+ if( pi_index[i_id] & 0x1 )
{
- if( NewLine( &vspu, &i_id ) < 0 )
- return;
-
- if( !b_aligned )
- b_aligned = 1;
+ pi_index[i_id]++;
}
- else
+
+ i_id = ~i_id & 0x1;
+
+ i_y++;
+ i_x = 0;
+
+ if( i_width <= i_y )
{
- /* we have a boo boo ! */
- intf_DbgMsg( "video_spu: unknown code 0x%x "
- "(dest %x side %x, x=%d, y=%d)",
- i_code, p_from[i_id], i_id, vspu.i_x, vspu.i_y );
- if( NewLine( &vspu, &i_id ) < 0 )
- return;
- continue;
+ return;
}
}
}
}
-static int NewLine( vout_spu_t *p_vspu, int *i_id )
-{
- *i_id = 1 - *i_id;
-
- p_vspu->i_x = 0;
- p_vspu->i_y++;
-
- return( p_vspu->i_width - p_vspu->i_y );
-
-}
-
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ * Henri Fallon <henri@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
+ * Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
+ * Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Vincent Seguin <seguin@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by