]> git.sesse.net Git - vlc/blobdiff - modules/access/vcdx/access.c
More printf lint for cygwin (and possibly others)
[vlc] / modules / access / vcdx / access.c
index ae44dd07865eecd131664acd1018c5e8594fd091..27c41c5510734d38f2172760bd52f24ed97f24df 100644 (file)
@@ -3,8 +3,8 @@
  *         using libcdio, libvcd and libvcdinfo. vlc-specific things tend
  *         to go here.
  *****************************************************************************
- * Copyright (C) 2000, 2003 VideoLAN
- * $Id: access.c,v 1.13 2003/12/22 14:32:55 sam Exp $
+ * Copyright (C) 2000, 2003, 2004 VideoLAN
+ * $Id$
  *
  * Authors: Rocky Bernstein <rocky@panix.com>
  *          Johan Bilien <jobi@via.ecp.fr>
@@ -76,7 +76,8 @@ static char *VCDParse       ( input_thread_t *,
                               /*out*/ bool *play_single_item );
 
 static void VCDUpdateVar( input_thread_t *p_input, int i_entry, int i_action,
-                          const char *varname, const char *label );
+                          const char *p_varname, char *p_label,
+                         const char *p_debug_label );
 
 static vcdinfo_obj_t *vcd_Open   ( vlc_object_t *p_this, const char *psz_dev );
 
@@ -158,7 +159,8 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
 
     i_read = 0;
 
-    dbg_print( (INPUT_DBG_CALL), "lsn: %u", p_vcd->cur_lsn );
+    dbg_print( (INPUT_DBG_CALL), "lsn: %lu", 
+              (long unsigned int) p_vcd->cur_lsn );
 
     /* Compute the number of blocks we have to read */
 
@@ -172,7 +174,8 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
 
         /* We've run off of the end of this entry. Do we continue or stop? */
         dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),
-                   "end reached, cur: %u", p_vcd->cur_lsn );
+                   "end reached, cur: %lu", 
+                  (long unsigned int) p_vcd->cur_lsn );
 
         read_status = vcdplayer_pbc_is_on( p_vcd )
           ? vcdplayer_pbc_nav( p_input )
@@ -227,7 +230,8 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
                           p_vcd->cur_lsn,
                           p_buffer + (i_index*M2F2_SECTOR_SIZE) ) < 0 )
         {
-          LOG_ERR ("could not read sector %d", p_vcd->cur_lsn );
+          LOG_ERR ("could not read sector %lu", 
+                  (long unsigned int) p_vcd->cur_lsn );
           return -1;
         }
 
@@ -248,14 +252,14 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
               p_vcd->cur_lsn >= p_vcd->p_entries[i_entry+1] )
             {
               dbg_print( INPUT_DBG_PBC,
-                         "new entry, i_entry %d, sector %d, es %d",
-                         i_entry, p_vcd->cur_lsn,
+                         "new entry, i_entry %d, sector %lu, es %u",
+                         i_entry, (long unsigned int) p_vcd->cur_lsn,
                          p_vcd->p_entries[i_entry] );
               p_vcd->play_item.num =
                 ++ p_input->stream.p_selected_area->i_part;
               p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;
               VCDUpdateVar( p_input, p_vcd->play_item.num, VLC_VAR_SETVALUE,
-                            "chapter", "Setting entry" );
+                            "chapter", _("Entry"), "Setting entry" );
             }
           vlc_mutex_unlock( &p_input->stream.stream_lock );
         }
@@ -268,7 +272,8 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
         if ( VCDReadSector( VLC_OBJECT(p_input), p_vcd->vcd,
                             p_vcd->cur_lsn, p_last_sector ) < 0 )
         {
-            LOG_ERR ("could not read sector %d", p_vcd->cur_lsn );
+            LOG_ERR ("could not read sector %lu", 
+                    (long unsigned int) p_vcd->cur_lsn );
             return -1;
         }
 
