]> git.sesse.net Git - vlc/commitdiff
-Various bug fixes in dvd_netlist. Some bugs seem to remain though.
authorStéphane Borel <stef@videolan.org>
Sun, 1 Apr 2001 07:31:38 +0000 (07:31 +0000)
committerStéphane Borel <stef@videolan.org>
Sun, 1 Apr 2001 07:31:38 +0000 (07:31 +0000)
-New function input_ToggleES for interaction with interface.
-Changes in gnome interface : navigation menus are now splited, there
are radio item in menus and the code should be better.
-First step for dvd_ifo rewritting. Now allocation/disallocation is
being done as it has to be.
-Fixed a bug in title management that make dvd like Seven work.

include/input_ext-intf.h
plugins/dvd/dvd_ifo.c
plugins/dvd/dvd_ifo.h
plugins/dvd/dvd_netlist.c
plugins/dvd/input_dvd.c
plugins/dvd/input_dvd.h
plugins/gnome/gnome_callbacks.c
plugins/gnome/intf_gnome.c
plugins/gnome/intf_gnome.h
src/input/input_ext-intf.c
src/input/input_programs.c

index a688892a72ed1366e9d648771c2df90df078c183..16b76e2294636e2deac37cc1e88a0fd03a01fb22 100644 (file)
@@ -4,7 +4,7 @@
  * control the pace of reading. 
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.28 2001/03/07 10:31:10 stef Exp $
+ * $Id: input_ext-intf.h,v 1.29 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -353,3 +353,6 @@ void input_Seek     ( struct input_thread_s *, off_t );
 void input_DumpStream( struct input_thread_s * );
 char * input_OffsetToTime( struct input_thread_s *, char * psz_buffer, off_t );
 int  input_ChangeES ( struct input_thread_s *, struct es_descriptor_s *, int );
+int  input_ToggleES ( struct input_thread_s *,
+                      struct es_descriptor_s *,
+                      boolean_t );
index 6e2d74858ac8eb1e9b5e6144d235592f8294461f..10a67cc3903a76ff5915260125ca3ed67294cb48 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ifo.c: Functions for ifo parsing
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.c,v 1.15 2001/03/06 10:21:59 massiot Exp $
+ * $Id: dvd_ifo.c,v 1.16 2001/04/01 07:31:38 stef Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
 /*
  * Local prototypes
  */
-static vmg_t ReadVMG    ( ifo_t* );
-void         CommandRead( ifo_command_t );
-
-/*
- * IFO Management.
- */
-
-/*****************************************************************************
- * IfoInit : Creates an ifo structure and prepares for parsing directly
- * on DVD device.
- *****************************************************************************/
-ifo_t IfoInit( int i_fd )
-{
-    ifo_t       ifo;
-    u32         i_lba;
-    
-    /* If we are here the dvd device has already been opened */
-    ifo.i_fd = i_fd;
-
-    i_lba = UDFFindFile( i_fd, "/VIDEO_TS/VIDEO_TS.IFO");
-
-    ifo.i_off = (off_t)(i_lba) * DVD_LB_SIZE;
-    ifo.i_pos = lseek( ifo.i_fd, ifo.i_off, SEEK_SET );
-
-    /* Video Manager Initialization */
-    intf_WarnMsg( 2, "ifo: initializing VMG" );
-    ifo.vmg = ReadVMG( &ifo );
-
-    return ifo;
-}
-
-/*****************************************************************************
- * IfoEnd : Frees all the memory allocated to ifo structures
- *****************************************************************************/
-void IfoEnd( ifo_t* p_ifo )
-{
-#if 0
-    int     i,j;
-
-    /* Free structures from video title sets */
-    for( j=0 ; j<p_ifo->vmg.mat.i_tts_nb ; j++ )
-    {
-        free( p_ifo->p_vts[j].vobu_admap.pi_vobu_ssector );
-        free( p_ifo->p_vts[j].c_adt.p_cell_inf );
-        free( p_ifo->p_vts[j].m_vobu_admap.pi_vobu_ssector );
-        free( p_ifo->p_vts[j].m_c_adt.p_cell_inf );
-        for( i=0 ; i<p_ifo->p_vts[j].tmap_ti.i_nb ; i++ )
-        {
-            free( p_ifo->p_vts[j].tmap_ti.p_tmap[i].pi_sector );
-        }
-        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].pgci_ti.p_srp );
-        for( i=0 ; i<p_ifo->p_vts[j].pgci_ut.i_lu_nb ; i++ )
-        {
-            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 );
-
-    /* Free structures from video manager */
-    free( p_ifo->vmg.vobu_admap.pi_vobu_ssector );
-    free( p_ifo->vmg.c_adt.p_cell_inf );
-    for( i=0 ; i<p_ifo->vmg.pgci_ut.i_lu_nb ; i++ )
-    {
-        free( p_ifo->vmg.pgci_ut.p_pgci_inf[i].p_srp );
-    }
-    free( p_ifo->vmg.pgci_ut.p_pgci_inf );
-    free( p_ifo->vmg.pgci_ut.p_lu );
-    for( i=1 ; i<=8 ; i++ )
-    {
-        free( p_ifo->vmg.ptl_mait.p_ptl_mask->ppi_ptl_mask[i] );
-    }
-    free( p_ifo->vmg.ptl_mait.p_ptl_desc );
-    free( p_ifo->vmg.ptl_mait.p_ptl_mask );
-    free( p_ifo->vmg.vts_atrt.pi_vts_atrt_sbyte );
-    free( p_ifo->vmg.vts_atrt.p_vts_atrt );
-    free( p_ifo->vmg.pgc.p_cell_pos_inf );
-    free( p_ifo->vmg.pgc.p_cell_play_inf );
-    free( p_ifo->vmg.pgc.prg_map.pi_entry_cell );
-    free( p_ifo->vmg.pgc.com_tab.p_cell_com );
-    free( p_ifo->vmg.pgc.com_tab.p_post_com );
-    free( p_ifo->vmg.pgc.com_tab.p_pre_com );
-#endif
-    return;
-}
+void            CommandRead     ( command_desc_t );
+static int      ReadTitle       ( ifo_t * , title_t * );
+static int      FreeTitle       ( title_t * );
+static int      ReadUnitInf     ( ifo_t * , unit_inf_t * );
+static int      FreeUnitInf     ( unit_inf_t * );
+static int      ReadTitleUnit   ( ifo_t * , title_unit_t * );
+static int      FreeTitleUnit   ( title_unit_t * );
+static int      ReadVobuMap     ( ifo_t * , vobu_map_t * );
+static int      FreeVobuMap     ( vobu_map_t * );
+static int      ReadCellInf     ( ifo_t * , cell_inf_t * );
+static int      FreeCellInf     ( cell_inf_t * );
+static int      FreeTitleSet    ( vts_t * );
 
 /*
  * Macros to process ifo files
@@ -198,960 +121,1252 @@ void IfoEnd( ifo_t* p_ifo )
                               p_ifo->i_pos + (i_len), SEEK_SET );           \
     }
 
+
+
 /*
- * Function common to Video Manager and Video Title set Processing
+ * IFO Management.
  */
 
 /*****************************************************************************
- * ReadPGC : Fills the Program Chain structure.
+ * IfoInit : Creates an ifo structure and prepares for parsing directly
+ *           on DVD device. Then reads information from the management table.
  *****************************************************************************/
-#define GETCOMMAND( p_com )                                                 \
-    {                                                                       \
-        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;                                                  \
+int IfoInit( ifo_t ** pp_ifo, int i_fd )
+{
+    ifo_t *             p_ifo;
+    u64                 i_temp;
+    u32                 i_lba;
+    int                 i, j, k;
+    off_t               i_start;
+
+    
+    p_ifo = malloc( sizeof(ifo_t) );
+    if( p_ifo == NULL )
+    {
+        intf_ErrMsg( "ifo error: unable to allocate memory. aborting" );
+        return -1;
     }
 
-static pgc_t ReadPGC( ifo_t* p_ifo )
-{
-    pgc_t   pgc;
-    int     i;
-    off_t   i_start = p_ifo->i_pos;
+    *pp_ifo = p_ifo;
 
-//fprintf( stderr, "PGC\n" );
+    /* if we are here the dvd device has already been opened */
+    p_ifo->i_fd = i_fd;
+
+    /* find the start sector of video information on the dvd */
+    i_lba = UDFFindFile( i_fd, "/VIDEO_TS/VIDEO_TS.IFO");
+
+    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 );
+
+    /*
+     * read the video manager information table
+     */
+#define manager_inf     p_ifo->vmg.manager_inf
+//fprintf( stderr, "VMGI\n" );
 
+    GET( manager_inf.psz_id , 12 );
+    manager_inf.psz_id[12] = '\0';
+    GETL( &manager_inf.i_vmg_end_sector );
+    FLUSH( 12 );
+    GETL( &manager_inf.i_vmg_inf_end_sector );
+    FLUSH( 1 );
+    GETC( &manager_inf.i_spec_ver );
+    GETL( &manager_inf.i_cat );
+    GETS( &manager_inf.i_volume_nb );
+    GETS( &manager_inf.i_volume );
+    GETC( &manager_inf.i_disc_side );
+    FLUSH( 19 );
+    GETS( &manager_inf.i_title_set_nb );
+    GET( manager_inf.ps_provider_id, 32 );
+    GETLL( &manager_inf.i_pos_code );
+    FLUSH( 24 );
+    GETL( &manager_inf.i_vmg_inf_end_byte );
+    GETL( &manager_inf.i_first_play_title_start_byte );
+    FLUSH( 56 );
+    GETL( &manager_inf.i_vob_start_sector );
+    GETL( &manager_inf.i_title_inf_start_sector );
+    GETL( &manager_inf.i_title_unit_start_sector );
+    GETL( &manager_inf.i_parental_inf_start_sector );
+    GETL( &manager_inf.i_vts_inf_start_sector );
+    GETL( &manager_inf.i_text_data_start_sector );
+    GETL( &manager_inf.i_cell_inf_start_sector );
+    GETL( &manager_inf.i_vobu_map_start_sector );
+    FLUSH( 32 );
+//    GETS( &manager_inf.video_atrt );
     FLUSH(2);
-    GETC( &pgc.i_prg_nb );
-    GETC( &pgc.i_cell_nb );
-//fprintf( stderr, "PGC: Prg: %d Cell: %d\n", pgc.i_prg_nb, pgc.i_cell_nb );
-    GETL( &pgc.i_play_time );
-    GETL( &pgc.i_prohibited_user_op );
-    for( i=0 ; i<8 ; i++ )
+    FLUSH( 1 );
+    GETC( &manager_inf.i_audio_nb );
+//fprintf( stderr, "vmgi audio nb : %d\n", manager_inf.i_audio_nb );
+    for( i=0 ; i < 8 ; i++ )
     {
-        GETS( &pgc.pi_audio_status[i] );
+        GETLL( &i_temp );
     }
-    for( i=0 ; i<32 ; i++ )
+    FLUSH( 17 );
+    GETC( &manager_inf.i_spu_nb );
+//fprintf( stderr, "vmgi subpic nb : %d\n", manager_inf.i_subpic_nb );
+    for( i=0 ; i < manager_inf.i_spu_nb ; i++ )
     {
-        GETL( &pgc.pi_subpic_status[i] );
+        GET( &i_temp, 6 );
+        /* FIXME : take care of endianness */
     }
-    GETS( &pgc.i_next_pgc_nb );
-    GETS( &pgc.i_prev_pgc_nb );
-    GETS( &pgc.i_goup_pgc_nb );
-//fprintf( stderr, "PGC: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb );
-    GETC( &pgc.i_still_time );
-    GETC( &pgc.i_play_mode );
-    for( i=0 ; i<16 ; i++ )
+
+    /*
+     * read first play title.
+     */
+    p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                          manager_inf.i_first_play_title_start_byte,
+                          SEEK_SET );
+    if( ReadTitle( p_ifo, &p_ifo->vmg.title ) < 0)
     {
-        GETL( &pgc.pi_yuv_color[i] );
-        /* FIXME : We have to erase the extra bit */
+        return -1;
     }
-    GETS( &pgc.i_com_tab_sbyte );
-    GETS( &pgc.i_prg_map_sbyte );
-    GETS( &pgc.i_cell_play_inf_sbyte );
-    GETS( &pgc.i_cell_pos_inf_sbyte );
 
-    /* Parsing of pgc_com_tab_t */
-    if( pgc.i_com_tab_sbyte )
+    /*
+     * fills the title information structure.
+     */
+#define title_inf       p_ifo->vmg.title_inf
+    if( manager_inf.i_title_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
-                            + pgc.i_com_tab_sbyte, SEEK_SET );
-        GETS( &pgc.com_tab.i_pre_com_nb );
-        GETS( &pgc.com_tab.i_post_com_nb );
-        GETS( &pgc.com_tab.i_cell_com_nb );
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                              manager_inf.i_title_inf_start_sector *DVD_LB_SIZE,
+                              SEEK_SET );
+//fprintf( stderr, "title inf\n" );
+    
+        GETS( &title_inf.i_title_nb );
+//fprintf( stderr, "title_inf: TTU nb %d\n", title_inf.i_title_nb );
         FLUSH( 2 );
-        if( pgc.com_tab.i_pre_com_nb )
-        {
-            pgc.com_tab.p_pre_com =
-                      malloc(pgc.com_tab.i_pre_com_nb *sizeof(ifo_command_t));
-            if( pgc.com_tab.p_pre_com == NULL )
-            {
-                intf_ErrMsg( "Out of memory" );
-                p_ifo->b_error = 1;
-                return pgc;
-            }
-            for( i=0 ; i<pgc.com_tab.i_pre_com_nb ; i++ )
-            {
-                GETCOMMAND( &pgc.com_tab.p_pre_com[i] );
-            }
-        }
-        if( pgc.com_tab.i_post_com_nb )
+        GETL( &title_inf.i_end_byte );
+    
+        /* parsing of title attributes */
+        title_inf.p_attr = malloc( title_inf.i_title_nb *sizeof(title_attr_t) );
+        if( title_inf.p_attr == NULL )
         {
-            pgc.com_tab.p_post_com =
-                      malloc(pgc.com_tab.i_post_com_nb *sizeof(ifo_command_t));
-            if( pgc.com_tab.p_post_com == NULL )
-            {
-                intf_ErrMsg( "Out of memory" );
-                p_ifo->b_error = 1;
-                return pgc;
-            }
-            for( i=0 ; i<pgc.com_tab.i_post_com_nb ; i++ )
-            {
-                GETCOMMAND( &pgc.com_tab.p_post_com[i] );
-            }
+            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
+            return -1;
         }
-        if( pgc.com_tab.i_cell_com_nb )
+    
+        for( i = 0 ; i < title_inf.i_title_nb ; i++ )
         {
-            pgc.com_tab.p_cell_com =
-                      malloc(pgc.com_tab.i_cell_com_nb *sizeof(ifo_command_t));
-            if( pgc.com_tab.p_cell_com == NULL )
-            {
-                intf_ErrMsg( "Out of memory" );
-                p_ifo->b_error = 1;
-                return pgc;
-            }
-            for( i=0 ; i<pgc.com_tab.i_cell_com_nb ; i++ )
-            {
-                GETCOMMAND( &pgc.com_tab.p_cell_com[i] );
-            }
+            GETC( &title_inf.p_attr[i].i_play_type );
+            GETC( &title_inf.p_attr[i].i_angle_nb );
+            GETS( &title_inf.p_attr[i].i_chapter_nb );
+            GETS( &title_inf.p_attr[i].i_parental_id );
+            GETC( &title_inf.p_attr[i].i_title_set_num );
+            GETC( &title_inf.p_attr[i].i_title_num );
+            GETL( &title_inf.p_attr[i].i_start_sector );
+//fprintf( stderr, "title_inf: %d %d %d\n", ptr.p_tts[i].i_ptt_nb, ptr.p_tts[i].i_tts_nb,ptr.p_tts[i].i_vts_ttn );
         }
     }
-    /* Parsing of pgc_prg_map_t */
-    if( pgc.i_prg_map_sbyte )
+    else
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
-                            + pgc.i_prg_map_sbyte, SEEK_SET );
-        pgc.prg_map.pi_entry_cell = malloc( pgc.i_prg_nb *sizeof(u8) );
-        if( pgc.prg_map.pi_entry_cell == NULL )
-        {
-            intf_ErrMsg( "Out of memory" );
-            p_ifo->b_error = 1;
-            return pgc;
-        }
-        GET( pgc.prg_map.pi_entry_cell, pgc.i_prg_nb );
-        /* FIXME : check endianness here */
+        title_inf.p_attr = NULL;
     }
-    /* Parsing of cell_play_inf_t */
-    if( pgc.i_cell_play_inf_sbyte )
+#undef title_inf
+
+    /*
+     * fills the title unit structure.
+     */
+    if( manager_inf.i_title_unit_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
-                            + pgc.i_cell_play_inf_sbyte, SEEK_SET );
-        pgc.p_cell_play_inf = malloc( pgc.i_cell_nb *sizeof(cell_play_inf_t) );
-        if( pgc.p_cell_play_inf == NULL )
-        {
-            intf_ErrMsg( "Out of memory" );
-            p_ifo->b_error = 1;
-            return pgc;
-        }
-        for( i=0 ; i<pgc.i_cell_nb ; i++ )
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                        manager_inf.i_title_unit_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit ) < 0 )
         {
-            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_com_nb );
-            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_first_ilvu_vobu_esector );
-            GETL( &pgc.p_cell_play_inf[i].i_lvobu_ssector );
-            GETL( &pgc.p_cell_play_inf[i].i_lsector );
+            return -1;
         }
     }
-    /* Parsing of cell_pos_inf_map */
-    if( pgc.i_cell_pos_inf_sbyte )
+
+    /*
+     * fills the structure about parental information.
+     */
+#define parental        p_ifo->vmg.parental_inf
+    if( manager_inf.i_parental_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
-                            + pgc.i_cell_pos_inf_sbyte, SEEK_SET );
-        pgc.p_cell_pos_inf = malloc( pgc.i_cell_nb *sizeof(cell_pos_inf_t) );
-        if( pgc.p_cell_pos_inf == NULL )
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                        manager_inf.i_parental_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        i_start = p_ifo->i_pos;
+
+//fprintf( stderr, "PTL\n" );
+    
+        GETS( &parental.i_country_nb );
+        GETS( &parental.i_vts_nb );
+        GETL( &parental.i_end_byte );
+        
+        parental.p_parental_desc = malloc( parental.i_country_nb *
+                                           sizeof(parental_desc_t) );
+        if( parental.p_parental_desc == NULL )
         {
-            intf_ErrMsg( "Out of memory" );
-            p_ifo->b_error = 1;
-            return pgc;
+            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
+            return -1;
         }
-        for( i=0 ; i<pgc.i_cell_nb ; i++ )
+
+        for( i = 0 ; i < parental.i_country_nb ; i++ )
         {
-            GETS( &pgc.p_cell_pos_inf[i].i_vob_id );
-            FLUSH( 1 );
-            GETC( &pgc.p_cell_pos_inf[i].i_cell_id );
+            GET( parental.p_parental_desc[i].ps_country_code, 2 );
+            FLUSH( 2 );
+            GETS( &parental.p_parental_desc[i].i_parental_mask_start_byte );
+            FLUSH( 2 );
         }
-    } 
-
-    return pgc;
-}
 
-/*****************************************************************************
- * ReadUnit : Fills Menu Language Unit Table/ PGC Info Table
- *****************************************************************************/
-static pgci_inf_t ReadUnit( ifo_t* p_ifo )
-{
-    pgci_inf_t      inf;
-    int             i;
-    off_t           i_start = p_ifo->i_pos;
-
-//fprintf( stderr, "Unit\n" );
+        parental.p_parental_mask = malloc( parental.i_country_nb *
+                                           sizeof(parental_mask_t) );
+        if( parental.p_parental_mask == NULL )
+        {
+            intf_ErrMsg( "ifo erro: out of memory in IfoInit" );
+            return -1;
+        }
 
-    GETS( &inf.i_srp_nb );
-    FLUSH( 2 );
-    GETL( &inf.i_lu_ebyte );
-    inf.p_srp = malloc( inf.i_srp_nb *sizeof(pgci_srp_t) );
-    if( inf.p_srp == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return inf;
-    }
-    for( i=0 ; i<inf.i_srp_nb ; i++ )
-    {
-        GETC( &inf.p_srp[i].i_pgc_cat_mask );
-        GETC( &inf.p_srp[i].i_pgc_cat );
-        GETS( &inf.p_srp[i].i_par_mask );
-        GETL( &inf.p_srp[i].i_pgci_sbyte );
+        for( i = 0 ; i < parental.i_country_nb ; i++ )
+        {
+            p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
+                       parental.p_parental_desc[i].i_parental_mask_start_byte,
+                       SEEK_SET );
+            for( j = 0 ; j < 8 ; j++ )
+            {
+                parental.p_parental_mask[i].ppi_mask[j] =
+                            malloc( ( parental.i_vts_nb + 1 ) *sizeof(u16) );
+                if( parental.p_parental_mask[i].ppi_mask[j] == NULL )
+                {
+                    intf_ErrMsg( "ifo error: out of memory in IfoInit" );
+                    return -1;
+                }        
+                for( k = 0 ; k < parental.i_vts_nb + 1 ; k++ )
+                {
+                    GETS( &parental.p_parental_mask[i].ppi_mask[j][k] );
+                }
+            }
+        }
     }
