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 @@
* 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: Stphane Borel <stef@via.ecp.fr>
*
......@@ -35,6 +35,7 @@
#include "defs.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
......@@ -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;
......
......@@ -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: Stphane Borel <stef@via.ecp.fr>
*
......@@ -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];
......
......@@ -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 <henri@videolan.org>
* Stphane Borel <stef@videolan.org>
......@@ -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 );
}
......@@ -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 <henri@videolan.org>
* Stphane Borel <stef@videolan.org>
......@@ -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 * );
......@@ -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: Stphane Borel <stef@via.ecp.fr>
*
......@@ -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;
}
......
......@@ -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 * );
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