@@ -330,15 +335,36 @@ VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
         p_input->stream.p_selected_area = p_area;
 
         /* Update the navigation variables without triggering a callback */
+
         VCDUpdateVar( p_input, i_track, VLC_VAR_SETVALUE, "title",
-                      "Setting track");
+                      _("Track"), "Setting track");
 
         var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );
         for( i = p_area->i_plugin_data; i < i_nb; i++ )
         {
           VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
-                        "chapter",  "Adding entry choice");
+                        "chapter",  
+                       p_vcd->play_item.type == VCDINFO_ITEM_TYPE_SEGMENT ?
+                       _("Segment"): _("Entry"),
+                       "Adding entry choice");
         }
+
+       if (p_vcd->b_svd) {
+         unsigned int audio_type = 
+           vcdinfo_get_track_audio_type(p_vcd->vcd, i_track);
+         unsigned int i_channels = 
+           vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type);
+         
+         var_Change( p_input, "audio_channels", VLC_VAR_CLEARCHOICES, NULL, 
+                     NULL );
+         
+         for( i = 0;  i < i_channels; i++ )
+           {
+             VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
+                           "audio_channels",  NULL, "Adding audio choice");
+           }
+       }
+
     }
 
     if (i_track == 0)
@@ -382,7 +408,7 @@ VCDSeek( input_thread_t * p_input, off_t i_off )
             if( p_vcd->cur_lsn < p_vcd->p_entries[i_entry] )
             {
               VCDUpdateVar( p_input, i_entry, VLC_VAR_SETVALUE,
-                            "chapter", "Setting entry" );
+                            "chapter", _("Entry"), "Setting entry" );
               break;
             }
         }
@@ -394,8 +420,9 @@ VCDSeek( input_thread_t * p_input, off_t i_off )
     p_input->stream.p_selected_area->i_tell = i_off;
 
     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
-    "orig %d, cur: %d, offset: %lld, start: %lld, entry %d",
-               p_vcd->origin_lsn, p_vcd->cur_lsn, i_off,
+               "orig %lu, cur: %lu, offset: %lld, start: %lld, entry %d",
+               (long unsigned int) p_vcd->origin_lsn, 
+              (long unsigned int) p_vcd->cur_lsn, i_off,
                p_input->stream.p_selected_area->i_start, i_entry );
 
     vlc_mutex_unlock( &p_input->stream.stream_lock );
@@ -413,14 +440,14 @@ VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid )
 {
     thread_vcd_data_t *     p_vcd= (thread_vcd_data_t *)p_input->p_access_data;
     input_area_t *          p_area;
+    bool                    b_was_still;
 
     dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n",
               itemid.num, itemid.type);
 
     if (!p_input->p_access_data) return VLC_EGENERIC;
-
-    p_vcd->in_still = false;
-    p_vcd->cur_lid  = VCDINFO_INVALID_LID;
+    
+    b_was_still = p_vcd->in_still;
 
 #define area p_input->stream.pp_areas
 
@@ -434,6 +461,7 @@ VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid )
         LOG_ERR ("Invalid track number %d", itemid.num );
         return VLC_EGENERIC;
       }
+      p_vcd->in_still  = false;
       p_area           = area[itemid.num];
       p_area->i_part   = p_area->i_plugin_data;
       p_input->stream.b_seekable = 1;
@@ -518,6 +546,7 @@ VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid )
         return VLC_EGENERIC;
       } else {
         track_t cur_track  = vcdinfo_get_track(p_vcd->vcd,  itemid.num);
+        p_vcd->in_still    = false;
         p_area             = area[cur_track];
         p_area->i_part     = itemid.num;
         p_input->stream.b_seekable = 1;
@@ -532,12 +561,22 @@ VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid )
 
 #undef area
 
+#if 1
+    if ( p_vcd->in_still != b_was_still ) {
+      if (p_input->stream.pp_selected_es) {
+       input_SetStatus( p_input, INPUT_STATUS_END );
+       input_SetStatus( p_input, INPUT_STATUS_PLAY );
+      }
+    }
+#endif
+
     p_vcd->play_item = itemid;
 
     dbg_print( (INPUT_DBG_CALL),
-               "i_start %lld, i_size: %lld, i_tell: %lld, lsn %d",
+               "i_start %lld, i_size: %lld, i_tell: %lld, lsn %lu",
                p_area->i_start, p_area->i_size,
-               p_area->i_tell, p_vcd->cur_lsn );
+               p_area->i_tell, 
+              (long unsigned int) p_vcd->cur_lsn );
 
     return VLC_SUCCESS;
 }
@@ -652,7 +691,9 @@ VCDSegments( input_thread_t * p_input )
     }
 
     /* Update the navigation variables without triggering a callback */
-    VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", "Setting track" );
+    VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", _("Track"),
+                 "Setting track" );
+
     var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );
 
     for( i = 0 ; i < num_segments ; i++ )
@@ -660,7 +701,7 @@ VCDSegments( input_thread_t * p_input )
       p_vcd->p_segments[i] = vcdinfo_get_seg_lsn(p_vcd->vcd, i);
       area[0]->i_part_nb ++;
       VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
-                    "chapter", "Adding segment choice");
+                    "chapter", _("Segment"), "Adding segment choice");
     }
 
 #undef area
@@ -883,14 +924,19 @@ VCDSetOrigin( input_thread_t *p_input, lsn_t origin_lsn,
   p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;
 
   dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN),
-             "origin: %d, cur_lsn: %d, end_lsn: %d, entry: %d, track: %d",
-             origin_lsn, cur_lsn, end_lsn, cur_entry, cur_track );
+             "origin: %lu, cur_lsn: %lu, end_lsn: %lu, entry: %d, track: %d",
+             (long unsigned int) origin_lsn, 
+            (long unsigned int) cur_lsn, 
+            (long unsigned int) end_lsn, cur_entry, cur_track );
 
   p_input->stream.p_selected_area->i_tell =
     (off_t) (p_vcd->cur_lsn - p_vcd->origin_lsn) * (off_t)M2F2_SECTOR_SIZE;
 
   VCDUpdateVar( p_input, cur_entry, VLC_VAR_SETVALUE,
-                "chapter", "Setting entry");
+                "chapter", 
+               p_vcd->play_item.type == VCDINFO_ITEM_TYPE_ENTRY ?
+               _("Entry") : _("Segment"), 
+               "Setting entry/segment");
 }
 
 /*****************************************************************************
@@ -925,6 +971,7 @@ VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd,
   typedef struct {
     uint8_t subheader   [8];
     uint8_t data        [M2F2_SECTOR_SIZE];
+    uint8_t spare       [4];
   } vcdsector_t;
   vcdsector_t vcd_sector;
 
@@ -932,7 +979,8 @@ VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd,
                              &vcd_sector, cur_lsn, true)
       != 0)
     {
-      msg_Warn( p_this, "Could not read LSN %d", cur_lsn );
+      msg_Warn( p_this, "Could not read LSN %lu", 
+               (long unsigned int) cur_lsn );
       return -1;
     }
 
@@ -946,76 +994,147 @@ VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd,
 ****************************************************************************/
 static void
 VCDUpdateVar( input_thread_t *p_input, int i_num, int i_action,
-              const char *varname, const char *label)
+              const char *p_varname, char *p_label, 
+             const char *p_debug_label)
 {
   vlc_value_t val;
   val.i_int = i_num;
   if (NULL != p_vcd_input) {
     thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data;
-    dbg_print( INPUT_DBG_PBC, "%s %d", label, i_num );
+    dbg_print( INPUT_DBG_PBC, "%s %d", p_debug_label, i_num );
   }
-  var_Change( p_input, varname, i_action, &val, NULL );
+  if (p_label) {
+    vlc_value_t text;
+    text.psz_string = p_label;
+    var_Change( p_input, p_varname, VLC_VAR_SETTEXT, &text, NULL );
+  }
+  var_Change( p_input, p_varname, i_action, &val, NULL );
 }
 
 
-#define meta_info_add_str(title, str) \
-  if ( str ) {                                                                \
-    dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str);                \
-    input_AddInfo( p_cat, _(title), "%s", str );                        \
+static inline void
+MetaInfoAddStr(input_thread_t *p_input, input_info_category_t *p_cat,
+               playlist_t *p_playlist, char *title,
+               const char *str)
+{
+  thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+  playlist_item_t *p_item;
+  if ( str ) {
+    dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str);
+    input_AddInfo( p_cat, title, "%s", str );
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_item = playlist_ItemGetByPos( p_playlist, -1 );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    vlc_mutex_lock( &p_item->lock );
+    playlist_ItemAddInfo( p_item, p_cat->psz_name, title,
+                          "%s",str );
+    vlc_mutex_unlock( &p_item->lock );
   }
+}
+
+
+static inline void
+MetaInfoAddNum(input_thread_t *p_input, input_info_category_t *p_cat,
+               playlist_t *p_playlist, char *title, int num)
+{
+  thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+  playlist_item_t *p_item;
+
+  vlc_mutex_lock( &p_playlist->object_lock );
+  p_item = playlist_ItemGetByPos( p_playlist, -1 );
+  vlc_mutex_unlock( &p_playlist->object_lock );
+
+  dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num);
+  input_AddInfo( p_cat, title, "%d", num );
 
-#define meta_info_add_num(title, num) \
-  dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num);                \
-  input_AddInfo( p_cat, _(title), "%d", num );                                \
+  vlc_mutex_lock( &p_item->lock );
+  playlist_ItemAddInfo( p_item ,  p_cat->psz_name, title, "%d",num );
+  vlc_mutex_unlock( &p_item->lock );
+}
+
+#define addstr(title, str) \
+  MetaInfoAddStr( p_input, p_cat, p_playlist, title, str );
+
+#define addnum(title, num) \
+  MetaInfoAddNum( p_input, p_cat, p_playlist, title, num );
 
 static void InformationCreate( input_thread_t *p_input  )
 {
   thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+  unsigned int i_nb = vcdinfo_get_num_entries(p_vcd->vcd);
+  unsigned int last_entry = 0;
   input_info_category_t *p_cat;
+  track_t i_track;
+  playlist_t *p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
+                                                 FIND_PARENT );
 
   p_cat = input_InfoCategory( p_input, "General" );
 
-  meta_info_add_str( "VCD Format", vcdinfo_get_format_version_str(p_vcd->vcd));
-  meta_info_add_str( "Album",      vcdinfo_get_album_id(p_vcd->vcd));
-  meta_info_add_str( "Application",vcdinfo_get_application_id(p_vcd->vcd));
-  meta_info_add_str( "Preparer",   vcdinfo_get_preparer_id(p_vcd->vcd));
-  meta_info_add_num( "Vol #",      vcdinfo_get_volume_num(p_vcd->vcd));
-  meta_info_add_num( "Vol max #",  vcdinfo_get_volume_count(p_vcd->vcd));
-  meta_info_add_str( "Volume Set", vcdinfo_get_volumeset_id(p_vcd->vcd));
-  meta_info_add_str( "Volume",     vcdinfo_get_volume_id(p_vcd->vcd));
-  meta_info_add_str( "Publisher",  vcdinfo_get_publisher_id(p_vcd->vcd));
-  meta_info_add_str( "System Id",  vcdinfo_get_system_id(p_vcd->vcd));
-  meta_info_add_num( "LIDs",       vcdinfo_get_num_LIDs(p_vcd->vcd));
-  meta_info_add_num( "Entries",    vcdinfo_get_num_entries(p_vcd->vcd));
-  meta_info_add_num( "Segments",   vcdinfo_get_num_segments(p_vcd->vcd));
-  meta_info_add_num( "Tracks",     vcdinfo_get_num_tracks(p_vcd->vcd));
+  addstr( _("VCD Format"),  vcdinfo_get_format_version_str(p_vcd->vcd) );
+  addstr( _("Album"),       vcdinfo_get_album_id(p_vcd->vcd));
+  addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) );
+  addstr( _("Preparer"),    vcdinfo_get_preparer_id(p_vcd->vcd) );
+  addnum( _("Vol #"),       vcdinfo_get_volume_num(p_vcd->vcd) );
+  addnum( _("Vol max #"),   vcdinfo_get_volume_count(p_vcd->vcd) );
+  addstr( _("Volume Set"),  vcdinfo_get_volumeset_id(p_vcd->vcd) );
+  addstr( _("Volume"),      vcdinfo_get_volume_id(p_vcd->vcd) );
+  addstr( _("Publisher"),   vcdinfo_get_publisher_id(p_vcd->vcd) );
+  addstr( _("System Id"),   vcdinfo_get_system_id(p_vcd->vcd) );
+  addnum( "LIDs",           vcdinfo_get_num_LIDs(p_vcd->vcd) );
+  addnum( _("Entries"),     vcdinfo_get_num_entries(p_vcd->vcd) );
+  addnum( _("Segments"),    vcdinfo_get_num_segments(p_vcd->vcd) );
+  addnum( _("Tracks"),      vcdinfo_get_num_tracks(p_vcd->vcd) );
+
+  /* Spit out track information. Could also include MSF info.
+   */
+
+#define TITLE_MAX 30
+  for( i_track = 1 ; i_track < p_vcd->num_tracks ; i_track++ ) {
+    char track_str[TITLE_MAX];
+    unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd, 
+                                                          i_track);
+    snprintf(track_str, TITLE_MAX, "%s%02d", _("Track"), i_track);
+    p_cat = input_InfoCategory( p_input, track_str );
+
+    if (p_vcd->b_svd) {
+      addnum(_("Audio Channels"),  
+            vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) );
+    }
 
+    addnum(_("First Entry Point"), last_entry );
+    for ( ; last_entry < i_nb 
+           && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track;
+         last_entry++ ) ;
+    addnum(_("Last Entry Point"), last_entry-1 );
+  }
 }
 
-#define add_format_str_info(val)                        \
-  {                                                        \
-    const char *str = val;                                \
-    unsigned int len;                                        \
-    if (val != NULL) {                                        \
-      len=strlen(str);                                        \
-      if (len != 0) {                                        \
-        strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));        \
-        tp += len;                                        \
+#define add_format_str_info(val)                              \
+  {                                                           \
+    const char *str = val;                                    \
+    unsigned int len;                                         \
+    if (val != NULL) {                                        \
+      len=strlen(str);                                        \
+      if (len != 0) {                                         \
+        strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));         \
+        tp += len;                                            \
       }                                                        \
-      saw_control_prefix = false;                        \
-    }                                                        \
+      saw_control_prefix = false;                             \
+    }                                                         \
   }
 
-#define add_format_num_info(val, fmt)                        \
-  {                                                        \
-    char num_str[10];                                        \
-    unsigned int len;                                   \
+#define add_format_num_info(val, fmt)                         \
+  {                                                           \
+    char num_str[10];                                         \
+    unsigned int len;                                         \
     sprintf(num_str, fmt, val);                                \
-    len=strlen(num_str);                                \
-    if (len != 0) {                                        \
+    len=strlen(num_str);                                      \
+    if (len != 0) {                                           \
       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        \
-      tp += len;                                        \
-    }                                                        \
+      tp += len;                                              \
+    }                                                         \
     saw_control_prefix = false;                                \
   }
 
@@ -1187,7 +1306,6 @@ VCDCreatePlayListItem(const input_thread_t *p_input,
                       const char *psz_source, int playlist_operation,
                       int i_pos)
 {
-  mtime_t i_duration = -1;
   char *p_author;
   char *p_title;
   char c_type;
@@ -1215,23 +1333,19 @@ VCDCreatePlayListItem(const input_thread_t *p_input,
 
   p_title =
     VCDFormatStr( p_input, p_vcd,
-                  config_GetPsz( p_input, MODULE_STRING "-title-format" ),
-                  psz_mrl, itemid );
-
-  playlist_AddExt( p_playlist, psz_mrl, p_title, i_duration,
-                   0, 0, playlist_operation, i_pos );
+                 config_GetPsz( p_input, MODULE_STRING "-title-format" ),
+                 psz_mrl, itemid );
+  
+  playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos );
 
   p_author =
     VCDFormatStr( p_input, p_vcd,
-                  config_GetPsz( p_input, MODULE_STRING "-author-format" ),
-                  psz_mrl, itemid );
+                 config_GetPsz( p_input, MODULE_STRING "-author-format" ),
+                 psz_mrl, itemid );
 