-    for( i=0 ; i<inf.i_srp_nb ; i++ )
+#undef parental
+
+    /*
+     * information and attributes about for each vts.
+     */
+#define vts_inf     p_ifo->vmg.vts_inf
+    if( manager_inf.i_vts_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd,
-                         i_start + inf.p_srp[i].i_pgci_sbyte,
-                         SEEK_SET );
-//fprintf( stderr, "Unit: PGC %d\n", i );
-        inf.p_srp[i].pgc = ReadPGC( p_ifo );
-    }
+        u64             i_temp;
 
-    return inf;
-}
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                        manager_inf.i_vts_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        i_start = p_ifo->i_pos;
+    
+//fprintf( stderr, "VTS ATTR\n" );
+    
+        GETS( &vts_inf.i_vts_nb );
+//fprintf( stderr, "VTS ATTR Nb: %d\n", vts_inf.i_vts_nb );
+        FLUSH( 2 );
+        GETL( &vts_inf.i_end_byte );
+        vts_inf.pi_vts_attr_start_byte =
+                            malloc( vts_inf.i_vts_nb *sizeof(u32) );
+        if( vts_inf.pi_vts_attr_start_byte == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
+            return -1;
+        }
 
-/*****************************************************************************
- * ReadUnitTable : Fills the PGCI Unit structure.
- *****************************************************************************/
-static pgci_ut_t ReadUnitTable( ifo_t* p_ifo )
-{
-    pgci_ut_t       pgci;
-    int             i;
-    off_t           i_start = p_ifo->i_pos;
+        for( i = 0 ; i < vts_inf.i_vts_nb ; i++ )
+        {
+            GETL( &vts_inf.pi_vts_attr_start_byte[i] );
+        }
 
-//fprintf( stderr, "Unit Table\n" );
+        vts_inf.p_vts_attr = malloc( vts_inf.i_vts_nb *sizeof(vts_attr_t) );
+        if( vts_inf.p_vts_attr == NULL )
+        {
+            intf_ErrMsg( "ifo erro: out of memory in IfoInit" );
+            return -1;
+        }
 
-    GETS( &pgci.i_lu_nb );
-    FLUSH( 2 );
-    GETL( &pgci.i_ebyte );
-    pgci.p_lu = malloc( pgci.i_lu_nb *sizeof(pgci_lu_t) );
-    if( pgci.p_lu == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return pgci;
-    }
-    for( i=0 ; i<pgci.i_lu_nb ; i++ )
-    {
-        GET( pgci.p_lu[i].ps_lang_code, 2 );
-        FLUSH( 1 );
-        GETC( &pgci.p_lu[i].i_existence_mask );
-        GETL( &pgci.p_lu[i].i_lu_sbyte );
+        for( i = 0 ; i < vts_inf.i_vts_nb ; i++ )
+        {
+            p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
+                                    vts_inf.pi_vts_attr_start_byte[i],
+                                    SEEK_SET );
+            GETL( &vts_inf.p_vts_attr[i].i_end_byte );
+            GETL( &vts_inf.p_vts_attr[i].i_cat_app_type );
+    //        GETS( &vts_inf.p_vts_attr[i].vts_menu_video_attr );
+            FLUSH(2);
+            FLUSH( 1 );
+            GETC( &vts_inf.p_vts_attr[i].i_vts_menu_audio_nb );
+//fprintf( stderr, "m audio nb : %d\n", vts_inf.p_vts_vts_inf[i].i_vtsm_audio_nb );
+            for( j = 0 ; j < 8 ; j++ )
+            {
+                GETLL( &i_temp );
+            }
+            FLUSH( 17 );
+            GETC( &vts_inf.p_vts_attr[i].i_vts_menu_spu_nb );
+//fprintf( stderr, "m subp nb : %d\n", vts_inf.p_vts_vts_inf[i].i_vtsm_subpic_nb );
+            for( j = 0 ; j < 28 ; j++ )
+            {
+                GET( &i_temp, 6 );
+                /* FIXME : Fix endianness issue here */
+            }
+            FLUSH( 2 );
+    //        GETS( &vts_inf.p_vts_attr[i].vtstt_video_vts_inf );
+            FLUSH(2);
+            FLUSH( 1 );
+            GETL( &vts_inf.p_vts_attr[i].i_vts_title_audio_nb );
+//fprintf( stderr, "tt audio nb : %d\n", vts_inf.p_vts_vts_inf[i].i_vtstt_audio_nb );
+            for( j = 0 ; j < 8 ; j++ )
+            {
+                GETLL( &i_temp );
+            }
+            FLUSH( 17 );
+            GETC( &vts_inf.p_vts_attr[i].i_vts_title_spu_nb );
+//fprintf( stderr, "tt subp nb : %d\n", vts_inf.p_vts_vts_inf[i].i_vtstt_subpic_nb );
+            for( j=0 ; j<28/*vts_inf.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ )
+            {
+                GET( &i_temp, 6 );
+                /* FIXME : Fix endianness issue here */
+            }
+        }
     }
-    pgci.p_pgci_inf = malloc( pgci.i_lu_nb *sizeof(pgci_inf_t) );
-    if( pgci.p_pgci_inf == NULL )
+#undef vts_inf
+
+    /*
+     * global cell map.
+     */
+    if( manager_inf.i_cell_inf_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return pgci;
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                        manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf ) < 0 )
+        {
+            return -1;
+        }
     }
-    for( i=0 ; i<pgci.i_lu_nb ; i++ )
+
+    /*
+     * global vob unit map.
+     */
+    if( manager_inf.i_vobu_map_start_sector )
     {
-        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 );
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
+                        manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map ) < 0 )
+        {
+            return -1;
+        }
     }
+#undef manager_inf
 
-    return pgci;
-}
-
-/*****************************************************************************
- * ReadCellInf : Fills the Cell Information structure.
- *****************************************************************************/
-static c_adt_t ReadCellInf( ifo_t* p_ifo )
-{
-    c_adt_t         c_adt;
-    off_t           i_start = p_ifo->i_pos;
-    int             i;
+    p_ifo->vts.b_initialized = 0;
 
-//fprintf( stderr, "CELL ADD\n" );
+    intf_WarnMsg( 1, "ifo info: vmg initialized" );
 
-    GETS( &c_adt.i_vob_nb );
-    FLUSH( 2 );
-    GETL( &c_adt.i_ebyte );
-    c_adt.i_cell_nb =
-        ( i_start + c_adt.i_ebyte + 1 - p_ifo->i_pos ) / sizeof(cell_inf_t);
-    c_adt.p_cell_inf = malloc( c_adt.i_cell_nb *sizeof(cell_inf_t) );
-    if( c_adt.p_cell_inf == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return c_adt;
-    }
-    for( i = 0 ; i < c_adt.i_cell_nb ; i++ )
-    {
-        GETS( &c_adt.p_cell_inf[i].i_vob_id );
-        GETC( &c_adt.p_cell_inf[i].i_cell_id );
-        FLUSH( 1 );
-        GETL( &c_adt.p_cell_inf[i].i_ssector );
-        GETL( &c_adt.p_cell_inf[i].i_esector );
-    }
-    
-    return c_adt;
+    return 0;
 }
 
 /*****************************************************************************
- * ReadMap : Fills the VOBU Map structure.
+ * IfoTitleSet: Parse vts*.ifo files to fill the Video Title Set structure.
  *****************************************************************************/
-static vobu_admap_t ReadMap( ifo_t* p_ifo )
+int IfoTitleSet( ifo_t * p_ifo )
 {
-    vobu_admap_t        map;
-    int                 i, i_max;
-    off_t               i_start = p_ifo->i_pos;
-    
-//fprintf( stderr, "VOBU ADMAP\n" );
+    off_t       i_off;
+    off_t       i_start;
+    u64         i_temp;
+    int         i, j;
 
-    GETL( &map.i_ebyte );
-    i_max = ( i_start + map.i_ebyte + 1 - p_ifo->i_pos ) / sizeof(u32);
-    map.pi_vobu_ssector = malloc( i_max *sizeof(u32) );
-    for( i=0 ; i<i_max ; i++ )
+    if( p_ifo->vts.b_initialized )
     {
-        GETL( &map.pi_vobu_ssector[i] );
+        FreeTitleSet( &p_ifo->vts );
     }
 
-    return map;
-}
-/*
- * Video Manager Information Processing.
- * This is what is contained in video_ts.ifo.
- */
+    i_off =
+    (off_t)( p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_start_sector )
+                   * DVD_LB_SIZE
+                   + p_ifo->i_off;
 
-/*****************************************************************************
- * ReadVMGInfMat : Fills the Management Information structure.
- *****************************************************************************/
-static vmgi_mat_t ReadVMGInfMat( ifo_t* p_ifo )
-{
-    vmgi_mat_t  mat;
-    u64         i_temp;
-    int         i;
-//    off_t     i_start = p_ifo->i_pos;
+    p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
 
-//fprintf( stderr, "VMGI\n" );
+    p_ifo->vts.i_pos = p_ifo->i_pos;
+
+#define manager_inf p_ifo->vts.manager_inf
+    /*
+     * reads manager information
+     */
+//fprintf( stderr, "VTSI\n" );
 
-    GET( mat.psz_id , 12 );
-    mat.psz_id[12] = '\0';
-    GETL( &mat.i_lsector );
+    GET( manager_inf.psz_id , 12 );
+    manager_inf.psz_id[12] = '\0';
+    GETL( &manager_inf.i_end_sector );
     FLUSH( 12 );
-    GETL( &mat.i_i_lsector );
+    GETL( &manager_inf.i_inf_end_sector );
     FLUSH( 1 );
-    GETC( &mat.i_spec_ver );
-    GETL( &mat.i_cat );
-    GETS( &mat.i_vol_nb );
-    GETS( &mat.i_vol );
-    GETC( &mat.i_disc_side );
-    FLUSH( 19 );
-    GETS( &mat.i_tts_nb );
-    GET( mat.ps_provider_id, 32 );
-    GETLL( &mat.i_pos_code );
+    GETC( &manager_inf.i_spec_ver );
+    GETL( &manager_inf.i_cat );
+    FLUSH( 90 );
+    GETL( &manager_inf.i_inf_end_byte );
+    FLUSH( 60 );
+    GETL( &manager_inf.i_menu_vob_start_sector );
+    GETL( &manager_inf.i_title_vob_start_sector );
+    GETL( &manager_inf.i_title_inf_start_sector );
+    GETL( &manager_inf.i_title_unit_start_sector );
+    GETL( &manager_inf.i_menu_unit_start_sector );
+    GETL( &manager_inf.i_time_inf_start_sector );
+    GETL( &manager_inf.i_menu_cell_inf_start_sector );
+    GETL( &manager_inf.i_menu_vobu_map_start_sector );
+    GETL( &manager_inf.i_cell_inf_start_sector );
+    GETL( &manager_inf.i_vobu_map_start_sector );
     FLUSH( 24 );
-    GETL( &mat.i_i_mat_ebyte );
-    GETL( &mat.i_fp_pgc_sbyte );
-    FLUSH( 56 );
-    GETL( &mat.i_vobs_ssector );
-    GETL( &mat.i_ptt_srpt_ssector );
-    GETL( &mat.i_pgci_ut_ssector );
-    GETL( &mat.i_ptl_mait_ssector );
-    GETL( &mat.i_vts_atrt_ssector );
-    GETL( &mat.i_txtdt_mg_ssector );
-    GETL( &mat.i_c_adt_ssector );
-    GETL( &mat.i_vobu_admap_ssector );
-    FLUSH( 32 );
-//    GETS( &mat.video_atrt );
+//    GETS( &manager_inf.m_video_atrt );
 FLUSH(2);
     FLUSH( 1 );
-    GETC( &mat.i_audio_nb );
-//fprintf( stderr, "vmgi audio nb : %d\n", mat.i_audio_nb );
-    for( i=0 ; i < 8 ; i++ )
+    GETC( &manager_inf.i_menu_audio_nb );
+    for( i=0 ; i<8 ; i++ )
     {
         GETLL( &i_temp );
     }
     FLUSH( 17 );
-    GETC( &mat.i_subpic_nb );
-//fprintf( stderr, "vmgi subpic nb : %d\n", mat.i_subpic_nb );
-    for( i=0 ; i < mat.i_subpic_nb ; i++ )
+    GETC( &manager_inf.i_menu_spu_nb );
+    for( i=0 ; i<28 ; i++ )
     {
         GET( &i_temp, 6 );
         /* FIXME : take care of endianness */
     }
+    FLUSH( 2 );
+//    GETS( &manager_inf.video_atrt );
+FLUSH(2);
+    FLUSH( 1 );
+    GETC( &manager_inf.i_audio_nb );
+//fprintf( stderr, "vtsi audio nb : %d\n", manager_inf.i_audio_nb );
+    for( i=0 ; i<8 ; i++ )
+    {
+        GETLL( &i_temp );
+//fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
+        i_temp >>= 32;
+        manager_inf.p_audio_attr[i].i_lang_code = i_temp & 0xffff;
+        i_temp >>= 16;
+        manager_inf.p_audio_attr[i].i_num_channels = i_temp & 0x7;
+        i_temp >>= 4;
+        manager_inf.p_audio_attr[i].i_sample_freq = i_temp & 0x3;
+        i_temp >>= 2;
+        manager_inf.p_audio_attr[i].i_quantization = i_temp & 0x3;
+        i_temp >>= 2;
+        manager_inf.p_audio_attr[i].i_appl_mode = i_temp & 0x3;
+        i_temp >>= 2;
+        manager_inf.p_audio_attr[i].i_type = i_temp & 0x3;
+        i_temp >>= 2;
+        manager_inf.p_audio_attr[i].i_multichannel_extension = i_temp & 0x1;
+        i_temp >>= 1;
+        manager_inf.p_audio_attr[i].i_coding_mode = i_temp & 0x7;
+    }
+    FLUSH( 17 );
+    GETC( &manager_inf.i_spu_nb );
+//fprintf( stderr, "vtsi subpic nb : %d\n", manager_inf.i_subpic_nb );
+    for( i=0 ; i<manager_inf.i_spu_nb ; i++ )
+    {
+        GET( &i_temp, 6 );
+        i_temp = hton64( i_temp ) >> 16;
+//fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
+        manager_inf.p_spu_attr[i].i_caption = i_temp & 0xff;
+        i_temp >>= 16;
+        manager_inf.p_spu_attr[i].i_lang_code = i_temp & 0xffff;
+        i_temp >>= 16;
+        manager_inf.p_spu_attr[i].i_prefix = i_temp & 0xffff;
+    }
 
-    return mat;
-}
+    /*
+     * reads title information: set of pointers to title
+     */
+#define title_inf p_ifo->vts.title_inf
+    if( manager_inf.i_title_inf_start_sector )
+    {
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_title_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
 
-/*****************************************************************************
- * ReadVMGTitlePointer : Fills the Part Of Title Search Pointer structure.
- *****************************************************************************/
-static vmg_ptt_srpt_t ReadVMGTitlePointer( ifo_t* p_ifo )
-{
-    vmg_ptt_srpt_t  ptr;
-    int             i;
-//    off_t           i_start = p_ifo->i_pos;
+        i_start = p_ifo->i_pos;
+    
+//fprintf( stderr, "VTS PTR\n" );
+   
+        GETS( &title_inf.i_title_nb );
+//fprintf( stderr, "VTS title_inf nb: %d\n", title_inf.i_title_nb );
+        FLUSH( 2 );
+        GETL( &title_inf.i_end_byte );
 
-//fprintf( stderr, "PTR\n" );
+        title_inf.pi_start_byte = malloc( title_inf.i_title_nb *sizeof(u32) );
+        if( title_inf.pi_start_byte == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
+            return -1;
+        }
 
-    GETS( &ptr.i_ttu_nb );
-//fprintf( stderr, "PTR: TTU nb %d\n", ptr.i_ttu_nb );
-    FLUSH( 2 );
-    GETL( &ptr.i_ebyte );
-    /* Parsing of tts */
-    ptr.p_tts = malloc( ptr.i_ttu_nb *sizeof(tts_t) );
-    if( ptr.p_tts == NULL )
+        for( i = 0 ; i < title_inf.i_title_nb ; i++ )
+        {
+            GETL( &title_inf.pi_start_byte[i] );
+        }
+
+        /* Parsing of tts */
+        title_inf.p_title_start = malloc( title_inf.i_title_nb
+                                         *sizeof(title_start_t) );
+        if( title_inf.p_title_start == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
+            return -1;
+        }
+
+        for( i = 0 ; i < title_inf.i_title_nb ; i++ )
+        {
+            p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
+                            title_inf.pi_start_byte[i], SEEK_SET );
+
+            GETS( &title_inf.p_title_start[i].i_program_chain_num );
+            GETS( &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 );
+        }
+    }
+#undef title_inf
+
+    /*
+     * menu unit information
+     */
+    if( manager_inf.i_menu_unit_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return ptr;
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_menu_unit_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit ) < 0 )
+        {
+            return -1;
+        }
     }
-    for( i=0 ; i<ptr.i_ttu_nb ; i++ )
+
+    /*
+     * title unit information
+     */
+    if( manager_inf.i_title_unit_start_sector )
     {
-        GETC( &ptr.p_tts[i].i_play_type );
-        GETC( &ptr.p_tts[i].i_angle_nb );
-        GETS( &ptr.p_tts[i].i_ptt_nb );
-        GETS( &ptr.p_tts[i].i_parental_id );
-        GETC( &ptr.p_tts[i].i_tts_nb );
-        GETC( &ptr.p_tts[i].i_vts_ttn );
-        GETL( &ptr.p_tts[i].i_ssector );
-//fprintf( stderr, "PTR: %d %d %d\n", ptr.p_tts[i].i_ptt_nb, ptr.p_tts[i].i_tts_nb,ptr.p_tts[i].i_vts_ttn );
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_title_unit_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit ) < 0 )
+        {
+            return -1;
+        }
     }
 
-    return ptr;
-}
+    /*
+     * time map inforamtion
+     */
+#define time_inf p_ifo->vts.time_inf
+    if( manager_inf.i_time_inf_start_sector )
+    {
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_time_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
 
-/*****************************************************************************
- * ReadParentalInf : Fills the Parental Management structure.
- *****************************************************************************/
-static vmg_ptl_mait_t ReadParentalInf( ifo_t* p_ifo )
-{
-    vmg_ptl_mait_t  par;
-    int             i, j, k;
-    off_t           i_start = p_ifo->i_pos;
+//fprintf( stderr, "TMAP\n" );
 
-//fprintf( stderr, "PTL\n" );
+        GETS( &time_inf.i_nb );
+        FLUSH( 2 );
+        GETL( &time_inf.i_end_byte );
+
+        time_inf.pi_start_byte = malloc( time_inf.i_nb *sizeof(u32) );
+        if( time_inf.pi_start_byte == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
+            return -1;
+        }
+
+        for( i = 0 ; i < time_inf.i_nb ; i++ )
+        {    
+            GETL( &time_inf.pi_start_byte[i] );
+        }
+
+        time_inf.p_time_map = malloc( time_inf.i_nb *sizeof(time_map_t) );
+        if( time_inf.p_time_map == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
+            return -1;
+        }
 
-    GETS( &par.i_country_nb );
-    GETS( &par.i_vts_nb );
-    GETL( &par.i_ebyte );
-    par.p_ptl_desc = malloc( par.i_country_nb *sizeof(vmg_ptl_mai_desc_t) );
-    if( par.p_ptl_desc == NULL )
+        for( i = 0 ; i < time_inf.i_nb ; i++ )
+        {    
+            GETC( &time_inf.p_time_map[i].i_time_unit );
+            FLUSH( 1 );
+            GETS( &time_inf.p_time_map[i].i_entry_nb );
+
+            time_inf.p_time_map[i].pi_sector =
+                     malloc( time_inf.p_time_map[i].i_entry_nb *sizeof(u32) );
+            if( time_inf.p_time_map[i].pi_sector == NULL )
+            {
+                intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
+                return -1;
+            }
+
+            for( j = 0 ; j < time_inf.p_time_map[i].i_entry_nb ; j++ )
+            {
+                GETL( &time_inf.p_time_map[i].pi_sector[j] );
+            }
+        }
+    }
+#undef time_inf
+
+    if( manager_inf.i_menu_cell_inf_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return par;
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_menu_cell_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf ) < 0 )
+        {
+            return -1;
+        }
     }
