Commit 88a15495 authored by Stéphane Borel's avatar Stéphane Borel

New features for libdvdcss: we have three ways now to decode a title key.

1) Crack the title key (the method that was here before). The only change
here is that we search the key for the exact chapter we are seeking with
DVDSetArea (in case the key has changed within a title). It is maybe not a
good idea.

2) Crack the disc key, which allows us to decode instantly all title keys.
I've used an algorithm from Frank Stevenson ; it eats much memory (64MB),
and takes about 15 s at launch time.

3) Decode the disc key with player keys (libcss method). However, you need
licensed player keys at build time for that to work.

To choose between libdvdcss methods, a command line options is supplied:

        vlc --dvdcss <method> where method is one of title, disc, key.

Note that all these changes only work with linux now, since we have to add a
specific ioctl to read title key. I hope that I haven't broken too many things.
parent 563c5e17
This diff is collapsed.
...@@ -18,6 +18,9 @@ if test -r extras/libdvdcss/libdvdcss.c; then ...@@ -18,6 +18,9 @@ if test -r extras/libdvdcss/libdvdcss.c; then
HAVE_LIBDVDCSS=1 HAVE_LIBDVDCSS=1
LIBDVDCSS_VERSION=0.0.3 LIBDVDCSS_VERSION=0.0.3
AC_SUBST(LIBDVDCSS_VERSION) AC_SUBST(LIBDVDCSS_VERSION)
if test -r extras/libdvdcss/csskeys.h; then
AC_DEFINE(HAVE_CSSKEYS,1,css decryption with player keys)
fi
fi fi
dnl Save CFLAGS and LDFLAGS dnl Save CFLAGS and LDFLAGS
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* css.h: Structures for DVD authentification and unscrambling * css.h: Structures for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: css.h,v 1.5 2001/07/25 00:23:40 sam Exp $ * $Id: css.h,v 1.6 2001/10/13 15:34:21 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -37,6 +37,7 @@ typedef struct disc_s ...@@ -37,6 +37,7 @@ typedef struct disc_s
dvd_key_t p_key2; dvd_key_t p_key2;
dvd_key_t p_key_check; dvd_key_t p_key_check;
u8 i_varient; u8 i_varient;
u8 p_disc_key[2048];
} disc_t; } disc_t;
typedef struct dvd_title_s typedef struct dvd_title_s
...@@ -50,7 +51,7 @@ typedef struct css_s ...@@ -50,7 +51,7 @@ typedef struct css_s
{ {
int i_agid; int i_agid;
disc_t disc; disc_t disc;
u8 p_disc_key[2048]; dvd_key_t p_title_key;
} css_t; } css_t;
/***************************************************************************** /*****************************************************************************
...@@ -59,7 +60,8 @@ typedef struct css_s ...@@ -59,7 +60,8 @@ typedef struct css_s
struct css_s; struct css_s;
int CSSTest ( dvdcss_handle ); int CSSTest ( dvdcss_handle );
int CSSInit ( dvdcss_handle ); int CSSAuth ( dvdcss_handle );
int CSSGetKey ( dvdcss_handle, int, dvd_key_t ); int CSSGetDiscKey ( dvdcss_handle );
int CSSGetTitleKey ( dvdcss_handle, int );
int CSSDescrambleSector ( u8 * , u8 * ); int CSSDescrambleSector ( u8 * , u8 * );
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* csstables.h: CSS Tables for DVD unscrambling * csstables.h: CSS Tables for DVD unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: csstables.h,v 1.2 2001/07/11 02:01:03 sam Exp $ * $Id: csstables.h,v 1.3 2001/10/13 15:34:21 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
static u8 p_css_tab1[ 256 ] = static u8 p_css_tab1[ 256 ] =
{ {
0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ioctl.c: DVD ioctl replacement function * ioctl.c: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ioctl.c,v 1.12 2001/09/28 15:24:11 massiot Exp $ * $Id: ioctl.c,v 1.13 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Markus Kuespert <ltlBeBoy@beosmail.com> * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
*****************************************************************************/ *****************************************************************************/
#include "defs.h" #include "defs.h"
#include <stdio.h>
#include <string.h> /* memcpy(), memset() */ #include <string.h> /* memcpy(), memset() */
#include <sys/types.h> #include <sys/types.h>
...@@ -77,6 +79,7 @@ ...@@ -77,6 +79,7 @@
#include "ioctl.h" #include "ioctl.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes, BeOS specific * Local prototypes, BeOS specific
*****************************************************************************/ *****************************************************************************/
...@@ -234,9 +237,9 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ) ...@@ -234,9 +237,9 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
} }
/***************************************************************************** /*****************************************************************************
* ioctl_ReadKey: get the disc key * ioctl_ReadDiscKey: get the disc key
*****************************************************************************/ *****************************************************************************/
int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) int ioctl_ReadDiscKey( int i_fd, int *pi_agid, u8 *p_key )
{ {
int i_ret; int i_ret;
...@@ -316,7 +319,6 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -316,7 +319,6 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
dvd.grantID = *pi_agid; dvd.grantID = *pi_agid;
i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd ); i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );
memcpy( p_key, dvddki.discKeyStructures, 2048 ); memcpy( p_key, dvddki.discKeyStructures, 2048 );
#elif defined( WIN32 ) #elif defined( WIN32 )
...@@ -368,6 +370,57 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -368,6 +370,57 @@ int ioctl_ReadKey( int i_fd, int *pi_agid, u8 *p_key )
return i_ret; return i_ret;
} }
/*****************************************************************************
* ioctl_ReadTitleKey: get the title key
*****************************************************************************/
int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo dvd_ai;
memset( &dvd_ai, 0, sizeof(dvd_ai) );
dvd_ai.type = DVD_LU_SEND_TITLE_KEY;
dvd_ai.lstk.agid = *pi_agid;
dvd_ai.lstk.lba = i_pos;
i_ret = ioctl( i_fd, DVD_AUTH, &dvd_ai );
if( i_ret < 0 )
{
return i_ret;
}
memcpy( p_key, dvd_ai.lstk.title_key, 5 );
#elif defined( HAVE_BSD_DVD_STRUCT )
i_ret = -1;
#elif defined( SYS_BEOS )
i_ret = -1;
#elif defined( SOLARIS_USCSI )
i_ret = -1;
#elif defined( SYS_DARWIN )
i_ret = 0;
memset( p_key, 0x00, KEY_SIZE );
#elif defined( WIN32 )
i_ret = -1;
#else
i_ret = -1;
#endif
return i_ret;
}
/***************************************************************************** /*****************************************************************************
* ioctl_ReportAgid: get AGID from the drive * ioctl_ReportAgid: get AGID from the drive
*****************************************************************************/ *****************************************************************************/
...@@ -745,14 +798,12 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key ) ...@@ -745,14 +798,12 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
memset(&dvd, 0, sizeof(dvd)); memset(&dvd, 0, sizeof(dvd));
memset(&dvdk1i, 0, sizeof(dvdk1i)); memset(&dvdk1i, 0, sizeof(dvdk1i));
dvd.buffer = &dvdk1i; dvd.buffer = &dvdk1i;
dvd.bufferLength = sizeof(dvdk1i); dvd.bufferLength = sizeof(dvdk1i);
dvd.format = kDVDKeyFormatKey1; dvd.format = kDVDKeyFormatKey1;
dvd.grantID = *pi_agid; dvd.grantID = *pi_agid;
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd ); i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
memcpy( p_key, dvdk1i.key1Value, 5 ); memcpy( p_key, dvdk1i.key1Value, 5 );
#elif defined( WIN32 ) #elif defined( WIN32 )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ioctl.h: DVD ioctl replacement function * ioctl.h: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ioctl.h,v 1.6 2001/08/08 02:48:44 sam Exp $ * $Id: ioctl.h,v 1.7 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
*****************************************************************************/ *****************************************************************************/
int ioctl_ReadCopyright ( int, int, int * ); int ioctl_ReadCopyright ( int, int, int * );
int ioctl_ReadKey ( int, int *, u8 * ); int ioctl_ReadDiscKey ( int, int *, u8 * );
int ioctl_ReadTitleKey ( int, int *, int, u8 * );
int ioctl_ReportAgid ( int, int * ); int ioctl_ReportAgid ( int, int * );
int ioctl_ReportChallenge ( int, int *, u8 * ); int ioctl_ReportChallenge ( int, int *, u8 * );
int ioctl_ReportKey1 ( int, int *, u8 * ); int ioctl_ReportKey1 ( int, int *, u8 * );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libdvdcss.c: DVD reading library. * libdvdcss.c: DVD reading library.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.c,v 1.15 2001/09/09 13:43:25 sam Exp $ * $Id: libdvdcss.c,v 1.16 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -80,7 +80,7 @@ static int _win32_dvdcss_aread ( int i_fd, void *p_data, int i_blocks ); ...@@ -80,7 +80,7 @@ static int _win32_dvdcss_aread ( int i_fd, void *p_data, int i_blocks );
/***************************************************************************** /*****************************************************************************
* dvdcss_open: initialize library, open a DVD device, crack CSS key * dvdcss_open: initialize library, open a DVD device, crack CSS key
*****************************************************************************/ *****************************************************************************/
extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) extern dvdcss_handle dvdcss_open ( char *psz_target, int i_method, int i_flags )
{ {
int i_ret; int i_ret;
...@@ -102,6 +102,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) ...@@ -102,6 +102,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags )
dvdcss->p_titles = NULL; dvdcss->p_titles = NULL;
dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG; dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG;
dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET); dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET);
dvdcss->i_method = i_method;
dvdcss->psz_error = "no error"; dvdcss->psz_error = "no error";
i_ret = _dvdcss_open( dvdcss, psz_target ); i_ret = _dvdcss_open( dvdcss, psz_target );
...@@ -128,7 +129,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags ) ...@@ -128,7 +129,7 @@ extern dvdcss_handle dvdcss_open ( char *psz_target, int i_flags )
/* If disc is CSS protected and the ioctls work, authenticate the drive */ /* If disc is CSS protected and the ioctls work, authenticate the drive */
if( dvdcss->b_encrypted && dvdcss->b_ioctls ) if( dvdcss->b_encrypted && dvdcss->b_ioctls )
{ {
i_ret = CSSInit( dvdcss ); i_ret = CSSGetDiscKey( dvdcss );
if( i_ret < 0 ) if( i_ret < 0 )
{ {
...@@ -152,27 +153,36 @@ extern char * dvdcss_error ( dvdcss_handle dvdcss ) ...@@ -152,27 +153,36 @@ extern char * dvdcss_error ( dvdcss_handle dvdcss )
/***************************************************************************** /*****************************************************************************
* dvdcss_seek: seek into the device * dvdcss_seek: seek into the device
*****************************************************************************/ *****************************************************************************/
extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks ) extern int dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks, int i_flags )
{ {
/* title cracking method is too slow to be used at each seek */
if( ( ( i_flags & DVDCSS_SEEK_MPEG ) && ( dvdcss->i_method != DVDCSS_TITLE ) )
|| ( i_flags & DVDCSS_SEEK_INI ) )
{
/* check the title key */
dvdcss_title( dvdcss, i_blocks );
}
return _dvdcss_seek( dvdcss, i_blocks ); return _dvdcss_seek( dvdcss, i_blocks );
} }
/***************************************************************************** /*****************************************************************************
* dvdcss_title: crack the current title key if needed * dvdcss_title: crack or decrypt the current title key if needed
*****************************************************************************
* This function should only be called by dvdcss_seek and should eventually
* not be external if possible.
*****************************************************************************/ *****************************************************************************/
extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block ) extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block )
{ {
dvd_title_t *p_title; dvd_title_t *p_title;
dvd_key_t p_key; dvd_title_t *p_newtitle;
int i_ret; int i_ret;
if( ! dvdcss->b_encrypted ) if( ! dvdcss->b_encrypted )
{ {
return 0; return 0;
} }
//fprintf( stderr, "looking for a key for offset %i\n", i_block );
/* Check if we've already cracked this key */ /* Check if we've already cracked this key */
p_title = dvdcss->p_titles; p_title = dvdcss->p_titles;
while( p_title != NULL while( p_title != NULL
...@@ -186,11 +196,12 @@ extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block ) ...@@ -186,11 +196,12 @@ extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block )
&& p_title->i_startlb == i_block ) && p_title->i_startlb == i_block )
{ {
/* We've already cracked this key, nothing to do */ /* We've already cracked this key, nothing to do */
memcpy( dvdcss->css.p_title_key, p_title->p_key, sizeof(dvd_key_t) );
return 0; return 0;
} }
/* Crack CSS title key for current VTS */ /* Crack or decrypt CSS title key for current VTS */
i_ret = CSSGetKey( dvdcss, i_block, p_key ); i_ret = CSSGetTitleKey( dvdcss, i_block );
if( i_ret < 0 ) if( i_ret < 0 )
{ {
...@@ -203,49 +214,39 @@ extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block ) ...@@ -203,49 +214,39 @@ extern int dvdcss_title ( dvdcss_handle dvdcss, int i_block )
return -1; return -1;
} }
//fprintf( stderr, "cracked key is %.2x %.2x %.2x %.2x %.2x\n", /* Find our spot in the list */
// p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] ); p_newtitle = NULL;
p_title = dvdcss->p_titles;
/* Add key to keytable if it isn't empty */ while( ( p_title != NULL ) && ( p_title->i_startlb < i_block ) )
/* We need to cache the fact that a title is unencrypted
if( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] ) */
{ {
dvd_title_t *p_newtitle; p_newtitle = p_title;
p_title = p_title->p_next;
/* Find our spot in the list */ }
p_newtitle = NULL;
p_title = dvdcss->p_titles;
while( p_title != NULL
&& p_title->i_startlb < i_block )
{
p_newtitle = p_title;
p_title = p_title->p_next;
}
/* Save the found title */ /* Save the found title */
p_title = p_newtitle; p_title = p_newtitle;
/* Write in the new title and its key */ /* Write in the new title and its key */
p_newtitle = malloc( sizeof( dvd_title_t ) ); p_newtitle = malloc( sizeof( dvd_title_t ) );
p_newtitle->i_startlb = i_block; p_newtitle->i_startlb = i_block;
memcpy( p_newtitle->p_key, p_key, KEY_SIZE ); memcpy( p_newtitle->p_key, dvdcss->css.p_title_key, KEY_SIZE );
/* Link the new title, either at the beginning or inside the list */ /* Link the new title, either at the beginning or inside the list */
if( p_title == NULL ) if( p_title == NULL )
{ {
dvdcss->p_titles = p_newtitle; dvdcss->p_titles = p_newtitle;
p_newtitle->p_next = NULL; p_newtitle->p_next = NULL;
} }
else else
{ {
p_newtitle->p_next = p_title->p_next; p_newtitle->p_next = p_title->p_next;
p_title->p_next = p_newtitle; p_title->p_next = p_newtitle;
}
} }
return 0; return 0;
} }
#define Pkey dvdcss->css.p_title_key
/***************************************************************************** /*****************************************************************************
* dvdcss_read: read data from the device, decrypt if requested * dvdcss_read: read data from the device, decrypt if requested
*****************************************************************************/ *****************************************************************************/
...@@ -253,7 +254,6 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -253,7 +254,6 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
int i_blocks, int i_blocks,
int i_flags ) int i_flags )
{ {
dvd_title_t *p_title;
int i_ret, i_index; int i_ret, i_index;
i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks ); i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks );
...@@ -265,25 +265,9 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -265,25 +265,9 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
return i_ret; return i_ret;
} }
/* find our key */
p_title = dvdcss->p_titles;
while( p_title != NULL
&& p_title->p_next
&& p_title->p_next->i_startlb <= dvdcss->i_seekpos )
{
p_title = p_title->p_next;
}
if( p_title == NULL )
{
/* no css key found to use, so no decryption to do */
return 0;
}
/* For what we believe is an unencrypted title, /* For what we believe is an unencrypted title,
check that there are no encrypted blocks */ check that there are no encrypted blocks */
if( !( p_title->p_key[0] | p_title->p_key[1] | p_title->p_key[2] | if( !( Pkey[0] | Pkey[1] | Pkey[2] | Pkey[3] | Pkey[4] ) )
p_title->p_key[3] | p_title->p_key[4] ) )
{ {
for( i_index = i_ret; i_index; i_index-- ) for( i_index = i_ret; i_index; i_index-- )
{ {
...@@ -301,7 +285,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -301,7 +285,7 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
/* Decrypt the blocks we managed to read */ /* Decrypt the blocks we managed to read */
for( i_index = i_ret; i_index; i_index-- ) for( i_index = i_ret; i_index; i_index-- )
{ {
CSSDescrambleSector( p_title->p_key, p_buffer ); CSSDescrambleSector( dvdcss->css.p_title_key, p_buffer );
((u8*)p_buffer)[0x14] &= 0x8f; ((u8*)p_buffer)[0x14] &= 0x8f;
(u8*)p_buffer += DVDCSS_BLOCK_SIZE; (u8*)p_buffer += DVDCSS_BLOCK_SIZE;
} }
...@@ -310,14 +294,13 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, ...@@ -310,14 +294,13 @@ extern int dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer,
} }
/***************************************************************************** /*****************************************************************************
* dvdcss_readv: read data to an iovec structure, decrypt if reaquested * dvdcss_readv: read data to an iovec structure, decrypt if requested
*****************************************************************************/ *****************************************************************************/
extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
int i_blocks, int i_blocks,
int i_flags ) int i_flags )
{ {
#define P_IOVEC ((struct iovec*)p_iovec) #define P_IOVEC ((struct iovec*)p_iovec)
dvd_title_t *p_title;
int i_ret, i_index; int i_ret, i_index;
void *iov_base; void *iov_base;
size_t iov_len; size_t iov_len;
...@@ -331,20 +314,6 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -331,20 +314,6 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
return i_ret; return i_ret;
} }
/* Find our key */
p_title = dvdcss->p_titles;
while( p_title != NULL
&& p_title->p_next != NULL
&& p_title->p_next->i_startlb <= dvdcss->i_seekpos )
{
p_title = p_title->p_next;
}
if( p_title == NULL )
{
/* no css key found to use, so no decryption to do */
return 0;
}
/* Initialize loop for decryption */ /* Initialize loop for decryption */
iov_base = P_IOVEC->iov_base; iov_base = P_IOVEC->iov_base;
...@@ -366,7 +335,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -366,7 +335,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
iov_len = P_IOVEC->iov_len; iov_len = P_IOVEC->iov_len;
} }
CSSDescrambleSector( p_title->p_key, iov_base ); CSSDescrambleSector( dvdcss->css.p_title_key, iov_base );
((u8*)iov_base)[0x14] &= 0x8f; ((u8*)iov_base)[0x14] &= 0x8f;
(u8*)iov_base += DVDCSS_BLOCK_SIZE; (u8*)iov_base += DVDCSS_BLOCK_SIZE;
...@@ -376,6 +345,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec, ...@@ -376,6 +345,7 @@ extern int dvdcss_readv ( dvdcss_handle dvdcss, void *p_iovec,
return i_ret; return i_ret;
#undef P_IOVEC #undef P_IOVEC
} }
#undef Pkey
/***************************************************************************** /*****************************************************************************
* dvdcss_close: close the DVD device and clean up the library * dvdcss_close: close the DVD device and clean up the library
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* private.h: private DVD reading library data * private.h: private DVD reading library data
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.h,v 1.7 2001/09/09 13:43:25 sam Exp $ * $Id: libdvdcss.h,v 1.8 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -37,6 +37,7 @@ struct dvdcss_s ...@@ -37,6 +37,7 @@ struct dvdcss_s
int i_seekpos; int i_seekpos;
/* Decryption stuff */ /* Decryption stuff */
int i_method;
css_t css; css_t css;
boolean_t b_ioctls; boolean_t b_ioctls;
boolean_t b_encrypted; boolean_t b_encrypted;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libdvdcss.h: DVD reading library, exported functions. * libdvdcss.h: DVD reading library, exported functions.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvdcss.h,v 1.5 2001/07/27 14:43:30 sam Exp $ * $Id: dvdcss.h,v 1.6 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -37,18 +37,30 @@ typedef struct dvdcss_s* dvdcss_handle; ...@@ -37,18 +37,30 @@ typedef struct dvdcss_s* dvdcss_handle;
#define DVDCSS_READ_DECRYPT (1 << 0) #define DVDCSS_READ_DECRYPT (1 << 0)
#define DVDCSS_SEEK_INI (1 << 0)
#define DVDCSS_SEEK_MPEG (2 << 0)
#define DVDCSS_BLOCK_SIZE 2048 #define DVDCSS_BLOCK_SIZE 2048
/*****************************************************************************
* libdvdcss method: used like init flags
*****************************************************************************/
#define DVDCSS_KEY 0
#define DVDCSS_DISC 1
#define DVDCSS_TITLE 2
/***************************************************************************** /*****************************************************************************
* Exported prototypes * Exported prototypes
*****************************************************************************/ *****************************************************************************/
extern dvdcss_handle dvdcss_open ( char *psz_target, extern dvdcss_handle dvdcss_open ( char *psz_target,
int i_method,
int i_flags ); int i_flags );
extern int dvdcss_close ( dvdcss_handle ); extern int dvdcss_close ( dvdcss_handle );
extern int dvdcss_title ( dvdcss_handle, extern int dvdcss_title ( dvdcss_handle,
int i_block ); int i_block );
extern int dvdcss_seek ( dvdcss_handle, extern int dvdcss_seek ( dvdcss_handle,
int i_blocks ); int i_blocks,
int i_flags );
extern int dvdcss_read ( dvdcss_handle, extern int dvdcss_read ( dvdcss_handle,
void *p_buffer, void *p_buffer,
int i_blocks, int i_blocks,
......
...@@ -220,6 +220,8 @@ ...@@ -220,6 +220,8 @@
#define INPUT_AUDIO_VAR "vlc_input_audio" #define INPUT_AUDIO_VAR "vlc_input_audio"
#define INPUT_CHANNEL_VAR "vlc_input_channel" #define INPUT_CHANNEL_VAR "vlc_input_channel"
#define INPUT_SUBTITLE_VAR "vlc_input_subtitle" #define INPUT_SUBTITLE_VAR "vlc_input_subtitle"
#define INPUT_DVDCSS_VAR "vlc_input_dvdcss"
#define INPUT_DVDCSS_DEFAULT "title"
/* VCD defaults */ /* VCD defaults */
#define INPUT_VCD_DEVICE_VAR "vlc_vcd_device" #define INPUT_VCD_DEVICE_VAR "vlc_vcd_device"
......
...@@ -172,6 +172,9 @@ ...@@ -172,6 +172,9 @@
/* Define if you have the pth library (-lpth). */ /* Define if you have the pth library (-lpth). */
#undef HAVE_LIBPTH #undef HAVE_LIBPTH
/* css decryption with player keys */
#undef HAVE_CSSKEYS
/* long getopt support */ /* long getopt support */
#undef HAVE_GETOPT_LONG #undef HAVE_GETOPT_LONG
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing * dvd_ifo.c: Functions for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.37 2001/08/09 20:16:17 jlj Exp $ * $Id: dvd_ifo.c,v 1.38 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* German Tischler <tanis@gaspode.franken.de> * German Tischler <tanis@gaspode.franken.de>
...@@ -1047,7 +1047,8 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, int i_block, int i_bytes ...@@ -1047,7 +1047,8 @@ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, int i_block, int i_bytes
if( p_title->i_chapter_map_start_byte ) if( p_title->i_chapter_map_start_byte )
{ {
p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle, p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle,
OFF2LB( i_start + p_title->i_chapter_map_start_byte ) ); OFF2LB( i_start + p_title->i_chapter_map_start_byte ),
DVDCSS_NOFLAGS );
p_title->chapter_map.pi_start_cell = p_title->chapter_map.pi_start_cell =
malloc( p_title->i_chapter_nb * sizeof(chapter_map_t) ); malloc( p_title->i_chapter_nb * sizeof(chapter_map_t) );
...@@ -2098,7 +2099,7 @@ void CommandPrint( ifo_t ifo ) ...@@ -2098,7 +2099,7 @@ void CommandPrint( ifo_t ifo )
*****************************************************************************/ *****************************************************************************/
static u8* FillBuffer( ifo_t* p_ifo, u8* p_buf, int i_pos ) static u8* FillBuffer( ifo_t* p_ifo, u8* p_buf, int i_pos )
{ {
p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle, i_pos ); p_ifo->i_pos = dvdcss_seek( p_ifo->dvdhandle, i_pos, DVDCSS_NOFLAGS );
dvdcss_read( p_ifo->dvdhandle, p_buf, 1, DVDCSS_NOFLAGS ); dvdcss_read( p_ifo->dvdhandle, p_buf, 1, DVDCSS_NOFLAGS );
return p_buf; return p_buf;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* contains the basic udf handling functions * contains the basic udf handling functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_udf.c,v 1.13 2001/08/06 13:28:00 sam Exp $ * $Id: dvd_udf.c,v 1.14 2001/10/13 15:34:21 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -109,7 +109,7 @@ typedef struct ad_s ...@@ -109,7 +109,7 @@ typedef struct ad_s
static int UDFReadLB( dvdcss_handle dvdhandle, off_t i_lba, static int UDFReadLB( dvdcss_handle dvdhandle, off_t i_lba,
size_t i_block_count, u8 *pi_data ) size_t i_block_count, u8 *pi_data )
{ {
if( dvdcss_seek( dvdhandle, i_lba ) < 0 ) if( dvdcss_seek( dvdhandle, i_lba, DVDCSS_NOFLAGS ) < 0 )
{ {
intf_ErrMsg( "UDF: Postion not found" ); intf_ErrMsg( "UDF: Postion not found" );
return 0; return 0;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* -dvd_udf to find files * -dvd_udf to find files
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.87 2001/10/02 16:46:59 massiot Exp $ * $Id: input_dvd.c,v 1.88 2001/10/13 15:34:21 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -199,7 +199,7 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -199,7 +199,7 @@ static void DVDInit( input_thread_t * p_input )
p_dvd->dvdhandle = (dvdcss_handle) p_input->i_handle; p_dvd->dvdhandle = (dvdcss_handle) p_input->i_handle;
dvdcss_seek( p_dvd->dvdhandle, 0 ); dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS );
/* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive /* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
* DVD_DATA_READ_ONCE at most */ * DVD_DATA_READ_ONCE at most */
...@@ -306,6 +306,8 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -306,6 +306,8 @@ static void DVDInit( input_thread_t * p_input )
static void DVDOpen( struct input_thread_s *p_input ) static void DVDOpen( struct input_thread_s *p_input )
{ {
dvdcss_handle dvdhandle; dvdcss_handle dvdhandle;
char * psz_method;
int i_method;
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
...@@ -320,14 +322,33 @@ static void DVDOpen( struct input_thread_s *p_input ) ...@@ -320,14 +322,33 @@ static void DVDOpen( struct input_thread_s *p_input )
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/* XXX: put this shit in an access plugin */ /* XXX: put this shit in an access plugin */
psz_method = main_GetPszVariable( INPUT_DVDCSS_VAR,
INPUT_DVDCSS_DEFAULT );
if( !strncmp( psz_method, "key", 3 ) )
{
i_method = DVDCSS_KEY;
}
else if( !strncmp( psz_method, "disc", 4 ) )
{
i_method = DVDCSS_DISC;
}
else
{
i_method = DVDCSS_TITLE;
}
if( strlen( p_input->p_source ) > 4 if( strlen( p_input->p_source ) > 4
&& !strncasecmp( p_input->p_source, "dvd:", 4 ) ) && !strncasecmp( p_input->p_source, "dvd:", 4 ) )
{ {
dvdhandle = dvdcss_open( p_input->p_source + 4, DVDCSS_INIT_QUIET ); dvdhandle = dvdcss_open( p_input->p_source + 4,
i_method,
DVDCSS_INIT_QUIET );
} }
else else
{ {
dvdhandle = dvdcss_open( p_input->p_source, DVDCSS_INIT_QUIET ); dvdhandle = dvdcss_open( p_input->p_source,
i_method,
DVDCSS_INIT_QUIET );
} }
if( dvdhandle == NULL ) if( dvdhandle == NULL )
...@@ -429,11 +450,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -429,11 +450,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
intf_WarnMsgImm( 3, "dvd: title %d vts_title %d pgc %d", intf_WarnMsgImm( 3, "dvd: title %d vts_title %d pgc %d",
p_dvd->i_title, i_vts_title, p_dvd->i_title_id ); p_dvd->i_title, i_vts_title, p_dvd->i_title_id );
/*
* Tell libdvdcss we changed title
*/
dvdcss_title( p_dvd->dvdhandle,
vts.i_pos + vts.manager_inf.i_title_vob_start_sector );
/* /*
* Angle management * Angle management
...@@ -745,6 +761,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -745,6 +761,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
} }
} }
/*
* Force libdvdcss to check its title key.
* It is only useful for title cracking method. Methods using the decrypted
* disc key are fast enough to check the key at each seek
*/
dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_start, DVDCSS_SEEK_INI );
#define title \ #define title \
p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
if( p_area->i_angle != p_dvd->i_angle ) if( p_area->i_angle != p_dvd->i_angle )
...@@ -809,6 +832,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -809,6 +832,7 @@ static int DVDRead( input_thread_t * p_input,
i_sector = p_dvd->i_title_start + p_dvd->i_sector; i_sector = p_dvd->i_title_start + p_dvd->i_sector;
i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1; i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1;
/* Get the position of the next cell if we're at cell end */ /* Get the position of the next cell if we're at cell end */
if( i_block_once <= 0 ) if( i_block_once <= 0 )
{ {
...@@ -827,7 +851,8 @@ static int DVDRead( input_thread_t * p_input, ...@@ -827,7 +851,8 @@ static int DVDRead( input_thread_t * p_input,
/* Position the fd pointer on the right address */ /* Position the fd pointer on the right address */
i_sector = dvdcss_seek( p_dvd->dvdhandle, i_sector = dvdcss_seek( p_dvd->dvdhandle,
p_dvd->i_title_start + p_dvd->i_sector ); p_dvd->i_title_start + p_dvd->i_sector,
DVDCSS_SEEK_MPEG );
/* update chapter : it will be easier when we have navigation /* update chapter : it will be easier when we have navigation
* ES support */ * ES support */
...@@ -1079,8 +1104,9 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) ...@@ -1079,8 +1104,9 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
p_input->stream.p_selected_area->i_tell = p_input->stream.p_selected_area->i_tell =
LB2OFF ( dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_title_start LB2OFF ( dvdcss_seek( p_dvd->dvdhandle,
+ p_dvd->i_sector ) ) p_dvd->i_title_start + p_dvd->i_sector,
DVDCSS_SEEK_MPEG ) )
- p_input->stream.p_selected_area->i_start; - p_input->stream.p_selected_area->i_start;
intf_WarnMsg( 7, "Program Cell: %d Cell: %d Chapter: %d", intf_WarnMsg( 7, "Program Cell: %d Cell: %d Chapter: %d",
...@@ -1211,7 +1237,9 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) ...@@ -1211,7 +1237,9 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector; p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector;
/* Position the fd pointer on the right address */ /* Position the fd pointer on the right address */
p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_start ); p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle,
p_dvd->i_start,
DVDCSS_SEEK_MPEG );
p_dvd->i_chapter = i_chapter; p_dvd->i_chapter = i_chapter;
return 0; return 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_spdif: ac3 passthrough output * aout_spdif: ac3 passthrough output
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: aout_spdif.c,v 1.16 2001/09/30 00:33:22 stef Exp $ * $Id: aout_spdif.c,v 1.17 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -118,7 +118,7 @@ void aout_SpdifThread( aout_thread_t * p_aout ) ...@@ -118,7 +118,7 @@ void aout_SpdifThread( aout_thread_t * p_aout )
} }
else else
{ {
mwait( m_play - 4* m_frame_time ); mwait( m_play - 3* m_frame_time );
} }
m_old = m_play; m_old = m_play;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* and spawn threads. * and spawn threads.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: main.c,v 1.117 2001/10/03 15:10:55 sam Exp $ * $Id: main.c,v 1.118 2001/10/13 15:34:21 stef Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -129,6 +129,7 @@ ...@@ -129,6 +129,7 @@
#define OPT_YUV 183 #define OPT_YUV 183
#define OPT_DOWNMIX 184 #define OPT_DOWNMIX 184
#define OPT_IMDCT 185 #define OPT_IMDCT 185
#define OPT_DVDCSS 186
#define OPT_SYNCHRO 190 #define OPT_SYNCHRO 190
#define OPT_WARNING 191 #define OPT_WARNING 191
...@@ -199,6 +200,7 @@ static const struct option longopts[] = ...@@ -199,6 +200,7 @@ static const struct option longopts[] =
{ "dvdaudio", 1, 0, 'a' }, { "dvdaudio", 1, 0, 'a' },
{ "dvdchannel", 1, 0, 'c' }, { "dvdchannel", 1, 0, 'c' },
{ "dvdsubtitle", 1, 0, 's' }, { "dvdsubtitle", 1, 0, 's' },
{ "dvdcss_method", 1, 0, OPT_DVDCSS },
/* Input options */ /* Input options */
{ "input", 1, 0, OPT_INPUT }, { "input", 1, 0, OPT_INPUT },
...@@ -738,16 +740,16 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -738,16 +740,16 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
break; break;
/* DVD options */ /* DVD options */
case 't': case 't': /* --dvdtitle */
main_PutIntVariable( INPUT_TITLE_VAR, atoi(optarg) ); main_PutIntVariable( INPUT_TITLE_VAR, atoi(optarg) );
break; break;
case 'T': case 'T': /* --dvdchapter */
main_PutIntVariable( INPUT_CHAPTER_VAR, atoi(optarg) ); main_PutIntVariable( INPUT_CHAPTER_VAR, atoi(optarg) );
break; break;
case 'u': case 'u': /* --dvdangle */
main_PutIntVariable( INPUT_ANGLE_VAR, atoi(optarg) ); main_PutIntVariable( INPUT_ANGLE_VAR, atoi(optarg) );
break; break;
case 'a': case 'a': /* --dvdaudio */
if ( ! strcmp(optarg, "ac3") ) if ( ! strcmp(optarg, "ac3") )
main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_AC3 ); main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_AC3 );
else if ( ! strcmp(optarg, "lpcm") ) else if ( ! strcmp(optarg, "lpcm") )
...@@ -757,12 +759,15 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -757,12 +759,15 @@ static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
else else
main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_NOAUDIO ); main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_NOAUDIO );
break; break;
case 'c': case 'c': /* --dvdchannel */
main_PutIntVariable( INPUT_CHANNEL_VAR, atoi(optarg) ); main_PutIntVariable( INPUT_CHANNEL_VAR, atoi(optarg) );
break; break;
case 's': case 's': /* --dvdsubtitle */
main_PutIntVariable( INPUT_SUBTITLE_VAR, atoi(optarg) ); main_PutIntVariable( INPUT_SUBTITLE_VAR, atoi(optarg) );
break; break;
case OPT_DVDCSS: /* --dvdcss */
main_PutPszVariable( INPUT_DVDCSS_VAR, optarg );
break;
/* Input options */ /* Input options */
case OPT_INPUT: /* --input */ case OPT_INPUT: /* --input */
...@@ -888,6 +893,7 @@ static void Usage( int i_fashion ) ...@@ -888,6 +893,7 @@ static void Usage( int i_fashion )
"\n -a, --dvdaudio <type> \tchoose DVD audio type" "\n -a, --dvdaudio <type> \tchoose DVD audio type"
"\n -c, --dvdchannel <channel> \tchoose DVD audio channel" "\n -c, --dvdchannel <channel> \tchoose DVD audio channel"
"\n -s, --dvdsubtitle <channel> \tchoose DVD subtitle channel" "\n -s, --dvdsubtitle <channel> \tchoose DVD subtitle channel"
"\n , --dvdcss <method> \tselect DVDCSS decryption method"
"\n" "\n"
"\n --input \tinput method" "\n --input \tinput method"
"\n --channels \tenable channels" "\n --channels \tenable channels"
...@@ -917,7 +923,7 @@ static void Usage( int i_fashion ) ...@@ -917,7 +923,7 @@ static void Usage( int i_fashion )
"\n " AOUT_SPDIF_VAR "={1|0} \tAC3 pass-through mode" "\n " AOUT_SPDIF_VAR "={1|0} \tAC3 pass-through mode"
"\n " DOWNMIX_METHOD_VAR "=<method name> \tAC3 downmix method" "\n " DOWNMIX_METHOD_VAR "=<method name> \tAC3 downmix method"
"\n " IMDCT_METHOD_VAR "=<method name> \tAC3 IMDCT method" "\n " IMDCT_METHOD_VAR "=<method name> \tAC3 IMDCT method"
"\n " AOUT_RATE_VAR "=<rate> \toutput rate" ); "\n " AOUT_RATE_VAR "=<rate> \toutput rate" );
/* Video parameters */ /* Video parameters */
intf_MsgImm( "\nVideo parameters:" intf_MsgImm( "\nVideo parameters:"
...@@ -938,22 +944,23 @@ static void Usage( int i_fashion ) ...@@ -938,22 +944,23 @@ static void Usage( int i_fashion )
/* DVD parameters */ /* DVD parameters */
intf_MsgImm( "\nDVD parameters:" intf_MsgImm( "\nDVD parameters:"
"\n " INPUT_DVD_DEVICE_VAR "=<device> \tDVD device" "\n " INPUT_DVD_DEVICE_VAR "=<device> \tDVD device"
"\n " INPUT_TITLE_VAR "=<title> \ttitle number" "\n " INPUT_TITLE_VAR "=<title> \ttitle number"
"\n " INPUT_CHAPTER_VAR "=<chapter> \tchapter number" "\n " INPUT_CHAPTER_VAR "=<chapter> \tchapter number"
"\n " INPUT_ANGLE_VAR "=<angle> \tangle number" "\n " INPUT_ANGLE_VAR "=<angle> \tangle number"
"\n " INPUT_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type" "\n " INPUT_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type"
"\n " INPUT_CHANNEL_VAR "=[0-15] \taudio channel" "\n " INPUT_CHANNEL_VAR "=[0-15] \taudio channel"
"\n " INPUT_SUBTITLE_VAR "=[0-31] \tsubtitle channel" ); "\n " INPUT_SUBTITLE_VAR "=[0-31] \tsubtitle channel"
"\n " INPUT_DVDCSS_VAR "={csskey|disc|title} \tdvdcss method" );
/* Input parameters */ /* Input parameters */
intf_MsgImm( "\nInput parameters:" intf_MsgImm( "\nInput parameters:"
"\n " INPUT_SERVER_VAR "=<hostname> \tvideo server" "\n " INPUT_SERVER_VAR "=<hostname> \tvideo server"
"\n " INPUT_PORT_VAR "=<port> \tvideo server port" "\n " INPUT_PORT_VAR "=<port> \tvideo server port"
"\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface" "\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface"
"\n " INPUT_BCAST_ADDR_VAR "=<addr> \tbroadcast mode" "\n " INPUT_BCAST_ADDR_VAR "=<addr> \tbroadcast mode"
"\n " INPUT_CHANNEL_SERVER_VAR "=<hostname> \tchannel server" "\n " INPUT_CHANNEL_SERVER_VAR "=<hostname> \tchannel server"
"\n " INPUT_CHANNEL_PORT_VAR "=<port> \tchannel server port" ); "\n " INPUT_CHANNEL_PORT_VAR "=<port> \tchannel server port" );
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment