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

. Correction of bugs in ifo parsing. Now the structures should be well

initialized. It remains some segfaults but it globally works.
. DVD mode is enabled with option --dvd. For the moment, it only read
the first vts and find the movie if it is at the beginning of the title
set.

Coming soon:
. udf filesystem management to access over 2Gb zones.
. detection of the offset to the movie inside a vts when it is not at
the beginning.

Is there a chance that using fopen/fseek function instead of open/lseek
system calls solve the 2Gb issue ?
parent a9729877
...@@ -128,9 +128,12 @@ void IfoEnd( ifo_t* p_ifo ) ...@@ -128,9 +128,12 @@ void IfoEnd( ifo_t* p_ifo )
} }
free( p_ifo->p_vts[j].tmap_ti.pi_sbyte ); free( p_ifo->p_vts[j].tmap_ti.pi_sbyte );
free( p_ifo->p_vts[j].tmap_ti.p_tmap ); free( p_ifo->p_vts[j].tmap_ti.p_tmap );
free( p_ifo->p_vts[j].pgci_ti.p_lu_desc ); free( p_ifo->p_vts[j].pgci_ti.p_srp );
free( p_ifo->p_vts[j].pgci_ti.p_lu ); for( i=0 ; i<p_ifo->p_vts[j].pgci_ut.i_lu_nb ; i++ )
free( p_ifo->p_vts[j].pgci_ut.p_lu_desc ); {
free( p_ifo->p_vts[j].pgci_ut.p_pgci_inf[i].p_srp );
}
free( p_ifo->p_vts[j].pgci_ut.p_pgci_inf );
free( p_ifo->p_vts[j].pgci_ut.p_lu ); free( p_ifo->p_vts[j].pgci_ut.p_lu );
} }
...@@ -141,9 +144,9 @@ void IfoEnd( ifo_t* p_ifo ) ...@@ -141,9 +144,9 @@ void IfoEnd( ifo_t* p_ifo )
free( p_ifo->vmg.c_adt.p_cell_inf ); free( p_ifo->vmg.c_adt.p_cell_inf );
for( i=0 ; i<p_ifo->vmg.pgci_ut.i_lu_nb ; i++ ) for( i=0 ; i<p_ifo->vmg.pgci_ut.i_lu_nb ; i++ )
{ {
free( p_ifo->vmg.pgci_ut.p_lu[i].p_srp ); free( p_ifo->vmg.pgci_ut.p_pgci_inf[i].p_srp );
} }
free( p_ifo->vmg.pgci_ut.p_lu_desc ); free( p_ifo->vmg.pgci_ut.p_pgci_inf );
free( p_ifo->vmg.pgci_ut.p_lu ); free( p_ifo->vmg.pgci_ut.p_lu );
for( i=1 ; i<=8 ; i++ ) for( i=1 ; i<=8 ; i++ )
{ {
...@@ -169,50 +172,53 @@ void IfoEnd( ifo_t* p_ifo ) ...@@ -169,50 +172,53 @@ void IfoEnd( ifo_t* p_ifo )
#define GET( p_field , i_len ) \ #define GET( p_field , i_len ) \
{ \ { \
read( p_ifo->i_fd , p_field , i_len ); \ read( p_ifo->i_fd , (p_field) , (i_len) ); \
fprintf(stderr, "Pos : %d\n", p_ifo->i_pos - i_start); \ fprintf(stderr, "Pos : %d Val : %llx\n", p_ifo->i_pos - i_start, \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + i_len , SEEK_SET );\ (long long int) *(p_field) ); \
p_ifo->i_pos = \
lseek( p_ifo->i_fd, p_ifo->i_pos + (i_len), SEEK_SET ); \
} }
#define GETC( p_field ) \ #define GETC( p_field ) \
{ \ { \
read( p_ifo->i_fd , p_field , 1 ); \ read( p_ifo->i_fd , (p_field) , 1 ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \ fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \ *(p_field) ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET ); \ p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET ); \
} }
#define GETS( p_field ) \ #define GETS( p_field ) \
{ \ { \
read( p_ifo->i_fd , p_field , 2 ); \ read( p_ifo->i_fd , (p_field) , 2 ); \
*p_field = ntohs( *p_field ); \ *(p_field) = ntohs( *(p_field) ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \ fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \ *(p_field) ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET ); \ p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET ); \
} }
#define GETL( p_field ) \ #define GETL( p_field ) \
{ \ { \
read( p_ifo->i_fd , p_field , 4 ); \ read( p_ifo->i_fd , (p_field) , 4 ); \
*p_field = ntohl( *p_field ); \ *(p_field) = ntohl( *(p_field) ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \ fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \ *(p_field) ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET ); \ p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET ); \
} }
#define GETLL( p_field ) \ #define GETLL( p_field ) \
{ \ { \
read( p_ifo->i_fd , p_field , 8 ); \ read( p_ifo->i_fd , (p_field) , 8 ); \
*p_field = ntoh64( *p_field ); \ *(p_field) = ntoh64( *(p_field) ); \
fprintf(stderr, "Pos : %d Value : %lld\n", p_ifo->i_pos - i_start, \ fprintf(stderr, "Pos : %d Value : %lld\n", p_ifo->i_pos - i_start, \
*p_field ); \ *(p_field) ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET ); \ p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET ); \
} }
#define FLUSH( i_len ) \ #define FLUSH( i_len ) \
{ \ { \
fprintf(stderr, "Pos : %d\n", p_ifo->i_pos - i_start ); \ fprintf(stderr, "Pos : %d\n", p_ifo->i_pos - i_start ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + i_len , SEEK_SET );\ p_ifo->i_pos = lseek( p_ifo->i_fd , \
p_ifo->i_pos + (i_len), SEEK_SET ); \
} }
/* /*
...@@ -266,15 +272,23 @@ fprintf( stderr, "PGC\n" ); ...@@ -266,15 +272,23 @@ fprintf( stderr, "PGC\n" );
GETS( &pgc.com_tab.i_pre_com_nb ); GETS( &pgc.com_tab.i_pre_com_nb );
GETS( &pgc.com_tab.i_post_com_nb ); GETS( &pgc.com_tab.i_post_com_nb );
GETS( &pgc.com_tab.i_cell_com_nb ); GETS( &pgc.com_tab.i_cell_com_nb );
pgc.com_tab.psz_pre_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb)); FLUSH( 2 );
if( pgc.com_tab.i_pre_com_nb )
{
pgc.com_tab.psz_pre_com =
malloc(8*pgc.com_tab.i_pre_com_nb);
if( pgc.com_tab.psz_pre_com == NULL ) if( pgc.com_tab.psz_pre_com == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1; p_ifo->b_error = 1;
return pgc; return pgc;
} }
GET( pgc.com_tab.psz_pre_com, 8*pgc.com_tab.i_pre_com_nb ); GET( pgc.com_tab.psz_pre_com, (8*pgc.com_tab.i_pre_com_nb) );
pgc.com_tab.psz_post_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb)); }
if( pgc.com_tab.i_post_com_nb )
{
pgc.com_tab.psz_post_com =
malloc(8*pgc.com_tab.i_post_com_nb);
if( pgc.com_tab.psz_post_com == NULL ) if( pgc.com_tab.psz_post_com == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
...@@ -282,7 +296,11 @@ fprintf( stderr, "PGC\n" ); ...@@ -282,7 +296,11 @@ fprintf( stderr, "PGC\n" );
return pgc; return pgc;
} }
GET( pgc.com_tab.psz_post_com, 8*pgc.com_tab.i_post_com_nb ); GET( pgc.com_tab.psz_post_com, 8*pgc.com_tab.i_post_com_nb );
pgc.com_tab.psz_cell_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb)); }
if( pgc.com_tab.i_cell_com_nb )
{
pgc.com_tab.psz_cell_com =
malloc(8*pgc.com_tab.i_cell_com_nb);
if( pgc.com_tab.psz_cell_com == NULL ) if( pgc.com_tab.psz_cell_com == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
...@@ -291,12 +309,13 @@ fprintf( stderr, "PGC\n" ); ...@@ -291,12 +309,13 @@ fprintf( stderr, "PGC\n" );
} }
GET( pgc.com_tab.psz_cell_com, 8*pgc.com_tab.i_cell_com_nb ); GET( pgc.com_tab.psz_cell_com, 8*pgc.com_tab.i_cell_com_nb );
} }
}
/* Parsing of pgc_prg_map_t */ /* Parsing of pgc_prg_map_t */
if( pgc.i_prg_map_sbyte ) if( pgc.i_prg_map_sbyte )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
+ pgc.i_prg_map_sbyte, SEEK_SET ); + pgc.i_prg_map_sbyte, SEEK_SET );
pgc.prg_map.pi_entry_cell = malloc( sizeof(pgc.i_prg_nb) ); pgc.prg_map.pi_entry_cell = malloc( pgc.i_prg_nb *sizeof(u8) );
if( pgc.prg_map.pi_entry_cell == NULL ) if( pgc.prg_map.pi_entry_cell == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
...@@ -322,7 +341,7 @@ fprintf( stderr, "PGC\n" ); ...@@ -322,7 +341,7 @@ fprintf( stderr, "PGC\n" );
{ {
GETS( &pgc.p_cell_play_inf[i].i_cat ); GETS( &pgc.p_cell_play_inf[i].i_cat );
GETC( &pgc.p_cell_play_inf[i].i_still_time ); GETC( &pgc.p_cell_play_inf[i].i_still_time );
GETS( &pgc.p_cell_play_inf[i].i_com_nb ); GETC( &pgc.p_cell_play_inf[i].i_com_nb );
GETL( &pgc.p_cell_play_inf[i].i_play_time ); GETL( &pgc.p_cell_play_inf[i].i_play_time );
GETL( &pgc.p_cell_play_inf[i].i_entry_sector ); GETL( &pgc.p_cell_play_inf[i].i_entry_sector );
GETL( &pgc.p_cell_play_inf[i].i_first_ilvu_vobu_esector ); GETL( &pgc.p_cell_play_inf[i].i_first_ilvu_vobu_esector );
...@@ -354,75 +373,88 @@ fprintf( stderr, "PGC\n" ); ...@@ -354,75 +373,88 @@ fprintf( stderr, "PGC\n" );
} }
/***************************************************************************** /*****************************************************************************
* ReadUnitTable : Fills the Language Unit structure. * ReadUnit : Fills Menu Language Unit Table/ PGC Info Table
*****************************************************************************/ *****************************************************************************/
static pgci_ut_t ReadUnitTable( ifo_t* p_ifo ) static pgci_inf_t ReadUnit( ifo_t* p_ifo )
{ {
pgci_ut_t lang; pgci_inf_t inf;
int i, j; int i;
int i_start = p_ifo->i_pos; int i_start = p_ifo->i_pos;
fprintf( stderr, "LU\n" ); fprintf( stderr, "Unit\n" );
GETS( &lang.i_lu_nb ); GETS( &inf.i_srp_nb );
FLUSH( 2 ); FLUSH( 2 );
GETL( &lang.i_ebyte ); GETL( &inf.i_lu_ebyte );
lang.p_lu_desc = malloc( lang.i_lu_nb *sizeof(pgci_lu_desc_t) ); inf.p_srp = malloc( inf.i_srp_nb *sizeof(pgci_srp_t) );
if( lang.p_lu_desc == NULL ) if( inf.p_srp == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1; p_ifo->b_error = 1;
return lang; return inf;
}
for( i=0 ; i<lang.i_lu_nb ; i++ )
{
GETS( &lang.p_lu_desc[i].i_lang_code );
FLUSH( 1 );
GETC( &lang.p_lu_desc[i].i_existence_mask );
GETL( &lang.p_lu_desc[i].i_lu_sbyte );
} }
lang.p_lu = malloc( lang.i_lu_nb *sizeof(pgci_lu_t) ); for( i=0 ; i<inf.i_srp_nb ; i++ )
if( lang.p_lu == NULL )
{ {
intf_ErrMsg( "Out of memory" ); GETC( &inf.p_srp[i].i_pgc_cat_mask );
p_ifo->b_error = 1; GETC( &inf.p_srp[i].i_pgc_cat );
return lang; GETS( &inf.p_srp[i].i_par_mask );
GETL( &inf.p_srp[i].i_pgci_sbyte );
} }
for( i=0 ; i<lang.i_lu_nb ; i++ ) for( i=0 ; i<inf.i_srp_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start + p_ifo->i_pos = lseek( p_ifo->i_fd,
lang.p_lu_desc[i].i_lu_sbyte, i_start + inf.p_srp[i].i_pgci_sbyte,
SEEK_SET ); SEEK_SET );
GETS( &lang.p_lu[i].i_srp_nb ); inf.p_srp[i].pgc = ReadPGC( p_ifo );
}
return inf;
}
/*****************************************************************************
* ReadUnitTable : Fills the PGCI Unit structure.
*****************************************************************************/
static pgci_ut_t ReadUnitTable( ifo_t* p_ifo )
{
pgci_ut_t pgci;
int i;
int i_start = p_ifo->i_pos;
fprintf( stderr, "Unit Table\n" );
GETS( &pgci.i_lu_nb );
FLUSH( 2 ); FLUSH( 2 );
GETL( &lang.p_lu[i].i_lu_ebyte ); GETL( &pgci.i_ebyte );
lang.p_lu[i].p_srp = malloc( lang.p_lu[i].i_srp_nb * pgci.p_lu = malloc( pgci.i_lu_nb *sizeof(pgci_lu_t) );
sizeof(pgci_srp_t) ); if( pgci.p_lu == NULL )
if( lang.p_lu[i].p_srp == NULL )
{ {
intf_ErrMsg( "Out of memory" ); intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1; p_ifo->b_error = 1;
return lang; return pgci;
} }
for( j=0 ; j<lang.p_lu[i].i_srp_nb ; j++ ) for( i=0 ; i<pgci.i_lu_nb ; i++ )
{ {
GETC( &lang.p_lu[i].p_srp[j].i_pgc_cat_mask ); GETS( &pgci.p_lu[i].i_lang_code );
GETC( &lang.p_lu[i].p_srp[j].i_pgc_cat ); FLUSH( 1 );
GETS( &lang.p_lu[i].p_srp[j].i_par_mask ); GETC( &pgci.p_lu[i].i_existence_mask );
GETL( &lang.p_lu[i].p_srp[j].i_pgci_sbyte ); GETL( &pgci.p_lu[i].i_lu_sbyte );
} }
for( j=0 ; j<lang.p_lu[i].i_srp_nb ; j++ ) pgci.p_pgci_inf = malloc( pgci.i_lu_nb *sizeof(pgci_inf_t) );
if( pgci.p_pgci_inf == NULL )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, intf_ErrMsg( "Out of memory" );
i_start + lang.p_lu[i].p_srp[j].i_pgci_sbyte, p_ifo->b_error = 1;
SEEK_SET ); return pgci;
/* FIXME : Bad parsing somiewhere by here : various information
* don't match */
//lang.p_lu[i].p_srp[j].pgc = ReadPGC( p_ifo );
} }
for( i=0 ; i<pgci.i_lu_nb ; i++ )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
pgci.p_lu[i].i_lu_sbyte,
SEEK_SET );
pgci.p_pgci_inf[i] = ReadUnit( p_ifo );
} }
return lang; return pgci;
} }
/***************************************************************************** /*****************************************************************************
...@@ -965,7 +997,7 @@ static vts_t ReadVTS( ifo_t* p_ifo ) ...@@ -965,7 +997,7 @@ static vts_t ReadVTS( ifo_t* p_ifo )
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
vts.mat.i_pgcit_ssector *DVD_LB_SIZE, vts.mat.i_pgcit_ssector *DVD_LB_SIZE,
SEEK_SET ); SEEK_SET );
vts.pgci_ti = ReadUnitTable( p_ifo ); vts.pgci_ti = ReadUnit( p_ifo );
} }
if( vts.mat.i_tmap_ti_ssector ) if( vts.mat.i_tmap_ti_ssector )
{ {
......
...@@ -118,13 +118,13 @@ typedef struct pgc_s ...@@ -118,13 +118,13 @@ typedef struct pgc_s
*/ */
/* Menu PGCI Language unit Descriptor */ /* Menu PGCI Language unit Descriptor */
typedef struct pgci_lu_desc_s typedef struct pgci_lu_s
{ {
u16 i_lang_code; // 2 bytes (ISO-xx) u16 i_lang_code; // 2 bytes (ISO-xx)
// char ??? // char ???
u8 i_existence_mask; // 1 byte u8 i_existence_mask; // 1 byte
u32 i_lu_sbyte; // 4 bytes u32 i_lu_sbyte; // 4 bytes
} pgci_lu_desc_t; } pgci_lu_t;
typedef struct pgci_srp_s typedef struct pgci_srp_s
{ {
...@@ -137,13 +137,13 @@ typedef struct pgci_srp_s ...@@ -137,13 +137,13 @@ typedef struct pgci_srp_s
/* Menu PGCI Language Unit Table /* Menu PGCI Language Unit Table
* - start at i_lu_sbyte */ * - start at i_lu_sbyte */
typedef struct pgci_lu_s typedef struct pgci_inf_s
{ {
u16 i_srp_nb; // 2 bytes u16 i_srp_nb; // 2 bytes
// char[2] ??? // char[2] ???
u32 i_lu_ebyte; // 4 bytes u32 i_lu_ebyte; // 4 bytes
pgci_srp_t* p_srp; // i_srp_nb * 8 bytes pgci_srp_t* p_srp; // i_srp_nb * 8 bytes
} pgci_lu_t; } pgci_inf_t;
/* Main Struct for Menu PGCI /* Main Struct for Menu PGCI
* - start at i_*_pgci_ut_ssector */ * - start at i_*_pgci_ut_ssector */
...@@ -152,8 +152,8 @@ typedef struct pgci_ut_s ...@@ -152,8 +152,8 @@ typedef struct pgci_ut_s
u16 i_lu_nb; // 2 bytes; ??? u16 i_lu_nb; // 2 bytes; ???
// char[2] ??? // char[2] ???
u32 i_ebyte; // 4 bytes u32 i_ebyte; // 4 bytes
pgci_lu_desc_t* p_lu_desc; // i_lu_nb * 8 bytes
pgci_lu_t* p_lu; // i_lu_nb * 8 bytes pgci_lu_t* p_lu; // i_lu_nb * 8 bytes
pgci_inf_t* p_pgci_inf; // i_lu_nb * 8 bytes
} pgci_ut_t; } pgci_ut_t;
/* /*
...@@ -445,7 +445,7 @@ typedef struct vts_s ...@@ -445,7 +445,7 @@ typedef struct vts_s
/* Video Title Set Menu PGCI Unit Table */ /* Video Title Set Menu PGCI Unit Table */
pgci_ut_t pgci_ut; pgci_ut_t pgci_ut;
/* Video Title Set Program Chain Info Table */ /* Video Title Set Program Chain Info Table */
pgci_ut_t pgci_ti; pgci_inf_t pgci_ti;
/* Video Title Set Time Map Table */ /* Video Title Set Time Map Table */
vts_tmap_ti_t tmap_ti; vts_tmap_ti_t tmap_ti;
/* VTSM Cell Adress Table Information */ /* VTSM Cell Adress Table Information */
......
...@@ -88,7 +88,7 @@ static int DVDProbe( input_thread_t * p_input ) ...@@ -88,7 +88,7 @@ static int DVDProbe( input_thread_t * p_input )
static void DVDInit( input_thread_t * p_input ) static void DVDInit( input_thread_t * p_input )
{ {
thread_dvd_data_t * p_method; thread_dvd_data_t * p_method;
u32 i_start;// = 2048*90000; u32 i_start;
if( (p_method = malloc( sizeof(thread_dvd_data_t) )) == NULL ) if( (p_method = malloc( sizeof(thread_dvd_data_t) )) == NULL )
{ {
...@@ -101,17 +101,13 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -101,17 +101,13 @@ static void DVDInit( input_thread_t * p_input )
lseek( p_input->i_handle, 0, SEEK_SET ); lseek( p_input->i_handle, 0, SEEK_SET );
vlc_mutex_lock( &p_input->stream.stream_lock ); /* Ifo initialisation */
p_method->ifo = IfoInit( p_input->i_handle ); p_method->ifo = IfoInit( p_input->i_handle );
IfoRead( &(p_method->ifo) ); IfoRead( &(p_method->ifo) );
vlc_mutex_unlock( &p_input->stream.stream_lock );
i_start = p_method->ifo.p_vts[0].i_pos + i_start = p_method->ifo.p_vts[0].i_pos +
p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE; p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
fprintf(stderr, "Begin at : %d\n", i_start ); fprintf(stderr, "Begin at : %d\n", i_start );
lseek( p_input->i_handle, i_start, SEEK_SET ); lseek( p_input->i_handle, i_start, SEEK_SET );
input_InitStream( p_input, sizeof( stream_ps_data_t ) ); input_InitStream( p_input, sizeof( stream_ps_data_t ) );
......
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