-    for( i=0 ; i<par.i_country_nb ; i++ )
+
+    if( manager_inf.i_menu_vobu_map_start_sector )
     {
-        GET( par.p_ptl_desc[i].ps_country_code, 2 );
-        FLUSH( 2 );
-        GETS( &par.p_ptl_desc[i].i_ptl_mai_sbyte );
-        FLUSH( 2 );
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_menu_vobu_map_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map ) < 0 )
+        {
+            return -1;
+        }
     }
-    par.p_ptl_mask = malloc( par.i_country_nb *sizeof(vmg_ptl_mask_t) );
-    if( par.p_ptl_mask == NULL )
+
+    if( manager_inf.i_cell_inf_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return par;
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_cell_inf_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadCellInf( p_ifo, &p_ifo->vts.cell_inf ) )
+        {
+            return -1;
+        }
     }
-    for( i=0 ; i<par.i_country_nb ; i++ )
+
+    if( manager_inf.i_vobu_map_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
-                         par.p_ptl_desc[i].i_ptl_mai_sbyte, SEEK_SET );
-        for( j=1 ; j<=8 ; j++ )
+        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->vts.i_pos +
+                        manager_inf.i_vobu_map_start_sector *DVD_LB_SIZE,
+                        SEEK_SET );
+        if( ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map ) )
         {
-            par.p_ptl_mask[i].ppi_ptl_mask[j] =
-                                    malloc( par.i_vts_nb *sizeof(u16) );
-            if( par.p_ptl_mask[i].ppi_ptl_mask[j] == NULL )
-            {
-                intf_ErrMsg( "Out of memory" );
-                p_ifo->b_error = 1;
-                return par;
-            }        
-            for( k=0 ; k<par.i_vts_nb ; k++ )
-            {
-                GETS( &par.p_ptl_mask[i].ppi_ptl_mask[j][k] );
-            }
+            return -1;
         }
     }
 
-    return par;
+    intf_WarnMsg( 2, "ifo info: VTS %d initialized",
+         p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_title_set_num );
+
+#undef manager_inf
+
+    p_ifo->vts.b_initialized = 1;
+
+    return 0;
 }
 
 /*****************************************************************************
- * ReadVTSAttr : Fills the structure about VTS attributes.
+ * FreeTitleSet : free all structures allocated by IfoTitleSet
  *****************************************************************************/
-static vmg_vts_atrt_t ReadVTSAttr( ifo_t* p_ifo )
+static int FreeTitleSet( vts_t * p_vts )
 {
-    vmg_vts_atrt_t  atrt;
-    int             i, j;
-    u64             i_temp;
-    off_t           i_start = p_ifo->i_pos;
+    int     i;
 
-//fprintf( stderr, "VTS ATTR\n" );
+    if( p_vts->manager_inf.i_vobu_map_start_sector )
+    {
+        FreeVobuMap( &p_vts->vobu_map );
+    }
 
-    GETS( &atrt.i_vts_nb );
-//fprintf( stderr, "VTS ATTR Nb: %d\n", atrt.i_vts_nb );
-    FLUSH( 2 );
-    GETL( &atrt.i_ebyte );
-    atrt.pi_vts_atrt_sbyte = malloc( atrt.i_vts_nb *sizeof(u32) );
-    if( atrt.pi_vts_atrt_sbyte == NULL )
+    if( p_vts->manager_inf.i_cell_inf_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return atrt;
+        FreeCellInf( &p_vts->cell_inf );
     }
-    for( i=0 ; i<atrt.i_vts_nb ; i++ )
+
+    if( p_vts->manager_inf.i_menu_vobu_map_start_sector )
     {
-        GETL( &atrt.pi_vts_atrt_sbyte[i] );
+        FreeVobuMap( &p_vts->menu_vobu_map );
     }
-    atrt.p_vts_atrt = malloc( atrt.i_vts_nb *sizeof(vts_atrt_t) );
-    if( atrt.p_vts_atrt == NULL )
+
+    if( p_vts->manager_inf.i_menu_cell_inf_start_sector )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return atrt;
+        FreeCellInf( &p_vts->menu_cell_inf );
     }
-    for( i=0 ; i<atrt.i_vts_nb ; i++ )
+
+    if( p_vts->manager_inf.i_time_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
-                                atrt.pi_vts_atrt_sbyte[i],
-                                SEEK_SET );
-        GETL( &atrt.p_vts_atrt[i].i_ebyte );
-        GETL( &atrt.p_vts_atrt[i].i_cat_app_type );
-//        GETS( &atrt.p_vts_atrt[i].vtsm_video_atrt );
-FLUSH(2);
-        FLUSH( 1 );
-        GETC( &atrt.p_vts_atrt[i].i_vtsm_audio_nb );
-//fprintf( stderr, "m audio nb : %d\n", atrt.p_vts_atrt[i].i_vtsm_audio_nb );
-        for( j=0 ; j<8 ; j++ )
-        {
-            GETLL( &i_temp );
-        }
-        FLUSH( 17 );
-        GETC( &atrt.p_vts_atrt[i].i_vtsm_subpic_nb );
-//fprintf( stderr, "m subp nb : %d\n", atrt.p_vts_atrt[i].i_vtsm_subpic_nb );
-        for( j=0 ; j<28 ; j++ )
-        {
-            GET( &i_temp, 6 );
-            /* FIXME : Fix endianness issue here */
-        }
-        FLUSH( 2 );
-//        GETS( &atrt.p_vts_atrt[i].vtstt_video_atrt );
-FLUSH(2);
-        FLUSH( 1 );
-        GETL( &atrt.p_vts_atrt[i].i_vtstt_audio_nb );
-//fprintf( stderr, "tt audio nb : %d\n", atrt.p_vts_atrt[i].i_vtstt_audio_nb );
-        for( j=0 ; j<8 ; j++ )
+        for( i = 0 ; i < p_vts->time_inf.i_nb ; i++ )
         {
-            GETLL( &i_temp );
-        }
-        FLUSH( 17 );
-        GETC( &atrt.p_vts_atrt[i].i_vtstt_subpic_nb );
-//fprintf( stderr, "tt subp nb : %d\n", atrt.p_vts_atrt[i].i_vtstt_subpic_nb );
-        for( j=0 ; j<28/*atrt.p_vts_atrt[i].i_vtstt_subpic_nb*/ ; j++ )
-        {
-            GET( &i_temp, 6 );
-            /* FIXME : Fix endianness issue here */
+            free( p_vts->time_inf.p_time_map[i].pi_sector );
         }
+
+        free( p_vts->time_inf.p_time_map );
+        free( p_vts->time_inf.pi_start_byte );
     }
 
-    return atrt;
+    if( p_vts->manager_inf.i_title_unit_start_sector )
+    {
+        FreeUnitInf( &p_vts->title_unit );
+    }
+
+    if( p_vts->manager_inf.i_menu_unit_start_sector )
+    {
+        FreeTitleUnit( &p_vts->menu_unit );
+    }
+
+    if( p_vts->manager_inf.i_title_inf_start_sector )
+    {
+        free( p_vts->title_inf.pi_start_byte );
+        free( p_vts->title_inf.p_title_start );
+    }
+
+    p_vts->b_initialized = 0;
+    
+    return 0;
 }
-                           
+
 /*****************************************************************************
- * ReadVMG : Parse video_ts.ifo file to fill the Video Manager structure.
+ * IfoEnd : Frees all the memory allocated to ifo structures
  *****************************************************************************/
-static vmg_t ReadVMG( ifo_t* p_ifo )
+void IfoEnd( ifo_t * p_ifo )
 {
-    vmg_t       vmg;
+    int     i, j;
+
+    FreeTitleSet( &p_ifo->vts );
 
-    p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off, SEEK_SET);
-    vmg.mat = ReadVMGInfMat( p_ifo );
-    p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off + 
-                              vmg.mat.i_fp_pgc_sbyte, SEEK_SET );
-    vmg.pgc = ReadPGC( p_ifo );
-    if( vmg.mat.i_ptt_srpt_ssector )
+    if( p_ifo->vmg.manager_inf.i_vobu_map_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_ptt_srpt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.ptt_srpt = ReadVMGTitlePointer( p_ifo );
+        FreeVobuMap( &p_ifo->vmg.vobu_map );
     }
-    if( vmg.mat.i_pgci_ut_ssector )
+
+    if( p_ifo->vmg.manager_inf.i_cell_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_pgci_ut_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.pgci_ut = ReadUnitTable( p_ifo );
+        FreeCellInf( &p_ifo->vmg.cell_inf );
     }
-    if( vmg.mat.i_ptl_mait_ssector )
+
+    if( p_ifo->vmg.manager_inf.i_vts_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_ptl_mait_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.ptl_mait = ReadParentalInf( p_ifo );
+        free( p_ifo->vmg.vts_inf.p_vts_attr );
+        free( p_ifo->vmg.vts_inf.pi_vts_attr_start_byte );
     }
-    if( vmg.mat.i_vts_atrt_ssector )
+
+    /* free parental information structures */
+    if( p_ifo->vmg.manager_inf.i_parental_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_vts_atrt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.vts_atrt = ReadVTSAttr( p_ifo );
+        for( i = 0 ; i < p_ifo->vmg.parental_inf.i_country_nb ; i++ )
+        {
+            for( j = 0 ; j < 8 ; j++ )
+            {
+                free( p_ifo->vmg.parental_inf.p_parental_mask[i].ppi_mask[j] );
+            }
+        }
+
+        free( p_ifo->vmg.parental_inf.p_parental_mask );
+        free( p_ifo->vmg.parental_inf.p_parental_desc );
     }
-    if( vmg.mat.i_c_adt_ssector )
+
+    if( p_ifo->vmg.manager_inf.i_title_unit_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_c_adt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.c_adt = ReadCellInf( p_ifo );
+        FreeTitleUnit( &p_ifo->vmg.title_unit );
     }
-    if( vmg.mat.i_vobu_admap_ssector )
+
+    if( p_ifo->vmg.manager_inf.i_title_inf_start_sector )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
-                        vmg.mat.i_vobu_admap_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vmg.vobu_admap = ReadMap( p_ifo );
+        free( p_ifo->vmg.title_inf.p_attr );
     }
-    return vmg;
-}
 
+    FreeTitle( &p_ifo->vmg.title );
+
+    free( p_ifo );
+
+    return;
+}
 /*
- * Video Title Set Information Processing.
- * This is what is contained in vts_*.ifo.
+ * Function common to Video Manager and Video Title set Processing
  */
 
 /*****************************************************************************
- * ReadVTSInfMat : Fills the Title Set Information structure.
+ * ReadTitle : Fills the title structure.
+ *****************************************************************************
+ * Titles are logical stream units that correspond to a whole inside the dvd.
+ * Several title can point to the same part of the physical DVD, and give
+ * map to different anglesfor instance.
  *****************************************************************************/
-static vtsi_mat_t ReadVTSInfMat( ifo_t* p_ifo )
+#define GETCOMMAND( p_com )                                                 \
+    {                                                                       \
+        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 )
 {
-    vtsi_mat_t  mat;
-    int         i;
-    u64         i_temp;
-//    off_t       i_start = p_ifo->i_pos;
+    off_t     i_start;
+    int       i;
 
-//fprintf( stderr, "VTSI\n" );
+    i_start = p_ifo->i_pos;
 
-    GET( mat.psz_id , 12 );
-    mat.psz_id[12] = '\0';
-    GETL( &mat.i_lsector );
-    FLUSH( 12 );
-    GETL( &mat.i_i_lsector );
-    FLUSH( 1 );
-    GETC( &mat.i_spec_ver );
-    GETL( &mat.i_cat );
-    FLUSH( 90 );
-    GETL( &mat.i_mat_ebyte );
-    FLUSH( 60 );
-    GETL( &mat.i_m_vobs_ssector );
-    GETL( &mat.i_tt_vobs_ssector );
-    GETL( &mat.i_ptt_srpt_ssector );
-    GETL( &mat.i_pgcit_ssector );
-    GETL( &mat.i_m_pgci_ut_ssector );
-    GETL( &mat.i_tmap_ti_ssector );
-    GETL( &mat.i_m_c_adt_ssector );
-    GETL( &mat.i_m_vobu_admap_ssector );
-    GETL( &mat.i_c_adt_ssector );
-    GETL( &mat.i_vobu_admap_ssector );
-    FLUSH( 24 );
-//    GETS( &mat.m_video_atrt );
-FLUSH(2);
-    FLUSH( 1 );
-    GETC( &mat.i_m_audio_nb );
+//fprintf( stderr, "PGC\n" );
+
+    FLUSH(2);
+    GETC( &p_title->i_chapter_nb );
+    GETC( &p_title->i_cell_nb );
+//fprintf( stderr, "title: Prg: %d Cell: %d\n", pgc.i_prg_nb, pgc.i_cell_nb );
+    GETL( &p_title->i_play_time );
+    GETL( &p_title->i_prohibited_user_op );
     for( i=0 ; i<8 ; i++ )
     {
-        GETLL( &i_temp );
+        GETS( &p_title->pi_audio_status[i] );
     }
-    FLUSH( 17 );
-    GETC( &mat.i_m_subpic_nb );
-    for( i=0 ; i<28 ; i++ )
+    for( i=0 ; i<32 ; i++ )
     {
-        GET( &i_temp, 6 );
-        /* FIXME : take care of endianness */
+        GETL( &p_title->pi_subpic_status[i] );
     }
-    FLUSH( 2 );
-//    GETS( &mat.video_atrt );
-FLUSH(2);
-    FLUSH( 1 );
-    GETC( &mat.i_audio_nb );
-//fprintf( stderr, "vtsi audio nb : %d\n", mat.i_audio_nb );
-    for( i=0 ; i<8 ; i++ )
+    GETS( &p_title->i_next_title_num );
+    GETS( &p_title->i_prev_title_num );
+    GETS( &p_title->i_go_up_title_num );
+//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 );
+    GETC( &p_title->i_play_mode );
+    for( i=0 ; i<16 ; i++ )
     {
-        GETLL( &i_temp );
-//fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
-        i_temp >>= 32;
-        mat.p_audio_atrt[i].i_lang_code = i_temp & 0xffff;
-        i_temp >>= 16;
-        mat.p_audio_atrt[i].i_num_channels = i_temp & 0x7;
-        i_temp >>= 4;
-        mat.p_audio_atrt[i].i_sample_freq = i_temp & 0x3;
-        i_temp >>= 2;
-        mat.p_audio_atrt[i].i_quantization = i_temp & 0x3;
-        i_temp >>= 2;
-        mat.p_audio_atrt[i].i_appl_mode = i_temp & 0x3;
-        i_temp >>= 2;
-        mat.p_audio_atrt[i].i_type = i_temp & 0x3;
-        i_temp >>= 2;
-        mat.p_audio_atrt[i].i_multichannel_extension = i_temp & 0x1;
-        i_temp >>= 1;
-        mat.p_audio_atrt[i].i_coding_mode = i_temp & 0x7;
+        GETL( &p_title->pi_yuv_color[i] );
+        /* FIXME : We have to erase the extra bit */
     }
-    FLUSH( 17 );
-    GETC( &mat.i_subpic_nb );
-//fprintf( stderr, "vtsi subpic nb : %d\n", mat.i_subpic_nb );
-    for( i=0 ; i<mat.i_subpic_nb ; i++ )
+    GETS( &p_title->i_command_start_byte );
+    GETS( &p_title->i_chapter_map_start_byte );
+    GETS( &p_title->i_cell_play_start_byte );
+    GETS( &p_title->i_cell_pos_start_byte );
+
+    /* parsing of command_t */
+    if( p_title->i_command_start_byte )
     {
-        GET( &i_temp, 6 );
-        i_temp = hton64( i_temp ) >> 16;
-//fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
-        mat.p_subpic_atrt[i].i_caption = i_temp & 0xff;
-        i_temp >>= 16;
-        mat.p_subpic_atrt[i].i_lang_code = i_temp & 0xffff;
-        i_temp >>= 16;
-        mat.p_subpic_atrt[i].i_prefix = i_temp & 0xffff;
-    }
+        p_ifo->i_pos = lseek( p_ifo->i_fd,
+                              i_start + p_title->i_command_start_byte,
+                              SEEK_SET );
 
-    return mat;
-}
+        /* header */
+        GETS( &p_title->command.i_pre_command_nb );
+        GETS( &p_title->command.i_post_command_nb );
+        GETS( &p_title->command.i_cell_command_nb );
+        FLUSH( 2 );
 
-/*****************************************************************************
- * ReadVTSTitlePointer : Fills the Part Of Title Search Pointer structure.
- *****************************************************************************/
-static vts_ptt_srpt_t ReadVTSTitlePointer( ifo_t* p_ifo )
-{
-    vts_ptt_srpt_t  ptr;
-    int             i;
-    off_t           i_start = p_ifo->i_pos;
+        /* pre-title commands */
+        if( p_title->command.i_pre_command_nb )
+        {
+            p_title->command.p_pre_command =
+                           malloc( p_title->command.i_pre_command_nb
+                                   *sizeof(command_desc_t) );
 
-//fprintf( stderr, "VTS PTR\n" );
+            if( p_title->command.p_pre_command == NULL )
+            {
+                intf_ErrMsg( "ifo error: out of memory in ReadTitle" );
+                return -1;
+            }
 
-    GETS( &ptr.i_ttu_nb );
-//fprintf( stderr, "VTS PTR nb: %d\n", ptr.i_ttu_nb );
-    FLUSH( 2 );
-    GETL( &ptr.i_ebyte );
-    ptr.pi_ttu_sbyte = malloc( ptr.i_ttu_nb *sizeof(u32) );
-    if( ptr.pi_ttu_sbyte == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return ptr;
+            for( i = 0 ; i < p_title->command.i_pre_command_nb ; i++ )
+            {
+                GETCOMMAND( &p_title->command.p_pre_command[i] );
+            }
+        }
+        else
+        {
+            p_title->command.p_pre_command = NULL;
+        }
+
+        /* post-title commands */
+        if( p_title->command.i_post_command_nb )
+        {
+            p_title->command.p_post_command =
+                        malloc( p_title->command.i_post_command_nb
+                                *sizeof(command_desc_t) );
+
+            if( p_title->command.p_post_command == NULL )
+            {
+                intf_ErrMsg( "ifo error: out of memory in ReadTitle" );
+                return -1;
+            }
+
+            for( i=0 ; i<p_title->command.i_post_command_nb ; i++ )
+            {
+                GETCOMMAND( &p_title->command.p_post_command[i] );
+            }
+        }
+        else
+        {
+            p_title->command.p_post_command = NULL;
+        }
+
+        /* cell commands */
+        if( p_title->command.i_cell_command_nb )
+        {
+            p_title->command.p_cell_command =
+                        malloc( p_title->command.i_cell_command_nb
+                                *sizeof(command_desc_t) );
+
+            if( p_title->command.p_cell_command == NULL )
+            {
+                intf_ErrMsg( "ifo error: out of memory in ReadTitle" );
+                return -1;
+            }
+
+            for( i=0 ; i<p_title->command.i_cell_command_nb ; i++ )
+            {
+                GETCOMMAND( &p_title->command.p_cell_command[i] );
+            }
+        }
+        else
+        {
+            p_title->command.p_cell_command = NULL;
+        }
     }
-    for( i=0 ; i<ptr.i_ttu_nb ; i++ )
+
+    /* parsing of chapter_map_t: it gives the entry cell for each chapter */
+    if( p_title->i_chapter_map_start_byte )
     {
-        GETL( &ptr.pi_ttu_sbyte[i] );
+        p_ifo->i_pos = lseek( p_ifo->i_fd,
+                              i_start + p_title->i_chapter_map_start_byte,
+                              SEEK_SET );
+        
+        p_title->chapter_map.pi_start_cell =
+                    malloc( p_title->i_chapter_nb *sizeof(chapter_map_t) );
+        
+        if( p_title->chapter_map.pi_start_cell == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in Read Title" );
+            return -1;
+        }
+
+        GET( p_title->chapter_map.pi_start_cell, p_title->i_chapter_nb );
     }
-    /* Parsing of tts */
-    ptr.p_ttu = malloc( ptr.i_ttu_nb *sizeof(ttu_t) );
-    if( ptr.p_ttu == NULL )
+    else
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return ptr;
+        p_title->chapter_map.pi_start_cell = NULL; 
     }
