From: Stéphane Borel Date: Sat, 3 Mar 2001 07:07:01 +0000 (+0000) Subject: -completely changed title and chapter initialization. Now we have real X-Git-Tag: 0.2.70~90 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=dc0df7c21c633dd9c65bdcb6d4c241759a5794a7;p=vlc -completely changed title and chapter initialization. Now we have real title units. -Fixed size for a majority of DVD. --- diff --git a/plugins/dvd/dvd_css.c b/plugins/dvd/dvd_css.c index 3fabfd37c0..22b95e37f0 100644 --- a/plugins/dvd/dvd_css.c +++ b/plugins/dvd/dvd_css.c @@ -2,7 +2,7 @@ * dvd_css.c: Functions for DVD authentification and unscrambling ***************************************************************************** * 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: Stéphane Borel * @@ -35,6 +35,7 @@ #include "defs.h" #include +#include #include #include #include @@ -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 * 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 /* structures defined in cdrom.h or dvdio.h */ @@ -112,8 +113,13 @@ css_t CSSInit( int i_fd ) int i_error = -1; int i; - css.i_fd = i_fd; - css.b_error = 0; + p_css = malloc( sizeof(css_t) ); + if( p_css == NULL ) + { + return NULL; + } + + p_css->i_fd = i_fd; memset( &auth_info, 0, sizeof(auth_info) ); @@ -121,9 +127,10 @@ css_t CSSInit( int i_fd ) switch( CSSGetASF( i_fd ) ) { case -1: - css.b_error = 1; + free( p_css ); + return NULL; case 1: - return css; + return p_css; case 0: intf_WarnMsg( 3, "css info: authenticating" ); } @@ -151,14 +158,14 @@ css_t CSSInit( int i_fd ) /* Unable to authenticate without AGID */ if( i_error == -1 ) { - css.b_error = 1; intf_ErrMsg( "css error: could not get AGID" ); - return css; + free( p_css ); + return NULL; } for( i = 0 ; i < 10; ++i ) { - css.disc.pi_challenge[i] = i; + p_css->disc.pi_challenge[i] = i; } /* Send AGID to host */ @@ -167,43 +174,43 @@ css_t CSSInit( int i_fd ) /* Get challenge from host */ 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 */ - css.i_agid = auth_info.lsa.agid; + p_css->i_agid = auth_info.lsa.agid; /* Send challenge to LU */ if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 ) { intf_ErrMsg( "css error: failed sending challenge to LU" ); - css.b_error = 1; - return css; + free( p_css ); + return NULL; } /* Get key1 from LU */ if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0) { intf_ErrMsg( "css error: failed getting key1 from LU" ); - css.b_error = 1; - return css; + free( p_css ); + return NULL; } /* Send key1 to host */ 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 ) { - CSSCryptKey( 0, i, css.disc.pi_challenge, - css.disc.pi_key_check ); + CSSCryptKey( 0, i, p_css->disc.pi_challenge, + p_css->disc.pi_key_check ); - if( memcmp( css.disc.pi_key_check, - css.disc.pi_key1, KEY_SIZE ) == 0 ) + if( memcmp( p_css->disc.pi_key_check, + p_css->disc.pi_key1, KEY_SIZE ) == 0 ) { 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; break; } @@ -213,32 +220,32 @@ css_t CSSInit( int i_fd ) { intf_ErrMsg( "css error: drive would not authenticate" ); auth_info.type = DVD_AUTH_FAILURE; - css.b_error = 1; - return css; + free( p_css ); + return NULL; } /* Get challenge from LU */ if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) { intf_ErrMsg( "css error: failed getting challenge from LU" ); - css.b_error = 1; - return css; + free( p_css ); + return NULL; } /* Send challenge to host */ 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, - css.disc.pi_key2 ); + CSSCryptKey( 1, p_css->disc.i_varient, p_css->disc.pi_challenge, + p_css->disc.pi_key2 ); auth_info.type = DVD_HOST_SEND_KEY2; /* Get key2 from host */ 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 */ @@ -246,7 +253,8 @@ css_t CSSInit( int i_fd ) if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 ) { intf_ErrMsg( "css error: failed sending key2 to LU (expected)" ); - return css; + free( p_css ); + return NULL; } if( auth_info.type == DVD_AUTH_ESTABLISHED ) @@ -255,71 +263,83 @@ css_t CSSInit( int i_fd ) } else if( auth_info.type == DVD_AUTH_FAILURE ) { - css.b_error = 1; intf_ErrMsg( "css error: DVD authentication failed" ); + free( p_css ); + return NULL; } - memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE ); - memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE ); - CSSCryptKey( 2, css.disc.i_varient, - css.disc.pi_challenge, - css.disc.pi_key_check ); + memcpy( p_css->disc.pi_challenge, p_css->disc.pi_key1, KEY_SIZE ); + memcpy( p_css->disc.pi_challenge+KEY_SIZE, p_css->disc.pi_key2, KEY_SIZE ); + CSSCryptKey( 2, p_css->disc.i_varient, + p_css->disc.pi_challenge, + p_css->disc.pi_key_check ); intf_WarnMsg( 1, "css info: received Session Key" ); - if( css.i_agid < 0 ) + if( p_css->i_agid < 0 ) { - css.b_error = 1; - return css; + free( p_css ); + return NULL; } /* Test authentication success */ switch( CSSGetASF( i_fd ) ) { case -1: - css.b_error = 1; + free( p_css ); + return NULL; case 1: - return css; + return p_css; case 0: intf_WarnMsg( 3, "css info: getting disc key" ); } /* Get encrypted disc key */ dvd.type = DVD_STRUCT_DISCKEY; - dvd.disckey.agid = css.i_agid; + dvd.disckey.agid = p_css->i_agid; memset( dvd.disckey.value, 0, 2048 ); if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 ) { intf_ErrMsg( "css error: could not read Disc Key" ); - css.b_error = 1; - return css; + free( p_css ); + return NULL; } #if 1 /* Unencrypt disc key using bus key */ 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 /* Test authentication success */ switch( CSSGetASF( i_fd ) ) { case -1: case 0: - css.b_error = 1; + free( p_css ); + return NULL; case 1: - return css; + return p_css; } #else /* HAVE_CSS */ intf_ErrMsg( "css error: CSS decryption is disabled in this module" ); - css.i_fd = i_fd; - css.b_error = 1; + p_css = NULL; #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, i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1; 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; /* taking bit 1 */ i_carry = ( i_combined >> 1 ) & 1; diff --git a/plugins/dvd/dvd_css.h b/plugins/dvd/dvd_css.h index 0adadd157d..41afb88dfd 100644 --- a/plugins/dvd/dvd_css.h +++ b/plugins/dvd/dvd_css.h @@ -2,7 +2,7 @@ * dvd_css.h: Structures for DVD authentification and unscrambling ***************************************************************************** * 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: Stéphane Borel * @@ -48,7 +48,6 @@ typedef struct title_key_s typedef struct css_s { int i_fd; - boolean_t b_error; int i_agid; disc_t disc; u8 pi_disc_key[2048]; diff --git a/plugins/dvd/dvd_netlist.c b/plugins/dvd/dvd_netlist.c index a197015d4b..83f959b93c 100644 --- a/plugins/dvd/dvd_netlist.c +++ b/plugins/dvd/dvd_netlist.c @@ -7,7 +7,7 @@ * will only be given back to netlist when refcount is zero. ***************************************************************************** * 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 * Stéphane Borel @@ -64,23 +64,21 @@ * * Warning: i_nb_iovec, i_nb_data, i_nb_pes have to be 2^x *****************************************************************************/ -int DVDNetlistInit( input_thread_t * p_input, - int i_nb_iovec, int i_nb_data, int i_nb_pes, - size_t i_buffer_size, int i_read_once ) +dvd_netlist_t * DVDNetlistInit( int i_nb_iovec, int i_nb_data, int i_nb_pes, + size_t i_buffer_size, int i_read_once ) { - unsigned int i_loop; - netlist_t * p_netlist; + unsigned int i_loop; + dvd_netlist_t * p_netlist; /* First we allocate and initialise our netlist struct */ - p_input->p_method_data = malloc(sizeof(netlist_t)); - if ( p_input->p_method_data == NULL ) + p_netlist = malloc( sizeof(dvd_netlist_t) ); + if ( p_netlist == NULL ) { 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 */ p_netlist->i_read_once = i_read_once; @@ -89,7 +87,9 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->p_buffers == NULL ) { 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 */ @@ -97,7 +97,10 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->p_data == NULL ) { 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 */ @@ -105,7 +108,11 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->p_pes == NULL ) { 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 */ @@ -114,12 +121,25 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->pp_free_data == NULL ) { 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 = malloc( i_nb_pes *sizeof(pes_packet_t *) ); if ( p_netlist->pp_free_pes == NULL ) { 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 = @@ -127,6 +147,14 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->p_free_iovec == NULL ) { 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 */ @@ -134,7 +162,15 @@ int DVDNetlistInit( input_thread_t * p_input, if ( p_netlist->pi_refcount == NULL ) { 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 */ @@ -183,7 +219,7 @@ int DVDNetlistInit( input_thread_t * p_input, p_netlist->i_nb_pes = i_nb_pes - 1; 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, *****************************************************************************/ struct iovec * DVDGetiovec( void * p_method_data ) { - netlist_t * p_netlist; + dvd_netlist_t * p_netlist; /* cast */ - p_netlist = ( netlist_t * ) p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; /* check */ if( ( @@ -236,11 +272,11 @@ struct iovec * DVDGetiovec( void * p_method_data ) void DVDMviovec( void * p_method_data, int i_nb_iovec, struct data_packet_s ** pp_data ) { - netlist_t * p_netlist; - unsigned int i_loop = 0; + dvd_netlist_t * p_netlist; + unsigned int i_loop = 0; /* cast */ - p_netlist = (netlist_t *)p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; /* lock */ vlc_mutex_lock( &p_netlist->lock ); @@ -275,11 +311,11 @@ void DVDMviovec( void * p_method_data, int i_nb_iovec, *****************************************************************************/ struct data_packet_s * DVDNewPtr( void * p_method_data ) { - netlist_t * p_netlist; - struct data_packet_s * p_return; + dvd_netlist_t * p_netlist; + struct data_packet_s * p_return; /* cast */ - p_netlist = ( netlist_t * ) p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; #ifdef DEBUG if( i_buffer_size > p_netlist->i_buffer_size ) @@ -318,11 +354,11 @@ struct data_packet_s * DVDNewPtr( void * p_method_data ) struct data_packet_s * DVDNewPacket( void * p_method_data, size_t i_buffer_size ) { - netlist_t * p_netlist; + dvd_netlist_t * p_netlist; struct data_packet_s * p_packet; /* cast */ - p_netlist = (netlist_t *)p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; /* lock */ vlc_mutex_lock( &p_netlist->lock ); @@ -371,11 +407,11 @@ struct data_packet_s * DVDNewPacket( void * p_method_data, *****************************************************************************/ struct pes_packet_s * DVDNewPES( void * p_method_data ) { - netlist_t * p_netlist; - pes_packet_t * p_return; + dvd_netlist_t * p_netlist; + pes_packet_t * p_return; /* cast */ - p_netlist = (netlist_t *) p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; /* lock */ vlc_mutex_lock ( &p_netlist->lock ); @@ -410,10 +446,10 @@ struct pes_packet_s * DVDNewPES( void * p_method_data ) *****************************************************************************/ void DVDDeletePacket( void * p_method_data, data_packet_t * p_data ) { - netlist_t * p_netlist; + dvd_netlist_t * p_netlist; /* cast */ - p_netlist = (netlist_t *) p_method_data; + p_netlist = (dvd_netlist_t *) p_method_data; /* lock */ vlc_mutex_lock ( &p_netlist->lock ); @@ -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 ) { - netlist_t * p_netlist; - data_packet_t * p_current_packet,* p_next_packet; + dvd_netlist_t * p_netlist; + data_packet_t * p_current_packet; + data_packet_t * p_next_packet; /* cast */ - p_netlist = (netlist_t *)p_method_data; + p_netlist = (dvd_netlist_t *)p_method_data; /* lock */ vlc_mutex_lock ( &p_netlist->lock ); @@ -502,24 +539,19 @@ void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes ) /***************************************************************************** * 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 */ - vlc_mutex_destroy (&p_netlist->lock); + vlc_mutex_destroy( &p_netlist->lock ); /* free the FIFO, the buffer, and the netlist structure */ - free (p_netlist->pp_free_data); - free (p_netlist->pp_free_pes); - free (p_netlist->pi_refcount); - free (p_netlist->p_pes); - free (p_netlist->p_data); - free (p_netlist->p_buffers); + free( p_netlist->pp_free_data ); + free( p_netlist->pp_free_pes ); + free( p_netlist->pi_refcount ); + free( p_netlist->p_pes ); + free( p_netlist->p_data ); + free( p_netlist->p_buffers ); /* free the netlist */ - free (p_netlist); + free( p_netlist ); } diff --git a/plugins/dvd/dvd_netlist.h b/plugins/dvd/dvd_netlist.h index 21cd9c1ecd..9d7579c833 100644 --- a/plugins/dvd/dvd_netlist.h +++ b/plugins/dvd/dvd_netlist.h @@ -2,7 +2,7 @@ * dvd_netlist.h: Specific netlist structures for DVD packets ***************************************************************************** * 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 * Stéphane Borel @@ -25,7 +25,7 @@ /***************************************************************************** * netlist_t: structure to manage a netlist *****************************************************************************/ -typedef struct netlist_s +typedef struct dvd_netlist_s { vlc_mutex_t lock; @@ -57,14 +57,12 @@ typedef struct netlist_s /* Nb of packets read once */ unsigned int i_read_once; -} netlist_t; +} dvd_netlist_t; /***************************************************************************** * Prototypes *****************************************************************************/ -int DVDNetlistInit( struct input_thread_s *, - int , int, int, size_t, int ); - +struct dvd_netlist_s * DVDNetlistInit( int , int, int, size_t, int ); struct iovec * DVDGetiovec( void * p_method_data ); void DVDMviovec( void * , int, struct data_packet_s **); struct data_packet_s * DVDNewPtr( void * ); @@ -72,4 +70,4 @@ struct data_packet_s * DVDNewPacket( void *, size_t ); struct pes_packet_s * DVDNewPES( void * ); void DVDDeletePacket( void *, struct data_packet_s * ); void DVDDeletePES( void *, struct pes_packet_s * ); -void DVDNetlistEnd( struct input_thread_s * ); +void DVDNetlistEnd( struct dvd_netlist_s * ); diff --git a/plugins/dvd/input_dvd.c b/plugins/dvd/input_dvd.c index 2103592cfe..6ad1cff48b 100644 --- a/plugins/dvd/input_dvd.c +++ b/plugins/dvd/input_dvd.c @@ -10,7 +10,7 @@ * -dvd_udf to find files ***************************************************************************** * 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: Stéphane Borel * @@ -337,8 +337,54 @@ static int DVDCheckCSS( input_thread_t * p_input ) 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 + * When called to find chapter 1, also sets title size and end. *****************************************************************************/ 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_end_cell; 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 */ i_index = p_pgc->prg_map.pi_entry_cell[i_chapter-1] - 1; /* Search for cell_index in cell adress_table */ - 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 ) - { - 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 = DVDFindCell( p_dvd, i_index ); - 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 * (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 ); + /* compute size of the stream */ 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->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->i_chapter_nb = p_pgc->i_cell_nb; intf_WarnMsg( 3, "DVD: Start cell: %d End Cell: %d", i_start_cell, i_end_cell ); } @@ -416,6 +462,7 @@ static int DVDSetArea( input_thread_t * p_input, if( i_title >= 0 ) { + /* * We have to load all title information */ @@ -423,19 +470,30 @@ static int DVDSetArea( input_thread_t * p_input, /* Change the default area */ p_input->stream.p_selected_area = p_input->stream.pp_areas[i_title]; - /* Ifo VTS, and CSS reading */ - p_method->ifo.i_title = i_title; + p_method->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) ); - intf_WarnMsg( 2, "Ifo: VTS initialized" ); + intf_WarnMsg( 2, "ifo info: vts initialized" ); + /* css title key for current vts */ if( p_method->b_encrypted ) { - p_method->css.i_title = i_title; - p_method->css.i_title_pos = + p_method->p_css->i_title = + 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.mat.i_tt_vobs_ssector * DVD_LB_SIZE; - CSSGetKey( &(p_method->css) ); - intf_WarnMsg( 2, "css info: VTS key initialized" ); + CSSGetKey( p_method->p_css ); + intf_WarnMsg( 2, "css info: vts key initialized" ); } /* @@ -443,20 +501,18 @@ static int DVDSetArea( input_thread_t * p_input, */ DVDChapterSelect( p_method, 1 ); - /* start is : beginning of vts + offset to vobs + offset to vob x */ - p_method->i_start = 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: stream size: %lld", p_method->i_size ); - intf_WarnMsg( 2, "DVD: number of chapters: %lld", - p_method->i_chapter_nb ); + intf_WarnMsg( 2, "dvd info: title: %d", i_title ); + intf_WarnMsg( 2, "dvd info: vobstart at: %lld", p_method->i_start ); + intf_WarnMsg( 2, "dvd info: stream size: %lld", p_method->i_size ); + intf_WarnMsg( 2, "dvd info: number of chapters: %d", + p_input->stream.p_selected_area->i_part_nb ); /* Area definition */ 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_part_nb = p_method->i_chapter_nb; /* * Destroy obsolete ES by reinitializing program 0 @@ -476,7 +532,7 @@ static int DVDSetArea( input_thread_t * p_input, p_es->i_stream_id = 0xe0; p_es->i_type = MPEG2_VIDEO_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 */ i_nb = p_method->ifo.vts.mat.i_audio_nb; @@ -525,18 +581,18 @@ static int DVDSetArea( input_thread_t * p_input, break; case 0x04: /* LPCM */ i_id = 0; - intf_ErrMsg( "DVD: LPCM audio not handled yet" ); + intf_ErrMsg( "dvd error: LPCM audio not handled yet" ); break; case 0x06: /* DTS */ i_id = 0; - intf_ErrMsg( "DVD: DTS audio not handled yet" ); + intf_ErrMsg( "dvd error: DTS audio not handled yet" ); break; default: 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 ); } @@ -556,7 +612,7 @@ static int DVDSetArea( input_thread_t * p_input, p_es->i_type = DVD_SPU_ES; strcpy( p_es->psz_desc, Language( hton16( 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 ); /* The before the last spu has a 0x0 prefix */ @@ -602,14 +658,14 @@ static int DVDSetArea( input_thread_t * p_input, input_UnselectES( p_input, p_input->stream.pp_selected_es[i_index] ); 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 ); } } else { 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 ); } } @@ -622,7 +678,7 @@ static int DVDSetArea( input_thread_t * p_input, input_SelectES( p_input, ( p_es = p_input->stream.pp_programs[0]-> 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 ); } } @@ -641,7 +697,7 @@ static int DVDSetArea( input_thread_t * p_input, DVDSeek( p_input, p_method->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 ); } @@ -685,24 +741,26 @@ static void DVDInit( input_thread_t * p_input ) lseek( p_input->i_handle, 0, SEEK_SET ); /* Reading structures initialisation */ - DVDNetlistInit( p_input, 4096, 16384, 4096, DVD_LB_SIZE, - p_method->i_block_once ); - intf_WarnMsg( 2, "DVD: Netlist initialized" ); + p_input->p_method_data = + DVDNetlistInit( 4096, 16384, 4096, DVD_LB_SIZE, p_method->i_block_once ); + intf_WarnMsg( 2, "dvd info: netlist initialized" ); /* Ifo initialisation */ p_method->ifo = IfoInit( p_input->i_handle ); - intf_WarnMsg( 2, "Ifo: VMG initialized" ); + intf_WarnMsg( 2, "ifo info: vmg initialized" ); /* CSS initialisation */ 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" ); + p_input->b_error = 1; return; } + intf_WarnMsg( 2, "css info: initialized" ); } @@ -712,15 +770,12 @@ static void DVDInit( input_thread_t * p_input ) /* Set stream and area data */ vlc_mutex_lock( &p_input->stream.stream_lock ); - /* FIXME: We consider here that one title is one title set - * it is not true !!! */ - - intf_WarnMsg( 2, "DVD: Number of titles: %d", - p_method->ifo.vmg.mat.i_tts_nb ); +#define srpt p_method->ifo.vmg.ptt_srpt + intf_WarnMsg( 2, "dvd info: number of titles: %d", srpt.i_ttu_nb ); #define area p_input->stream.pp_areas /* 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 ); @@ -735,23 +790,24 @@ static void DVDInit( input_thread_t * p_input ) area[i]->i_size = 0; /* 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; + /* Offset to vts_i_0.ifo */ 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 vlc_mutex_unlock( &p_input->stream.stream_lock ); /* Get requested title - if none try to find one where is the movie */ - i_title = main_GetIntVariable( INPUT_TITLE_VAR, - p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb ); - if( i_title <= 0 || i_title >= p_method->ifo.vmg.mat.i_tts_nb ) + i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 ); + if( i_title <= 0 || i_title > srpt.i_ttu_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 */ i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 ); @@ -780,12 +836,16 @@ static void DVDInit( input_thread_t * p_input ) *****************************************************************************/ static void DVDEnd( input_thread_t * p_input ) { - /* FIXME: check order of calls */ -// CSSEnd( p_input ); -// IfoEnd( (ifo_t*)(&p_input->p_plugin_data->ifo ) ); - free( p_input->stream.p_demux_data ); - free( p_input->p_plugin_data ); - DVDNetlistEnd( p_input ); + thread_dvd_data_t * p_method; + dvd_netlist_t * p_netlist; + + p_method = (thread_dvd_data_t*)p_input->p_plugin_data; + p_netlist = (dvd_netlist_t *)p_input->p_method_data; + + 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, data_packet_t ** pp_packets ) { thread_dvd_data_t * p_method; - netlist_t * p_netlist; + dvd_netlist_t * p_netlist; struct iovec * p_vec; struct data_packet_s * pp_data[p_input->i_read_once]; u8 * pi_cur; @@ -807,8 +867,8 @@ static int DVDRead( input_thread_t * p_input, int i_packet; int i_pos; - p_method = ( thread_dvd_data_t * ) p_input->p_plugin_data; - p_netlist = ( netlist_t * ) p_input->p_method_data; + p_method = (thread_dvd_data_t *)p_input->p_plugin_data; + p_netlist = (dvd_netlist_t *)p_input->p_method_data; /* Get an iovec pointer */ if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL ) @@ -829,7 +889,7 @@ static int DVDRead( input_thread_t * p_input, { 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 ); ((u8*)(p_vec[i_iovec].iov_base))[0x14] &= 0x8F; } diff --git a/plugins/dvd/input_dvd.h b/plugins/dvd/input_dvd.h index b50f2a7476..5c7348f941 100644 --- a/plugins/dvd/input_dvd.h +++ b/plugins/dvd/input_dvd.h @@ -37,12 +37,17 @@ typedef struct thread_dvd_data_s int i_block_once; // Nb of block read once by // readv + /* Navigation information */ + int i_title; + int i_vts_title; int i_chapter_nb; off_t i_start; off_t i_size; + int i_end_cell; + /* Scrambling Information */ - struct css_s css; + struct css_s * p_css; /* Structure that contains all information of the DVD */ struct ifo_s ifo; @@ -52,16 +57,17 @@ typedef struct thread_dvd_data_s /***************************************************************************** * Prototypes in dvd_ifo.c *****************************************************************************/ -struct ifo_s IfoInit( int ); -int IfoReadVTS( struct ifo_s * ); -void IfoRead( struct ifo_s * ); -void IfoEnd( ifo_t * ); +struct ifo_s IfoInit ( int ); +int IfoReadVTS ( struct ifo_s * ); +void IfoRead ( struct ifo_s * ); +void IfoEnd ( ifo_t * ); /***************************************************************************** * Prototypes in dvd_css.c *****************************************************************************/ -int CSSTest ( int ); -struct css_s CSSInit ( int ); -int CSSGetKey ( struct css_s * ); -int CSSDescrambleSector( u8 * , u8 * ); +int CSSTest ( int ); +struct css_s * CSSInit ( int ); +void CSSEnd ( struct css_s * ); +int CSSGetKey ( struct css_s * ); +int CSSDescrambleSector ( u8 * , u8 * );