Commit dc0df7c2 authored by Stéphane Borel's avatar Stéphane Borel

-completely changed title and chapter initialization. Now we have real

title units.

-Fixed size for a majority of DVD.
parent 87dc702b
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_css.c: Functions for DVD authentification and unscrambling * dvd_css.c: Functions for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.c,v 1.16 2001/03/02 13:47:01 sam Exp $ * $Id: dvd_css.c,v 1.17 2001/03/03 07:07:01 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "defs.h" #include "defs.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -100,9 +101,9 @@ int CSSTest( int i_fd ) ...@@ -100,9 +101,9 @@ int CSSTest( int i_fd )
* Since we don't need the disc key to find the title key, we just run the * Since we don't need the disc key to find the title key, we just run the
* basic unavoidable commands to authenticate device and disc. * basic unavoidable commands to authenticate device and disc.
*****************************************************************************/ *****************************************************************************/
css_t CSSInit( int i_fd ) css_t * CSSInit( int i_fd )
{ {
css_t css; css_t * p_css;
#ifdef HAVE_CSS #ifdef HAVE_CSS
/* structures defined in cdrom.h or dvdio.h */ /* structures defined in cdrom.h or dvdio.h */
...@@ -112,8 +113,13 @@ css_t CSSInit( int i_fd ) ...@@ -112,8 +113,13 @@ css_t CSSInit( int i_fd )
int i_error = -1; int i_error = -1;
int i; int i;
css.i_fd = i_fd; p_css = malloc( sizeof(css_t) );
css.b_error = 0; if( p_css == NULL )
{
return NULL;
}
p_css->i_fd = i_fd;
memset( &auth_info, 0, sizeof(auth_info) ); memset( &auth_info, 0, sizeof(auth_info) );
...@@ -121,9 +127,10 @@ css_t CSSInit( int i_fd ) ...@@ -121,9 +127,10 @@ css_t CSSInit( int i_fd )
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( i_fd ) )
{ {
case -1: case -1:
css.b_error = 1; free( p_css );
return NULL;
case 1: case 1:
return css; return p_css;
case 0: case 0:
intf_WarnMsg( 3, "css info: authenticating" ); intf_WarnMsg( 3, "css info: authenticating" );
} }
...@@ -151,14 +158,14 @@ css_t CSSInit( int i_fd ) ...@@ -151,14 +158,14 @@ css_t CSSInit( int i_fd )
/* Unable to authenticate without AGID */ /* Unable to authenticate without AGID */
if( i_error == -1 ) if( i_error == -1 )
{ {
css.b_error = 1;
intf_ErrMsg( "css error: could not get AGID" ); intf_ErrMsg( "css error: could not get AGID" );
return css; free( p_css );
return NULL;
} }
for( i = 0 ; i < 10; ++i ) for( i = 0 ; i < 10; ++i )
{ {
css.disc.pi_challenge[i] = i; p_css->disc.pi_challenge[i] = i;
} }
/* Send AGID to host */ /* Send AGID to host */
...@@ -167,43 +174,43 @@ css_t CSSInit( int i_fd ) ...@@ -167,43 +174,43 @@ css_t CSSInit( int i_fd )
/* Get challenge from host */ /* Get challenge from host */
for( i = 0 ; i < 10 ; ++i ) for( i = 0 ; i < 10 ; ++i )
{ {
auth_info.hsc.chal[9-i] = css.disc.pi_challenge[i]; auth_info.hsc.chal[9-i] = p_css->disc.pi_challenge[i];
} }
/* Returning data, let LU change state */ /* Returning data, let LU change state */
css.i_agid = auth_info.lsa.agid; p_css->i_agid = auth_info.lsa.agid;
/* Send challenge to LU */ /* Send challenge to LU */
if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 ) if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
{ {
intf_ErrMsg( "css error: failed sending challenge to LU" ); intf_ErrMsg( "css error: failed sending challenge to LU" );
css.b_error = 1; free( p_css );
return css; return NULL;
} }
/* Get key1 from LU */ /* Get key1 from LU */
if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0) if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
{ {
intf_ErrMsg( "css error: failed getting key1 from LU" ); intf_ErrMsg( "css error: failed getting key1 from LU" );
css.b_error = 1; free( p_css );
return css; return NULL;
} }
/* Send key1 to host */ /* Send key1 to host */
for( i = 0 ; i < KEY_SIZE ; i++ ) for( i = 0 ; i < KEY_SIZE ; i++ )
{ {
css.disc.pi_key1[i] = auth_info.lsk.key[4-i]; p_css->disc.pi_key1[i] = auth_info.lsk.key[4-i];
} }
for( i = 0 ; i < 32 ; ++i ) for( i = 0 ; i < 32 ; ++i )
{ {
CSSCryptKey( 0, i, css.disc.pi_challenge, CSSCryptKey( 0, i, p_css->disc.pi_challenge,
css.disc.pi_key_check ); p_css->disc.pi_key_check );
if( memcmp( css.disc.pi_key_check, if( memcmp( p_css->disc.pi_key_check,
css.disc.pi_key1, KEY_SIZE ) == 0 ) p_css->disc.pi_key1, KEY_SIZE ) == 0 )
{ {
intf_WarnMsg( 3, "css info: drive authentic, using variant %d", i); intf_WarnMsg( 3, "css info: drive authentic, using variant %d", i);
css.disc.i_varient = i; p_css->disc.i_varient = i;
auth_info.type = DVD_LU_SEND_CHALLENGE; auth_info.type = DVD_LU_SEND_CHALLENGE;
break; break;
} }
...@@ -213,32 +220,32 @@ css_t CSSInit( int i_fd ) ...@@ -213,32 +220,32 @@ css_t CSSInit( int i_fd )
{ {
intf_ErrMsg( "css error: drive would not authenticate" ); intf_ErrMsg( "css error: drive would not authenticate" );
auth_info.type = DVD_AUTH_FAILURE; auth_info.type = DVD_AUTH_FAILURE;
css.b_error = 1; free( p_css );
return css; return NULL;
} }
/* Get challenge from LU */ /* Get challenge from LU */
if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
{ {
intf_ErrMsg( "css error: failed getting challenge from LU" ); intf_ErrMsg( "css error: failed getting challenge from LU" );
css.b_error = 1; free( p_css );
return css; return NULL;
} }
/* Send challenge to host */ /* Send challenge to host */
for( i = 0 ; i < 10 ; ++i ) for( i = 0 ; i < 10 ; ++i )
{ {
css.disc.pi_challenge[i] = auth_info.hsc.chal[9-i]; p_css->disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
} }
CSSCryptKey( 1, css.disc.i_varient, css.disc.pi_challenge, CSSCryptKey( 1, p_css->disc.i_varient, p_css->disc.pi_challenge,
css.disc.pi_key2 ); p_css->disc.pi_key2 );
auth_info.type = DVD_HOST_SEND_KEY2; auth_info.type = DVD_HOST_SEND_KEY2;
/* Get key2 from host */ /* Get key2 from host */
for( i = 0 ; i < KEY_SIZE ; ++i ) for( i = 0 ; i < KEY_SIZE ; ++i )
{ {
auth_info.hsk.key[4-i] = css.disc.pi_key2[i]; auth_info.hsk.key[4-i] = p_css->disc.pi_key2[i];
} }
/* Returning data, let LU change state */ /* Returning data, let LU change state */
...@@ -246,7 +253,8 @@ css_t CSSInit( int i_fd ) ...@@ -246,7 +253,8 @@ css_t CSSInit( int i_fd )
if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
{ {
intf_ErrMsg( "css error: failed sending key2 to LU (expected)" ); intf_ErrMsg( "css error: failed sending key2 to LU (expected)" );
return css; free( p_css );
return NULL;
} }
if( auth_info.type == DVD_AUTH_ESTABLISHED ) if( auth_info.type == DVD_AUTH_ESTABLISHED )
...@@ -255,71 +263,83 @@ css_t CSSInit( int i_fd ) ...@@ -255,71 +263,83 @@ css_t CSSInit( int i_fd )
} }
else if( auth_info.type == DVD_AUTH_FAILURE ) else if( auth_info.type == DVD_AUTH_FAILURE )
{ {
css.b_error = 1;
intf_ErrMsg( "css error: DVD authentication failed" ); intf_ErrMsg( "css error: DVD authentication failed" );
free( p_css );
return NULL;
} }
memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE ); memcpy( p_css->disc.pi_challenge, p_css->disc.pi_key1, KEY_SIZE );
memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE ); memcpy( p_css->disc.pi_challenge+KEY_SIZE, p_css->disc.pi_key2, KEY_SIZE );
CSSCryptKey( 2, css.disc.i_varient, CSSCryptKey( 2, p_css->disc.i_varient,
css.disc.pi_challenge, p_css->disc.pi_challenge,
css.disc.pi_key_check ); p_css->disc.pi_key_check );
intf_WarnMsg( 1, "css info: received Session Key" ); intf_WarnMsg( 1, "css info: received Session Key" );
if( css.i_agid < 0 ) if( p_css->i_agid < 0 )
{ {
css.b_error = 1; free( p_css );
return css; return NULL;
} }
/* Test authentication success */ /* Test authentication success */
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( i_fd ) )
{ {
case -1: case -1:
css.b_error = 1; free( p_css );
return NULL;
case 1: case 1:
return css; return p_css;
case 0: case 0:
intf_WarnMsg( 3, "css info: getting disc key" ); intf_WarnMsg( 3, "css info: getting disc key" );
} }
/* Get encrypted disc key */ /* Get encrypted disc key */
dvd.type = DVD_STRUCT_DISCKEY; dvd.type = DVD_STRUCT_DISCKEY;
dvd.disckey.agid = css.i_agid; dvd.disckey.agid = p_css->i_agid;
memset( dvd.disckey.value, 0, 2048 ); memset( dvd.disckey.value, 0, 2048 );
if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 ) if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
{ {
intf_ErrMsg( "css error: could not read Disc Key" ); intf_ErrMsg( "css error: could not read Disc Key" );
css.b_error = 1; free( p_css );
return css; return NULL;
} }
#if 1 #if 1
/* Unencrypt disc key using bus key */ /* Unencrypt disc key using bus key */
for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ ) for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
{ {
dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)]; dvd.disckey.value[i] ^= p_css->disc.pi_key_check[4 - (i % KEY_SIZE)];
} }
memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 ); memcpy( p_css->disc.pi_key_check, dvd.disckey.value, 2048 );
#endif #endif
/* Test authentication success */ /* Test authentication success */
switch( CSSGetASF( i_fd ) ) switch( CSSGetASF( i_fd ) )
{ {
case -1: case -1:
case 0: case 0:
css.b_error = 1; free( p_css );
return NULL;
case 1: case 1:
return css; return p_css;
} }
#else /* HAVE_CSS */ #else /* HAVE_CSS */
intf_ErrMsg( "css error: CSS decryption is disabled in this module" ); intf_ErrMsg( "css error: CSS decryption is disabled in this module" );
css.i_fd = i_fd; p_css = NULL;
css.b_error = 1;
#endif /* HAVE_CSS */ #endif /* HAVE_CSS */
return css; return p_css;
}
/*****************************************************************************
* CSSEnd : frees css structure
*****************************************************************************/
void CSSEnd( css_t * p_css )
{
#ifdef HAVE_CSS
free( p_css );
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -722,9 +742,6 @@ static void CSSCryptKey( int i_key_type, int i_varient, ...@@ -722,9 +742,6 @@ static void CSSCryptKey( int i_key_type, int i_varient,
i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1; i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o; i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
#define BIT0(x) ((x) & 1)
#define BIT1(x) (((x) >> 1) & 1)
i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o; i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
/* taking bit 1 */ /* taking bit 1 */
i_carry = ( i_combined >> 1 ) & 1; i_carry = ( i_combined >> 1 ) & 1;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_css.h: Structures for DVD authentification and unscrambling * dvd_css.h: Structures for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.h,v 1.4 2001/02/20 02:53:13 stef Exp $ * $Id: dvd_css.h,v 1.5 2001/03/03 07:07:01 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -48,7 +48,6 @@ typedef struct title_key_s ...@@ -48,7 +48,6 @@ typedef struct title_key_s
typedef struct css_s typedef struct css_s
{ {
int i_fd; int i_fd;
boolean_t b_error;
int i_agid; int i_agid;
disc_t disc; disc_t disc;
u8 pi_disc_key[2048]; u8 pi_disc_key[2048];
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* will only be given back to netlist when refcount is zero. * will only be given back to netlist when refcount is zero.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: dvd_netlist.c,v 1.1 2001/03/02 03:32:46 stef Exp $ * $Id: dvd_netlist.c,v 1.2 2001/03/03 07:07:01 stef Exp $
* *
* Authors: Henri Fallon <henri@videolan.org> * Authors: Henri Fallon <henri@videolan.org>
* Stphane Borel <stef@videolan.org> * Stphane Borel <stef@videolan.org>
...@@ -64,23 +64,21 @@ ...@@ -64,23 +64,21 @@
* *
* Warning: i_nb_iovec, i_nb_data, i_nb_pes have to be 2^x * Warning: i_nb_iovec, i_nb_data, i_nb_pes have to be 2^x
*****************************************************************************/ *****************************************************************************/
int DVDNetlistInit( input_thread_t * p_input, dvd_netlist_t * DVDNetlistInit( int i_nb_iovec, int i_nb_data, int i_nb_pes,
int i_nb_iovec, int i_nb_data, int i_nb_pes,
size_t i_buffer_size, int i_read_once ) size_t i_buffer_size, int i_read_once )
{ {
unsigned int i_loop; unsigned int i_loop;
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
/* First we allocate and initialise our netlist struct */ /* First we allocate and initialise our netlist struct */
p_input->p_method_data = malloc(sizeof(netlist_t)); p_netlist = malloc( sizeof(dvd_netlist_t) );
if ( p_input->p_method_data == NULL ) if ( p_netlist == NULL )
{ {
intf_ErrMsg("Unable to malloc the DVD netlist struct"); intf_ErrMsg("Unable to malloc the DVD netlist struct");
return (-1); free( p_netlist );
return NULL;
} }
p_netlist = (netlist_t *) p_input->p_method_data;
/* Nb of packets read once by input */ /* Nb of packets read once by input */
p_netlist->i_read_once = i_read_once; p_netlist->i_read_once = i_read_once;
...@@ -89,7 +87,9 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -89,7 +87,9 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->p_buffers == NULL ) if ( p_netlist->p_buffers == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (1)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (1)");
return (-1); free( p_netlist->p_buffers );
free( p_netlist );
return NULL;
} }
/* table of pointers to data packets */ /* table of pointers to data packets */
...@@ -97,7 +97,10 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -97,7 +97,10 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->p_data == NULL ) if ( p_netlist->p_data == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (2)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (2)");
return (-1); free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist );
return NULL;
} }
/* table of pointer to PES packets */ /* table of pointer to PES packets */
...@@ -105,7 +108,11 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -105,7 +108,11 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->p_pes == NULL ) if ( p_netlist->p_pes == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (3)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (3)");
return (-1); free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist->p_pes );
free( p_netlist );
return NULL;
} }
/* allocate the FIFOs : tables of free pointers */ /* allocate the FIFOs : tables of free pointers */
...@@ -114,12 +121,25 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -114,12 +121,25 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->pp_free_data == NULL ) if ( p_netlist->pp_free_data == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (4)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (4)");
free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist->p_pes );
free( p_netlist->pp_free_data );
free( p_netlist );
return NULL;
} }
p_netlist->pp_free_pes = p_netlist->pp_free_pes =
malloc( i_nb_pes *sizeof(pes_packet_t *) ); malloc( i_nb_pes *sizeof(pes_packet_t *) );
if ( p_netlist->pp_free_pes == NULL ) if ( p_netlist->pp_free_pes == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (5)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (5)");
free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist->p_pes );
free( p_netlist->pp_free_data );
free( p_netlist->pp_free_pes );
free( p_netlist );
return NULL;
} }
p_netlist->p_free_iovec = p_netlist->p_free_iovec =
...@@ -127,6 +147,14 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -127,6 +147,14 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->p_free_iovec == NULL ) if ( p_netlist->p_free_iovec == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (6)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (6)");
free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist->p_pes );
free( p_netlist->pp_free_data );
free( p_netlist->pp_free_pes );
free( p_netlist->p_free_iovec );
free( p_netlist );
return NULL;
} }
/* table for reference counter of iovecs */ /* table for reference counter of iovecs */
...@@ -134,7 +162,15 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -134,7 +162,15 @@ int DVDNetlistInit( input_thread_t * p_input,
if ( p_netlist->pi_refcount == NULL ) if ( p_netlist->pi_refcount == NULL )
{ {
intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)"); intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)");
return (-1); free( p_netlist->p_buffers );
free( p_netlist->p_data );
free( p_netlist->p_pes );
free( p_netlist->pp_free_data );
free( p_netlist->pp_free_pes );
free( p_netlist->p_free_iovec );
free( p_netlist->pi_refcount );
free( p_netlist );
return NULL;
} }
/* Fill the data FIFO */ /* Fill the data FIFO */
...@@ -183,7 +219,7 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -183,7 +219,7 @@ int DVDNetlistInit( input_thread_t * p_input,
p_netlist->i_nb_pes = i_nb_pes - 1; p_netlist->i_nb_pes = i_nb_pes - 1;
p_netlist->i_buffer_size = i_buffer_size; p_netlist->i_buffer_size = i_buffer_size;
return (0); /* Everything went all right */ return p_netlist; /* Everything went all right */
} }
/***************************************************************************** /*****************************************************************************
...@@ -195,10 +231,10 @@ int DVDNetlistInit( input_thread_t * p_input, ...@@ -195,10 +231,10 @@ int DVDNetlistInit( input_thread_t * p_input,
*****************************************************************************/ *****************************************************************************/
struct iovec * DVDGetiovec( void * p_method_data ) struct iovec * DVDGetiovec( void * p_method_data )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
/* cast */ /* cast */
p_netlist = ( netlist_t * ) p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
/* check */ /* check */
if( ( if( (
...@@ -236,11 +272,11 @@ struct iovec * DVDGetiovec( void * p_method_data ) ...@@ -236,11 +272,11 @@ struct iovec * DVDGetiovec( void * p_method_data )
void DVDMviovec( void * p_method_data, int i_nb_iovec, void DVDMviovec( void * p_method_data, int i_nb_iovec,
struct data_packet_s ** pp_data ) struct data_packet_s ** pp_data )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
unsigned int i_loop = 0; unsigned int i_loop = 0;
/* cast */ /* cast */
p_netlist = (netlist_t *)p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */ /* lock */
vlc_mutex_lock( &p_netlist->lock ); vlc_mutex_lock( &p_netlist->lock );
...@@ -275,11 +311,11 @@ void DVDMviovec( void * p_method_data, int i_nb_iovec, ...@@ -275,11 +311,11 @@ void DVDMviovec( void * p_method_data, int i_nb_iovec,
*****************************************************************************/ *****************************************************************************/
struct data_packet_s * DVDNewPtr( void * p_method_data ) struct data_packet_s * DVDNewPtr( void * p_method_data )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
struct data_packet_s * p_return; struct data_packet_s * p_return;
/* cast */ /* cast */
p_netlist = ( netlist_t * ) p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
#ifdef DEBUG #ifdef DEBUG
if( i_buffer_size > p_netlist->i_buffer_size ) if( i_buffer_size > p_netlist->i_buffer_size )
...@@ -318,11 +354,11 @@ struct data_packet_s * DVDNewPtr( void * p_method_data ) ...@@ -318,11 +354,11 @@ struct data_packet_s * DVDNewPtr( void * p_method_data )
struct data_packet_s * DVDNewPacket( void * p_method_data, struct data_packet_s * DVDNewPacket( void * p_method_data,
size_t i_buffer_size ) size_t i_buffer_size )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
struct data_packet_s * p_packet; struct data_packet_s * p_packet;
/* cast */ /* cast */
p_netlist = (netlist_t *)p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */ /* lock */
vlc_mutex_lock( &p_netlist->lock ); vlc_mutex_lock( &p_netlist->lock );
...@@ -371,11 +407,11 @@ struct data_packet_s * DVDNewPacket( void * p_method_data, ...@@ -371,11 +407,11 @@ struct data_packet_s * DVDNewPacket( void * p_method_data,
*****************************************************************************/ *****************************************************************************/
struct pes_packet_s * DVDNewPES( void * p_method_data ) struct pes_packet_s * DVDNewPES( void * p_method_data )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
pes_packet_t * p_return; pes_packet_t * p_return;
/* cast */ /* cast */
p_netlist = (netlist_t *) p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &p_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
...@@ -410,10 +446,10 @@ struct pes_packet_s * DVDNewPES( void * p_method_data ) ...@@ -410,10 +446,10 @@ struct pes_packet_s * DVDNewPES( void * p_method_data )
*****************************************************************************/ *****************************************************************************/
void DVDDeletePacket( void * p_method_data, data_packet_t * p_data ) void DVDDeletePacket( void * p_method_data, data_packet_t * p_data )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
/* cast */ /* cast */
p_netlist = (netlist_t *) p_method_data; p_netlist = (dvd_netlist_t *) p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &p_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
...@@ -450,11 +486,12 @@ void DVDDeletePacket( void * p_method_data, data_packet_t * p_data ) ...@@ -450,11 +486,12 @@ void DVDDeletePacket( void * p_method_data, data_packet_t * p_data )
*****************************************************************************/ *****************************************************************************/
void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes ) void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes )
{ {
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
data_packet_t * p_current_packet,* p_next_packet; data_packet_t * p_current_packet;
data_packet_t * p_next_packet;
/* cast */ /* cast */
p_netlist = (netlist_t *)p_method_data; p_netlist = (dvd_netlist_t *)p_method_data;
/* lock */ /* lock */
vlc_mutex_lock ( &p_netlist->lock ); vlc_mutex_lock ( &p_netlist->lock );
...@@ -502,24 +539,19 @@ void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes ) ...@@ -502,24 +539,19 @@ void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes )
/***************************************************************************** /*****************************************************************************
* DVDNetlistEnd: frees all allocated structures * DVDNetlistEnd: frees all allocated structures
*****************************************************************************/ *****************************************************************************/
void DVDNetlistEnd( input_thread_t * p_input) void DVDNetlistEnd( dvd_netlist_t * p_netlist )
{ {
netlist_t * p_netlist;
/* cast */
p_netlist = ( netlist_t * ) p_input->p_method_data;
/* destroy the mutex lock */ /* destroy the mutex lock */
vlc_mutex_destroy (&p_netlist->lock); vlc_mutex_destroy( &p_netlist->lock );
/* free the FIFO, the buffer, and the netlist structure */ /* free the FIFO, the buffer, and the netlist structure */
free (p_netlist->pp_free_data); free( p_netlist->pp_free_data );
free (p_netlist->pp_free_pes); free( p_netlist->pp_free_pes );
free (p_netlist->pi_refcount); free( p_netlist->pi_refcount );
free (p_netlist->p_pes); free( p_netlist->p_pes );
free (p_netlist->p_data); free( p_netlist->p_data );
free (p_netlist->p_buffers); free( p_netlist->p_buffers );
/* free the netlist */ /* free the netlist */
free (p_netlist); free( p_netlist );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_netlist.h: Specific netlist structures for DVD packets * dvd_netlist.h: Specific netlist structures for DVD packets
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN * Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: dvd_netlist.h,v 1.1 2001/03/02 03:32:46 stef Exp $ * $Id: dvd_netlist.h,v 1.2 2001/03/03 07:07:01 stef Exp $
* *
* Authors: Henri Fallon <henri@videolan.org> * Authors: Henri Fallon <henri@videolan.org>
* Stphane Borel <stef@videolan.org> * Stphane Borel <stef@videolan.org>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/***************************************************************************** /*****************************************************************************
* netlist_t: structure to manage a netlist * netlist_t: structure to manage a netlist
*****************************************************************************/ *****************************************************************************/
typedef struct netlist_s typedef struct dvd_netlist_s
{ {
vlc_mutex_t lock; vlc_mutex_t lock;
...@@ -57,14 +57,12 @@ typedef struct netlist_s ...@@ -57,14 +57,12 @@ typedef struct netlist_s
/* Nb of packets read once */ /* Nb of packets read once */
unsigned int i_read_once; unsigned int i_read_once;
} netlist_t; } dvd_netlist_t;
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
int DVDNetlistInit( struct input_thread_s *, struct dvd_netlist_s * DVDNetlistInit( int , int, int, size_t, int );
int , int, int, size_t, int );
struct iovec * DVDGetiovec( void * p_method_data ); struct iovec * DVDGetiovec( void * p_method_data );
void DVDMviovec( void * , int, struct data_packet_s **); void DVDMviovec( void * , int, struct data_packet_s **);
struct data_packet_s * DVDNewPtr( void * ); struct data_packet_s * DVDNewPtr( void * );
...@@ -72,4 +70,4 @@ struct data_packet_s * DVDNewPacket( void *, size_t ); ...@@ -72,4 +70,4 @@ struct data_packet_s * DVDNewPacket( void *, size_t );
struct pes_packet_s * DVDNewPES( void * ); struct pes_packet_s * DVDNewPES( void * );
void DVDDeletePacket( void *, struct data_packet_s * ); void DVDDeletePacket( void *, struct data_packet_s * );
void DVDDeletePES( void *, struct pes_packet_s * ); void DVDDeletePES( void *, struct pes_packet_s * );
void DVDNetlistEnd( struct input_thread_s * ); void DVDNetlistEnd( struct dvd_netlist_s * );
...@@ -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.24 2001/03/02 13:49:37 massiot Exp $ * $Id: input_dvd.c,v 1.25 2001/03/03 07:07:01 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -337,8 +337,54 @@ static int DVDCheckCSS( input_thread_t * p_input ) ...@@ -337,8 +337,54 @@ static int DVDCheckCSS( input_thread_t * p_input )
return CSSTest( p_input->i_handle ); return CSSTest( p_input->i_handle );
} }
/*****************************************************************************
* DVDCellToOff: synchronize navigation maps with current offset
*****************************************************************************/
static int DVDCellToOff( thread_dvd_data_t * p_dvd )
{
return 0;
}
/*****************************************************************************
* DVDFindCell: from cell index in adress map from index in information table.
*****************************************************************************/
static int DVDFindCell( thread_dvd_data_t * p_dvd, int i_index )
{
pgc_t * p_pgc;
int i_cell;
p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
i_cell = 0;
while( ( p_pgc->p_cell_pos_inf[i_index].i_vob_id >
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_vob_id ) &&
p_dvd->ifo.vts.c_adt.i_cell_nb > i_cell )
{
//if( p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell+1].i_esector*DVD_LB_SIZE >
// p_dvd->i_start )
{
i_cell++;
}
}
while( ( p_pgc->p_cell_pos_inf[i_index].i_cell_id >
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_cell_id ) &&
p_dvd->ifo.vts.c_adt.i_cell_nb > i_cell )
{
//if( p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell+1].i_esector*DVD_LB_SIZE >
// p_dvd->i_start )
{
i_cell++;
}
}
return i_cell;
}
/***************************************************************************** /*****************************************************************************
* DVDChapterSelect: find the cell corresponding to requested chapter * DVDChapterSelect: find the cell corresponding to requested chapter
* When called to find chapter 1, also sets title size and end.
*****************************************************************************/ *****************************************************************************/
static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
{ {
...@@ -346,39 +392,39 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) ...@@ -346,39 +392,39 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
int i_start_cell; int i_start_cell;
int i_end_cell; int i_end_cell;
int i_index; int i_index;
int i_cell; int i_last_chapter;
p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[0].pgc; p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
/* Find cell index in Program chain for current chapter */ /* Find cell index in Program chain for current chapter */
i_index = p_pgc->prg_map.pi_entry_cell[i_chapter-1] - 1; i_index = p_pgc->prg_map.pi_entry_cell[i_chapter-1] - 1;
/* Search for cell_index in cell adress_table */ /* Search for cell_index in cell adress_table */
i_cell = 0; i_start_cell = DVDFindCell( p_dvd, i_index );
while( p_pgc->p_cell_pos_inf[i_index].i_vob_id >
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_vob_id )
{
i_cell++;
}
while( p_pgc->p_cell_pos_inf[i_index].i_cell_id >
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_cell_id )
{
i_cell++;
}
i_start_cell = i_cell; /* intf_WarnMsg( 3, "DVD: Cell: %d vob id: %d cell id: %d", i_start_cell, p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_vob_id, p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_cell_id );*/
/* start is : beginning of vts + offset to vobs + offset to vob x */
p_dvd->i_start = p_dvd->ifo.vts.i_pos + DVD_LB_SIZE * p_dvd->i_start = p_dvd->ifo.vts.i_pos + DVD_LB_SIZE *
(off_t)( p_dvd->ifo.vts.mat.i_tt_vobs_ssector + (off_t)( p_dvd->ifo.vts.mat.i_tt_vobs_ssector +
p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector ); p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector );
/* compute size of the stream */
if( i_chapter == 1 ) if( i_chapter == 1 )
{ {
i_end_cell = i_start_cell + p_pgc->i_cell_nb - 1; i_last_chapter =
p_dvd->ifo.vmg.ptt_srpt.p_tts[p_dvd->i_title-1].i_ptt_nb;
i_index = p_pgc->prg_map.pi_entry_cell[i_last_chapter - 1] - 1;
/* intf_WarnMsg( 3, "last: %d index: %d", i_last_chapter, i_index );*/
i_end_cell = DVDFindCell( p_dvd, i_index );
/* intf_WarnMsg( 3, "DVD: Cell: %d vob id: %d cell id: %d", i_end_cell, p_dvd->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_vob_id, p_dvd->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_cell_id );*/
p_dvd->i_size = (off_t)DVD_LB_SIZE * p_dvd->i_size = (off_t)DVD_LB_SIZE *
( p_dvd->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_esector - ( p_dvd->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_esector -
p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector + 1 ); p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector + 1 );
p_dvd->i_chapter_nb = p_pgc->i_cell_nb;
intf_WarnMsg( 3, "DVD: Start cell: %d End Cell: %d", intf_WarnMsg( 3, "DVD: Start cell: %d End Cell: %d",
i_start_cell, i_end_cell ); i_start_cell, i_end_cell );
} }
...@@ -416,6 +462,7 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -416,6 +462,7 @@ static int DVDSetArea( input_thread_t * p_input,
if( i_title >= 0 ) if( i_title >= 0 )
{ {
/* /*
* We have to load all title information * We have to load all title information
*/ */
...@@ -423,19 +470,30 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -423,19 +470,30 @@ static int DVDSetArea( input_thread_t * p_input,
/* Change the default area */ /* Change the default area */
p_input->stream.p_selected_area = p_input->stream.pp_areas[i_title]; p_input->stream.p_selected_area = p_input->stream.pp_areas[i_title];
/* Ifo VTS, and CSS reading */ p_method->i_title = i_title;
p_method->ifo.i_title = i_title;
/* title position inside the selected vts */
p_method->i_vts_title =
p_method->ifo.vmg.ptt_srpt.p_tts[i_title-1].i_vts_ttn;
/* vts number */
p_method->ifo.i_title =
p_method->ifo.vmg.ptt_srpt.p_tts[i_title-1].i_tts_nb;
/* ifo vts */
IfoReadVTS( &(p_method->ifo) ); IfoReadVTS( &(p_method->ifo) );
intf_WarnMsg( 2, "Ifo: VTS initialized" ); intf_WarnMsg( 2, "ifo info: vts initialized" );
/* css title key for current vts */
if( p_method->b_encrypted ) if( p_method->b_encrypted )
{ {
p_method->css.i_title = i_title; p_method->p_css->i_title =
p_method->css.i_title_pos = p_method->ifo.vmg.ptt_srpt.p_tts[i_title-1].i_tts_nb;
p_method->p_css->i_title_pos =
p_method->ifo.vts.i_pos + p_method->ifo.vts.i_pos +
p_method->ifo.vts.mat.i_tt_vobs_ssector * DVD_LB_SIZE; p_method->ifo.vts.mat.i_tt_vobs_ssector * DVD_LB_SIZE;
CSSGetKey( &(p_method->css) ); CSSGetKey( p_method->p_css );
intf_WarnMsg( 2, "css info: VTS key initialized" ); intf_WarnMsg( 2, "css info: vts key initialized" );
} }
/* /*
...@@ -443,20 +501,18 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -443,20 +501,18 @@ static int DVDSetArea( input_thread_t * p_input,
*/ */
DVDChapterSelect( p_method, 1 ); DVDChapterSelect( p_method, 1 );
/* start is : beginning of vts + offset to vobs + offset to vob x */
p_method->i_start = p_method->i_start =
lseek( p_input->i_handle, p_method->i_start, SEEK_SET ); lseek( p_input->i_handle, p_method->i_start, SEEK_SET );
intf_WarnMsg( 2, "DVD: vobstart at: %lld", p_method->i_start ); intf_WarnMsg( 2, "dvd info: title: %d", i_title );
intf_WarnMsg( 2, "DVD: stream size: %lld", p_method->i_size ); intf_WarnMsg( 2, "dvd info: vobstart at: %lld", p_method->i_start );
intf_WarnMsg( 2, "DVD: number of chapters: %lld", intf_WarnMsg( 2, "dvd info: stream size: %lld", p_method->i_size );
p_method->i_chapter_nb ); intf_WarnMsg( 2, "dvd info: number of chapters: %d",
p_input->stream.p_selected_area->i_part_nb );
/* Area definition */ /* Area definition */
p_input->stream.p_selected_area->i_start = p_method->i_start; p_input->stream.p_selected_area->i_start = p_method->i_start;
p_input->stream.p_selected_area->i_size = p_method->i_size; p_input->stream.p_selected_area->i_size = p_method->i_size;
p_input->stream.p_selected_area->i_part_nb = p_method->i_chapter_nb;
/* /*
* Destroy obsolete ES by reinitializing program 0 * Destroy obsolete ES by reinitializing program 0
...@@ -476,7 +532,7 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -476,7 +532,7 @@ static int DVDSetArea( input_thread_t * p_input,
p_es->i_stream_id = 0xe0; p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG2_VIDEO_ES; p_es->i_type = MPEG2_VIDEO_ES;
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
intf_WarnMsg( 1, "DVD: Video MPEG2 stream" ); intf_WarnMsg( 1, "dvd info: video MPEG2 stream" );
/* Audio ES, in the order they appear in .ifo */ /* Audio ES, in the order they appear in .ifo */
i_nb = p_method->ifo.vts.mat.i_audio_nb; i_nb = p_method->ifo.vts.mat.i_audio_nb;
...@@ -525,18 +581,18 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -525,18 +581,18 @@ static int DVDSetArea( input_thread_t * p_input,
break; break;
case 0x04: /* LPCM */ case 0x04: /* LPCM */
i_id = 0; i_id = 0;
intf_ErrMsg( "DVD: LPCM audio not handled yet" ); intf_ErrMsg( "dvd error: LPCM audio not handled yet" );
break; break;
case 0x06: /* DTS */ case 0x06: /* DTS */
i_id = 0; i_id = 0;
intf_ErrMsg( "DVD: DTS audio not handled yet" ); intf_ErrMsg( "dvd error: DTS audio not handled yet" );
break; break;
default: default:
i_id = 0; i_id = 0;
intf_ErrMsg( "DVD: unkown audio" ); intf_ErrMsg( "dvd error: unkown audio" );
} }
intf_WarnMsg( 1, "DVD: Audio stream %d %s\t(0x%x)", intf_WarnMsg( 1, "dvd info: audio stream %d %s\t(0x%x)",
i, p_es->psz_desc, i_id ); i, p_es->psz_desc, i_id );
} }
...@@ -556,7 +612,7 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -556,7 +612,7 @@ static int DVDSetArea( input_thread_t * p_input,
p_es->i_type = DVD_SPU_ES; p_es->i_type = DVD_SPU_ES;
strcpy( p_es->psz_desc, Language( hton16( strcpy( p_es->psz_desc, Language( hton16(
p_method->ifo.vts.mat.p_subpic_atrt[i-1].i_lang_code ) ) ); p_method->ifo.vts.mat.p_subpic_atrt[i-1].i_lang_code ) ) );
intf_WarnMsg( 1, "DVD: SPU stream %d %s\t(0x%x)", intf_WarnMsg( 1, "dvd info: spu stream %d %s\t(0x%x)",
i, p_es->psz_desc, i_id ); i, p_es->psz_desc, i_id );
/* The before the last spu has a 0x0 prefix */ /* The before the last spu has a 0x0 prefix */
...@@ -602,14 +658,14 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -602,14 +658,14 @@ static int DVDSetArea( input_thread_t * p_input,
input_UnselectES( p_input, input_UnselectES( p_input,
p_input->stream.pp_selected_es[i_index] ); p_input->stream.pp_selected_es[i_index] );
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
intf_WarnMsg( 1, "DVD: Audio %d selected -> %s (0x%x)", intf_WarnMsg( 1, "dvd info: audio %d selected -> %s (0x%x)",
i_audio, p_es->psz_desc, p_es->i_id ); i_audio, p_es->psz_desc, p_es->i_id );
} }
} }
else else
{ {
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
intf_WarnMsg( 1, "DVD: Audio %d selected -> %s (0x%x)", intf_WarnMsg( 1, "dvd info: audio %d selected -> %s (0x%x)",
i_audio, p_es->psz_desc, p_es->i_id ); i_audio, p_es->psz_desc, p_es->i_id );
} }
} }
...@@ -622,7 +678,7 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -622,7 +678,7 @@ static int DVDSetArea( input_thread_t * p_input,
input_SelectES( p_input, ( p_es = p_input->stream.pp_programs[0]-> input_SelectES( p_input, ( p_es = p_input->stream.pp_programs[0]->
pp_es[ i_spu + p_method->ifo.vts.mat.i_audio_nb ] ) ); pp_es[ i_spu + p_method->ifo.vts.mat.i_audio_nb ] ) );
intf_WarnMsg( 1, "DVD: SPU %d selected -> %s (0x%x)", intf_WarnMsg( 1, "dvd info: spu %d selected -> %s (0x%x)",
i_spu, p_es->psz_desc, p_es->i_id ); i_spu, p_es->psz_desc, p_es->i_id );
} }
} }
...@@ -641,7 +697,7 @@ static int DVDSetArea( input_thread_t * p_input, ...@@ -641,7 +697,7 @@ static int DVDSetArea( input_thread_t * p_input,
DVDSeek( p_input, p_method->i_start - DVDSeek( p_input, p_method->i_start -
p_input->stream.p_selected_area->i_start ); p_input->stream.p_selected_area->i_start );
intf_WarnMsg( 2, "DVD: Chapter %d start at: %lld", i_chapter, intf_WarnMsg( 2, "dvd info: chapter %d start at: %lld", i_chapter,
p_input->stream.p_selected_area->i_tell ); p_input->stream.p_selected_area->i_tell );
} }
...@@ -685,24 +741,26 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -685,24 +741,26 @@ static void DVDInit( input_thread_t * p_input )
lseek( p_input->i_handle, 0, SEEK_SET ); lseek( p_input->i_handle, 0, SEEK_SET );
/* Reading structures initialisation */ /* Reading structures initialisation */
DVDNetlistInit( p_input, 4096, 16384, 4096, DVD_LB_SIZE, p_input->p_method_data =
p_method->i_block_once ); DVDNetlistInit( 4096, 16384, 4096, DVD_LB_SIZE, p_method->i_block_once );
intf_WarnMsg( 2, "DVD: Netlist initialized" ); intf_WarnMsg( 2, "dvd info: netlist initialized" );
/* Ifo initialisation */ /* Ifo initialisation */
p_method->ifo = IfoInit( p_input->i_handle ); p_method->ifo = IfoInit( p_input->i_handle );
intf_WarnMsg( 2, "Ifo: VMG initialized" ); intf_WarnMsg( 2, "ifo info: vmg initialized" );
/* CSS initialisation */ /* CSS initialisation */
if( p_method->b_encrypted ) if( p_method->b_encrypted )
{ {
p_method->css = CSSInit( p_input->i_handle ); p_method->p_css = CSSInit( p_input->i_handle );
if( ( p_input->b_error = p_method->css.b_error ) ) if( p_method->p_css == NULL )
{ {
intf_ErrMsg( "css error: fatal failure" ); intf_ErrMsg( "css error: fatal failure" );
p_input->b_error = 1;
return; return;
} }
intf_WarnMsg( 2, "css info: initialized" ); intf_WarnMsg( 2, "css info: initialized" );
} }
...@@ -712,15 +770,12 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -712,15 +770,12 @@ static void DVDInit( input_thread_t * p_input )
/* Set stream and area data */ /* Set stream and area data */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
/* FIXME: We consider here that one title is one title set #define srpt p_method->ifo.vmg.ptt_srpt
* it is not true !!! */ intf_WarnMsg( 2, "dvd info: number of titles: %d", srpt.i_ttu_nb );
intf_WarnMsg( 2, "DVD: Number of titles: %d",
p_method->ifo.vmg.mat.i_tts_nb );
#define area p_input->stream.pp_areas #define area p_input->stream.pp_areas
/* We start from 1 here since area 0 is reserved for video_ts.vob */ /* We start from 1 here since area 0 is reserved for video_ts.vob */
for( i = 1 ; i <= p_method->ifo.vmg.mat.i_tts_nb ; i++ ) for( i = 1 ; i <= srpt.i_ttu_nb ; i++ )
{ {
input_AddArea( p_input ); input_AddArea( p_input );
...@@ -735,23 +790,24 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -735,23 +790,24 @@ static void DVDInit( input_thread_t * p_input )
area[i]->i_size = 0; area[i]->i_size = 0;
/* Number of chapter */ /* Number of chapter */
area[i]->i_part_nb = 0; area[i]->i_part_nb = srpt.p_tts[i-1].i_ptt_nb;
area[i]->i_part = 1; area[i]->i_part = 1;
/* Offset to vts_i_0.ifo */ /* Offset to vts_i_0.ifo */
area[i]->i_plugin_data = p_method->ifo.i_off + area[i]->i_plugin_data = p_method->ifo.i_off +
( p_method->ifo.vmg.ptt_srpt.p_tts[i-1].i_ssector * DVD_LB_SIZE ); ( srpt.p_tts[i-1].i_ssector * DVD_LB_SIZE );
} }
#undef area #undef area
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Get requested title - if none try to find one where is the movie */ /* Get requested title - if none try to find one where is the movie */
i_title = main_GetIntVariable( INPUT_TITLE_VAR, i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 );
p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb ); if( i_title <= 0 || i_title > srpt.i_ttu_nb )
if( i_title <= 0 || i_title >= p_method->ifo.vmg.mat.i_tts_nb )
{ {
i_title = p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb; i_title = 1;
} }
#undef srpt
/* Get requested chapter - if none defaults to first one */ /* Get requested chapter - if none defaults to first one */
i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 ); i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 );
...@@ -780,12 +836,16 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -780,12 +836,16 @@ static void DVDInit( input_thread_t * p_input )
*****************************************************************************/ *****************************************************************************/
static void DVDEnd( input_thread_t * p_input ) static void DVDEnd( input_thread_t * p_input )
{ {
/* FIXME: check order of calls */ thread_dvd_data_t * p_method;
// CSSEnd( p_input ); dvd_netlist_t * p_netlist;
// IfoEnd( (ifo_t*)(&p_input->p_plugin_data->ifo ) );
free( p_input->stream.p_demux_data ); p_method = (thread_dvd_data_t*)p_input->p_plugin_data;
free( p_input->p_plugin_data ); p_netlist = (dvd_netlist_t *)p_input->p_method_data;
DVDNetlistEnd( p_input );
CSSEnd( p_method->p_css );
// IfoEnd( p_method->p_ifo ) );
free( p_method );
DVDNetlistEnd( p_netlist );
} }
/***************************************************************************** /*****************************************************************************
...@@ -798,7 +858,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -798,7 +858,7 @@ static int DVDRead( input_thread_t * p_input,
data_packet_t ** pp_packets ) data_packet_t ** pp_packets )
{ {
thread_dvd_data_t * p_method; thread_dvd_data_t * p_method;
netlist_t * p_netlist; dvd_netlist_t * p_netlist;
struct iovec * p_vec; struct iovec * p_vec;
struct data_packet_s * pp_data[p_input->i_read_once]; struct data_packet_s * pp_data[p_input->i_read_once];
u8 * pi_cur; u8 * pi_cur;
...@@ -807,8 +867,8 @@ static int DVDRead( input_thread_t * p_input, ...@@ -807,8 +867,8 @@ static int DVDRead( input_thread_t * p_input,
int i_packet; int i_packet;
int i_pos; int i_pos;
p_method = ( thread_dvd_data_t * ) p_input->p_plugin_data; p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
p_netlist = ( netlist_t * ) p_input->p_method_data; p_netlist = (dvd_netlist_t *)p_input->p_method_data;
/* Get an iovec pointer */ /* Get an iovec pointer */
if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL ) if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL )
...@@ -829,7 +889,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -829,7 +889,7 @@ static int DVDRead( input_thread_t * p_input,
{ {
if( p_method->b_encrypted ) if( p_method->b_encrypted )
{ {
CSSDescrambleSector( p_method->css.pi_title_key, CSSDescrambleSector( p_method->p_css->pi_title_key,
p_vec[i_iovec].iov_base ); p_vec[i_iovec].iov_base );
((u8*)(p_vec[i_iovec].iov_base))[0x14] &= 0x8F; ((u8*)(p_vec[i_iovec].iov_base))[0x14] &= 0x8F;
} }
......
...@@ -37,12 +37,17 @@ typedef struct thread_dvd_data_s ...@@ -37,12 +37,17 @@ typedef struct thread_dvd_data_s
int i_block_once; // Nb of block read once by int i_block_once; // Nb of block read once by
// readv // readv
/* Navigation information */
int i_title;
int i_vts_title;
int i_chapter_nb; int i_chapter_nb;
off_t i_start; off_t i_start;
off_t i_size; off_t i_size;
int i_end_cell;
/* Scrambling Information */ /* Scrambling Information */
struct css_s css; struct css_s * p_css;
/* Structure that contains all information of the DVD */ /* Structure that contains all information of the DVD */
struct ifo_s ifo; struct ifo_s ifo;
...@@ -52,16 +57,17 @@ typedef struct thread_dvd_data_s ...@@ -52,16 +57,17 @@ typedef struct thread_dvd_data_s
/***************************************************************************** /*****************************************************************************
* Prototypes in dvd_ifo.c * Prototypes in dvd_ifo.c
*****************************************************************************/ *****************************************************************************/
struct ifo_s IfoInit( int ); struct ifo_s IfoInit ( int );
int IfoReadVTS( struct ifo_s * ); int IfoReadVTS ( struct ifo_s * );
void IfoRead( struct ifo_s * ); void IfoRead ( struct ifo_s * );
void IfoEnd( ifo_t * ); void IfoEnd ( ifo_t * );
/***************************************************************************** /*****************************************************************************
* Prototypes in dvd_css.c * Prototypes in dvd_css.c
*****************************************************************************/ *****************************************************************************/
int CSSTest ( int ); int CSSTest ( int );
struct css_s CSSInit ( int ); struct css_s * CSSInit ( int );
void CSSEnd ( struct css_s * );
int CSSGetKey ( struct css_s * ); int CSSGetKey ( struct css_s * );
int CSSDescrambleSector( u8 * , u8 * ); int CSSDescrambleSector ( u8 * , u8 * );
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