-    for( i=0 ; i<ptr.i_ttu_nb ; i++ )
+
+    /* parsing of cell_play_t */
+    if( p_title->i_cell_play_start_byte )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
-                        ptr.pi_ttu_sbyte[i], SEEK_SET );
-        GETS( &ptr.p_ttu[i].i_pgc_nb );
-        GETS( &ptr.p_ttu[i].i_prg_nb );
-//fprintf( stderr, "VTS %d PTR Pgc: %d Prg: %d\n", i,ptr.p_ttu[i].i_pgc_nb, ptr.p_ttu[i].i_prg_nb );
+        p_ifo->i_pos = lseek( p_ifo->i_fd,
+                              i_start + p_title->i_cell_play_start_byte,
+                              SEEK_SET );
+
+        p_title->p_cell_play = malloc( p_title->i_cell_nb
+                                       *sizeof(cell_play_t) );
+    
+        if( p_title->p_cell_play == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory in ReadTitle" );
+            return -1;
+        }
+
+        for( i = 0 ; i < p_title->i_cell_nb ; i++ )
+        {
+            GETS( &p_title->p_cell_play[i].i_category );
+            GETC( &p_title->p_cell_play[i].i_still_time );
+            GETC( &p_title->p_cell_play[i].i_command_nb );
+            GETL( &p_title->p_cell_play[i].i_play_time );
+            GETL( &p_title->p_cell_play[i].i_start_sector );
+            GETL( &p_title->p_cell_play[i].i_first_ilvu_vobu_esector );
+            GETL( &p_title->p_cell_play[i].i_last_vobu_start_sector );
+            GETL( &p_title->p_cell_play[i].i_end_sector );
+        }
     }
 
-    return ptr;
+    /* Parsing of cell_pos_t */
+    if( p_title->i_cell_pos_start_byte )
+    {
+        p_ifo->i_pos = lseek( p_ifo->i_fd,
+                              i_start + p_title->i_cell_pos_start_byte,
+                              SEEK_SET );
+
+        p_title->p_cell_pos = malloc( p_title->i_cell_nb
+                                      *sizeof(cell_pos_t) );
+
+        if( p_title->p_cell_pos == NULL )
+        {
+            intf_ErrMsg( "ifo error: out of memory" );
+            return -1;
+        }
+
+        for( i = 0 ; i < p_title->i_cell_nb ; i++ )
+        {
+            GETS( &p_title->p_cell_pos[i].i_vob_id );
+            FLUSH( 1 );
+            GETC( &p_title->p_cell_pos[i].i_cell_id );
+        }
+    } 
+
+    return 0;
 }
 
 /*****************************************************************************
- * ReadVTSTimeMap : Fills the time map table
+ * FreeTitle: frees alla structure allocated by a call to ReadTitle
  *****************************************************************************/
-static vts_tmap_ti_t ReadVTSTimeMap( ifo_t* p_ifo )
+static int FreeTitle( title_t * p_title )
 {
-    vts_tmap_ti_t   tmap;
-    int             i,j;
-//    off_t           i_start = p_ifo->i_pos;
+    if( p_title->i_command_start_byte )
+    {
+        if( p_title->command.i_pre_command_nb )
+        {
+            free( p_title->command.p_pre_command );
+        }
 
-//fprintf( stderr, "TMAP\n" );
+        if( p_title->command.i_post_command_nb )
+        {
+            free( p_title->command.p_post_command );
+        }
 
-    GETS( &tmap.i_nb );
-    FLUSH( 2 );
-    GETL( &tmap.i_ebyte );
-    tmap.pi_sbyte = malloc( tmap.i_nb *sizeof(u32) );
-    if( tmap.pi_sbyte == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return tmap;
-    }
-    for( i=0 ; i<tmap.i_nb ; i++ )
-    {    
-        GETL( &tmap.pi_sbyte[i] );
-    }
-    tmap.p_tmap = malloc( tmap.i_nb *sizeof(tmap_t) );
-    if( tmap.p_tmap == NULL )
-    {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return tmap;
-    }
-    for( i=0 ; i<tmap.i_nb ; i++ )
-    {    
-        GETC( &tmap.p_tmap[i].i_time_unit );
-        FLUSH( 1 );
-        GETS( &tmap.p_tmap[i].i_entry_nb );
-        tmap.p_tmap[i].pi_sector =
-                    malloc( tmap.p_tmap[i].i_entry_nb *sizeof(u32) );
-        if( tmap.p_tmap[i].pi_sector == NULL )
+        if( p_title->command.i_cell_command_nb )
+        {
+            free( p_title->command.p_cell_command );
+        }
+
+        if( p_title->i_chapter_map_start_byte )
         {
-            intf_ErrMsg( "Out of memory" );
-            p_ifo->b_error = 1;
-            return tmap;
+            free( p_title->chapter_map.pi_start_cell );
         }
-        for( j=0 ; j<tmap.p_tmap[i].i_entry_nb ; j++ )
+
+        if( p_title->i_cell_play_start_byte )
         {
-            GETL( &tmap.p_tmap[i].pi_sector[j] );
+            free( p_title->p_cell_play );
+        }
+
+        if( p_title->i_cell_pos_start_byte )
+        {
+            free( p_title->p_cell_pos );
         }
     }
 
-    return tmap;
+    return 0;
 }
-    
 
 /*****************************************************************************
- * IfoReadVTS : Parse vts*.ifo files to fill the Video Title Set structure.
+ * ReadUnitInf : Fills Menu Language Unit Table/ PGC Info Table
  *****************************************************************************/
-int IfoReadVTS( ifo_t* p_ifo )
+static int ReadUnitInf( ifo_t * p_ifo, unit_inf_t * p_unit_inf )
 {
-    vts_t       vts;
-    off_t       i_off;
-    int         i_title;
-
-    intf_WarnMsg( 2, "ifo: initializing VTS %d", p_ifo->i_title );
-
-    i_title = p_ifo->i_title;
-    i_off = (off_t)( p_ifo->vmg.ptt_srpt.p_tts[i_title-1].i_ssector )
-                   * DVD_LB_SIZE
-                   + p_ifo->i_off;
+    off_t           i_start;
+    int             i;
 
-    p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
+    i_start = p_ifo->i_pos;
+//fprintf( stderr, "Unit\n" );
 
-    vts.i_pos = p_ifo->i_pos;
+    GETS( &p_unit_inf->i_title_nb );
+    FLUSH( 2 );
+    GETL( &p_unit_inf->i_end_byte );
 
-    vts.mat = ReadVTSInfMat( p_ifo );
-    if( vts.mat.i_ptt_srpt_ssector )
+    p_unit_inf->p_title =
+            malloc( p_unit_inf->i_title_nb *sizeof(unit_title_t) );
+    if( p_unit_inf->p_title == NULL )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_ptt_srpt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.ptt_srpt = ReadVTSTitlePointer( p_ifo );
+        intf_ErrMsg( "ifo error: out of memory in ReadUnit" );
+        return -1;
     }
-    if( vts.mat.i_m_pgci_ut_ssector )
+
+    for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_m_pgci_ut_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.pgci_ut = ReadUnitTable( p_ifo );
+        GETC( &p_unit_inf->p_title[i].i_category_mask );
+        GETC( &p_unit_inf->p_title[i].i_category );
+        GETS( &p_unit_inf->p_title[i].i_parental_mask );
+        GETL( &p_unit_inf->p_title[i].i_title_start_byte );
     }
-    if( vts.mat.i_pgcit_ssector )
+
+    for( i = 0 ; i < p_unit_inf->i_title_nb ; i++ )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_pgcit_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.pgci_ti = ReadUnit( p_ifo );
+        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\n", i );
+        ReadTitle( p_ifo, &p_unit_inf->p_title[i].title );
     }
-    if( vts.mat.i_tmap_ti_ssector )
+
+    return 0;
+}
+
+/*****************************************************************************
+ * FreeUnitInf : frees a structure allocated by ReadUnit
+ *****************************************************************************/ 
+static int FreeUnitInf( unit_inf_t * p_unit_inf )
+{
+    if( p_unit_inf->p_title != NULL )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_tmap_ti_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.tmap_ti = ReadVTSTimeMap( p_ifo );
+        free( p_unit_inf->p_title );
     }
-    if( vts.mat.i_m_c_adt_ssector )
+
+    return 0;
+}
+
+
+/*****************************************************************************
+ * ReadTitleUnit: Fills the Title Unit structure.
+ *****************************************************************************/
+static int ReadTitleUnit( ifo_t * p_ifo, title_unit_t * p_title_unit )
+{
+    int             i;
+    off_t           i_start = p_ifo->i_pos;
+
+//fprintf( stderr, "Unit Table\n" );
+
+    GETS( &p_title_unit->i_unit_nb );
+    FLUSH( 2 );
+    GETL( &p_title_unit->i_end_byte );
+
+    p_title_unit->p_unit = malloc( p_title_unit->i_unit_nb *sizeof(unit_t) );
+    if( p_title_unit->p_unit == NULL )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_m_c_adt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.m_c_adt = ReadCellInf( p_ifo );
+        intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" );
+        return -1;
     }
-    if( vts.mat.i_m_vobu_admap_ssector )
+
+    for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_m_vobu_admap_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.m_vobu_admap = ReadMap( p_ifo );
+        GET( p_title_unit->p_unit[i].ps_lang_code, 2 );
+        FLUSH( 1 );
+        GETC( &p_title_unit->p_unit[i].i_existence_mask );
+        GETL( &p_title_unit->p_unit[i].i_unit_inf_start_byte );
     }
-    if( vts.mat.i_c_adt_ssector )
+
+    p_title_unit->p_unit_inf =
+                malloc( p_title_unit->i_unit_nb *sizeof(unit_inf_t) );
+    if( p_title_unit->p_unit_inf == NULL )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_c_adt_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.c_adt = ReadCellInf( p_ifo );
+        intf_ErrMsg( "ifo error: out of memory in ReadTitleUnit" );
+        return -1;
     }
-    if( vts.mat.i_vobu_admap_ssector )
+
+    for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
     {
-        p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
-                        vts.mat.i_vobu_admap_ssector *DVD_LB_SIZE,
-                        SEEK_SET );
-        vts.vobu_admap = ReadMap( p_ifo );
+        p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
+                              p_title_unit->p_unit[i].i_unit_inf_start_byte,
+                              SEEK_SET );
+        ReadUnitInf( p_ifo, &p_title_unit->p_unit_inf[i] );
     }
 
-    p_ifo->vts = vts;
-
     return 0;
 }
 
-/*
- * DVD Information Management
- */
-#if 0
 /*****************************************************************************
- * IfoRead : Function that fills structure and calls specified functions
- * to do it.
+ * FreeTitleUnit: frees a structure allocateed by ReadTitleUnit
  *****************************************************************************/
-void IfoRead( ifo_t* p_ifo )
+static int FreeTitleUnit( title_unit_t * p_title_unit )
 {
     int     i;
-    off_t   i_off;
 
-    /* Video Title Sets initialization */
-    p_ifo->p_vts = malloc( p_ifo->vmg.mat.i_tts_nb *sizeof(vts_t) );
-    if( p_ifo->p_vts == NULL )
+    if( p_title_unit->p_unit_inf != NULL )
     {
-        intf_ErrMsg( "Out of memory" );
-        p_ifo->b_error = 1;
-        return;
+        for( i = 0 ; i < p_title_unit->i_unit_nb ; i++ )
+        {
+            FreeUnitInf( &p_title_unit->p_unit_inf[i] );
+        }
+
+        free( p_title_unit->p_unit_inf );
     }
 
-    for( i=0 ; i<p_ifo->vmg.mat.i_tts_nb ; i++ )
+    return 0;
+}
+
+/*****************************************************************************
+ * ReadCellInf : Fills the Cell Information structure.
+ *****************************************************************************/
+static int ReadCellInf( ifo_t * p_ifo, cell_inf_t * p_cell_inf )
+{
+    off_t           i_start;
+    int             i;
+
+    i_start = p_ifo->i_pos;
+//fprintf( stderr, "CELL ADD\n" );
+
+    GETS( &p_cell_inf->i_vob_nb );
+    FLUSH( 2 );
+    GETL( &p_cell_inf->i_end_byte );
+
+    p_cell_inf->i_cell_nb =
+        ( i_start + p_cell_inf->i_end_byte + 1 - p_ifo->i_pos )
+        / sizeof(cell_map_t);
+
+    p_cell_inf->p_cell_map =
+                malloc( p_cell_inf->i_cell_nb *sizeof(cell_map_t) );
+    if( p_cell_inf->p_cell_map == NULL )
     {
+        intf_ErrMsg( "ifo error: out of memory in ReadCellInf" );
+        return -1;
+    }
 
-        intf_WarnMsg( 2, "ifo: initializing VTS %d", i+1 );
+    for( i = 0 ; i < p_cell_inf->i_cell_nb ; i++ )
+    {
+        GETS( &p_cell_inf->p_cell_map[i].i_vob_id );
+        GETC( &p_cell_inf->p_cell_map[i].i_cell_id );
+        FLUSH( 1 );
+        GETL( &p_cell_inf->p_cell_map[i].i_start_sector );
+        GETL( &p_cell_inf->p_cell_map[i].i_end_sector );
+    }
+    
+    return 0;
+}
 
-        i_off = (off_t)( p_ifo->vmg.ptt_srpt.p_tts[i].i_ssector ) *DVD_LB_SIZE
-                       + p_ifo->i_off;
+/*****************************************************************************
+ * FreeCellInf : frees structures allocated by ReadCellInf
+ *****************************************************************************/
+static int FreeCellInf( cell_inf_t * p_cell_inf )
+{
+    free( p_cell_inf->p_cell_map );
 
-        p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
+    return 0;
+}
 
-        /* FIXME : I really don't know why udf find file
-         * does not give the exact beginning of file */
+/*****************************************************************************
+ * ReadVobuMap : Fills the VOBU Map structure.
+ *****************************************************************************/
+static int ReadVobuMap( ifo_t * p_ifo, vobu_map_t * p_vobu_map )
+{
+    off_t               i_start;
+    int                 i, i_max;
+    
+    i_start = p_ifo->i_pos;
+//fprintf( stderr, "VOBU ADMAP\n" );
 
-        p_ifo->p_vts[i] = ReadVTS( p_ifo );
+    GETL( &p_vobu_map->i_end_byte );
+    i_max = ( i_start + p_vobu_map->i_end_byte + 1 - p_ifo->i_pos )
+            / sizeof(u32);
 
+    p_vobu_map->pi_vobu_start_sector = malloc( i_max *sizeof(u32) );
+    if( p_vobu_map->pi_vobu_start_sector == NULL )
+    {
+        intf_ErrMsg( "ifo error: out of memory in ReadVobuMap" );
+        return -1;
     }
 
-    return; 
+    for( i = 0 ; i < i_max ; i++ )
+    {
+        GETL( &p_vobu_map->pi_vobu_start_sector[i] );
+    }
+
+    return 0;
 }
-#endif
+
+/*****************************************************************************
+ * FreeVobuMap: frees structures allocated by ReadVobuMap
+ *****************************************************************************/
+static int FreeVobuMap( vobu_map_t * p_vobu_map )
+{
+    free( p_vobu_map->pi_vobu_start_sector );
+
+    return 0;
+}
+
 /*
  * IFO virtual machine : a set of commands that give the
  * interactive behaviour of the dvd
  */
-#if 1
+#if 0
 
 #define OP_VAL_16(i) (ntoh16( com.data.pi_16[i]))
 #define OP_VAL_8(i) ((com.data.pi_8[i]))
index 58e1ed6e27e66788bf4592dd600ba441177eac1d..8e99052364921586ee1be2702bd3c9286daac6dc 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ifo.h: Structures for ifo parsing
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.h,v 1.8 2001/02/22 08:44:45 stef Exp $
+ * $Id: dvd_ifo.h,v 1.9 2001/04/01 07:31:38 stef Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -76,7 +76,7 @@ typedef struct ifo_spu_t
 
 
 /* Ifo vitual machine Commands */
-typedef struct ifo_command_s
+typedef struct command_desc_s
 {
     u8              i_type      :3;
     u8              i_direct    :1;
@@ -89,162 +89,162 @@ typedef struct ifo_command_s
                u8          pi_8[6];
                u16         pi_16[3];
     } data;
-} ifo_command_t;
+} command_desc_t;
 
 /* Program Chain Command Table
   - start at i_pgc_com_tab_sbyte */
-typedef struct pgc_com_tab_s
+typedef struct command_s
 {
-    u16             i_pre_com_nb;               // 2 bytes
-    u16             i_post_com_nb;              // 2 bytes
-    u16             i_cell_com_nb;              // 2 bytes
+    u16             i_pre_command_nb;               // 2 bytes
+    u16             i_post_command_nb;              // 2 bytes
+    u16             i_cell_command_nb;              // 2 bytes
 //    char[2]         ???
-    ifo_command_t*  p_pre_com;                  // i_pre_com_nb * 8 bytes
-    ifo_command_t*  p_post_com;                 // i_post_com_nb * 8 bytes
-    ifo_command_t*  p_cell_com;                 // i_cell_com_nb * 8 bytes
-} pgc_com_tab_t;
+    command_desc_t* p_pre_command;                  // i_pre_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;
 
 /* Program Chain Map Table
  * - start at "i_pgc_prg_map_sbyte" */
-typedef struct pgc_prg_map_s
+typedef struct chapter_map_s
 {
-    u8*             pi_entry_cell;              // i_prg_nb * 1 byte 
-} pgc_prg_map_t;
+    u8*             pi_start_cell;              // i_prg_nb * 1 byte 
+} chapter_map_t;
 
 /* Cell Playback Information Table
  * we have a pointer to such a structure for each cell  
  * - first start at "i_cell_play_inf_sbyte" */
-typedef struct cell_play_inf_s
+typedef struct cell_play_s
 {
     /* This information concerns the currently selected cell */
-    u16             i_cat;                      // 2 bytes
+    u16             i_category;                      // 2 bytes
     u8              i_still_time;               // 1 byte; in seconds; ff=inf
-    u8              i_com_nb;                   // 1 byte; 0 = no com
+    u8              i_command_nb;                   // 1 byte; 0 = no com
     u32             i_play_time;                // 4 bytes
-    u32             i_entry_sector;             // 4 bytes
+    u32             i_start_sector;             // 4 bytes
     u32             i_first_ilvu_vobu_esector;  // 4 bytes; ???
-    u32             i_lvobu_ssector;            // 4 bytes
-    u32             i_lsector;                  // 4 bytes
-} cell_play_inf_t;
+    u32             i_last_vobu_start_sector;            // 4 bytes
+    u32             i_end_sector;                  // 4 bytes
+} cell_play_t;
 
 /* Cell Position Information Table
  * we have a pointer to such a structure for each cell 
  * - first start at "i_cell_pos_inf_sbyte" */
-typedef struct cell_pos_inf_s
+typedef struct cell_pos_s
 {
     /* This information concerns the currently selected cell */
     u16             i_vob_id;                   // 2 bytes
 //    char            ???
     u8              i_cell_id;                  // 1 byte
-} cell_pos_inf_t;
+} cell_pos_t;
 
 /* Main structure for Program Chain
  * - start at i_fp_pgc_sbyte
  * - or at i_vmgm_pgci_sbyte in vmgm_pgci_srp_t */
