Commit 7fecb798 authored by Stéphane Borel's avatar Stéphane Borel

-Fixed a bug in area management added in my last commit

-Change the way ifo are read ; I hope this fixes problems with some
compilers

-Added error checks in dvd input
parent 3ad76f44
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing * dvd_ifo.c: Functions for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.18 2001/04/10 17:47:05 stef Exp $ * $Id: dvd_ifo.c,v 1.19 2001/04/12 02:40:09 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -50,78 +50,83 @@ ...@@ -50,78 +50,83 @@
* Local prototypes * Local prototypes
*/ */
void CommandRead ( command_desc_t ); void CommandRead ( command_desc_t );
static int ReadTitle ( ifo_t * , title_t * ); static int ReadTitle ( ifo_t * , title_t *, off_t );
static int FreeTitle ( title_t * ); static int FreeTitle ( title_t * );
static int ReadUnitInf ( ifo_t * , unit_inf_t * ); static int ReadUnitInf ( ifo_t * , unit_inf_t *, off_t );
static int FreeUnitInf ( unit_inf_t * ); static int FreeUnitInf ( unit_inf_t * );
static int ReadTitleUnit ( ifo_t * , title_unit_t * ); static int ReadTitleUnit ( ifo_t * , title_unit_t *, off_t );
static int FreeTitleUnit ( title_unit_t * ); static int FreeTitleUnit ( title_unit_t * );
static int ReadVobuMap ( ifo_t * , vobu_map_t * ); static int ReadVobuMap ( ifo_t * , vobu_map_t *, off_t );
static int FreeVobuMap ( vobu_map_t * ); static int FreeVobuMap ( vobu_map_t * );
static int ReadCellInf ( ifo_t * , cell_inf_t * ); static int ReadCellInf ( ifo_t * , cell_inf_t *, off_t );
static int FreeCellInf ( cell_inf_t * ); static int FreeCellInf ( cell_inf_t * );
static int FreeTitleSet ( vts_t * ); static int FreeTitleSet ( vts_t * );
/* /*****************************************************************************
* Macros to process ifo files * ReadByte and so
*/ *****************************************************************************/
static __inline__ u8* FillBuffer( ifo_t* p_ifo, u8* pi_buffer, off_t i_pos )
#define GET( p_field , i_len ) \ {
{ \ memset( pi_buffer, 0, DVD_LB_SIZE );
read( p_ifo->i_fd , (p_field) , (i_len) ); \ p_ifo->i_pos = lseek( p_ifo->i_fd, i_pos, SEEK_SET );
/* fprintf(stderr, "Pos : %lld Val : %llx\n", \ read( p_ifo->i_fd, pi_buffer, DVD_LB_SIZE );
(long long)(p_ifo->i_pos - i_start), \
(long long)*(p_field) ); */ \
p_ifo->i_pos += i_len; \
}
#define GETC( p_field ) \ return pi_buffer;
{ \ }
read( p_ifo->i_fd , (p_field) , 1 ); \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); */ \
p_ifo->i_pos += 1; \
}
#define GETS( p_field ) \ static __inline__ u8 ReadByte( u8** ppi_buffer )
{ \ {
read( p_ifo->i_fd , (p_field) , 2 ); \ u8 i_ret;
*(p_field) = ntohs( *(p_field) ); \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); */ \
p_ifo->i_pos += 2; \
}
#define GETL( p_field ) \ i_ret = *(*ppi_buffer)++;
{ \
read( p_ifo->i_fd , (p_field) , 4 ); \
*(p_field) = ntohl( *(p_field) ); \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); */ \
p_ifo->i_pos += 4; \
}
#define GETLL( p_field ) \ return i_ret;
{ \ }
read( p_ifo->i_fd , (p_field) , 8 ); \
*(p_field) = ntoh64( *(p_field) ); \
/*fprintf(stderr, "Pos : %lld Value : %lld\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); */ \
p_ifo->i_pos += 8; \
}
#define FLUSH( i_len ) \ static __inline__ u16 ReadWord( u8** ppi_buffer )
{ \ {
/*fprintf(stderr, "Pos : %lld\n", (long long)(p_ifo->i_pos - i_start));*/ \ u16 i_ret;
p_ifo->i_pos = lseek( p_ifo->i_fd , \
p_ifo->i_pos + (i_len), SEEK_SET ); \ i_ret = U16_AT(*ppi_buffer);
} (*ppi_buffer) += 2;
return i_ret;
}
static __inline__ u32 ReadDouble( u8** ppi_buffer )
{
u32 i_ret;
i_ret = U32_AT(*ppi_buffer);
(*ppi_buffer) += 4;
return i_ret;
}
static __inline__ u64 ReadQuad( u8** ppi_buffer )
{
u64 i_ret;
i_ret = U64_AT(*ppi_buffer);
(*ppi_buffer) += 8;
return i_ret;
}
static __inline__ void ReadBits( u8** ppi_buffer, u8* pi_dest, int i_nb )
{
memcpy( pi_dest, *ppi_buffer, i_nb );
*ppi_buffer += i_nb;
return;
}
static __inline__ void DumpBits( u8** ppi_buffer, int i_nb )
{
*ppi_buffer += i_nb;
return;
}
/* /*
* IFO Management. * IFO Management.
...@@ -150,6 +155,8 @@ int IfoCreate( thread_dvd_data_t * p_dvd ) ...@@ -150,6 +155,8 @@ int IfoCreate( thread_dvd_data_t * p_dvd )
*****************************************************************************/ *****************************************************************************/
int IfoInit( ifo_t * p_ifo ) int IfoInit( ifo_t * p_ifo )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8* p_current;
u64 i_temp; u64 i_temp;
u32 i_lba; u32 i_lba;
int i, j, k; int i, j, k;
...@@ -159,8 +166,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -159,8 +166,8 @@ int IfoInit( ifo_t * p_ifo )
i_lba = UDFFindFile( p_ifo->i_fd, "/VIDEO_TS/VIDEO_TS.IFO"); i_lba = UDFFindFile( p_ifo->i_fd, "/VIDEO_TS/VIDEO_TS.IFO");
p_ifo->i_off = (off_t)(i_lba) * DVD_LB_SIZE; p_ifo->i_off = (off_t)(i_lba) * DVD_LB_SIZE;
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off, SEEK_SET );
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off );
//i_start = p_ifo->i_pos; //i_start = p_ifo->i_pos;
/* /*
* read the video manager information table * read the video manager information table
...@@ -168,59 +175,57 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -168,59 +175,57 @@ int IfoInit( ifo_t * p_ifo )
#define manager_inf p_ifo->vmg.manager_inf #define manager_inf p_ifo->vmg.manager_inf
//fprintf( stderr, "VMGI\n" ); //fprintf( stderr, "VMGI\n" );
GET( manager_inf.psz_id , 12 ); ReadBits( &p_current, manager_inf.psz_id, 12 );
manager_inf.psz_id[12] = '\0'; manager_inf.psz_id[12] = '\0';
GETL( &manager_inf.i_vmg_end_sector ); manager_inf.i_vmg_end_sector = ReadDouble( &p_current );
FLUSH( 12 ); DumpBits( &p_current, 12 );
GETL( &manager_inf.i_vmg_inf_end_sector ); manager_inf.i_vmg_inf_end_sector = ReadDouble( &p_current );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &manager_inf.i_spec_ver ); manager_inf.i_spec_ver = ReadByte( &p_current );
GETL( &manager_inf.i_cat ); manager_inf.i_cat = ReadDouble( &p_current );
GETS( &manager_inf.i_volume_nb ); manager_inf.i_volume_nb = ReadWord( &p_current );
GETS( &manager_inf.i_volume ); manager_inf.i_volume = ReadWord( &p_current );
GETC( &manager_inf.i_disc_side ); manager_inf.i_disc_side = ReadByte( &p_current );
FLUSH( 19 ); DumpBits( &p_current, 19 );
GETS( &manager_inf.i_title_set_nb ); manager_inf.i_title_set_nb = ReadWord( &p_current );
GET( manager_inf.ps_provider_id, 32 ); ReadBits( &p_current, manager_inf.ps_provider_id, 32 );
GETLL( &manager_inf.i_pos_code ); manager_inf.i_pos_code = ReadQuad( &p_current );
FLUSH( 24 ); DumpBits( &p_current, 24 );
GETL( &manager_inf.i_vmg_inf_end_byte ); manager_inf.i_vmg_inf_end_byte = ReadDouble( &p_current );
GETL( &manager_inf.i_first_play_title_start_byte ); manager_inf.i_first_play_title_start_byte = ReadDouble( &p_current );
FLUSH( 56 ); DumpBits( &p_current, 56 );
GETL( &manager_inf.i_vob_start_sector ); manager_inf.i_vob_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_title_inf_start_sector ); manager_inf.i_title_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_title_unit_start_sector ); manager_inf.i_title_unit_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_parental_inf_start_sector ); manager_inf.i_parental_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_vts_inf_start_sector ); manager_inf.i_vts_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_text_data_start_sector ); manager_inf.i_text_data_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_cell_inf_start_sector ); manager_inf.i_cell_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_vobu_map_start_sector ); manager_inf.i_vobu_map_start_sector = ReadDouble( &p_current );
FLUSH( 32 ); DumpBits( &p_current, 32 );
// GETS( &manager_inf.video_atrt ); // GETS( &manager_inf.video_atrt );
FLUSH(2); DumpBits( &p_current, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &manager_inf.i_audio_nb ); manager_inf.i_audio_nb = ReadByte( &p_current );
//fprintf( stderr, "vmgi audio nb : %d\n", manager_inf.i_audio_nb ); //fprintf( stderr, "vmgi audio nb : %d\n", manager_inf.i_audio_nb );
for( i=0 ; i < 8 ; i++ ) for( i=0 ; i < 8 ; i++ )
{ {
GETLL( &i_temp ); i_temp = ReadQuad( &p_current );
} }
FLUSH( 17 ); DumpBits( &p_current, 17 );
GETC( &manager_inf.i_spu_nb ); manager_inf.i_spu_nb = ReadByte( &p_current );
//fprintf( stderr, "vmgi subpic nb : %d\n", manager_inf.i_spu_nb ); //fprintf( stderr, "vmgi subpic nb : %d\n", manager_inf.i_spu_nb );
for( i=0 ; i < manager_inf.i_spu_nb ; i++ ) for( i=0 ; i < manager_inf.i_spu_nb ; i++ )
{ {
GET( &i_temp, 6 ); ReadBits( &p_current, (u8*)(&i_temp), 6 );
/* FIXME : take care of endianness */ /* FIXME : take care of endianness */
} }
/* /*
* read first play title. * read first play title.
*/ */
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + if( ReadTitle( p_ifo, &p_ifo->vmg.title, p_ifo->i_off +
manager_inf.i_first_play_title_start_byte, manager_inf.i_first_play_title_start_byte ) < 0 )
SEEK_SET );
if( ReadTitle( p_ifo, &p_ifo->vmg.title ) < 0)
{ {
return -1; return -1;
} }
...@@ -231,15 +236,14 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -231,15 +236,14 @@ int IfoInit( ifo_t * p_ifo )
#define title_inf p_ifo->vmg.title_inf #define title_inf p_ifo->vmg.title_inf
if( manager_inf.i_title_inf_start_sector ) if( manager_inf.i_title_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off +
manager_inf.i_title_inf_start_sector *DVD_LB_SIZE, manager_inf.i_title_inf_start_sector *DVD_LB_SIZE );
SEEK_SET ); //fprintf( stderr, "title inf %lld\n", p_ifo->i_pos );
//fprintf( stderr, "title inf\n" );
GETS( &title_inf.i_title_nb ); title_inf.i_title_nb = ReadWord( &p_current );
//fprintf( stderr, "title_inf: TTU nb %d\n", title_inf.i_title_nb ); //fprintf( stderr, "title_inf: TTU nb %d\n", title_inf.i_title_nb );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &title_inf.i_end_byte ); title_inf.i_end_byte = ReadDouble( &p_current );
/* parsing of title attributes */ /* parsing of title attributes */
title_inf.p_attr = malloc( title_inf.i_title_nb *sizeof(title_attr_t) ); title_inf.p_attr = malloc( title_inf.i_title_nb *sizeof(title_attr_t) );
...@@ -251,13 +255,13 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -251,13 +255,13 @@ int IfoInit( ifo_t * p_ifo )
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < title_inf.i_title_nb ; i++ )
{ {
GETC( &title_inf.p_attr[i].i_play_type ); title_inf.p_attr[i].i_play_type = ReadByte( &p_current );
GETC( &title_inf.p_attr[i].i_angle_nb ); title_inf.p_attr[i].i_angle_nb = ReadByte( &p_current );
GETS( &title_inf.p_attr[i].i_chapter_nb ); title_inf.p_attr[i].i_chapter_nb = ReadWord( &p_current );
GETS( &title_inf.p_attr[i].i_parental_id ); title_inf.p_attr[i].i_parental_id = ReadWord( &p_current );
GETC( &title_inf.p_attr[i].i_title_set_num ); title_inf.p_attr[i].i_title_set_num = ReadByte( &p_current );
GETC( &title_inf.p_attr[i].i_title_num ); title_inf.p_attr[i].i_title_num = ReadByte( &p_current );
GETL( &title_inf.p_attr[i].i_start_sector ); title_inf.p_attr[i].i_start_sector = ReadDouble( &p_current );
//fprintf( stderr, "title_inf: %d %d %d\n",title_inf.p_attr[i].i_chapter_nb ,title_inf.p_attr[i].i_title_set_num,title_inf.p_attr[i].i_title_num ); //fprintf( stderr, "title_inf: %d %d %d\n",title_inf.p_attr[i].i_chapter_nb ,title_inf.p_attr[i].i_title_set_num,title_inf.p_attr[i].i_title_num );
} }
} }
...@@ -272,10 +276,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -272,10 +276,8 @@ int IfoInit( ifo_t * p_ifo )
*/ */
if( manager_inf.i_title_unit_start_sector ) if( manager_inf.i_title_unit_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit, p_ifo->i_off +
manager_inf.i_title_unit_start_sector *DVD_LB_SIZE, manager_inf.i_title_unit_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit ) < 0 )
{ {
return -1; return -1;
} }
...@@ -287,16 +289,15 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -287,16 +289,15 @@ int IfoInit( ifo_t * p_ifo )
#define parental p_ifo->vmg.parental_inf #define parental p_ifo->vmg.parental_inf
if( manager_inf.i_parental_inf_start_sector ) if( manager_inf.i_parental_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off +
manager_inf.i_parental_inf_start_sector *DVD_LB_SIZE, manager_inf.i_parental_inf_start_sector *DVD_LB_SIZE );
SEEK_SET );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "PTL\n" ); //fprintf( stderr, "PTL\n" );
GETS( &parental.i_country_nb ); parental.i_country_nb = ReadWord( &p_current );
GETS( &parental.i_vts_nb ); parental.i_vts_nb = ReadWord( &p_current );
GETL( &parental.i_end_byte ); parental.i_end_byte = ReadDouble( &p_current );
parental.p_parental_desc = malloc( parental.i_country_nb * parental.p_parental_desc = malloc( parental.i_country_nb *
sizeof(parental_desc_t) ); sizeof(parental_desc_t) );
...@@ -308,10 +309,12 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -308,10 +309,12 @@ int IfoInit( ifo_t * p_ifo )
for( i = 0 ; i < parental.i_country_nb ; i++ ) for( i = 0 ; i < parental.i_country_nb ; i++ )
{ {
GET( parental.p_parental_desc[i].ps_country_code, 2 ); ReadBits( &p_current,
FLUSH( 2 ); parental.p_parental_desc[i].ps_country_code, 2 );
GETS( &parental.p_parental_desc[i].i_parental_mask_start_byte ); DumpBits( &p_current, 2 );
FLUSH( 2 ); parental.p_parental_desc[i].i_parental_mask_start_byte =
ReadWord( &p_current );
DumpBits( &p_current, 2 );
} }
parental.p_parental_mask = malloc( parental.i_country_nb * parental.p_parental_mask = malloc( parental.i_country_nb *
...@@ -324,9 +327,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -324,9 +327,8 @@ int IfoInit( ifo_t * p_ifo )
for( i = 0 ; i < parental.i_country_nb ; i++ ) for( i = 0 ; i < parental.i_country_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start + p_current = FillBuffer( p_ifo, pi_buffer, i_start +
parental.p_parental_desc[i].i_parental_mask_start_byte, parental.p_parental_desc[i].i_parental_mask_start_byte );
SEEK_SET );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
parental.p_parental_mask[i].ppi_mask[j] = parental.p_parental_mask[i].ppi_mask[j] =
...@@ -338,7 +340,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -338,7 +340,8 @@ int IfoInit( ifo_t * p_ifo )
} }
for( k = 0 ; k < parental.i_vts_nb + 1 ; k++ ) for( k = 0 ; k < parental.i_vts_nb + 1 ; k++ )
{ {
GETS( &parental.p_parental_mask[i].ppi_mask[j][k] ); parental.p_parental_mask[i].ppi_mask[j][k] =
ReadWord( &p_current );
} }
} }
} }
...@@ -353,17 +356,16 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -353,17 +356,16 @@ int IfoInit( ifo_t * p_ifo )
{ {
u64 i_temp; u64 i_temp;
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_off +
manager_inf.i_vts_inf_start_sector *DVD_LB_SIZE, manager_inf.i_vts_inf_start_sector *DVD_LB_SIZE );
SEEK_SET );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VTS ATTR\n" ); //fprintf( stderr, "VTS ATTR\n" );
GETS( &vts_inf.i_vts_nb ); vts_inf.i_vts_nb = ReadWord( &p_current );;
//fprintf( stderr, "VTS ATTR Nb: %d\n", vts_inf.i_vts_nb ); //fprintf( stderr, "VTS ATTR Nb: %d\n", vts_inf.i_vts_nb );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &vts_inf.i_end_byte ); vts_inf.i_end_byte = ReadDouble( &p_current );
vts_inf.pi_vts_attr_start_byte = vts_inf.pi_vts_attr_start_byte =
malloc( vts_inf.i_vts_nb *sizeof(u32) ); malloc( vts_inf.i_vts_nb *sizeof(u32) );
if( vts_inf.pi_vts_attr_start_byte == NULL ) if( vts_inf.pi_vts_attr_start_byte == NULL )
...@@ -374,7 +376,7 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -374,7 +376,7 @@ int IfoInit( ifo_t * p_ifo )
for( i = 0 ; i < vts_inf.i_vts_nb ; i++ ) for( i = 0 ; i < vts_inf.i_vts_nb ; i++ )
{ {
GETL( &vts_inf.pi_vts_attr_start_byte[i] ); vts_inf.pi_vts_attr_start_byte[i] = ReadDouble( &p_current );
} }
vts_inf.p_vts_attr = malloc( vts_inf.i_vts_nb *sizeof(vts_attr_t) ); vts_inf.p_vts_attr = malloc( vts_inf.i_vts_nb *sizeof(vts_attr_t) );
...@@ -386,44 +388,44 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -386,44 +388,44 @@ int IfoInit( ifo_t * p_ifo )
for( i = 0 ; i < vts_inf.i_vts_nb ; i++ ) for( i = 0 ; i < vts_inf.i_vts_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start + p_current = FillBuffer( p_ifo, pi_buffer, i_start +
vts_inf.pi_vts_attr_start_byte[i], vts_inf.pi_vts_attr_start_byte[i] );
SEEK_SET ); vts_inf.p_vts_attr[i].i_end_byte = ReadDouble( &p_current );
GETL( &vts_inf.p_vts_attr[i].i_end_byte ); vts_inf.p_vts_attr[i].i_cat_app_type = ReadDouble( &p_current );
GETL( &vts_inf.p_vts_attr[i].i_cat_app_type );
// GETS( &vts_inf.p_vts_attr[i].vts_menu_video_attr ); // GETS( &vts_inf.p_vts_attr[i].vts_menu_video_attr );
FLUSH(2); DumpBits( &p_current, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &vts_inf.p_vts_attr[i].i_vts_menu_audio_nb ); vts_inf.p_vts_attr[i].i_vts_menu_audio_nb = ReadByte( &p_current );
//fprintf( stderr, "m audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_audio_nb ); //fprintf( stderr, "m audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_audio_nb );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
GETLL( &i_temp ); i_temp = ReadQuad( &p_current );;
} }
FLUSH( 17 ); DumpBits( &p_current, 17 );
GETC( &vts_inf.p_vts_attr[i].i_vts_menu_spu_nb ); vts_inf.p_vts_attr[i].i_vts_menu_spu_nb = ReadByte( &p_current );
//fprintf( stderr, "m subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_spu_nb ); //fprintf( stderr, "m subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_menu_spu_nb );
for( j = 0 ; j < 28 ; j++ ) for( j = 0 ; j < 28 ; j++ )
{ {
GET( &i_temp, 6 ); ReadBits( &p_current, (u8*)(&i_temp), 6 );
/* FIXME : Fix endianness issue here */ /* FIXME : Fix endianness issue here */
} }
FLUSH( 2 ); DumpBits( &p_current, 2 );
// GETS( &vts_inf.p_vts_attr[i].vtstt_video_vts_inf ); // GETS( &vts_inf.p_vts_attr[i].vtstt_video_vts_inf );
FLUSH(2); DumpBits( &p_current, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETL( &vts_inf.p_vts_attr[i].i_vts_title_audio_nb ); vts_inf.p_vts_attr[i].i_vts_title_audio_nb =
ReadDouble( &p_current );
//fprintf( stderr, "tt audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_audio_nb ); //fprintf( stderr, "tt audio nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_audio_nb );
for( j = 0 ; j < 8 ; j++ ) for( j = 0 ; j < 8 ; j++ )
{ {
GETLL( &i_temp ); i_temp = ReadQuad( &p_current );;
} }
FLUSH( 17 ); DumpBits( &p_current, 17 );
GETC( &vts_inf.p_vts_attr[i].i_vts_title_spu_nb ); vts_inf.p_vts_attr[i].i_vts_title_spu_nb = ReadByte( &p_current );
//fprintf( stderr, "tt subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_spu_nb ); //fprintf( stderr, "tt subp nb : %d\n", vts_inf.p_vts_attr[i].i_vts_title_spu_nb );
for( j=0 ; j<28/*vts_inf.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ ) for( j=0 ; j<28/*vts_inf.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ )
{ {
GET( &i_temp, 6 ); ReadBits( &p_current, (u8*)(&i_temp), 6 );
/* FIXME : Fix endianness issue here */ /* FIXME : Fix endianness issue here */
} }
} }
...@@ -435,10 +437,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -435,10 +437,8 @@ int IfoInit( ifo_t * p_ifo )
*/ */
if( manager_inf.i_cell_inf_start_sector ) if( manager_inf.i_cell_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf, p_ifo->i_off +
manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE, manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf ) < 0 )
{ {
return -1; return -1;
} }
...@@ -449,10 +449,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -449,10 +449,8 @@ int IfoInit( ifo_t * p_ifo )
*/ */
if( manager_inf.i_vobu_map_start_sector ) if( manager_inf.i_vobu_map_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map, p_ifo->i_off +
manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE, manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map ) < 0 )
{ {
return -1; return -1;
} }
...@@ -471,6 +469,8 @@ int IfoInit( ifo_t * p_ifo ) ...@@ -471,6 +469,8 @@ int IfoInit( ifo_t * p_ifo )
*****************************************************************************/ *****************************************************************************/
int IfoTitleSet( ifo_t * p_ifo ) int IfoTitleSet( ifo_t * p_ifo )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8 * p_current;
off_t i_off; off_t i_off;
off_t i_start; off_t i_start;
u64 i_temp; u64 i_temp;
...@@ -488,7 +488,7 @@ int IfoTitleSet( ifo_t * p_ifo ) ...@@ -488,7 +488,7 @@ int IfoTitleSet( ifo_t * p_ifo )
//fprintf(stderr, "offset: %lld\n" , i_off ); //fprintf(stderr, "offset: %lld\n" , i_off );
p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET ); p_current = FillBuffer( p_ifo, pi_buffer, i_off );
//i_start = p_ifo->i_pos; //i_start = p_ifo->i_pos;
p_ifo->vts.i_pos = p_ifo->i_pos; p_ifo->vts.i_pos = p_ifo->i_pos;
...@@ -498,52 +498,52 @@ int IfoTitleSet( ifo_t * p_ifo ) ...@@ -498,52 +498,52 @@ int IfoTitleSet( ifo_t * p_ifo )
*/ */
//fprintf( stderr, "VTSI\n" ); //fprintf( stderr, "VTSI\n" );
GET( manager_inf.psz_id , 12 ); ReadBits( &p_current, manager_inf.psz_id , 12 );
manager_inf.psz_id[12] = '\0'; manager_inf.psz_id[12] = '\0';
GETL( &manager_inf.i_end_sector ); manager_inf.i_end_sector = ReadDouble( &p_current );
FLUSH( 12 ); DumpBits( &p_current, 12 );
GETL( &manager_inf.i_inf_end_sector ); manager_inf.i_inf_end_sector = ReadDouble( &p_current );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &manager_inf.i_spec_ver ); manager_inf.i_spec_ver = ReadByte( &p_current );
GETL( &manager_inf.i_cat ); manager_inf.i_cat = ReadDouble( &p_current );
FLUSH( 90 ); DumpBits( &p_current, 90 );
GETL( &manager_inf.i_inf_end_byte ); manager_inf.i_inf_end_byte = ReadDouble( &p_current );
FLUSH( 60 ); DumpBits( &p_current, 60 );
GETL( &manager_inf.i_menu_vob_start_sector ); manager_inf.i_menu_vob_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_title_vob_start_sector ); manager_inf.i_title_vob_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_title_inf_start_sector ); manager_inf.i_title_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_title_unit_start_sector ); manager_inf.i_title_unit_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_menu_unit_start_sector ); manager_inf.i_menu_unit_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_time_inf_start_sector ); manager_inf.i_time_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_menu_cell_inf_start_sector ); manager_inf.i_menu_cell_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_menu_vobu_map_start_sector ); manager_inf.i_menu_vobu_map_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_cell_inf_start_sector ); manager_inf.i_cell_inf_start_sector = ReadDouble( &p_current );
GETL( &manager_inf.i_vobu_map_start_sector ); manager_inf.i_vobu_map_start_sector = ReadDouble( &p_current );
FLUSH( 24 ); DumpBits( &p_current, 24 );
// GETS( &manager_inf.m_video_atrt ); // GETS( &manager_inf.m_video_atrt );
FLUSH(2); DumpBits( &p_current, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &manager_inf.i_menu_audio_nb ); manager_inf.i_menu_audio_nb = ReadByte( &p_current );
for( i=0 ; i<8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
GETLL( &i_temp ); i_temp = ReadQuad( &p_current );
} }
FLUSH( 17 ); DumpBits( &p_current, 17 );
GETC( &manager_inf.i_menu_spu_nb ); manager_inf.i_menu_spu_nb = ReadByte( &p_current );
for( i=0 ; i<28 ; i++ ) for( i = 0 ; i < 28 ; i++ )
{ {
GET( &i_temp, 6 ); ReadBits( &p_current, (u8*)(&i_temp), 6 );
/* FIXME : take care of endianness */ /* FIXME : take care of endianness */
} }
FLUSH( 2 ); DumpBits( &p_current, 2 );
// GETS( &manager_inf.video_atrt ); // GETS( &manager_inf.video_atrt );
FLUSH(2); DumpBits( &p_current, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &manager_inf.i_audio_nb ); manager_inf.i_audio_nb = ReadByte( &p_current );
//fprintf( stderr, "vtsi audio nb : %d\n", manager_inf.i_audio_nb ); //fprintf( stderr, "vtsi audio nb : %d\n", manager_inf.i_audio_nb );
for( i=0 ; i<8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
GETLL( &i_temp ); i_temp = ReadQuad( &p_current );
//fprintf( stderr, "Audio %d: %llx\n", i, i_temp ); //fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
i_temp >>= 8; i_temp >>= 8;
manager_inf.p_audio_attr[i].i_bar = i_temp & 0xff; manager_inf.p_audio_attr[i].i_bar = i_temp & 0xff;
...@@ -570,12 +570,12 @@ FLUSH(2); ...@@ -570,12 +570,12 @@ FLUSH(2);
i_temp >>= 1; i_temp >>= 1;
manager_inf.p_audio_attr[i].i_coding_mode = i_temp & 0x7; manager_inf.p_audio_attr[i].i_coding_mode = i_temp & 0x7;
} }
FLUSH( 17 ); DumpBits( &p_current, 17 );
GETC( &manager_inf.i_spu_nb ); manager_inf.i_spu_nb = ReadByte( &p_current );
//fprintf( stderr, "vtsi subpic nb : %d\n", manager_inf.i_spu_nb ); //fprintf( stderr, "vtsi subpic nb : %d\n", manager_inf.i_spu_nb );
for( i=0 ; i<manager_inf.i_spu_nb ; i++ ) for( i=0 ; i<manager_inf.i_spu_nb ; i++ )
{ {
GET( &i_temp, 6 ); ReadBits( &p_current, (u8*)(&i_temp), 6 );
i_temp = hton64( i_temp ) >> 16; i_temp = hton64( i_temp ) >> 16;
//fprintf( stderr, "Subpic %d: %llx\n", i, i_temp ); //fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
manager_inf.p_spu_attr[i].i_caption = i_temp & 0xff; manager_inf.p_spu_attr[i].i_caption = i_temp & 0xff;
...@@ -591,18 +591,17 @@ FLUSH(2); ...@@ -591,18 +591,17 @@ FLUSH(2);
#define title_inf p_ifo->vts.title_inf #define title_inf p_ifo->vts.title_inf
if( manager_inf.i_title_inf_start_sector ) if( manager_inf.i_title_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->vts.i_pos +
manager_inf.i_title_inf_start_sector *DVD_LB_SIZE, manager_inf.i_title_inf_start_sector *DVD_LB_SIZE );
SEEK_SET );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VTS PTR\n" ); //fprintf( stderr, "VTS PTR\n" );
GETS( &title_inf.i_title_nb ); title_inf.i_title_nb = ReadWord( &p_current );
//fprintf( stderr, "VTS title_inf nb: %d\n", title_inf.i_title_nb ); //fprintf( stderr, "VTS title_inf nb: %d\n", title_inf.i_title_nb );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &title_inf.i_end_byte ); title_inf.i_end_byte = ReadDouble( &p_current );
title_inf.pi_start_byte = malloc( title_inf.i_title_nb *sizeof(u32) ); title_inf.pi_start_byte = malloc( title_inf.i_title_nb *sizeof(u32) );
if( title_inf.pi_start_byte == NULL ) if( title_inf.pi_start_byte == NULL )
...@@ -613,7 +612,7 @@ FLUSH(2); ...@@ -613,7 +612,7 @@ FLUSH(2);
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < title_inf.i_title_nb ; i++ )
{ {
GETL( &title_inf.pi_start_byte[i] ); title_inf.pi_start_byte[i] = ReadDouble( &p_current );
} }
/* Parsing of tts */ /* Parsing of tts */
...@@ -627,11 +626,12 @@ FLUSH(2); ...@@ -627,11 +626,12 @@ FLUSH(2);
for( i = 0 ; i < title_inf.i_title_nb ; i++ ) for( i = 0 ; i < title_inf.i_title_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start + p_current = FillBuffer( p_ifo, pi_buffer, i_start +
title_inf.pi_start_byte[i], SEEK_SET ); title_inf.pi_start_byte[i] );
GETS( &title_inf.p_title_start[i].i_program_chain_num ); title_inf.p_title_start[i].i_program_chain_num =
GETS( &title_inf.p_title_start[i].i_program_num ); ReadWord( &p_current );
title_inf.p_title_start[i].i_program_num = ReadWord( &p_current );
//fprintf( stderr, "VTS %d title_inf Pgc: %d Prg: %d\n", i,title_inf.p_title_start[i].i_program_chain_num, title_inf.p_title_start[i].i_program_num ); //fprintf( stderr, "VTS %d title_inf Pgc: %d Prg: %d\n", i,title_inf.p_title_start[i].i_program_chain_num, title_inf.p_title_start[i].i_program_num );
} }
} }
...@@ -642,10 +642,8 @@ FLUSH(2); ...@@ -642,10 +642,8 @@ FLUSH(2);
*/ */
if( manager_inf.i_menu_unit_start_sector ) if( manager_inf.i_menu_unit_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit, p_ifo->vts.i_pos +
manager_inf.i_menu_unit_start_sector *DVD_LB_SIZE, manager_inf.i_menu_unit_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit ) < 0 )
{ {
return -1; return -1;
} }
...@@ -656,10 +654,8 @@ FLUSH(2); ...@@ -656,10 +654,8 @@ FLUSH(2);
*/ */
if( manager_inf.i_title_unit_start_sector ) if( manager_inf.i_title_unit_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit, p_ifo->vts.i_pos +
manager_inf.i_title_unit_start_sector *DVD_LB_SIZE, manager_inf.i_title_unit_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit ) < 0 )
{ {
return -1; return -1;
} }
...@@ -671,15 +667,16 @@ FLUSH(2); ...@@ -671,15 +667,16 @@ FLUSH(2);
#define time_inf p_ifo->vts.time_inf #define time_inf p_ifo->vts.time_inf
if( manager_inf.i_time_inf_start_sector ) if( manager_inf.i_time_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + u8 pi_buffer[2*DVD_LB_SIZE];
manager_inf.i_time_inf_start_sector *DVD_LB_SIZE,
SEEK_SET ); p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->vts.i_pos +
manager_inf.i_time_inf_start_sector *DVD_LB_SIZE );
//fprintf( stderr, "TMAP\n" ); //fprintf( stderr, "TMAP\n" );
GETS( &time_inf.i_nb ); time_inf.i_nb = ReadWord( &p_current );;
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &time_inf.i_end_byte ); time_inf.i_end_byte = ReadDouble( &p_current );
time_inf.pi_start_byte = malloc( time_inf.i_nb *sizeof(u32) ); time_inf.pi_start_byte = malloc( time_inf.i_nb *sizeof(u32) );
if( time_inf.pi_start_byte == NULL ) if( time_inf.pi_start_byte == NULL )
...@@ -690,7 +687,7 @@ FLUSH(2); ...@@ -690,7 +687,7 @@ FLUSH(2);
for( i = 0 ; i < time_inf.i_nb ; i++ ) for( i = 0 ; i < time_inf.i_nb ; i++ )
{ {
GETL( &time_inf.pi_start_byte[i] ); time_inf.pi_start_byte[i] = ReadDouble( &p_current );
} }
time_inf.p_time_map = malloc( time_inf.i_nb *sizeof(time_map_t) ); time_inf.p_time_map = malloc( time_inf.i_nb *sizeof(time_map_t) );
...@@ -702,9 +699,9 @@ FLUSH(2); ...@@ -702,9 +699,9 @@ FLUSH(2);
for( i = 0 ; i < time_inf.i_nb ; i++ ) for( i = 0 ; i < time_inf.i_nb ; i++ )
{ {
GETC( &time_inf.p_time_map[i].i_time_unit ); time_inf.p_time_map[i].i_time_unit = ReadByte( &p_current );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETS( &time_inf.p_time_map[i].i_entry_nb ); time_inf.p_time_map[i].i_entry_nb = ReadWord( &p_current );
time_inf.p_time_map[i].pi_sector = time_inf.p_time_map[i].pi_sector =
malloc( time_inf.p_time_map[i].i_entry_nb *sizeof(u32) ); malloc( time_inf.p_time_map[i].i_entry_nb *sizeof(u32) );
...@@ -716,7 +713,7 @@ FLUSH(2); ...@@ -716,7 +713,7 @@ FLUSH(2);
for( j = 0 ; j < time_inf.p_time_map[i].i_entry_nb ; j++ ) for( j = 0 ; j < time_inf.p_time_map[i].i_entry_nb ; j++ )
{ {
GETL( &time_inf.p_time_map[i].pi_sector[j] ); time_inf.p_time_map[i].pi_sector[j] = ReadDouble( &p_current );
} }
} }
} }
...@@ -724,10 +721,8 @@ FLUSH(2); ...@@ -724,10 +721,8 @@ FLUSH(2);
if( manager_inf.i_menu_cell_inf_start_sector ) if( manager_inf.i_menu_cell_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf, p_ifo->vts.i_pos +
manager_inf.i_menu_cell_inf_start_sector *DVD_LB_SIZE, manager_inf.i_menu_cell_inf_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf ) < 0 )
{ {
return -1; return -1;
} }
...@@ -735,10 +730,8 @@ FLUSH(2); ...@@ -735,10 +730,8 @@ FLUSH(2);
if( manager_inf.i_menu_vobu_map_start_sector ) if( manager_inf.i_menu_vobu_map_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map, p_ifo->vts.i_pos +
manager_inf.i_menu_vobu_map_start_sector *DVD_LB_SIZE, manager_inf.i_menu_vobu_map_start_sector *DVD_LB_SIZE ) < 0 )
SEEK_SET );
if( ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map ) < 0 )
{ {
return -1; return -1;
} }
...@@ -746,10 +739,8 @@ FLUSH(2); ...@@ -746,10 +739,8 @@ FLUSH(2);
if( manager_inf.i_cell_inf_start_sector ) if( manager_inf.i_cell_inf_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadCellInf( p_ifo, &p_ifo->vts.cell_inf, p_ifo->vts.i_pos +
manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE, manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE ) )
SEEK_SET );
if( ReadCellInf( p_ifo, &p_ifo->vts.cell_inf ) )
{ {
return -1; return -1;
} }
...@@ -757,10 +748,8 @@ FLUSH(2); ...@@ -757,10 +748,8 @@ FLUSH(2);
if( manager_inf.i_vobu_map_start_sector ) if( manager_inf.i_vobu_map_start_sector )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos + if( ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map, p_ifo->vts.i_pos +
manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE, manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE ) )
SEEK_SET );
if( ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map ) )
{ {
return -1; return -1;
} }
...@@ -835,9 +824,9 @@ static int FreeTitleSet( vts_t * p_vts ) ...@@ -835,9 +824,9 @@ static int FreeTitleSet( vts_t * p_vts )
} }
/***************************************************************************** /*****************************************************************************
* IfoEnd : Frees all the memory allocated to ifo structures * IfoDestroy : Frees all the memory allocated to ifo structures
*****************************************************************************/ *****************************************************************************/
void IfoEnd( ifo_t * p_ifo ) void IfoDestroy( ifo_t * p_ifo )
{ {
int i, j; int i, j;
...@@ -901,86 +890,60 @@ void IfoEnd( ifo_t * p_ifo ) ...@@ -901,86 +890,60 @@ void IfoEnd( ifo_t * p_ifo )
* Several title can point to the same part of the physical DVD, and give * Several title can point to the same part of the physical DVD, and give
* map to different anglesfor instance. * map to different anglesfor instance.
*****************************************************************************/ *****************************************************************************/
#define GETCOMMAND( p_com ) \ static int ReadTitle( ifo_t * p_ifo, title_t * p_title, off_t i_pos )
{ \
read( p_ifo->i_fd , (p_com) , 8 ); \
/*fprintf(stderr, "Pos : %lld Type : %d direct : %d cmd : %d dircmp : %d cmp : %d subcmd : %d v0 : %d v2 : %d v4 : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
(int)((p_com)->i_type), \
(int)((p_com)->i_direct), \
(int)((p_com)->i_cmd), \
(int)((p_com)->i_dir_cmp), \
(int)((p_com)->i_cmp), \
(int)((p_com)->i_sub_cmd), \
(int)((p_com)->data.pi_16[0]), \
(int)((p_com)->data.pi_16[1]), \
(int)((p_com)->data.pi_16[2]));*/ \
/* CommandRead( *(p_com) );*/ \
p_ifo->i_pos += 8; \
}
static int ReadTitle( ifo_t * p_ifo, title_t * p_title )
{ {
off_t i_start; u8 pi_buffer[DVD_LB_SIZE];
int i; u8 * p_current;
u16 i_temp; off_t i_start;
int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_pos, SEEK_SET );
//fprintf( stderr, "PGC @ %lld\n",p_ifo->i_pos ); //fprintf( stderr, "PGC @ %lld\n",p_ifo->i_pos );
FLUSH(2); DumpBits( &p_current, 2);
#if 0 p_title->i_chapter_nb = ReadByte( &p_current );
GETC( &p_title->i_chapter_nb ); p_title->i_cell_nb = ReadByte( &p_current );
fprintf( stderr, "title: prg %d\n", p_title->i_chapter_nb );
FLUSH(0);
GETC( &p_title->i_cell_nb );
fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
#endif
GETS( &i_temp );
//fprintf(stderr, "title : temp = %x\n", i_temp );
p_title->i_chapter_nb = (i_temp & 0xFF );
p_title->i_cell_nb = (i_temp & 0xFF00 ) >> 8;
//fprintf( stderr, "title: Prg: %d Cell: %d\n",p_title->i_chapter_nb,p_title->i_cell_nb ); //fprintf( stderr, "title: Prg: %d Cell: %d\n",p_title->i_chapter_nb,p_title->i_cell_nb );
GETL( &p_title->i_play_time ); p_title->i_play_time = ReadDouble( &p_current );
GETL( &p_title->i_prohibited_user_op ); p_title->i_prohibited_user_op = ReadDouble( &p_current );
for( i=0 ; i<8 ; i++ ) for( i = 0 ; i < 8 ; i++ )
{ {
GETS( &p_title->pi_audio_status[i] ); p_title->pi_audio_status[i] = ReadWord( &p_current );
} }
for( i=0 ; i<32 ; i++ ) for( i = 0 ; i < 32 ; i++ )
{ {
GETL( &p_title->pi_subpic_status[i] ); p_title->pi_subpic_status[i] = ReadDouble( &p_current );
} }
GETS( &p_title->i_next_title_num ); p_title->i_next_title_num = ReadWord( &p_current );
GETS( &p_title->i_prev_title_num ); p_title->i_prev_title_num = ReadWord( &p_current );
GETS( &p_title->i_go_up_title_num ); p_title->i_go_up_title_num = ReadWord( &p_current );
//fprintf( stderr, "title: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb ); //fprintf( stderr, "title: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb );
GETC( &p_title->i_still_time ); p_title->i_still_time = ReadByte( &p_current );
GETC( &p_title->i_play_mode ); p_title->i_play_mode = ReadByte( &p_current );
for( i=0 ; i<16 ; i++ ) for( i = 0 ; i < 16 ; i++ )
{ {
GETL( &p_title->pi_yuv_color[i] ); p_title->pi_yuv_color[i] = ReadDouble( &p_current );
/* FIXME : We have to erase the extra bit */ /* FIXME : We have to erase the extra bit */
} }
GETS( &p_title->i_command_start_byte ); p_title->i_command_start_byte = ReadWord( &p_current );
GETS( &p_title->i_chapter_map_start_byte ); p_title->i_chapter_map_start_byte = ReadWord( &p_current );
GETS( &p_title->i_cell_play_start_byte ); p_title->i_cell_play_start_byte = ReadWord( &p_current );
GETS( &p_title->i_cell_pos_start_byte ); p_title->i_cell_pos_start_byte = ReadWord( &p_current );
/* parsing of command_t */ /* parsing of command_t */
if( p_title->i_command_start_byte ) if( p_title->i_command_start_byte )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_current = FillBuffer( p_ifo, pi_buffer,
i_start + p_title->i_command_start_byte, i_start + p_title->i_command_start_byte );
SEEK_SET );
/* header */ /* header */
GETS( &p_title->command.i_pre_command_nb ); p_title->command.i_pre_command_nb = ReadWord( &p_current );
GETS( &p_title->command.i_post_command_nb ); p_title->command.i_post_command_nb = ReadWord( &p_current );
GETS( &p_title->command.i_cell_command_nb ); p_title->command.i_cell_command_nb = ReadWord( &p_current );
FLUSH( 2 ); DumpBits( &p_current, 2 );
/* pre-title commands */ /* pre-title commands */
if( p_title->command.i_pre_command_nb ) if( p_title->command.i_pre_command_nb )
...@@ -997,7 +960,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -997,7 +960,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ ) for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ )
{ {
GETCOMMAND( &p_title->command.p_pre_command[i] ); p_title->command.p_pre_command[i] = ReadQuad( &p_current );
} }
} }
else else
...@@ -1020,7 +983,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1020,7 +983,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
for( i=0 ; i<p_title->command.i_post_command_nb ; i++ ) for( i=0 ; i<p_title->command.i_post_command_nb ; i++ )
{ {
GETCOMMAND( &p_title->command.p_post_command[i] ); p_title->command.p_post_command[i] = ReadQuad( &p_current );
} }
} }
else else
...@@ -1043,7 +1006,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1043,7 +1006,7 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
for( i=0 ; i<p_title->command.i_cell_command_nb ; i++ ) for( i=0 ; i<p_title->command.i_cell_command_nb ; i++ )
{ {
GETCOMMAND( &p_title->command.p_cell_command[i] ); p_title->command.p_cell_command[i] = ReadQuad( &p_current );
} }
} }
else else
...@@ -1068,7 +1031,8 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1068,7 +1031,8 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
return -1; return -1;
} }
GET( p_title->chapter_map.pi_start_cell, p_title->i_chapter_nb ); ReadBits( &p_current, p_title->chapter_map.pi_start_cell,
p_title->i_chapter_nb );
} }
else else
{ {
...@@ -1078,9 +1042,8 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1078,9 +1042,8 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
/* parsing of cell_play_t */ /* parsing of cell_play_t */
if( p_title->i_cell_play_start_byte ) if( p_title->i_cell_play_start_byte )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_current = FillBuffer( p_ifo, pi_buffer,
i_start + p_title->i_cell_play_start_byte, i_start + p_title->i_cell_play_start_byte );
SEEK_SET );
p_title->p_cell_play = malloc( p_title->i_cell_nb p_title->p_cell_play = malloc( p_title->i_cell_nb
*sizeof(cell_play_t) ); *sizeof(cell_play_t) );
...@@ -1093,23 +1056,24 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1093,23 +1056,24 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
for( i = 0 ; i < p_title->i_cell_nb ; i++ ) for( i = 0 ; i < p_title->i_cell_nb ; i++ )
{ {
GETS( &p_title->p_cell_play[i].i_category ); p_title->p_cell_play[i].i_category = ReadWord( &p_current );
GETC( &p_title->p_cell_play[i].i_still_time ); p_title->p_cell_play[i].i_still_time = ReadByte( &p_current );
GETC( &p_title->p_cell_play[i].i_command_nb ); p_title->p_cell_play[i].i_command_nb = ReadByte( &p_current );
GETL( &p_title->p_cell_play[i].i_play_time ); p_title->p_cell_play[i].i_play_time = ReadDouble( &p_current );
GETL( &p_title->p_cell_play[i].i_start_sector ); p_title->p_cell_play[i].i_start_sector = ReadDouble( &p_current );
GETL( &p_title->p_cell_play[i].i_first_ilvu_vobu_esector ); p_title->p_cell_play[i].i_first_ilvu_vobu_esector =
GETL( &p_title->p_cell_play[i].i_last_vobu_start_sector ); ReadDouble( &p_current );
GETL( &p_title->p_cell_play[i].i_end_sector ); p_title->p_cell_play[i].i_last_vobu_start_sector =
ReadDouble( &p_current );
p_title->p_cell_play[i].i_end_sector = ReadDouble( &p_current );
} }
} }
/* Parsing of cell_pos_t */ /* Parsing of cell_pos_t */
if( p_title->i_cell_pos_start_byte ) if( p_title->i_cell_pos_start_byte )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, p_current = FillBuffer( p_ifo, pi_buffer,
i_start + p_title->i_cell_pos_start_byte, i_start + p_title->i_cell_pos_start_byte );
SEEK_SET );
p_title->p_cell_pos = malloc( p_title->i_cell_nb p_title->p_cell_pos = malloc( p_title->i_cell_nb
*sizeof(cell_pos_t) ); *sizeof(cell_pos_t) );
...@@ -1122,9 +1086,9 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb ); ...@@ -1122,9 +1086,9 @@ fprintf( stderr, "title: cell %d\n", p_title->i_cell_nb );
for( i = 0 ; i < p_title->i_cell_nb ; i++ ) for( i = 0 ; i < p_title->i_cell_nb ; i++ )
{ {
GETS( &p_title->p_cell_pos[i].i_vob_id ); p_title->p_cell_pos[i].i_vob_id = ReadWord( &p_current );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &p_title->p_cell_pos[i].i_cell_id ); p_title->p_cell_pos[i].i_cell_id = ReadByte( &p_current );
} }
} }
...@@ -1175,17 +1139,21 @@ static int FreeTitle( title_t * p_title ) ...@@ -1175,17 +1139,21 @@ static int FreeTitle( title_t * p_title )
/***************************************************************************** /*****************************************************************************
* ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table * ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table
*****************************************************************************/ *****************************************************************************/
static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf ) static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf, off_t i_pos )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8 * p_current;
off_t i_start; off_t i_start;
int i; int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "Unit\n" ); //fprintf( stderr, "Unit\n" );
GETS( &p_unit_inf->i_title_nb ); p_unit_inf->i_title_nb = ReadWord( &p_current );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &p_unit_inf->i_end_byte ); p_unit_inf->i_end_byte = ReadDouble( &p_current );
p_unit_inf->p_title = p_unit_inf->p_title =
malloc( p_unit_inf->i_title_nb *sizeof(unit_title_t) ); malloc( p_unit_inf->i_title_nb *sizeof(unit_title_t) );
...@@ -1197,19 +1165,17 @@ static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf ) ...@@ -1197,19 +1165,17 @@ static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf )
for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
{ {
GETC( &p_unit_inf->p_title[i].i_category_mask ); p_unit_inf->p_title[i].i_category_mask = ReadByte( &p_current );
GETC( &p_unit_inf->p_title[i].i_category ); p_unit_inf->p_title[i].i_category = ReadByte( &p_current );
GETS( &p_unit_inf->p_title[i].i_parental_mask ); p_unit_inf->p_title[i].i_parental_mask = ReadWord( &p_current );
GETL( &p_unit_inf->p_title[i].i_title_start_byte ); p_unit_inf->p_title[i].i_title_start_byte = ReadDouble( &p_current );
} }
for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ ) for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
p_unit_inf->p_title[i].i_title_start_byte,
SEEK_SET );
//fprintf( stderr, "Unit: PGC %d @ %lld\n", i, p_ifo->i_pos ); //fprintf( stderr, "Unit: PGC %d @ %lld\n", i, p_ifo->i_pos );
ReadTitle( p_ifo, &p_unit_inf->p_title[i].title ); ReadTitle( p_ifo, &p_unit_inf->p_title[i].title, i_start +
p_unit_inf->p_title[i].i_title_start_byte );
} }
return 0; return 0;
...@@ -1232,16 +1198,21 @@ static int FreeUnitInf( unit_inf_t * p_unit_inf ) ...@@ -1232,16 +1198,21 @@ static int FreeUnitInf( unit_inf_t * p_unit_inf )
/***************************************************************************** /*****************************************************************************
* ReadTitleUnit: Fills the Title Unit structure. * ReadTitleUnit: Fills the Title Unit structure.
*****************************************************************************/ *****************************************************************************/
static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit ) static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit,
off_t i_pos )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8 * p_current;
int i; int i;
off_t i_start = p_ifo->i_pos; off_t i_start;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos );
i_start = p_ifo->i_pos;
//fprintf( stderr, "Unit Table\n" ); //fprintf( stderr, "Unit Table\n" );
GETS( &p_title_unit->i_unit_nb ); p_title_unit->i_unit_nb = ReadWord( &p_current );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &p_title_unit->i_end_byte ); p_title_unit->i_end_byte = ReadDouble( &p_current );
//fprintf(stderr, "Unit: nb %d end %d\n", p_title_unit->i_unit_nb, p_title_unit->i_end_byte ); //fprintf(stderr, "Unit: nb %d end %d\n", p_title_unit->i_unit_nb, p_title_unit->i_end_byte );
...@@ -1254,10 +1225,11 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit ) ...@@ -1254,10 +1225,11 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit )
for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
{ {
GET( p_title_unit->p_unit[i].ps_lang_code, 2 ); ReadBits( &p_current, p_title_unit->p_unit[i].ps_lang_code, 2 );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETC( &p_title_unit->p_unit[i].i_existence_mask ); p_title_unit->p_unit[i].i_existence_mask = ReadByte( &p_current );
GETL( &p_title_unit->p_unit[i].i_unit_inf_start_byte ); p_title_unit->p_unit[i].i_unit_inf_start_byte =
ReadDouble( &p_current );
} }
p_title_unit->p_unit_inf = p_title_unit->p_unit_inf =
...@@ -1270,10 +1242,8 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit ) ...@@ -1270,10 +1242,8 @@ static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit )
for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ ) for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
{ {
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start + ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i], i_start +
p_title_unit->p_unit[i].i_unit_inf_start_byte, p_title_unit->p_unit[i].i_unit_inf_start_byte );
SEEK_SET );
ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i] );
} }
return 0; return 0;
...@@ -1302,17 +1272,20 @@ static int FreeTitleUnit( title_unit_t * p_title_unit ) ...@@ -1302,17 +1272,20 @@ static int FreeTitleUnit( title_unit_t * p_title_unit )
/***************************************************************************** /*****************************************************************************
* ReadCellInf : Fills the Cell Information structure. * ReadCellInf : Fills the Cell Information structure.
*****************************************************************************/ *****************************************************************************/
static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf ) static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf, off_t i_pos )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8 * p_current;
off_t i_start; off_t i_start;
int i; int i;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "CELL ADD\n" ); //fprintf( stderr, "CELL ADD\n" );
GETS( &p_cell_inf->i_vob_nb ); p_cell_inf->i_vob_nb = ReadWord( &p_current );
FLUSH( 2 ); DumpBits( &p_current, 2 );
GETL( &p_cell_inf->i_end_byte ); p_cell_inf->i_end_byte = ReadDouble( &p_current );
p_cell_inf->i_cell_nb = p_cell_inf->i_cell_nb =
( i_start + p_cell_inf->i_end_byte + 1 - p_ifo->i_pos ) ( i_start + p_cell_inf->i_end_byte + 1 - p_ifo->i_pos )
...@@ -1330,11 +1303,11 @@ static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf ) ...@@ -1330,11 +1303,11 @@ static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf )
for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ ) for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ )
{ {
GETS( &p_cell_inf->p_cell_map[i].i_vob_id ); p_cell_inf->p_cell_map[i].i_vob_id = ReadWord( &p_current );
GETC( &p_cell_inf->p_cell_map[i].i_cell_id ); p_cell_inf->p_cell_map[i].i_cell_id = ReadByte( &p_current );
FLUSH( 1 ); DumpBits( &p_current, 1 );
GETL( &p_cell_inf->p_cell_map[i].i_start_sector ); p_cell_inf->p_cell_map[i].i_start_sector = ReadDouble( &p_current );
GETL( &p_cell_inf->p_cell_map[i].i_end_sector ); p_cell_inf->p_cell_map[i].i_end_sector = ReadDouble( &p_current );
} }
return 0; return 0;
...@@ -1353,15 +1326,18 @@ static int FreeCellInf( cell_inf_t * p_cell_inf ) ...@@ -1353,15 +1326,18 @@ static int FreeCellInf( cell_inf_t * p_cell_inf )
/***************************************************************************** /*****************************************************************************
* ReadVobuMap : Fills the VOBU Map structure. * ReadVobuMap : Fills the VOBU Map structure.
*****************************************************************************/ *****************************************************************************/
static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map ) static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map, off_t i_pos )
{ {
u8 pi_buffer[DVD_LB_SIZE];
u8 * p_current;
off_t i_start; off_t i_start;
int i, i_max; int i, i_max;
p_current = FillBuffer( p_ifo, pi_buffer, i_pos );
i_start = p_ifo->i_pos; i_start = p_ifo->i_pos;
//fprintf( stderr, "VOBU ADMAP\n" ); //fprintf( stderr, "VOBU ADMAP\n" );
GETL( &p_vobu_map->i_end_byte ); p_vobu_map->i_end_byte = ReadDouble( &p_current );
i_max = ( i_start + p_vobu_map->i_end_byte + 1 - p_ifo->i_pos ) i_max = ( i_start + p_vobu_map->i_end_byte + 1 - p_ifo->i_pos )
/ sizeof(u32); / sizeof(u32);
...@@ -1374,7 +1350,11 @@ static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map ) ...@@ -1374,7 +1350,11 @@ static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map )
for( i = 0 ; i < i_max ; i++ ) for( i = 0 ; i < i_max ; i++ )
{ {
GETL( &p_vobu_map->pi_vobu_start_sector[i] ); p_vobu_map->pi_vobu_start_sector[i] = ReadDouble( &p_current );
if( p_current == pi_buffer + DVD_LB_SIZE )
{
p_current = FillBuffer( p_ifo, pi_buffer, p_ifo->i_pos );
}
} }
return 0; return 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dvd_ifo.h: Structures for ifo parsing * dvd_ifo.h: Structures for ifo parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.h,v 1.11 2001/04/08 07:24:47 stef Exp $ * $Id: dvd_ifo.h,v 1.12 2001/04/12 02:40:09 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -99,9 +99,13 @@ typedef struct command_s ...@@ -99,9 +99,13 @@ typedef struct command_s
u16 i_post_command_nb; // 2 bytes u16 i_post_command_nb; // 2 bytes
u16 i_cell_command_nb; // 2 bytes u16 i_cell_command_nb; // 2 bytes
// char[2] ??? // char[2] ???
command_desc_t* p_pre_command; // i_pre_com_nb * 8 bytes u64* p_pre_command; // i_pre_com_nb * 8 bytes
command_desc_t* p_post_command; // i_post_com_nb * 8 bytes u64* p_post_command; // i_post_com_nb * 8 bytes
command_desc_t* p_cell_command; // i_cell_com_nb * 8 bytes u64* p_cell_command; // i_pre_com_nb * 8 bytes
// command_desc_t* p_cell_command; // i_cell_com_nb * 8 bytes
// command_desc_t* p_post_command; // i_post_com_nb * 8 bytes
// command_desc_t* p_cell_command; // i_cell_com_nb * 8 bytes
} command_t; } command_t;
/* Program Chain Map Table /* Program Chain Map Table
......
...@@ -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.42 2001/04/11 04:31:59 sam Exp $ * $Id: input_dvd.c,v 1.43 2001/04/12 02:40:09 stef Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -362,13 +362,13 @@ static int DVDFindCell( thread_dvd_data_t * p_dvd ) ...@@ -362,13 +362,13 @@ static int DVDFindCell( thread_dvd_data_t * p_dvd )
{ {
i_cell++; i_cell++;
} }
/*
intf_WarnMsg( 1, "FindCell: i_cell %d i_index %d found %d nb %d", intf_WarnMsg( 1, "FindCell: i_cell %d i_index %d found %d nb %d",
p_dvd->i_cell, p_dvd->i_cell,
p_dvd->i_prg_cell, p_dvd->i_prg_cell,
i_cell, i_cell,
cell.i_cell_nb ); cell.i_cell_nb );
*/
if( i_cell == cell.i_cell_nb ) if( i_cell == cell.i_cell_nb )
{ {
intf_ErrMsg( "dvd error: can't find cell" ); intf_ErrMsg( "dvd error: can't find cell" );
...@@ -411,7 +411,7 @@ static int DVDFindSector( thread_dvd_data_t * p_dvd ) ...@@ -411,7 +411,7 @@ static int DVDFindSector( thread_dvd_data_t * p_dvd )
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); title.p_cell_play[p_dvd->i_prg_cell].i_end_sector );
intf_WarnMsg( 1, "cell: %d sector1: 0x%x end1: 0x%x\n" /* intf_WarnMsg( 1, "cell: %d sector1: 0x%x end1: 0x%x\n"
"index: %d sector2: 0x%x end2: 0x%x", "index: %d sector2: 0x%x end2: 0x%x",
p_dvd->i_cell, p_dvd->i_cell,
p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
...@@ -419,6 +419,7 @@ static int DVDFindSector( thread_dvd_data_t * p_dvd ) ...@@ -419,6 +419,7 @@ static int DVDFindSector( thread_dvd_data_t * p_dvd )
p_dvd->i_prg_cell, p_dvd->i_prg_cell,
title.p_cell_play[p_dvd->i_prg_cell].i_start_sector, title.p_cell_play[p_dvd->i_prg_cell].i_start_sector,
title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); title.p_cell_play[p_dvd->i_prg_cell].i_end_sector );
*/
#undef title #undef title
return 0; return 0;
...@@ -439,7 +440,11 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) ...@@ -439,7 +440,11 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
p_dvd->i_sector = 0; p_dvd->i_sector = 0;
/* Search for cell_index in cell adress_table and initialize start sector */ /* Search for cell_index in cell adress_table and initialize start sector */
DVDFindSector( p_dvd ); if( DVDFindSector( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: can't select chapter" );
return -1;
}
/* start is : beginning of vts vobs + offset to vob x */ /* start is : beginning of vts vobs + offset to vob x */
p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_start = p_dvd->i_title_start +
...@@ -504,7 +509,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -504,7 +509,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return -1; return -1;
} }
//intf_WarnMsg( 3, "cell nb %d", p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title.i_cell_nb );
#define vmg p_dvd->p_ifo->vmg #define vmg p_dvd->p_ifo->vmg
#define vts p_dvd->p_ifo->vts #define vts p_dvd->p_ifo->vts
/* title position inside the selected vts */ /* title position inside the selected vts */
...@@ -513,11 +517,11 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -513,11 +517,11 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
p_dvd->i_program_chain = p_dvd->i_program_chain =
vts.title_inf.p_title_start[p_dvd->i_vts_title-1].i_program_chain_num; vts.title_inf.p_title_start[p_dvd->i_vts_title-1].i_program_chain_num;
intf_WarnMsg( 1, "dvd: title %d vts_title %d pgc %d", /* intf_WarnMsg( 1, "dvd: title %d vts_title %d pgc %d",
p_dvd->i_title, p_dvd->i_title,
p_dvd->i_vts_title, p_dvd->i_vts_title,
p_dvd->i_program_chain ); p_dvd->i_program_chain );
*/
/* css title key for current vts */ /* css title key for current vts */
if( p_dvd->b_encrypted ) if( p_dvd->b_encrypted )
{ {
...@@ -558,9 +562,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) ...@@ -558,9 +562,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
p_dvd->i_prg_cell = -1 + p_dvd->i_prg_cell = -1 +
vts.title_unit.p_title[p_dvd->i_program_chain-1].title.i_cell_nb; vts.title_unit.p_title[p_dvd->i_program_chain-1].title.i_cell_nb;
intf_WarnMsg( 3, "cell nb %d", vts.title_unit.p_title[p_dvd->i_program_chain-1].title.i_cell_nb ); if( DVDFindCell( p_dvd ) < 0 )
{
DVDFindCell( p_dvd ); intf_ErrMsg( "dvd error: can't find title end" );
p_input->b_error = 1;
return -1;
}
/* temporary hack to fix size in some dvds */ /* temporary hack to fix size in some dvds */
if( p_dvd->i_cell >= vts.cell_inf.i_cell_nb ) if( p_dvd->i_cell >= vts.cell_inf.i_cell_nb )
...@@ -572,7 +579,12 @@ intf_WarnMsg( 3, "cell nb %d", vts.title_unit.p_title[p_dvd->i_program_chain-1]. ...@@ -572,7 +579,12 @@ intf_WarnMsg( 3, "cell nb %d", vts.title_unit.p_title[p_dvd->i_program_chain-1].
p_dvd->i_size = DVD_LB_SIZE * p_dvd->i_size = DVD_LB_SIZE *
(off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector ); (off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
DVDChapterSelect( p_dvd, 1 ); if( DVDChapterSelect( p_dvd, 1 ) < 0 )
{
intf_ErrMsg( "dvd error: can't find first chapter" );
p_input->b_error = 1;
return -1;
}
p_dvd->i_size -= (off_t)( p_dvd->i_sector + 1 ) *DVD_LB_SIZE; p_dvd->i_size -= (off_t)( p_dvd->i_sector + 1 ) *DVD_LB_SIZE;
...@@ -769,7 +781,12 @@ intf_WarnMsg( 3, "cell nb %d", vts.title_unit.p_title[p_dvd->i_program_chain-1]. ...@@ -769,7 +781,12 @@ intf_WarnMsg( 3, "cell nb %d", vts.title_unit.p_title[p_dvd->i_program_chain-1].
if( ( p_area->i_part > 0 ) && if( ( p_area->i_part > 0 ) &&
( p_area->i_part <= p_area->i_part_nb ) ) ( p_area->i_part <= p_area->i_part_nb ) )
{ {
DVDChapterSelect( p_dvd, p_area->i_part ); if( DVDChapterSelect( p_dvd, p_area->i_part ) < 0 )
{
intf_ErrMsg( "dvd error: can't set chapter in area" );
p_input->b_error = 1;
return -1;
}
p_input->stream.p_selected_area->i_tell = p_dvd->i_start - p_input->stream.p_selected_area->i_tell = p_dvd->i_start -
p_area->i_start; p_area->i_start;
...@@ -840,14 +857,14 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -840,14 +857,14 @@ static void DVDInit( input_thread_t * p_input )
/* Ifo allocation & initialisation */ /* Ifo allocation & initialisation */
if( IfoCreate( p_dvd ) < 0 ) if( IfoCreate( p_dvd ) < 0 )
{ {
intf_ErrMsg( "dvd error: allcation error in IFO" ); intf_ErrMsg( "dvd error: allcation error in ifo" );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
if( IfoInit( p_dvd->p_ifo ) < 0 ) if( IfoInit( p_dvd->p_ifo ) < 0 )
{ {
intf_ErrMsg( "dvd error: fatal failure in IFO" ); intf_ErrMsg( "dvd error: fatal failure in ifo" );
free( p_dvd ); free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
...@@ -859,22 +876,24 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -859,22 +876,24 @@ static void DVDInit( input_thread_t * p_input )
p_dvd->p_css = malloc( sizeof(css_t) ); p_dvd->p_css = malloc( sizeof(css_t) );
if( p_dvd->p_css == NULL ) if( p_dvd->p_css == NULL )
{ {
intf_ErrMsg( "dvd error: couldn't create CSS structure" ); intf_ErrMsg( "dvd error: couldn't create css structure" );
free( p_dvd ); free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
p_dvd->p_css->i_agid = 0;
if( CSSInit( p_input->i_handle, p_dvd->p_css ) < 0 ) if( CSSInit( p_input->i_handle, p_dvd->p_css ) < 0 )
{ {
intf_ErrMsg( "dvd error: fatal failure in CSS" ); intf_ErrMsg( "dvd error: fatal failure in css" );
free( p_dvd->p_css ); free( p_dvd->p_css );
free( p_dvd ); free( p_dvd );
p_input->b_error = 1; p_input->b_error = 1;
return; return;
} }
intf_WarnMsg( 2, "dvd info: CSS initialized" ); intf_WarnMsg( 2, "dvd info: css initialized" );
} }
/* Set stream and area data */ /* Set stream and area data */
...@@ -887,7 +906,8 @@ static void DVDInit( input_thread_t * p_input ) ...@@ -887,7 +906,8 @@ static void DVDInit( input_thread_t * p_input )
intf_WarnMsg( 2, "dvd info: number of titles: %d", title_inf.i_title_nb ); intf_WarnMsg( 2, "dvd info: number of titles: %d", title_inf.i_title_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 the default area 0
* is reserved for video_ts.vob */
for( i = 1 ; i <= title_inf.i_title_nb ; i++ ) for( i = 1 ; i <= title_inf.i_title_nb ; i++ )
{ {
input_AddArea( p_input ); input_AddArea( p_input );
...@@ -953,7 +973,7 @@ static void DVDEnd( input_thread_t * p_input ) ...@@ -953,7 +973,7 @@ static void DVDEnd( input_thread_t * p_input )
free( p_dvd->p_css ); free( p_dvd->p_css );
} }
IfoEnd( p_dvd->p_ifo ); IfoDestroy( p_dvd->p_ifo );
free( p_dvd ); free( p_dvd );
DVDNetlistEnd( p_netlist ); DVDNetlistEnd( p_netlist );
} }
...@@ -990,7 +1010,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -990,7 +1010,7 @@ static int DVDRead( input_thread_t * p_input,
/* Get an iovec pointer */ /* Get an iovec pointer */
if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL ) if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL )
{ {
intf_ErrMsg( "DVD: read error" ); intf_ErrMsg( "dvd error: can't get iovec" );
return -1; return -1;
} }
...@@ -1129,7 +1149,7 @@ static int DVDRead( input_thread_t * p_input, ...@@ -1129,7 +1149,7 @@ static int DVDRead( input_thread_t * p_input,
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell += i_read_bytes; p_input->stream.p_selected_area->i_tell += i_read_bytes;
b_eof = p_input->stream.p_selected_area->i_tell < p_dvd->i_size ? 0 : 1; b_eof = !( p_input->stream.p_selected_area->i_tell < p_dvd->i_size );
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -1192,9 +1212,15 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) ...@@ -1192,9 +1212,15 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
p_dvd->i_cell = 0; p_dvd->i_cell = 0;
/* Find first title cell which is inside program cell */ /* Find first title cell which is inside program cell */
DVDFindCell( p_dvd ); if( DVDFindCell( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: cell seeking failed" );
p_input->b_error = 1;
return;
}
i_cell = p_dvd->i_cell; i_cell = p_dvd->i_cell;
#define cell p_dvd->p_ifo->vts.cell_inf.p_cell_map[i_cell] #define cell p_dvd->p_ifo->vts.cell_inf.p_cell_map[i_cell]
/* parse cell address map to find title cell containing sector */ /* parse cell address map to find title cell containing sector */
while( cell.i_end_sector < p_dvd->i_sector ) while( cell.i_end_sector < p_dvd->i_sector )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dvd.h: thread structure of the DVD plugin * input_dvd.h: thread structure of the DVD plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_dvd.h,v 1.18 2001/04/11 04:31:59 sam Exp $ * $Id: input_dvd.h,v 1.19 2001/04/12 02:40:09 stef Exp $
* *
* Author: Stéphane Borel <stef@via.ecp.fr> * Author: Stéphane Borel <stef@via.ecp.fr>
* *
...@@ -78,5 +78,4 @@ int CSSDescrambleSector ( u8 * , u8 * ); ...@@ -78,5 +78,4 @@ int CSSDescrambleSector ( u8 * , u8 * );
int IfoCreate ( struct thread_dvd_data_s * ); int IfoCreate ( struct thread_dvd_data_s * );
int IfoInit ( struct ifo_s * ); int IfoInit ( struct ifo_s * );
int IfoTitleSet ( struct ifo_s * ); int IfoTitleSet ( struct ifo_s * );
void IfoEnd ( struct ifo_s * ); void IfoDestroy ( struct ifo_s * );
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.96 2001/04/10 17:47:05 stef Exp $ * $Id: input.c,v 1.97 2001/04/12 02:40:09 stef Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -126,12 +126,13 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -126,12 +126,13 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
p_input->stream.i_new_status = p_input->stream.i_new_rate = 0; p_input->stream.i_new_status = p_input->stream.i_new_rate = 0;
p_input->stream.i_mux_rate = 0; p_input->stream.i_mux_rate = 0;
/* no stream, no area */
p_input->stream.i_area_nb = 0; p_input->stream.i_area_nb = 0;
p_input->stream.pp_areas = NULL; p_input->stream.pp_areas = NULL;
p_input->stream.p_selected_area = NULL;
/* By default there is one areas in a stream */ /* By default there is one areas in a stream */
input_AddArea( p_input ); input_AddArea( p_input );
p_input->stream.p_selected_area = p_input->stream.pp_areas[0]; p_input->stream.p_selected_area = p_input->stream.pp_areas[0];
p_input->stream.p_selected_area->i_seek = NO_SEEK;
/* Initialize stream control properties. */ /* Initialize stream control properties. */
p_input->stream.control.i_status = PLAYING_S; p_input->stream.control.i_status = PLAYING_S;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.46 2001/04/10 17:47:05 stef Exp $ * $Id: input_programs.c,v 1.47 2001/04/12 02:40:09 stef Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -58,8 +58,6 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len ) ...@@ -58,8 +58,6 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
p_input->stream.pp_es = NULL; p_input->stream.pp_es = NULL;
p_input->stream.pp_selected_es = NULL; p_input->stream.pp_selected_es = NULL;
p_input->stream.pp_programs = NULL; p_input->stream.pp_programs = NULL;
p_input->stream.pp_areas = NULL;
p_input->stream.p_selected_area = NULL;
if( i_data_len ) if( i_data_len )
{ {
...@@ -91,6 +89,12 @@ void input_EndStream( input_thread_t * p_input ) ...@@ -91,6 +89,12 @@ void input_EndStream( input_thread_t * p_input )
input_DelES( p_input, p_input->stream.pp_es[0] ); input_DelES( p_input, p_input->stream.pp_es[0] );
} }
/* Free all areas */
while( p_input->stream.i_area_nb )
{
input_DelArea( p_input, p_input->stream.pp_areas[0] );
}
if( p_input->stream.p_demux_data != NULL ) if( p_input->stream.p_demux_data != NULL )
{ {
free( p_input->stream.p_demux_data ); free( p_input->stream.p_demux_data );
......
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