-  /* FIXME: This is horrible, but until the playlist interface is fixed up
-     something like this has to be done for the "Author" field.
-   */
   if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1;
-  free(p_playlist->pp_items[i_pos]->psz_author);
-  p_playlist->pp_items[i_pos]->psz_author = strdup(p_author);
+  playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s",
+                  p_author);
 }
 
 static int
@@ -1264,14 +1378,18 @@ VCDFixupPlayList( input_thread_t *p_input, thread_vcd_data_t *p_vcd,
 
   InformationCreate( p_input );
 
-  if ( play_single_item ) {
+  if ( play_single_item ) 
+    {
     /* May fill out more information when the playlist user interface becomes
        more mature.
      */
     VCDCreatePlayListItem(p_input, p_vcd, p_playlist, itemid,
                           psz_mrl, psz_mrl_max, psz_source, PLAYLIST_REPLACE,
                           p_playlist->i_index);
-  } else {
+
+    } 
+  else 
+    {
     vcdinfo_itemid_t list_itemid;
     list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY;
 
@@ -1349,13 +1467,15 @@ E_(Open) ( vlc_object_t *p_this )
 
     p_input->p_access_data = (void *)p_vcd;
     p_vcd->i_debug         = config_GetInt( p_this, MODULE_STRING "-debug" );
+    p_vcd->in_still        = false;
+    p_vcd->play_item.type  = VCDINFO_ITEM_TYPE_NOTFOUND;
 
     /* Set where to log errors messages from libcdio. */
     p_vcd_input = (input_thread_t *)p_this;
     cdio_log_set_handler ( cdio_log_handler );
     vcd_log_set_handler ( vcd_log_handler );
 
-    psz_source             = VCDParse( p_input, &itemid, &play_single_item );
+    psz_source = VCDParse( p_input, &itemid, &play_single_item );
 
     if ( NULL == psz_source )
     {
@@ -1389,6 +1509,8 @@ E_(Open) ( vlc_object_t *p_this )
         goto err_exit;
     }
 
+    p_vcd->b_svd= vcdinfo_get_tracksSVD(p_vcd->vcd);;
+    
     /* Get track information. */
     p_vcd->num_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input),
                                             vcdinfo_get_cd_image(p_vcd->vcd),
@@ -1454,7 +1576,8 @@ E_(Open) ( vlc_object_t *p_this )
     p_vcd->p_intf->b_block = VLC_FALSE;
     intf_RunThread( p_vcd->p_intf );
 
-    VCDFixupPlayList( p_input, p_vcd, psz_source, &itemid, play_single_item );
+    if (play_single_item)
+      VCDFixupPlayList( p_input, p_vcd, psz_source, &itemid, play_single_item );
 
     free( psz_source );
 
@@ -1479,6 +1602,7 @@ E_(Close) ( vlc_object_t *p_this )
 
     free( p_vcd->p_entries );
     free( p_vcd->p_segments );
+    free( p_vcd->p_sectors );
 
     /* For reasons that are a mystery to me we don't have to deal with
        stopping, and destroying the p_vcd->p_intf thread. And if we do