-typedef struct pgc_s
+typedef struct title_s
 {
     /* Global features of program chain */
 //    char[2]         ???
-    u8              i_prg_nb;                   // 1 byte
+    u8              i_chapter_nb;                   // 1 byte
     u8              i_cell_nb;                  // 1 byte
     u32             i_play_time;                // 4 bytes
     u32             i_prohibited_user_op;       // 4 bytes
     u16             pi_audio_status[8];         // 8*2 bytes
     u32             pi_subpic_status[32];       // 32*4 bytes
-    u16             i_next_pgc_nb;              // 2 bytes
-    u16             i_prev_pgc_nb;              // 2 bytes
-    u16             i_goup_pgc_nb;              // 2 bytes
+    u16             i_next_title_num;              // 2 bytes
+    u16             i_prev_title_num;              // 2 bytes
+    u16             i_go_up_title_num;              // 2 bytes
     u8              i_still_time;               // 1 byte ; in seconds
     u8              i_play_mode;                // 1 byte
     /* In video_ts.ifo, the 3 significant bytes of each color are
      * preceded by 1 unsignificant byte */
     u32             pi_yuv_color[16];           // 16*3 bytes
     /* Here come the start bytes of the following structures */
-    u16             i_com_tab_sbyte;            // 2 bytes
-    u16             i_prg_map_sbyte;            // 2 bytes
-    u16             i_cell_play_inf_sbyte;      // 2 bytes
-    u16             i_cell_pos_inf_sbyte;       // 2 bytes
+    u16             i_command_start_byte;            // 2 bytes
+    u16             i_chapter_map_start_byte;            // 2 bytes
+    u16             i_cell_play_start_byte;      // 2 bytes
+    u16             i_cell_pos_start_byte;       // 2 bytes
     /* Predefined structures */
-    pgc_com_tab_t   com_tab;
-    pgc_prg_map_t   prg_map;
-    cell_play_inf_t* p_cell_play_inf;           // i_cell_nb * 24 bytes
-    cell_pos_inf_t* p_cell_pos_inf;             // i_cell_nb * 4 bytes
-} pgc_t;
+    command_t       command;
+    chapter_map_t   chapter_map;
+    cell_play_t*    p_cell_play;           // i_cell_nb * 24 bytes
+    cell_pos_t*     p_cell_pos;             // i_cell_nb * 4 bytes
+} title_t;
 
 /*
  * Menu PGCI Unit Table
  */
 
 /* Menu PGCI Language unit Descriptor */
-typedef struct pgci_lu_s
+typedef struct unit_s
 {
     char            ps_lang_code[2];            // 2 bytes (ISO-xx)
 //    char            ???
     u8              i_existence_mask;           // 1 byte
-    u32             i_lu_sbyte;                 // 4 bytes
-} pgci_lu_t;
+    u32             i_unit_inf_start_byte;                 // 4 bytes
+} unit_t;
 
-typedef struct pgci_srp_s
+typedef struct unit_title_s
 {
-    u8              i_pgc_cat_mask;             // 1 byte
-    u8              i_pgc_cat;                  // 1 byte
-    u16             i_par_mask;                 // 2 bytes
-    u32             i_pgci_sbyte;               // 4 bytes
-    pgc_t           pgc;
-} pgci_srp_t;
+    u8              i_category_mask;             // 1 byte
+    u8              i_category;                  // 1 byte
+    u16             i_parental_mask;                 // 2 bytes
+    u32             i_title_start_byte;               // 4 bytes
+    title_t         title;
+} unit_title_t;
 
 /* Menu PGCI Language Unit Table 
  * - start at i_lu_sbyte */
-typedef struct pgci_inf_s
+typedef struct unit_inf_s
 {
-    u16             i_srp_nb;                   // 2 bytes
+    u16             i_title_nb;                   // 2 bytes
 //    char[2]         ???
-    u32             i_lu_ebyte;                 // 4 bytes
-    pgci_srp_t*     p_srp;                      // i_srp_nb * 8 bytes
-} pgci_inf_t;
+    u32             i_end_byte;                 // 4 bytes
+    unit_title_t *  p_title;                      // i_srp_nb * 8 bytes
+} unit_inf_t;
 
 /* Main Struct for Menu PGCI
  * - start at i_*_pgci_ut_ssector */
-typedef struct pgci_ut_s
+typedef struct title_unit_s
 {
-    u16             i_lu_nb;                    // 2 bytes; ???
+    u16             i_unit_nb;                    // 2 bytes; ???
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 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;
+    u32             i_end_byte;                    // 4 bytes
+    unit_t*         p_unit;                       // i_lu_nb * 8 bytes
+    unit_inf_t*     p_unit_inf;                 // i_lu_nb * 8 bytes
+} title_unit_t;
 
 /*
  * Cell Adress Table Information
  */
-typedef struct cell_inf_s
+typedef struct cell_map_s
 {
     u16             i_vob_id;                   // 2 bytes
     u8              i_cell_id;                  // 1 byte
 //    char            ???
-    u32             i_ssector;                  // 4 bytes
-    u32             i_esector;                  // 4 bytes
-} cell_inf_t;
+    u32             i_start_sector;                  // 4 bytes
+    u32             i_end_sector;                  // 4 bytes
+} cell_map_t;
 
-typedef struct c_adt_s
+typedef struct cell_inf_s
 {
     u16             i_vob_nb;                   // 2 bytes
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 bytes
+    u32             i_end_byte;                    // 4 bytes
     u16             i_cell_nb;                  // not in ifo; computed
                                                 // with e_byte
-    cell_inf_t*     p_cell_inf;
-} c_adt_t;
+    cell_map_t*     p_cell_map;
+} cell_inf_t;
 
 
 /*
  * VOBU Adress Map Table
  */
-typedef struct vobu_admap_s
+typedef struct vobu_map_s
 {
-    u32             i_ebyte;                    // 4 bytes
-    u32*            pi_vobu_ssector;            // (nb of vobu) * 4 bytes
-} vobu_admap_t;
+    u32             i_end_byte;                    // 4 bytes
+    u32*            pi_vobu_start_sector;            // (nb of vobu) * 4 bytes
+} vobu_map_t;
 
 /*****************************************************************************
  * Structures for Video Management (cf video_ts.ifo)
@@ -253,43 +253,43 @@ typedef struct vobu_admap_s
 /* 
  * Video Manager Information Management Table
  */ 
-typedef struct vmgi_mat_s
+typedef struct manager_inf_s
 {
     char            psz_id[13];                 // 12 bytes (DVDVIDEO-VMG)
-    u32             i_lsector;                  // 4 bytes
+    u32             i_vmg_end_sector;                  // 4 bytes
 //    char[12]        ???
-    u32             i_i_lsector;                // 4 bytes
+    u32             i_vmg_inf_end_sector;                // 4 bytes
 //    char            ???
     u8              i_spec_ver;                 // 1 byte
     u32             i_cat;                      // 4 bytes
-    u16             i_vol_nb;                   // 2 bytes
-    u16             i_vol;                      // 2 bytes
+    u16             i_volume_nb;                   // 2 bytes
+    u16             i_volume;                      // 2 bytes
     u8              i_disc_side;                // 1 bytes
 //    char[20]        ???
-    u16             i_tts_nb;                   // 2 bytes
+    u16             i_title_set_nb;                   // 2 bytes
     char            ps_provider_id[32];         // 32 bytes
     u64             i_pos_code;                 // 8 bytes
 //    char[24]        ???
-    u32             i_i_mat_ebyte;              // 4 bytes
-    u32             i_fp_pgc_sbyte;             // 4 bytes
+    u32             i_vmg_inf_end_byte;              // 4 bytes
+    u32             i_first_play_title_start_byte;             // 4 bytes
 //    char[56]        ???
-    u32             i_vobs_ssector;             // 4 bytes
-    u32             i_ptt_srpt_ssector;         // 4 bytes
-    u32             i_pgci_ut_ssector;          // 4 bytes
-    u32             i_ptl_mait_ssector;         // 4 bytes
-    u32             i_vts_atrt_ssector;         // 4 bytes
-    u32             i_txtdt_mg_ssector;         // 4 bytes
-    u32             i_c_adt_ssector;            // 4 bytes
-    u32             i_vobu_admap_ssector;       // 4 bytes
+    u32             i_vob_start_sector;             // 4 bytes
+    u32             i_title_inf_start_sector;         // 4 bytes
+    u32             i_title_unit_start_sector;          // 4 bytes
+    u32             i_parental_inf_start_sector;         // 4 bytes
+    u32             i_vts_inf_start_sector;         // 4 bytes
+    u32             i_text_data_start_sector;         // 4 bytes
+    u32             i_cell_inf_start_sector;            // 4 bytes
+    u32             i_vobu_map_start_sector;       // 4 bytes
 //    char[2]         ???
-    ifo_video_t     video_atrt;                 // 2 bytes
+    ifo_video_t     video_attr;                 // 2 bytes
 //    char            ???
     u8              i_audio_nb;                 // 1 byte
-    ifo_audio_t     p_audio_atrt[8];            // i_vmgm_audio_nb * 8 bytes
+    ifo_audio_t     p_audio_attr[8];            // i_vmgm_audio_nb * 8 bytes
 //    char[16]        ???
-    u8              i_subpic_nb;                // 1 byte
-    ifo_spu_t       p_subpic_atrt[32];          // i_subpic_nb * 6 bytes
-} vmgi_mat_t;
+    u8              i_spu_nb;                // 1 byte
+    ifo_spu_t       p_spu_attr[32];          // i_subpic_nb * 6 bytes
+} manager_inf_t;
 
 
 /* 
@@ -298,53 +298,53 @@ typedef struct vmgi_mat_s
 
 /* Title sets structure
  * we have a pointer to this structure for each tts */
-typedef struct tts_s
+typedef struct title_attr_s
 {
     u8              i_play_type;                // 1 byte
     u8              i_angle_nb;                 // 1 byte
-    u16             i_ptt_nb;                   // 2 bytes; Chapters/PGs
+    u16             i_chapter_nb;                  // 2 bytes; Chapters/PGs
     u16             i_parental_id;              // 2 bytes
-    u8              i_tts_nb;                   // 1 byte (VTS#)
-    u8              i_vts_ttn;                  // 1 byte ???
-    u32             i_ssector;                  // 4 bytes
-} tts_t;
+    u8              i_title_set_num;            // 1 byte (VTS#)
+    u8              i_title_num;                 // 1 byte ???
+    u32             i_start_sector;              // 4 bytes
+} title_attr_t;
 
 /* Main struct for tts
  * - start at "i_vmg_ptt_srpt_ssector" */
-typedef struct vmg_ptt_srpt_s
+typedef struct title_inf_s
 {
-    u16             i_ttu_nb;                   // 2 bytes
+    u16             i_title_nb;                   // 2 bytes
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 bytes
-    tts_t*          p_tts;                      // i_ttu_nb * 12 bytes
-} vmg_ptt_srpt_t;
+    u32             i_end_byte;                    // 4 bytes
+    title_attr_t *  p_attr;                     // i_ttu_nb * 12 bytes
+} title_inf_t;
 
 /*
  * Parental Management Information Table
  */
-typedef struct vmg_ptl_mai_desc_s
+typedef struct parental_desc_s
 {
     char            ps_country_code[2];         // 2 bytes
 //    char[2]         ???
-    u16             i_ptl_mai_sbyte;            // 2 bytes
+    u16             i_parental_mask_start_byte;            // 2 bytes
 //    char[2]         ???
-} vmg_ptl_mai_desc_t;
+} parental_desc_t;
 
-typedef struct vmg_ptl_mask_s
+typedef struct parental_mask_s
 {
-    u16*            ppi_ptl_mask[8];            // (i_vts_nb +1) * 8 * 2 bytes
-} vmg_ptl_mask_t;
+    u16*            ppi_mask[8];            // (i_vts_nb +1) * 8 * 2 bytes
+} parental_mask_t;
 
 /* Main struct for parental management
  * - start at i_vmg_ptl_mait_ssector */
-typedef struct vmg_ptl_mait_s
+typedef struct parental_inf_s
 {
     u16             i_country_nb;               // 2 bytes
     u16             i_vts_nb;                   // 2 bytes
-    u32             i_ebyte;                    // 4 bytes
-    vmg_ptl_mai_desc_t* p_ptl_desc;             // i_country_nb * 8 bytes
-    vmg_ptl_mask_t* p_ptl_mask;        // i_country_nb * sizeof(vmg_ptl_mask_t)
-} vmg_ptl_mait_t;
+    u32             i_end_byte;                    // 4 bytes
+    parental_desc_t* p_parental_desc;             // i_country_nb * 8 bytes
+    parental_mask_t* p_parental_mask;        // i_country_nb * sizeof(vmg_ptl_mask_t)
+} parental_inf_t;
 
 /*
  * Video Title Set Attribute Table
@@ -352,51 +352,51 @@ typedef struct vmg_ptl_mait_s
 
 /* Attribute structure : one for each vts
  * - start at pi_atrt_sbyte */
-typedef struct vts_atrt_s
+typedef struct vts_attr_s
 {
-    u32             i_ebyte;                    // 4 bytes
+    u32             i_end_byte;                    // 4 bytes
     u32             i_cat_app_type;             // 4 bytes
-    ifo_video_t     vtsm_video_atrt;          // 2 bytes
+    ifo_video_t     vts_menu_video_attr;          // 2 bytes
 //    char            ???
-    u8              i_vtsm_audio_nb;            // 1 byte
-    ifo_audio_t     p_vtsm_audio_atrt[8];       // 8 * 8 bytes
+    u8              i_vts_menu_audio_nb;            // 1 byte
+    ifo_audio_t     p_vts_menu_audio_attr[8];       // 8 * 8 bytes
 //    char[17]        ???
-    u8              i_vtsm_subpic_nb;           // 1 byte
-    ifo_spu_t       p_vtsm_subpic_atrt[28];     // i_vtsm_subpic_nb * 6 bytes
+    u8              i_vts_menu_spu_nb;           // 1 byte
+    ifo_spu_t       p_vts_menu_spu_attr[28];     // i_vtsm_subpic_nb * 6 bytes
 //    char[2]         ???
-    ifo_video_t     vtstt_video_atrt;         // 2 bytes
+    ifo_video_t     vts_title_video_attr;         // 2 bytes
 //    char            ???
-    u8              i_vtstt_audio_nb;           // 1 byte
-    ifo_audio_t     p_vtstt_audio_atrt[8];      // 8 * 8 bytes
+    u8              i_vts_title_audio_nb;           // 1 byte
+    ifo_audio_t     p_vts_title_audio_attr[8];      // 8 * 8 bytes
 //    char[17]        ???
-    u8              i_vtstt_subpic_nb;          // 1 byte
-    ifo_spu_t       p_vtstt_subpic_atrt[28];    // i_vtstt_subpic_nb * 6 bytes
-} vts_atrt_t;
+    u8              i_vts_title_spu_nb;          // 1 byte
+    ifo_spu_t       p_vts_title_spu_attr[28];    // i_vtstt_subpic_nb * 6 bytes
+} vts_attr_t;
 
 /* Main struct for vts attributes
  * - start at i_vmg_vts_atrt_ssector */
-typedef struct vmg_vts_atrt_s
+typedef struct vts_inf_s
 {
     u16             i_vts_nb;                   // 2 bytes
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 bytes
-    u32*            pi_vts_atrt_sbyte;          // i_vts_nb * 4 bytes
-    vts_atrt_t*     p_vts_atrt;
-} vmg_vts_atrt_t;
+    u32             i_end_byte;                    // 4 bytes
+    u32*            pi_vts_attr_start_byte;          // i_vts_nb * 4 bytes
+    vts_attr_t*     p_vts_attr;
+} vts_inf_t;
 
 /* 
  * Global Structure for Video Manager
  */
 typedef struct vmg_s 
 {
-    vmgi_mat_t      mat;
-    pgc_t           pgc;
-    vmg_ptt_srpt_t  ptt_srpt;
-    pgci_ut_t       pgci_ut;
-    vmg_ptl_mait_t  ptl_mait;
-    vmg_vts_atrt_t  vts_atrt;
-    c_adt_t         c_adt;
-    vobu_admap_t    vobu_admap;
+    manager_inf_t       manager_inf;
+    title_t             title;
+    title_inf_t         title_inf;
+    title_unit_t        title_unit;
+    parental_inf_t      parental_inf;
+    vts_inf_t           vts_inf;
+    cell_inf_t          cell_inf;
+    vobu_map_t          vobu_map;
 } vmg_t;
 
 /*****************************************************************************
@@ -406,46 +406,46 @@ typedef struct vmg_s
 /* 
  * Video Title Sets Information Management Table
  */ 
-typedef struct vtsi_mat_s
+typedef struct vts_manager_s
 {
     char            psz_id[13];                 // 12 bytes (DVDVIDEO-VTS)
-    u32             i_lsector;                  // 4 bytes
+    u32             i_end_sector;                  // 4 bytes
 //    char[12]        ???
-    u32             i_i_lsector;                // 4 bytes
+    u32             i_inf_end_sector;                // 4 bytes
 //    char            ???
     u8              i_spec_ver;                 // 1 byte
     u32             i_cat;                      // 4 bytes
 //    char[90]        ???
-    u32             i_mat_ebyte;                // 4 bytes
+    u32             i_inf_end_byte;                // 4 bytes
 //    char[60]        ???
-    u32             i_m_vobs_ssector;           // 4 bytes
-    u32             i_tt_vobs_ssector;          // 4 bytes
-    u32             i_ptt_srpt_ssector;         // 4 bytes
-    u32             i_pgcit_ssector;            // 4 bytes
-    u32             i_m_pgci_ut_ssector;        // 4 bytes
-    u32             i_tmap_ti_ssector;          // 4 bytes
-    u32             i_m_c_adt_ssector;          // 4 bytes
-    u32             i_m_vobu_admap_ssector;     // 4 bytes
-    u32             i_c_adt_ssector;            // 4 bytes
-    u32             i_vobu_admap_ssector;       // 4 bytes
+    u32             i_menu_vob_start_sector;           // 4 bytes
+    u32             i_title_vob_start_sector;          // 4 bytes
+    u32             i_title_inf_start_sector;         // 4 bytes
+    u32             i_title_unit_start_sector;            // 4 bytes
+    u32             i_menu_unit_start_sector;        // 4 bytes
+    u32             i_time_inf_start_sector;          // 4 bytes
+    u32             i_menu_cell_inf_start_sector;          // 4 bytes
+    u32             i_menu_vobu_map_start_sector;     // 4 bytes
+    u32             i_cell_inf_start_sector;            // 4 bytes
+    u32             i_vobu_map_start_sector;       // 4 bytes
 //    char[24]        ???
-    ifo_video_t     m_video_atrt;               // 2 bytes
+    ifo_video_t     menu_video_attr;               // 2 bytes
 //    char            ???
-    u8              i_m_audio_nb;               // 1 byte
-    ifo_audio_t     p_m_audio_atrt[8];          // i_vmgm_audio_nb * 8 bytes
+    u8              i_menu_audio_nb;               // 1 byte
+    ifo_audio_t     p_menu_audio_attr[8];          // i_vmgm_audio_nb * 8 bytes
 //    char[16]        ???
-    u8              i_m_subpic_nb;              // 1 byte
-    ifo_spu_t       p_m_subpic_atrt[32];        // i_subpic_nb * 6 bytes
+    u8              i_menu_spu_nb;              // 1 byte
+    ifo_spu_t       p_menu_spu_attr[32];        // i_subpic_nb * 6 bytes
                                                 // !!! only 28 subpics ???
 //    char[2]         ???
-    ifo_video_t     video_atrt;                 // 2 bytes
+    ifo_video_t     video_attr;                 // 2 bytes
 //    char            ???
     u8              i_audio_nb;                 // 1 byte
-    ifo_audio_t     p_audio_atrt[8];            // i_vmgm_audio_nb * 8 bytes
+    ifo_audio_t     p_audio_attr[8];            // i_vmgm_audio_nb * 8 bytes
 //    char[16]        ???
-    u8              i_subpic_nb;                // 1 byte
-    ifo_spu_t       p_subpic_atrt[32];          // i_subpic_nb * 6 bytes
-} vtsi_mat_t;
+    u8              i_spu_nb;                // 1 byte
+    ifo_spu_t       p_spu_attr[32];          // i_subpic_nb * 6 bytes
+} vts_manager_t;
 
 /* 
  * Part Of Title Search Pointer Table Information
@@ -453,70 +453,63 @@ typedef struct vtsi_mat_s
 
 /* Title sets structure
  * we have a pointer to this structure for each tts */
-typedef struct ttu_s
+typedef struct title_start_s
 {
-    u16             i_pgc_nb;                   // 2 bytes; Chapters/PGs
-    u16             i_prg_nb;                   // 2 bytes
-} ttu_t;
+    u16             i_program_chain_num;                   // 2 bytes; Chapters/PGs
+    u16             i_program_num;                   // 2 bytes
+} title_start_t;
 
 /* Main struct for tts
  * - start at "i_vts_ptt_srpt_ssector" */
-typedef struct vts_ptt_srpt_s
+typedef struct vts_title_s
 {
-    u16             i_ttu_nb;                   // 2 bytes
+    u16             i_title_nb;                   // 2 bytes
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 bytes
-    u32*            pi_ttu_sbyte;
-    ttu_t*          p_ttu;                      // i_ttu_nb * 4 bytes
-} vts_ptt_srpt_t;
+    u32             i_end_byte;                    // 4 bytes
+    u32*            pi_start_byte;
+    title_start_t * p_title_start;                      // i_ttu_nb * 4 bytes
+} vts_title_t;
 
 /*
  * Time Map table information
  */
 
 /* Time Map structure */
-typedef struct tmap_s
+typedef struct time_map_s
 {
     u8              i_time_unit;                // 1 byte
 //    char            ???
     u16             i_entry_nb;                 // 2 bytes
     u32*            pi_sector;                  // i_entry_nb * 4 bytes
-} tmap_t;
+} time_map_t;
 
 /* Main structure for tmap_ti
  * - start at "i_tmap_ti_ssector" */
-typedef struct vts_tmap_ti_s
+typedef struct time_inf_s
 {
     u16             i_nb;                       // 2 bytes
 //    char[2]         ???
-    u32             i_ebyte;                    // 4 bytes
-    u32*            pi_sbyte;                   // i_tmap_nb * 4 bytes
-    tmap_t*         p_tmap;
-} vts_tmap_ti_t;
+    u32             i_end_byte;                    // 4 bytes
+    u32*            pi_start_byte;                   // i_tmap_nb * 4 bytes
+    time_map_t*     p_time_map;
+} time_inf_t;
 
 /*
  * Video Title Set 
  */
 typedef struct vts_s
 {
+    boolean_t       b_initialized;
     off_t           i_pos;
-    vtsi_mat_t      mat;
-    /* Part Of Title Search Pointer Table Info */
-    vts_ptt_srpt_t  ptt_srpt;
-    /* Video Title Set Menu PGCI Unit Table */
-    pgci_ut_t       pgci_ut;
-    /* Video Title Set Program Chain Info Table */
-    pgci_inf_t      pgci_ti;
-    /* Video Title Set Time Map Table */
-    vts_tmap_ti_t   tmap_ti;
-    /* VTSM Cell Adress Table Information */
-    c_adt_t         m_c_adt;
-    /* VTSM VOBU Adress Map Table */
-    vobu_admap_t    m_vobu_admap;
-    /* VTS Cell Adress Table Information */
-    c_adt_t         c_adt;
-    /* VTS VOBU Adress Map Table */
-    vobu_admap_t    vobu_admap;
+    vts_manager_t   manager_inf;
+    vts_title_t     title_inf;
+    title_unit_t    menu_unit;
+    unit_inf_t      title_unit;
+    time_inf_t      time_inf;
+    cell_inf_t      menu_cell_inf;
+    vobu_map_t      menu_vobu_map;
+    cell_inf_t      cell_inf;
+    vobu_map_t      vobu_map;
 } vts_t;
 
 /*
@@ -524,19 +517,12 @@ typedef struct vts_s
  */
 typedef struct ifo_s
 {
-    /* File descriptor for the device */
-    int             i_fd;
-    /* Offset to video_ts.ifo on the device */
-    off_t           i_off;
-    /* Position of stream pointer */
-    off_t           i_pos;
-    /* Error Management */
-    boolean_t       b_error;
-    /* Current title set number */
-    int             i_title;
-    /* Structure described in video_ts */
-    vmg_t           vmg;
-    /* Vts ifo for current title set */
-    vts_t           vts;
+    int             i_fd;           /* File descriptor for the device */
+    off_t           i_off;          /* Offset to video_ts.ifo on the device */
+    off_t           i_pos;          /* Position of stream pointer */
+    boolean_t       b_error;        /* Error Management */
+    vmg_t           vmg;            /* Structure described in video_ts */
+    int             i_title;        /* Current title number */
+    vts_t           vts;            /* Vts ifo for current title set */
 } ifo_t;
 
index 7e3b02ce378a918fa22b5d2b3a48ac6c71a4e31e..4dded9c848152419e8a2b3fcf1e49b36f610ee44 100644 (file)
@@ -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.3 2001/03/22 01:23:03 stef Exp $
+ * $Id: dvd_netlist.c,v 1.4 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Henri Fallon <henri@videolan.org>
  *          Stéphane Borel <stef@videolan.org>
@@ -357,7 +357,7 @@ struct data_packet_s * DVDNewPacket( void * p_method_data,
 {
     dvd_netlist_t *         p_netlist;
     struct data_packet_s *  p_packet;
-
+//intf_ErrMsg( "netlist: New packet" );
     /* cast */
     p_netlist = (dvd_netlist_t *)p_method_data;
     
@@ -382,14 +382,18 @@ struct data_packet_s * DVDNewPacket( void * p_method_data,
     p_packet = p_netlist->pp_free_data[p_netlist->i_data_start];
         
     p_packet->p_buffer =
-               p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base;
+              p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base;
         
     p_packet->p_payload_start = p_packet->p_buffer;
         
     p_packet->p_payload_end =
-               p_packet->p_buffer + i_buffer_size;
+              p_packet->p_buffer + i_buffer_size;
+
+    p_packet->p_next = NULL;
+    p_packet->b_discard_payload = 0;
 
     p_packet->pi_refcount = p_netlist->pi_refcount + p_netlist->i_iovec_start;
+    (*p_packet->pi_refcount)++;
 
     p_netlist->i_iovec_start ++;
     p_netlist->i_iovec_start &= p_netlist->i_nb_iovec;
@@ -411,6 +415,7 @@ struct pes_packet_s * DVDNewPES( void * p_method_data )
     dvd_netlist_t *     p_netlist;
     pes_packet_t *      p_return;
     
+//intf_ErrMsg( "netlist: New pes" );
     /* cast */ 
     p_netlist = (dvd_netlist_t *)p_method_data;
     
@@ -433,9 +438,10 @@ struct pes_packet_s * DVDNewPES( void * p_method_data )
     vlc_mutex_unlock (&p_netlist->lock);
     
     /* initialize PES */
-    p_return->b_data_alignment = 
-        p_return->b_discontinuity = 
-        p_return->i_pts = p_return->i_dts = 0;
+    p_return->b_data_alignment = 0;
+    p_return->b_discontinuity = 0; 
+    p_return->i_pts = 0;
+    p_return->i_dts = 0;
     p_return->i_pes_size = 0;
     p_return->p_first = NULL;
 
@@ -462,6 +468,9 @@ void DVDDeletePacket( void * p_method_data, data_packet_t * p_data )
     
     p_netlist->pp_free_data[p_netlist->i_data_end] = p_data;
 
+    p_data->p_next = NULL;
+    p_data->b_discard_payload = 0;
+
     /* Update reference counter */
     (*p_data->pi_refcount)--;
 
@@ -510,7 +519,7 @@ void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes )
         /* Update reference counter */
         (*p_current_packet->pi_refcount)--;
 
-        if( (*p_current_packet->pi_refcount) == 0 )
+        if( (*p_current_packet->pi_refcount) <= 0 )
         {
             p_netlist->i_iovec_end++;
             p_netlist->i_iovec_end &= p_netlist->i_nb_iovec;
@@ -520,6 +529,7 @@ void DVDDeletePES( void * p_method_data, pes_packet_t * p_pes )
     
         p_next_packet = p_current_packet->p_next;
         p_current_packet->p_next = NULL;
+        p_current_packet->b_discard_payload = 0;
         p_current_packet = p_next_packet;
     }
  
index 4c13e8b13a22e2f29149df329710b7181d6e04a5..43c8609c3c59f88c5227c26838665616baec1621 100644 (file)
@@ -10,7 +10,7 @@
  *  -dvd_udf to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.34 2001/03/22 01:23:03 stef Exp $
+ * $Id: input_dvd.c,v 1.35 2001/04/01 07:31:38 stef Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -354,25 +354,26 @@ static int DVDCheckCSS( input_thread_t * p_input )
  *****************************************************************************/
 static int DVDFindCell( thread_dvd_data_t * p_dvd )
 {
-    pgc_t *             p_pgc;
     int                 i_cell;
     int                 i_index;
 
-    p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
+#define title \
+        p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title
+#define cell  p_dvd->p_ifo->vts.cell_inf
 
     i_cell = p_dvd->i_cell;
     i_index = p_dvd->i_prg_cell;
 
-    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_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 < p_dvd->ifo.vts.c_adt.i_cell_nb ) )
+    while( ( ( title.p_cell_pos[i_index].i_vob_id !=
+                   cell.p_cell_map[i_cell].i_vob_id ) ||
+      ( title.p_cell_pos[i_index].i_cell_id !=
+                   cell.p_cell_map[i_cell].i_cell_id ) ) &&
+           ( i_cell < cell.i_cell_nb ) )
     {
         i_cell++;
     }
 
-    if( i_cell == p_dvd->ifo.vts.c_adt.i_cell_nb )
+    if( i_cell == cell.i_cell_nb )
     {
         return -1;
     }
@@ -381,6 +382,8 @@ static int DVDFindCell( thread_dvd_data_t * p_dvd )
         p_dvd->i_cell = i_cell;
         return 0;
     }
+#undef title
+#undef cell
 }
 
 /*****************************************************************************
@@ -389,11 +392,10 @@ static int DVDFindCell( thread_dvd_data_t * p_dvd )
  *****************************************************************************/
 static int DVDFindSector( thread_dvd_data_t * p_dvd )
 {
-    pgc_t *              p_pgc;
+#define title \
+        p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title
 
-    p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
-
-    if( p_dvd->i_sector > p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_lsector )
+    if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector )
     {
         p_dvd->i_prg_cell++;
     }
@@ -405,13 +407,14 @@ static int DVDFindSector( thread_dvd_data_t * p_dvd )
 
     /* Find start and end sectors of new cell */
     p_dvd->i_sector = MAX(
-            p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_ssector,
-            p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_entry_sector );
+         p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector,
+         title.p_cell_play[p_dvd->i_prg_cell].i_start_sector );
     p_dvd->i_end_sector = MIN(
-            p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_esector,
-            p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_lsector );
+         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 );
 
-intf_WarnMsg( 3, "cell: %d sector1: 0x%x end1: 0x%x\nindex: %d sector2: 0x%x end2: 0x%x", p_dvd->i_cell, p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_ssector, p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_esector, p_dvd->i_prg_cell, p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_entry_sector, p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_lsector );
+//intf_WarnMsg( 3, "cell: %d sector1: 0x%x end1: 0x%x\nindex: %d sector2: 0x%x end2: 0x%x", p_dvd->i_cell, p_dvd->p_ifo->p_vts->c_adt.p_cell_inf[p_dvd->i_cell].i_ssector, p_dvd->p_ifo->p_vts->c_adt.p_cell_inf[p_dvd->i_cell].i_esector, p_dvd->i_prg_cell, p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_entry_sector, p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_lsector );
+#undef title
 
     return 0;
 }
@@ -422,12 +425,11 @@ intf_WarnMsg( 3, "cell: %d sector1: 0x%x end1: 0x%x\nindex: %d sector2: 0x%x end
  *****************************************************************************/
 static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
 {
-    pgc_t *              p_pgc;
-
-    p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
+#define title \
+        p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title
 
     /* Find cell index in Program chain for current chapter */
-    p_dvd->i_prg_cell = p_pgc->prg_map.pi_entry_cell[i_chapter-1] - 1;
+    p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1;
     p_dvd->i_cell = 0;
 
     /* Search for cell_index in cell adress_table and initialize start sector */
@@ -441,7 +443,7 @@ static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
     p_dvd->i_start = lseek( p_dvd->i_fd, p_dvd->i_start, SEEK_SET );
 
     p_dvd->i_chapter = i_chapter;
-
+#undef title
     return 0;
 }
 
@@ -458,7 +460,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
 {
     thread_dvd_data_t *  p_dvd;
     es_descriptor_t *    p_es;
-    int                  i_nb;
+    int                  i_audio;
+    int                  i_spu;
     u16                  i_id;
     u8                   i_ac3;
     u8                   i_mpeg;
@@ -482,26 +485,28 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
 
         /* title number: it is not vts nb! */
         p_dvd->i_title = p_area->i_id;
+        p_dvd->p_ifo->i_title = p_dvd->i_title;
+
+        /* ifo vts */
+        IfoTitleSet( p_dvd->p_ifo );
+        intf_WarnMsg( 2, "ifo info: vts initialized" );
 
+#define vmg p_dvd->p_ifo->vmg
+#define vts p_dvd->p_ifo->vts
         /* title position inside the selected vts */
         p_dvd->i_vts_title =
-                    p_dvd->ifo.vmg.ptt_srpt.p_tts[p_dvd->i_title-1].i_vts_ttn;
-
-        /* vts number */
-        p_dvd->ifo.i_title = p_dvd->i_title;
+                    vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_num;
+        p_dvd->i_program_chain =
+          vts.title_inf.p_title_start[p_dvd->i_vts_title-1].i_program_chain_num;
 
-        /* ifo vts */
-        IfoReadVTS( &(p_dvd->ifo) );
-        intf_WarnMsg( 2, "ifo info: vts initialized" );
-    
         /* css title key for current vts */
         if( p_dvd->b_encrypted )
         {
             p_dvd->p_css->i_title =
-                    p_dvd->ifo.vmg.ptt_srpt.p_tts[p_dvd->i_title-1].i_tts_nb;
+                    vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_set_num;
             p_dvd->p_css->i_title_pos =
-                    p_dvd->ifo.vts.i_pos +
-                    p_dvd->ifo.vts.mat.i_tt_vobs_ssector * DVD_LB_SIZE;
+                    vts.i_pos +
+                    vts.manager_inf.i_title_vob_start_sector * DVD_LB_SIZE;
             CSSGetKey( p_dvd->p_css );
             intf_WarnMsg( 2, "css info: vts key initialized" );
         }
@@ -511,24 +516,24 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
          */
         
         /* title set offset */
-        p_dvd->i_title_start = p_dvd->ifo.vts.i_pos + DVD_LB_SIZE *
-                      (off_t)( p_dvd->ifo.vts.mat.i_tt_vobs_ssector );
+        p_dvd->i_title_start = vts.i_pos + DVD_LB_SIZE *
+                      (off_t)( vts.manager_inf.i_title_vob_start_sector );
 
         /* last video cell */
         p_dvd->i_cell = 0;
         p_dvd->i_prg_cell = -1 +
-            p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc.i_cell_nb;
+            vts.title_unit.p_title[p_dvd->i_program_chain-1].title.i_cell_nb;
         DVDFindCell( p_dvd );
 
         /* temporary hack to fix size in some dvds */
-        if( p_dvd->i_cell >= p_dvd->ifo.vts.c_adt.i_cell_nb )
+        if( p_dvd->i_cell >= vts.cell_inf.i_cell_nb )
         {
-            p_dvd->i_cell = p_dvd->ifo.vts.c_adt.i_cell_nb - 1;
+            p_dvd->i_cell = vts.cell_inf.i_cell_nb - 1;
         }
 
         p_dvd->i_sector = 0;
         p_dvd->i_size = DVD_LB_SIZE *
-          (off_t)( p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_esector );
+          (off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
 
         DVDChapterSelect( p_dvd, 1 );
 
@@ -538,7 +543,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         intf_WarnMsg( 2, "dvd info: vobstart at: %lld", p_dvd->i_start );
         intf_WarnMsg( 2, "dvd info: stream size: %lld", p_dvd->i_size );
         intf_WarnMsg( 2, "dvd info: number of chapters: %d",
-                   p_dvd->ifo.vmg.ptt_srpt.p_tts[p_dvd->i_title-1].i_ptt_nb );
+                   vmg.title_inf.p_attr[p_dvd->i_title-1].i_chapter_nb );
 
         /* Area definition */
         p_input->stream.p_selected_area->i_start = p_dvd->i_start;
@@ -560,7 +565,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
 
             input_DelProgram( p_input, p_input->stream.pp_programs[0] );
 
-            free( p_input->stream.pp_selected_es );
             p_input->stream.pp_selected_es = NULL;
             p_input->stream.i_selected_es_number = 0;
         }
@@ -576,33 +580,31 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         input_SelectES( p_input, p_es );
         intf_WarnMsg( 1, "dvd info: video MPEG2 stream" );
 
-    
         /* Audio ES, in the order they appear in .ifo */
-        i_nb = p_dvd->ifo.vts.mat.i_audio_nb;
-    
+            
         i_ac3 = 0x7f;
         i_mpeg = 0xc0;
 
-        for( i = 1 ; i <= i_nb ; i++ )
+        for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
         {
 
 #ifdef DEBUG
         intf_DbgMsg( "Audio %d: %x %x %x %x %x %x %x %x %x %x %x %x\n", i,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_num_channels,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_coding_mode,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_multichannel_extension,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_type,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_appl_mode,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_foo,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_bar,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_appl_mode,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_quantization,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_sample_freq,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_lang_code,
-            p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_caption );
+            vts.manager_inf.p_audio_attr[i-1].i_num_channels,
+            vts.manager_inf.p_audio_attr[i-1].i_coding_mode,
+            vts.manager_inf.p_audio_attr[i-1].i_multichannel_extension,
+            vts.manager_inf.p_audio_attr[i-1].i_type,
+            vts.manager_inf.p_audio_attr[i-1].i_appl_mode,
+            vts.manager_inf.p_audio_attr[i-1].i_foo,
+            vts.manager_inf.p_audio_attr[i-1].i_bar,
+            vts.manager_inf.p_audio_attr[i-1].i_appl_mode,
+            vts.manager_inf.p_audio_attr[i-1].i_quantization,
+            vts.manager_inf.p_audio_attr[i-1].i_sample_freq,
+            vts.manager_inf.p_audio_attr[i-1].i_lang_code,
+            vts.manager_inf.p_audio_attr[i-1].i_caption );
 #endif
 
-            switch( p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_coding_mode )
+            switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
             {
             case 0x00:              /* AC3 */
                 i_id = ( ( i_ac3 + i ) << 8 ) | 0xbd;
@@ -612,7 +614,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
                 p_es->i_type = AC3_AUDIO_ES;
                 p_es->b_audio = 1;
                 strcpy( p_es->psz_desc, Language( hton16(
-                    p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_lang_code ) ) ); 
+                    vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); 
 
                 intf_WarnMsg( 1, "dvd info: audio stream %d %s\t(0x%x)",
                               i, p_es->psz_desc, i_id );
@@ -627,7 +629,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
                 p_es->i_type = MPEG2_AUDIO_ES;
                 p_es->b_audio = 1;
                 strcpy( p_es->psz_desc, Language( hton16(
-                    p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_lang_code ) ) ); 
+                    vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); 
 
                 intf_WarnMsg( 1, "dvd info: audio stream %d %s\t(0x%x)",
                               i, p_es->psz_desc, i_id );
@@ -645,17 +647,16 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
             default:
                 i_id = 0;
                 intf_ErrMsg( "dvd warning: unknown audio type %.2x",
-                         p_dvd->ifo.vts.mat.p_audio_atrt[i-1].i_coding_mode );
+                         vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
             }
         
         }
     
         /* Sub Picture ES */
-        i_nb = p_dvd->ifo.vts.mat.i_subpic_nb;
-    
+           
         b_last = 0;
         i_sub_pic = 0x20;
-        for( i = 1 ; i <= i_nb ; i++ )
+        for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
         {
             if( !b_last )
             {
@@ -666,16 +667,40 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
                 p_es->i_type = DVD_SPU_ES;
                 p_es->b_spu = 1;
                 strcpy( p_es->psz_desc, Language( hton16(
-                    p_dvd->ifo.vts.mat.p_subpic_atrt[i-1].i_lang_code ) ) ); 
+                    vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) ); 
                 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 */
                 b_last =
-                    ( p_dvd->ifo.vts.mat.p_subpic_atrt[i].i_prefix == 0 ); 
+                    ( vts.manager_inf.p_spu_attr[i].i_prefix == 0 ); 
             }
         }
 
+        /* For audio: first one if none or a not existing one specified */
+        i_audio = main_GetIntVariable( INPUT_CHANNEL_VAR, 1 );
+        if( i_audio < 0 || i_audio > vts.manager_inf.i_audio_nb )
+        {
+            main_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
+            i_audio = 1;
+        }
+        if( i_audio > 0 )
+        {
+            input_SelectES( p_input, p_input->stream.pp_es[i_audio] );
+        }
+    
+        /* for spu, default is none */
+        i_spu = main_GetIntVariable( INPUT_SUBTITLE_VAR, 0 );
+        if( i_spu < 0 || i_spu > vts.manager_inf.i_spu_nb )
+        {
+            main_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
+            i_spu = 0;
+        }
+        if( i_spu > 0 )
+        {
+            i_spu += vts.manager_inf.i_audio_nb;
+            input_SelectES( p_input, p_input->stream.pp_es[i_spu] );
+        }
     } // i_title >= 0
     else
     {
@@ -699,14 +724,13 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
                                     p_area->i_part, p_area->i_tell );
     }
 
-    /* By default first audio stream and no spu */
-    input_SelectES( p_input, p_input->stream.pp_es[1] );
-
     /* No PSM to read in DVD mode, we already have all information */
     p_input->stream.pp_programs[0]->b_is_ok = 1;
+    p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_START;
 
     vlc_mutex_unlock( &p_input->stream.stream_lock );
-
+#undef vts
+#undef vmg
     return 0;
 }
 
@@ -718,8 +742,6 @@ static void DVDInit( input_thread_t * p_input )
     thread_dvd_data_t *  p_dvd;
     int                  i_title;
     int                  i_chapter;
-    int                  i_audio;
-    int                  i_spu;
     int                  i;
 
     if( (p_dvd = malloc( sizeof(thread_dvd_data_t) )) == NULL )
@@ -747,8 +769,13 @@ static void DVDInit( input_thread_t * p_input )
     intf_WarnMsg( 2, "dvd info: netlist initialized" );
 
     /* Ifo initialisation */
-    p_dvd->ifo = IfoInit( p_input->i_handle );
-    intf_WarnMsg( 2, "ifo info: vmg initialized" );
+    if( IfoInit( &p_dvd->p_ifo, p_input->i_handle ) < 0 )
+    {
+            intf_ErrMsg( "ifo error: fatal failure" );
+            free( p_dvd );
+            p_input->b_error = 1;
+            return;
+    }
 
     /* CSS initialisation */
     if( p_dvd->b_encrypted )
@@ -758,6 +785,7 @@ static void DVDInit( input_thread_t * p_input )
         if( p_dvd->p_css == NULL )
         {
             intf_ErrMsg( "css error: fatal failure" );
+            free( p_dvd );
             p_input->b_error = 1;
             return;
         }
@@ -771,12 +799,12 @@ static void DVDInit( input_thread_t * p_input )
     /* Set stream and area data */
     vlc_mutex_lock( &p_input->stream.stream_lock );
 
-#define srpt p_dvd->ifo.vmg.ptt_srpt
-    intf_WarnMsg( 2, "dvd info: number of titles: %d", srpt.i_ttu_nb );
+#define title_inf p_dvd->p_ifo->vmg.title_inf
+    intf_WarnMsg( 2, "dvd info: number of titles: %d", title_inf.i_title_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 <= srpt.i_ttu_nb ; i++ )
+    for( i = 1 ; i <= title_inf.i_title_nb ; i++ )
     {
         input_AddArea( p_input );
 
@@ -790,12 +818,12 @@ static void DVDInit( input_thread_t * p_input )
         area[i]->i_size = 0;
 
         /* Number of chapters */
-        area[i]->i_part_nb = srpt.p_tts[i-1].i_ptt_nb;
+        area[i]->i_part_nb = title_inf.p_attr[i-1].i_chapter_nb;
         area[i]->i_part = 1;
 
         /* Offset to vts_i_0.ifo */
-        area[i]->i_plugin_data = p_dvd->ifo.i_off +
-                               ( srpt.p_tts[i-1].i_ssector * DVD_LB_SIZE );
+        area[i]->i_plugin_data = p_dvd->p_ifo->i_off +
+                       ( title_inf.p_attr[i-1].i_start_sector * DVD_LB_SIZE );
     }   
 #undef area
 
@@ -803,11 +831,11 @@ static void DVDInit( input_thread_t * p_input )
 
     /* Get requested title - if none try the first title */
     i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 );
-    if( i_title <= 0 || i_title > srpt.i_ttu_nb )
+    if( i_title <= 0 || i_title > title_inf.i_title_nb )
     {
         i_title = 1;
     }
-#undef srpt
+#undef title_inf
     /* Get requested chapter - if none defaults to first one */
     i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 );
     if( i_chapter <= 0 )
@@ -816,28 +844,9 @@ static void DVDInit( input_thread_t * p_input )
     }
 
     p_input->stream.pp_areas[i_title]->i_part = i_chapter;
-    DVDSetArea( p_input, p_input->stream.pp_areas[i_title] );
 
-    /* For audio: first one if none or a not existing one specified */
-    i_audio = main_GetIntVariable( INPUT_CHANNEL_VAR, 1 );
-    if( i_audio <= 0 )
-    {
-        main_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
-        i_audio = 1;
-    }
-
-    input_ChangeES( p_input, p_input->stream.pp_es[i_audio], 1 );
-
-    i_spu = main_GetIntVariable( INPUT_SUBTITLE_VAR, 0 );
-    if( i_spu < 0 )
-    {
-        main_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
-        i_spu = 0;
-    }
-
-    /* We don't select spu here since we don't know the index :
-     * i_spu + i_audio_nb */
-//    input_ChangeES( p_input, p_input->stream.pp_es[i_spu], 1 );
+    /* set title, chapter, audio and subpic */
+    DVDSetArea( p_input, p_input->stream.pp_areas[i_title] );
 
     return;
 }
@@ -853,8 +862,12 @@ static void DVDEnd( input_thread_t * p_input )
     p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data;
     p_netlist = (dvd_netlist_t *)p_input->p_method_data;
 
-    CSSEnd( p_dvd->p_css );
-//    IfoEnd( p_dvd->p_ifo ) );
+    if( p_dvd->b_encrypted )
+    {
+        CSSEnd( p_dvd->p_css );
+    }
+
+    IfoEnd( p_dvd->p_ifo );
     free( p_dvd );
     DVDNetlistEnd( p_netlist );
 }
@@ -870,7 +883,6 @@ static int DVDRead( input_thread_t * p_input,
 {
     thread_dvd_data_t *     p_dvd;
     dvd_netlist_t *         p_netlist;
-    pgc_t *                 p_pgc;
     struct iovec *          p_vec;
     struct data_packet_s *  pp_data[p_input->i_read_once];
     u8 *                    pi_cur;
@@ -886,7 +898,8 @@ static int DVDRead( input_thread_t * p_input,
 
     p_dvd = (thread_dvd_data_t *)p_input->p_plugin_data;
     p_netlist = (dvd_netlist_t *)p_input->p_method_data;
-    p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
+#define title \
+    p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title
 
     /* Get an iovec pointer */
     if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL )
@@ -917,7 +930,7 @@ static int DVDRead( input_thread_t * p_input,
 
         /* update chapter : it will be easier when we have navigation
          * ES support */
-        if( p_pgc->prg_map.pi_entry_cell[p_dvd->i_chapter-1] <=
+        if( title.chapter_map.pi_start_cell[p_dvd->i_chapter-1] <=
             p_dvd->i_prg_cell )
         {
             p_dvd->i_chapter++;
@@ -1042,6 +1055,7 @@ static int DVDRead( input_thread_t * p_input,
     {
         return 1;
     }
+#undef title
 }
 
 
@@ -1063,14 +1077,14 @@ static int DVDRewind( input_thread_t * p_input )
 static void DVDSeek( input_thread_t * p_input, off_t i_off )
 {
     thread_dvd_data_t *     p_dvd;
-    pgc_t *                 p_pgc;
     off_t                   i_pos;
     int                     i_prg_cell;
     int                     i_cell;
     int                     i_chapter;
     
     p_dvd = ( thread_dvd_data_t * )p_input->p_plugin_data;
-    p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[p_dvd->i_vts_title-1].pgc;
+#define title \
+    p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_program_chain-1].title
 
     /* we have to take care of offset of beginning of title */
     i_pos = i_off + p_input->stream.p_selected_area->i_start
@@ -1083,7 +1097,7 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
     i_chapter = 1;
 
     /* parse vobu address map to find program cell */
-    while( p_pgc->p_cell_play_inf[i_prg_cell].i_lsector < p_dvd->i_sector  )
+    while( title.p_cell_play[i_prg_cell].i_end_sector < p_dvd->i_sector  )
     {
         i_prg_cell++;
     }
@@ -1095,9 +1109,9 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
     DVDFindCell( p_dvd );
 
     i_cell = p_dvd->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 */
-    while( p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_esector < p_dvd->i_sector )
+    while( cell.i_end_sector < p_dvd->i_sector )
     {
         i_cell++;
     }
@@ -1105,11 +1119,11 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off )
     p_dvd->i_cell = i_cell;
 
     p_dvd->i_end_sector = MIN(
-            p_dvd->ifo.vts.c_adt.p_cell_inf[p_dvd->i_cell].i_esector,
-            p_pgc->p_cell_play_inf[p_dvd->i_prg_cell].i_lsector );
+            cell.i_end_sector,
+            title.p_cell_play[p_dvd->i_prg_cell].i_end_sector );
 
     /* update chapter */
-    while( p_pgc->prg_map.pi_entry_cell[i_chapter-1] <= p_dvd->i_prg_cell )
+    while( title.chapter_map.pi_start_cell[i_chapter-1] <= p_dvd->i_prg_cell )
     {
         i_chapter++;
     }
index 4b58c8069c58a108d5cb324537bf155319e1ad3e..aef55375adddefe2a477ef9d0c27104ed79d9b65 100644 (file)
@@ -2,7 +2,7 @@
  * input_dvd.h: thread structure of the DVD plugin
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dvd.h,v 1.13 2001/03/21 13:42:33 sam Exp $
+ * $Id: input_dvd.h,v 1.14 2001/04/01 07:31:38 stef Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -41,6 +41,7 @@ typedef struct thread_dvd_data_s
     /* Navigation information */
     int                     i_title;
     int                     i_vts_title;
+    int                     i_program_chain;
 
     int                     i_chapter_nb;
     int                     i_chapter;
@@ -59,17 +60,16 @@ typedef struct thread_dvd_data_s
     struct css_s *          p_css;
 
     /* Structure that contains all information of the DVD */
-    struct ifo_s            ifo;
+    struct ifo_s *          p_ifo;
 
 } thread_dvd_data_t;
 
 /*****************************************************************************
  * Prototypes in dvd_ifo.c
  *****************************************************************************/
-struct ifo_s    IfoInit     ( int );
-int             IfoReadVTS  ( struct ifo_s * );
-void            IfoRead     ( struct ifo_s * );
-void            IfoEnd      ( ifo_t * );
+int   IfoInit     ( struct ifo_s **, int );
+int   IfoTitleSet ( struct ifo_s * );
+void  IfoEnd      ( struct ifo_s * );
 
 /*****************************************************************************
  * Prototypes in dvd_css.c
index e727f93fa5b705bd96f2a8c5e60ae9c6335f8a69..d7364db851d48fc33357fb2bbea134ac230bb5d4 100644 (file)
@@ -2,9 +2,10 @@
  * gnome_callbacks.c : Callbacks for the Gnome plugin.
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: gnome_callbacks.c,v 1.18 2001/03/21 13:42:34 sam Exp $
+ * $Id: gnome_callbacks.c,v 1.19 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Stéphane Borel <stef@via.ecp.fr>
  *      
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -244,7 +245,10 @@ on_menubar_audio_toggle                (GtkCheckMenuItem     *menuitem,
 
     p_es = (es_descriptor_t*)user_data;
 
-    input_ChangeES( p_intf->p_input, p_es, 1 );
+    if( p_intf->p_sys->b_menus_ready )
+    {
+        input_ToggleES( p_intf->p_input, p_es, menuitem->active );
+    }
 }
 
 
@@ -257,7 +261,10 @@ on_menubar_subtitle_toggle             (GtkCheckMenuItem     *menuitem,
 
     p_es = (es_descriptor_t*)user_data;
 
-    input_ChangeES( p_intf->p_input, p_es, 2 );
+    if( p_intf->p_sys->b_menus_ready )
+    {
+        input_ToggleES( p_intf->p_input, p_es, menuitem->active );
+    }
 }
 
 
@@ -267,9 +274,13 @@ on_menubar_title_toggle                (GtkCheckMenuItem     *menuitem,
 {
     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
 
-    p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)user_data );
-    p_intf->p_sys->b_menus_update = 1;
-    input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
+    if( menuitem->active && p_intf->p_sys->b_menus_ready )
+    {
+        p_intf->p_input->pf_set_area( p_intf->p_input,
+                                     (input_area_t*)user_data );
+        p_intf->p_sys->b_menus_update = 1;
+        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
+    }
 }
 
 
@@ -281,9 +292,12 @@ on_menubar_chapter_toggle              (GtkCheckMenuItem     *menuitem,
     input_area_t *  p_area    = p_intf->p_input->stream.p_selected_area;
     gint            i_chapter = (gint)user_data;
 
-    p_area->i_part = i_chapter;
+    if( menuitem->active && p_intf->p_sys->b_menus_ready )
+    {
+        p_area->i_part = i_chapter;
+        p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
+    }
 
-    p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
     input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
 }
 
@@ -558,7 +572,10 @@ on_popup_audio_toggle                  (GtkCheckMenuItem     *menuitem,
 
     p_es = (es_descriptor_t*)user_data;
 
-    input_ChangeES( p_intf->p_input, p_es, 1 );
+    if( p_intf->p_sys->b_menus_ready )
+    {
+        input_ToggleES( p_intf->p_input, p_es, menuitem->active );
+    }
 }
 
 
@@ -571,7 +588,10 @@ on_popup_subtitle_toggle            (GtkCheckMenuItem     *menuitem,
 
     p_es = (es_descriptor_t*)user_data;
 
-    input_ChangeES( p_intf->p_input, p_es, 2 );
+    if( p_intf->p_sys->b_menus_ready )
+    {
+        input_ToggleES( p_intf->p_input, p_es, menuitem->active );
+    }
 }
 
 
@@ -579,14 +599,15 @@ void
 on_popup_navigation_toggle             (GtkCheckMenuItem     *menuitem,
                                         gpointer             user_data)
 {
-    if( menuitem->active )
+    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
+
+    if( menuitem->active && p_intf->p_sys->b_menus_ready )
     {
-        intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
         input_area_t *  p_area;
         gint            i_title;
         gint            i_chapter;
 
-        i_title   = (gint)(user_data) / 100 ;
+        i_title   = (gint)(user_data) / 100;
         i_chapter = (gint)(user_data) - ( 100 * i_title );
 
         if( i_title != p_intf->p_input->stream.p_selected_area->i_id )
@@ -598,7 +619,7 @@ on_popup_navigation_toggle             (GtkCheckMenuItem     *menuitem,
         p_area->i_part = i_chapter;
 
         p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
-                input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
+        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
     }
 }
 
index fcb6f5b623f8fbbb269b9e15792cfcaf22756260..2a5143c2b9658f758fd7b69a17f82308fc5c161b 100644 (file)
@@ -2,9 +2,10 @@
  * intf_gnome.c: Gnome interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.c,v 1.23 2001/03/15 16:29:47 stef Exp $
+ * $Id: intf_gnome.c,v 1.24 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Stéphane Borel <stef@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -144,6 +145,7 @@ static int intf_Open( intf_thread_t *p_intf )
     p_intf->p_sys->b_window_changed = 0;
     p_intf->p_sys->b_playlist_changed = 0;
     p_intf->p_sys->b_menus_update = 1;
+    p_intf->p_sys->b_menus_ready = 0;
 
     p_intf->p_sys->b_slider_free = 1;
 
@@ -298,7 +300,9 @@ static gint GnomeManage( gpointer p_data )
     if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL &&
         p_intf->p_sys->b_menus_update )
     {
+        p_intf->p_sys->b_menus_ready = 0;
         GnomeSetupMenu( p_intf );
+        p_intf->p_sys->b_menus_ready = 1;
     }
 
     /* Manage the slider */
@@ -372,12 +376,12 @@ static gint GnomeLanguageMenus( gpointer          p_data,
     GtkWidget *         p_menu;
     GtkWidget *         p_separator;
     GtkWidget *         p_item;
-    GtkWidget *         p_item_off;
+    GtkWidget *         p_item_active;
     GSList *            p_group;
     char *              psz_name;
-    gint                b_active;
     gint                b_audio;
     gint                b_spu;
+    gint                i_item;
     gint                i;
 
     
@@ -385,32 +389,37 @@ static gint GnomeLanguageMenus( gpointer          p_data,
     /* cast */
     p_intf = (intf_thread_t *)p_data;
 
-    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
-
     /* removes previous menu */
     gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
+    gtk_widget_set_sensitive( p_root, FALSE );
 
-    b_audio = ( i_type == 1 );
     p_group = NULL;
 
     /* menu container */
     p_menu = gtk_menu_new();
 
     /* special case for "off" item */
-    b_active = ( p_es == NULL ) ? TRUE : FALSE;
     psz_name = "Off";
 
-    p_item_off = gtk_radio_menu_item_new_with_label( p_group, psz_name );
-    p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item_off ) );
-    gtk_widget_show( p_item_off );
-    gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_off ),
-                                    b_active );
-    gtk_menu_append( GTK_MENU( p_menu ), p_item_off );
+    p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
+    p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
+
+    gtk_widget_show( p_item );
+
+    /* signal hanling for off */
+    gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
+                        GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
+
+    gtk_menu_append( GTK_MENU( p_menu ), p_item );
 
     p_separator = gtk_menu_item_new();
+    gtk_widget_set_sensitive( p_separator, FALSE );
     gtk_widget_show( p_separator );
     gtk_menu_append( GTK_MENU( p_menu ), p_separator );
-    gtk_widget_set_sensitive( p_separator, FALSE );
+
+    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+    p_item_active = NULL;
+    i_item = 0;
 
     /* create a set of language buttons and append them to the container */
     for( i = 0 ; i < p_intf->p_input->stream.i_es_number ; i++ )
@@ -421,16 +430,24 @@ static gint GnomeLanguageMenus( gpointer          p_data,
 
         if( b_audio || b_spu )
         {
-            b_active = ( p_es == p_intf->p_input->stream.pp_es[i] ) ? TRUE :
-                                                                      FALSE;
+            i_item++;
             psz_name = p_intf->p_input->stream.pp_es[i]->psz_desc;
+            if( psz_name[0] == '\0' )
+            {
+                sprintf( psz_name, "Language %d", i_item );
+            }
 
             p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
             p_group =
                 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
-            gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item ),
-                                            b_active );
-            gtk_menu_append( GTK_MENU( p_menu ), p_item );
+
+            if( p_es == p_intf->p_input->stream.pp_es[i] )
+            {
+                /* don't lose p_item when we append into menu */
+                p_item_active = p_item;
+                gtk_object_ref( GTK_OBJECT( p_item_active ) );
+            }
+
             gtk_widget_show( p_item );
 
             /* setup signal hanling */
@@ -438,21 +455,29 @@ static gint GnomeLanguageMenus( gpointer          p_data,
                             GTK_SIGNAL_FUNC( pf_toggle ),
                             (gpointer)( p_intf->p_input->stream.pp_es[i] ) );
 
+            gtk_menu_append( GTK_MENU( p_menu ), p_item );
         }
     }
 
-    /* signal hanling for off - dunno why this does not work
-     * if it is before the loop */
-    gtk_signal_connect( GTK_OBJECT( p_item_off ), "toggled",
-                        GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
+    vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
 
     /* link the new menu to the menubar item */
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
 
-    /* be sure that menu is sensitive */
-    gtk_widget_set_sensitive( p_root, TRUE );
+    /* acitvation will call signals so we can only do it
+     * when submenu is attached to menu - to get intf_window */
+    if( p_item_active != NULL )
+    {
+        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
+                                        TRUE );
+        gtk_object_unref( GTK_OBJECT( p_item_active ) );
+    }
 
-    vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
+    /* be sure that menu is sensitive if non empty */
+    if( i_item > 0 )
+    {
+        gtk_widget_set_sensitive( p_root, TRUE );
+    }
 
     return TRUE;
 }
@@ -466,54 +491,96 @@ static gint GnomeChapterMenu( gpointer p_data, GtkWidget * p_chapter,
     intf_thread_t *     p_intf;
     char                psz_name[10];
     GtkWidget *         p_chapter_menu;
+    GtkWidget *         p_chapter_submenu;
+    GtkWidget *         p_menu_item;
     GtkWidget *         p_item;
+    GtkWidget *         p_item_selected;
     GSList *            p_chapter_group;
     gint                i_title;
     gint                i_chapter;
-    gint                b_active;
+    gint                i_nb;
 
     /* cast */
     p_intf = (intf_thread_t*)p_data;
 
     /* removes previous menu */
     gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_chapter ) );
+    gtk_widget_set_sensitive( p_chapter, FALSE );
 
+    p_chapter_submenu = NULL;
     p_chapter_group = NULL;
+    p_item_selected = NULL;
+    p_menu_item = NULL;
 
     i_title = p_intf->p_input->stream.p_selected_area->i_id;
     p_chapter_menu = gtk_menu_new();
+    i_nb = p_intf->p_input->stream.pp_areas[i_title]->i_part_nb;
 
-    for( i_chapter = 0;
-         i_chapter < p_intf->p_input->stream.pp_areas[i_title]->i_part_nb ;
-         i_chapter++ )
+    for( i_chapter = 0 ; i_chapter < i_nb ; i_chapter++ )
     {
-        b_active = ( p_intf->p_input->stream.pp_areas[i_title]->i_part
-                     == i_chapter + 1 ) ? 1 : 0;
-        
+        /* we group chapters in packets of ten for small screens */
+        if( ( i_chapter % 10 == 0 ) )// && ( i_nb > 20 ) )
+        {
+            if( i_chapter != 0 )
+            {
+                gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_menu_item ),
+                                           p_chapter_submenu );
+                gtk_menu_append( GTK_MENU( p_chapter_menu ), p_menu_item );
+            }
+
+            sprintf( psz_name, "%d - %d", i_chapter + 1, i_chapter + 10);
+            p_menu_item = gtk_menu_item_new_with_label( psz_name );
+            gtk_widget_show( p_menu_item );
+            p_chapter_submenu = gtk_menu_new();
+        }
+
         sprintf( psz_name, "Chapter %d", i_chapter + 1 );
 
         p_item = gtk_radio_menu_item_new_with_label( p_chapter_group,
                                                      psz_name );
         p_chapter_group =
             gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
-        gtk_menu_append( GTK_MENU( p_chapter_menu ), p_item );
+
+        if( p_intf->p_input->stream.pp_areas[i_title]->i_part
+                     == i_chapter + 1 )
+        {
+            p_item_selected = p_item;
+            gtk_object_ref( GTK_OBJECT( p_item_selected ) );
+        }
+        
         gtk_widget_show( p_item );
-        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item ),
-                                        b_active );
 
         /* setup signal hanling */
         gtk_signal_connect( GTK_OBJECT( p_item ),
                         "toggled",
                         GTK_SIGNAL_FUNC( pf_toggle ),
                         (gpointer)(i_chapter + 1) );
+
+        gtk_menu_append( GTK_MENU( p_chapter_submenu ), p_item );
     }
 
+    gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_menu_item ),
+                               p_chapter_submenu );
+    gtk_menu_append( GTK_MENU( p_chapter_menu ), p_menu_item );
+
+
     /* link the new menu to the title menu item */
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_chapter ),
                                p_chapter_menu );
 
-    /* be sure that chapter menu is sensitive */
-    gtk_widget_set_sensitive( p_chapter, TRUE );
+    /* toggle currently selected chapter */
+    if( p_item_selected != NULL )
+    {
+        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_selected ),
+                                        TRUE );
+        gtk_object_unref( GTK_OBJECT( p_item_selected ) );
+    }
+
+    /* be sure that chapter menu is sensitive, if there are several items */
+    if( p_intf->p_input->stream.pp_areas[i_title]->i_part_nb > 1 )
+    {
+        gtk_widget_set_sensitive( p_chapter, TRUE );
+    }
 
     return TRUE;
 }
@@ -532,53 +599,84 @@ static gint GnomeTitleMenu( gpointer       p_data,
     intf_thread_t *     p_intf;
     char                psz_name[10];
     GtkWidget *         p_title_menu;
+    GtkWidget *         p_title_submenu;
     GtkWidget *         p_title_item;
+    GtkWidget *         p_item_active;
     GtkWidget *         p_chapter_menu;
+    GtkWidget *         p_chapter_submenu;
+    GtkWidget *         p_title_menu_item;
+    GtkWidget *         p_chapter_menu_item;
     GtkWidget *         p_item;
     GSList *            p_title_group;
     GSList *            p_chapter_group;
     gint                i_title;
     gint                i_chapter;
-    gint                b_active;
+    gint                i_nb;
 
     /* cast */
     p_intf = (intf_thread_t*)p_data;
 
     p_title_menu = gtk_menu_new();
     p_title_group = NULL;
+    p_title_submenu = NULL;
+    p_title_menu_item = NULL;
     p_chapter_group = NULL;
+    p_chapter_submenu = NULL;
+    p_chapter_menu_item = NULL;
+    p_item_active = NULL;
+    i_nb = p_intf->p_input->stream.i_area_nb;
 
     /* loop on titles */
-    for( i_title = 1 ;
-         i_title < p_intf->p_input->stream.i_area_nb ;
-         i_title++ )
+    for( i_title = 1 ; i_title < i_nb ; i_title++ )
     {
-        b_active = ( p_intf->p_input->stream.pp_areas[i_title] ==
-                     p_intf->p_input->stream.p_selected_area ) ? 1 : 0;
-        sprintf( psz_name, "Title %d", i_title );
-
-        p_title_item = gtk_radio_menu_item_new_with_label( p_title_group,
-                                                           psz_name );
-        p_title_group =
-            gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_title_item ) );
-        gtk_menu_append( GTK_MENU( p_title_menu ), p_title_item );
-        gtk_widget_show( p_title_item );
+        /* we group titles in packets of ten for small screens */
+        if( ( i_title % 10 == 1 ))// && ( i_nb > 20 ) )
+        {
+            if( i_title != 1 )
+            {
+                gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
+                                           p_title_submenu );
+                gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
+            }
+
+            sprintf( psz_name, "%d - %d", i_title, i_title + 9 );
+            p_title_menu_item = gtk_menu_item_new_with_label( psz_name );
+            gtk_widget_show( p_title_menu_item );
+            p_title_submenu = gtk_menu_new();
+        }
 
-                                           
+        sprintf( psz_name, "Title %d", i_title );
 
         if( pf_toggle == on_menubar_title_toggle )
         {
+            p_title_item = gtk_radio_menu_item_new_with_label( p_title_group,
+                                                           psz_name );
+            p_title_group =
+              gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_title_item ) );
+
+            if( p_intf->p_input->stream.pp_areas[i_title] ==
+                         p_intf->p_input->stream.p_selected_area )
+            {
+                p_item_active = p_title_item;
+                gtk_object_ref( GTK_OBJECT( p_item_active ) );
+            }
 
-//            gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_title_item ),
-//                                        b_active );
             /* setup signal hanling */
             gtk_signal_connect( GTK_OBJECT( p_title_item ),
                      "toggled",
                      GTK_SIGNAL_FUNC( pf_toggle ),
                      (gpointer)(p_intf->p_input->stream.pp_areas[i_title]) );
+
+            if( p_intf->p_input->stream.i_area_nb > 1 )
+            {
+                /* be sure that menu is sensitive */
+                gtk_widget_set_sensitive( p_navigation, TRUE );
+            }
         }
         else
         {
+    
+            p_title_item = gtk_menu_item_new_with_label( psz_name );
             p_chapter_menu = gtk_menu_new();
     
             for( i_chapter = 0;
@@ -586,42 +684,85 @@ static gint GnomeTitleMenu( gpointer       p_data,
                         p_intf->p_input->stream.pp_areas[i_title]->i_part_nb ;
                  i_chapter++ )
             {
-                b_active = ( p_intf->p_input->stream.pp_areas[i_title]->i_part
-                             == i_chapter + 1 ) ? 1 : 0;
-                
+                /* we group chapters in packets of ten for small screens */
+                if( ( i_chapter % 10 == 0 ) )// && ( i_nb > 20 ) )
+                {
+                    if( i_chapter != 0 )
+                    {
+                        gtk_menu_item_set_submenu(
+                                    GTK_MENU_ITEM( p_chapter_menu_item ),
+                                    p_chapter_submenu );
+                        gtk_menu_append( GTK_MENU( p_chapter_menu ),
+                                         p_chapter_menu_item );
+                    }
+
+                    sprintf( psz_name, "%d - %d", i_chapter + 1,
+                                                  i_chapter + 10);
+                    p_chapter_menu_item =
+                            gtk_menu_item_new_with_label( psz_name );
+                    gtk_widget_show( p_chapter_menu_item );
+                    p_chapter_submenu = gtk_menu_new();
+                }
+
                 sprintf( psz_name, "Chapter %d", i_chapter + 1 );
     
                 p_item = gtk_radio_menu_item_new_with_label(
                                                 p_chapter_group, psz_name );
                 p_chapter_group = gtk_radio_menu_item_group(
                                                 GTK_RADIO_MENU_ITEM( p_item ) );
-                gtk_menu_append( GTK_MENU( p_chapter_menu ), p_item );
                 gtk_widget_show( p_item );
-//                gtk_check_menu_item_set_active(
-//                                    GTK_CHECK_MENU_ITEM( p_item ), b_active );
+
+                if( p_intf->p_input->stream.pp_areas[i_title]->i_part
+                             == i_chapter + 1 )
+                {
+                    p_item_active = p_item;
+                    gtk_object_ref( GTK_OBJECT( p_item_active ) );
+                }
 
                 /* setup signal hanling */
                 gtk_signal_connect( GTK_OBJECT( p_item ),
                            "toggled",
                            GTK_SIGNAL_FUNC( pf_toggle ),
                            (gpointer)( ( i_title * 100 ) + ( i_chapter + 1) ) );
-        }
 
-        /* link the new menu to the title menu item */
-        gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_item ),
-                                   p_chapter_menu );
-        }
+                gtk_menu_append( GTK_MENU( p_chapter_submenu ), p_item );
+            }
+
+            gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_chapter_menu_item ),
+                                       p_chapter_submenu );
+            gtk_menu_append( GTK_MENU( p_chapter_menu ), p_chapter_menu_item );
 
-        /* be sure that chapter menu is sensitive */
-        gtk_widget_set_sensitive( p_title_menu, TRUE );
+            /* link the new menu to the title menu item */
+            gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_item ),
+                                       p_chapter_menu );
 
+            if( p_intf->p_input->stream.pp_areas[i_title]->i_part_nb > 1 )
+            {
+                /* be sure that menu is sensitive */
+                gtk_widget_set_sensitive( p_navigation, TRUE );
+            }
+        }
+        gtk_widget_show( p_title_item );
+
+        gtk_menu_append( GTK_MENU( p_title_submenu ), p_title_item );
     }
 
+    gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
+                               p_title_submenu );
+    gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
+
+    /* be sure that menu is sensitive */
+    gtk_widget_set_sensitive( p_title_menu, TRUE );
+
     /* link the new menu to the menubar item */
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_navigation ), p_title_menu );
 
-    /* be sure that menu is sensitive */
-    gtk_widget_set_sensitive( p_navigation, TRUE );
+    if( p_item_active != NULL )
+    {
+        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
+                                        TRUE );
+        gtk_object_unref( GTK_OBJECT( p_item_active ) );
+    }
 
 
     return TRUE;
@@ -639,20 +780,22 @@ static gint GnomeSetupMenu( intf_thread_t * p_intf )
     GtkWidget *         p_popup_menu;
     gint                i;
 
-    p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
-                 p_intf->p_sys->p_window ), "menubar_title" ) );
-
-    GnomeTitleMenu( p_intf, p_menubar_menu, on_menubar_title_toggle );
-
-    p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
-                 p_intf->p_sys->p_window ), "menubar_chapter" ) );
-
-    GnomeChapterMenu( p_intf, p_menubar_menu, on_menubar_chapter_toggle );
+    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
 
-    p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
-                 p_intf->p_sys->p_popup ), "popup_navigation" ) );
+    if( p_intf->p_input->stream.i_area_nb > 1 )
+    {
+        p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
+                            p_intf->p_sys->p_window ), "menubar_title" ) );
+        GnomeTitleMenu( p_intf, p_menubar_menu, on_menubar_title_toggle );
 
-    GnomeTitleMenu( p_intf, p_popup_menu, on_popup_navigation_toggle );
+        p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
+                             p_intf->p_sys->p_popup ), "popup_navigation" ) );
+        GnomeTitleMenu( p_intf, p_popup_menu, on_popup_navigation_toggle );
+    
+        p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
+                             p_intf->p_sys->p_window ), "menubar_chapter" ) );
+        GnomeChapterMenu( p_intf, p_menubar_menu, on_menubar_chapter_toggle );
+    }
 
     /* look for selected ES */
     p_audio_es = NULL;
@@ -660,17 +803,19 @@ static gint GnomeSetupMenu( intf_thread_t * p_intf )
 
     for( i = 0 ; i < p_intf->p_input->stream.i_selected_es_number ; i++ )
     {
-        if( p_intf->p_input->stream.pp_es[i]->b_audio )
+        if( p_intf->p_input->stream.pp_selected_es[i]->b_audio )
         {
-            p_audio_es = p_intf->p_input->stream.pp_es[i];
+            p_audio_es = p_intf->p_input->stream.pp_selected_es[i];
         }
 
-        if( p_intf->p_input->stream.pp_es[i]->b_spu )
+        if( p_intf->p_input->stream.pp_selected_es[i]->b_spu )
         {
-            p_spu_es = p_intf->p_input->stream.pp_es[i];
+            p_spu_es = p_intf->p_input->stream.pp_selected_es[i];
         }
     }
 
+    vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
+
     /* audio menus */
 
     /* find audio root menu */
@@ -681,9 +826,9 @@ static gint GnomeSetupMenu( intf_thread_t * p_intf )
                  p_intf->p_sys->p_popup ), "popup_audio" ) );
 
     GnomeLanguageMenus( p_intf, p_menubar_menu, p_audio_es, 1,
-                      on_menubar_audio_toggle );
+                        on_menubar_audio_toggle );
     GnomeLanguageMenus( p_intf, p_popup_menu, p_audio_es, 1,
-                      on_popup_audio_toggle );
+                        on_popup_audio_toggle );
 
     /* sub picture menus */
 
@@ -695,9 +840,9 @@ static gint GnomeSetupMenu( intf_thread_t * p_intf )
                  p_intf->p_sys->p_popup ), "popup_subtitle" ) );
 
     GnomeLanguageMenus( p_intf, p_menubar_menu, p_spu_es, 2,
-                      on_menubar_subtitle_toggle  );
+                        on_menubar_subtitle_toggle  );
     GnomeLanguageMenus( p_intf, p_popup_menu, p_spu_es, 2,
-                      on_popup_subtitle_toggle );
+                        on_popup_subtitle_toggle );
 
     /* everything is ready */
     p_intf->p_sys->b_menus_update = 0;
index fadb04197f93589bd6206de27eee3ee4df2c9e3a..c79cab6f6bd5d3880f4d35f0364316b021754d2c 100644 (file)
@@ -2,7 +2,7 @@
  * intf_gnome.h: private Gnome interface description
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.h,v 1.3 2001/03/15 01:42:19 sam Exp $
+ * $Id: intf_gnome.h,v 1.4 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -37,7 +37,8 @@ typedef struct intf_sys_s
     boolean_t           b_window_changed;        /* window display toggled ? */
     boolean_t           b_playlist_changed;    /* playlist display toggled ? */
     boolean_t           b_slider_free;                      /* slider status */
-    boolean_t           b_menus_update;
+    boolean_t           b_menus_update;        /* do we need to update menus */
+    boolean_t           b_menus_ready;     /* has the update been commpleted */
 
     /* Windows and widgets */
     GtkWidget *         p_window;                             /* main window */
index 19ae83ddc71bb1af2fc749f78a399c5f9f103116..7e568578ac8ec041c82b93b6b8fb639506518e11 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-intf.c: services to the interface
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ext-intf.c,v 1.17 2001/03/21 13:42:34 sam Exp $
+ * $Id: input_ext-intf.c,v 1.18 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -296,3 +296,33 @@ int input_ChangeES( input_thread_t * p_input, es_descriptor_t * p_es,
 
     return 0;
 }
+
+/*****************************************************************************
+ * input_ToggleES: answers to a user request with calls to (Un)SelectES
+ *****************************************************************************
+ * Useful since the interface plugins know p_es.
+ * It only works for audio & spu ( to be sure nothing nasty is being done ).
+ * b_select is a boolean to know if we have to select or unselect ES
+ *****************************************************************************/
+int input_ToggleES( input_thread_t * p_input, es_descriptor_t * p_es,
+                    boolean_t b_select )
+{
+
+    vlc_mutex_lock( &p_input->stream.stream_lock );
+
+    if( p_es != NULL && ( p_es->b_audio || p_es->b_spu ) )
+    {
+        if( b_select )
+        {
+            input_SelectES( p_input, p_es );
+        }
+        else
+        {
+            input_UnselectES( p_input, p_es );
+        }
+    }
+
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+    return 0;
+}
index 2f405584271aa486f013439a70094d50d24762d4..7e3bb8d398064594ba6f8ba148ffe0cabea9508b 100644 (file)
@@ -2,7 +2,7 @@
  * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_programs.c,v 1.41 2001/03/15 01:42:20 sam Exp $
+ * $Id: input_programs.c,v 1.42 2001/04/01 07:31:38 stef Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -269,7 +269,7 @@ input_area_t * input_AddArea( input_thread_t * p_input )
     p_input->stream.pp_areas[i_area_index]->i_size = 0;
     p_input->stream.pp_areas[i_area_index]->i_tell = 0;
     p_input->stream.pp_areas[i_area_index]->i_seek = NO_SEEK;
-    p_input->stream.pp_areas[i_area_index]->i_part_nb = 0;
+    p_input->stream.pp_areas[i_area_index]->i_part_nb = 1;
     p_input->stream.pp_areas[i_area_index]->i_part= 0;
 
     return p_input->stream.pp_areas[i_area_index];
@@ -368,6 +368,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
 
     /* Init its values */
     p_es->i_id = i_es_id;
+    p_es->psz_desc[0] = '\0';
     p_es->p_pes = NULL;
     p_es->p_decoder_fifo = NULL;
     p_es->b_audio = 0;
@@ -591,6 +592,12 @@ int input_SelectES( input_thread_t * p_input, es_descriptor_t * p_es )
     decoder_capabilities_t  decoder;
     void *                  p_config;
 
+    if( p_es == NULL )
+    {
+        intf_ErrMsg( "Nothing to do in input_SelectES" );
+        return -1;
+    }
+
 #ifdef DEBUG_INPUT
     intf_DbgMsg( "Selecting ES 0x%x", p_es->i_id );
 #endif
@@ -683,6 +690,12 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
 
     int     i_index = 0;
 
+    if( p_es == NULL )
+    {
+        intf_ErrMsg( "Nothing to do in input_UnselectES" );
+        return -1;
+    }
+
 #ifdef DEBUG_INPUT
     intf_DbgMsg( "Unselecting ES 0x%x", p_es->i_id );
 #endif
@@ -693,12 +706,10 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
         return( -1 );
     }
 
-    /* Release lock, not to block the input thread. */
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
     input_EndDecoder( p_input, p_es );
-    vlc_mutex_lock( &p_input->stream.stream_lock );
 
-    if( p_es->p_decoder_fifo == NULL )
+    if( ( p_es->p_decoder_fifo == NULL ) &&
+        ( p_input->stream.i_selected_es_number > 0 ) )
     {
         p_input->stream.i_selected_es_number--;
 
@@ -715,11 +726,14 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
                                            p_input->stream.pp_selected_es,
                                            p_input->stream.i_selected_es_number
                                             * sizeof(es_descriptor_t *) );
+
         if( p_input->stream.pp_selected_es == NULL )
         {
-            intf_ErrMsg( "Unable to realloc memory in input_UnSelectES" );
-            return(-1);
+            intf_ErrMsg( "No more selected ES in input_UnselectES" );
+            vlc_mutex_unlock( &p_input->stream.stream_lock );
+            return( 1 );
         }
     }
+
     return( 0 );
 }