[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xine-cvslog
Subject:    [xine-cvs] CVS: xine-vcdnav/input Makefile.am,1.14,1.15 vcdio.c,1.44,1.45 vcdio.h,1.8,1.9 vcdplayer.
From:       Rocky Bernstein <rockyb () users ! sourceforge ! net>
Date:       2005-01-30 4:15:43
Message-ID: E1Cv6Ux-0008J0-4L () sc8-pr-cvs1 ! sourceforge ! net
[Download RAW message or body]

Update of /cvsroot/xine/xine-vcdnav/input
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31593/input

Modified Files:
	Makefile.am vcdio.c vcdio.h vcdplayer.c vcdplayer.h 
	xineplug_inp_cd.c xineplug_inp_vcd.c 
Log Message:
CDX: Add CD paranoia support
VCD: Synch up with VCD plugin in main branch.


Index: Makefile.am
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/Makefile.am,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Makefile.am	2 Apr 2004 12:55:49 -0000	1.14
+++ Makefile.am	30 Jan 2005 04:15:38 -0000	1.15
@@ -29,7 +29,7 @@
 
   xineplug_inp_cdx_la_LDFLAGS = -avoid-version -module
 
-  xineplug_inp_cdx_la_LIBADD = ../xine-extra/libxine_extra.la $(LIBCDIO_LIBS) \
$(CDDB_LIBS) +  xineplug_inp_cdx_la_LIBADD = ../xine-extra/libxine_extra.la \
$(LIBCDIO_LIBS) $(CDDB_LIBS) $(LIBCDIO_PARANOIA_LIBS)  CDDA_LTLIB = \
xineplug_inp_cdx.la  endif
 

Index: vcdio.c
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/vcdio.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- vcdio.c	28 Dec 2004 02:38:09 -0000	1.44
+++ vcdio.c	30 Jan 2005 04:15:39 -0000	1.45
@@ -1,7 +1,7 @@
 /*
   $Id$
  
-  Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
+  Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
   
   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
@@ -51,25 +51,25 @@
 #include "vcdplayer.h"
 #include "vcdio.h"
 
-#define LOG_ERR(this, s, args...) \
-       if (this != NULL && this->log_err != NULL) \
-          this->log_err("%s:  "s, __func__ , ##args)
+#define LOG_ERR(p_vcdplayer, s, args...) \
+       if (p_vcdplayer != NULL && p_vcdplayer->log_err != NULL) \
+          p_vcdplayer->log_err("%s:  "s, __func__ , ##args)
 
 #define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL;
 
 /*! Closes VCD device specified via "this", and also wipes memory of it 
    from it inside "this". */
 int
-vcdio_close(vcdplayer_t *this) 
+vcdio_close(vcdplayer_t *p_vcdplayer) 
 {
-  this->opened = false;
+  p_vcdplayer->opened = false;
 
-  FREE_AND_NULL(this->psz_source);
-  FREE_AND_NULL(this->track);
-  FREE_AND_NULL(this->segment);
-  FREE_AND_NULL(this->entry); 
+  FREE_AND_NULL(p_vcdplayer->psz_source);
+  FREE_AND_NULL(p_vcdplayer->track);
+  FREE_AND_NULL(p_vcdplayer->segment);
+  FREE_AND_NULL(p_vcdplayer->entry); 
   
-  return vcdinfo_close(this->vcd);
+  return vcdinfo_close(p_vcdplayer->vcd);
 }
 
 
@@ -107,6 +107,7 @@
   p_vcdplayer->psz_source = strdup(intended_vcd_device);
   p_vcdplayer->opened     = true;
   p_vcdplayer->i_lids     = vcdinfo_get_num_LIDs(p_vcdinfo);
+  p_vcdplayer->i_still    = 0;
 
   if (vcdinfo_read_psd (p_vcdinfo)) {
 
@@ -134,11 +135,11 @@
       calloc(p_vcdplayer->i_tracks, sizeof(vcdplayer_play_item_info_t));
     
     for (i=0; i<p_vcdplayer->i_tracks; i++) { 
-      unsigned int track_num=i+1;
+      track_t i_track=i+1;
       p_vcdplayer->track[i].size 
-        = vcdinfo_get_track_sect_count(p_vcdinfo, track_num);
+        = vcdinfo_get_track_sect_count(p_vcdinfo, i_track);
       p_vcdplayer->track[i].start_LSN 
-        = vcdinfo_get_track_lsn(p_vcdinfo, track_num);
+        = vcdinfo_get_track_lsn(p_vcdinfo, i_track);
     }
   } else 
     p_vcdplayer->track = NULL;
@@ -161,8 +162,8 @@
       calloc(p_vcdplayer->i_segments,  sizeof(vcdplayer_play_item_info_t));
     
     for (i=0; i<p_vcdplayer->i_segments; i++) { 
-      p_vcdplayer->segment[i].size =
-         vcdinfo_get_seg_sector_count(p_vcdinfo, i);
+      p_vcdplayer->segment[i].size 
+        = vcdinfo_get_seg_sector_count(p_vcdinfo, i);
       p_vcdplayer->segment[i].start_LSN 
         = vcdinfo_get_seg_lsn(p_vcdinfo, i);
     }

Index: vcdio.h
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/vcdio.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- vcdio.h	26 Dec 2004 18:25:35 -0000	1.8
+++ vcdio.h	30 Jan 2005 04:15:39 -0000	1.9
@@ -1,7 +1,7 @@
 /* 
   $Id$
 
-  Copyright (C) 2002 Rocky Bernstein <rocky@panix.com>
+  Copyright (C) 2002, 2004, 2005 Rocky Bernstein <rocky@panix.com>
   
   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
@@ -28,7 +28,7 @@
   read nlen bytes, return number of bytes read.
 */
 off_t 
-vcdio_read (vcdplayer_t *p_vcdplayer, char *buf, const off_t nlen);
+vcdio_read (vcdplayer_t *p_vcdplayer, char *psz_buf, const off_t nlen);
 
 /*! Opens VCD device and initializes things.
 
@@ -37,7 +37,7 @@
      to open new device. 
 */
 bool
-vcdio_open(vcdplayer_t *p_vcdplayer, char *intended_vcd_device);
+vcdio_open(vcdplayer_t *p_vcdplayer, char *psz_device);
 
 /*! Closes VCD device specified via "this", and also wipes memory of it 
    from it inside "this". */

Index: vcdplayer.c
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/vcdplayer.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -r1.89 -r1.90
--- vcdplayer.c	28 Dec 2004 09:15:48 -0000	1.89
+++ vcdplayer.c	30 Jan 2005 04:15:39 -0000	1.90
@@ -1,7 +1,7 @@
 /* 
   $Id$
  
-  Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
+  Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
   
   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
@@ -41,9 +41,9 @@
 #include "vcdplayer.h"
 #include "vcdio.h"
 
-#define LOG_ERR(this, s, args...) \
-       if (this != NULL && this->log_err != NULL) \
-          this->log_err("%s:  "s, __func__ , ##args)
+#define LOG_ERR(p_vcdplayer, s, args...) \
+       if (p_vcdplayer != NULL && p_vcdplayer->log_err != NULL) \
+          p_vcdplayer->log_err("%s:  "s, __func__ , ##args)
 
 unsigned long int vcdplayer_debug = 0;
 
@@ -163,7 +163,7 @@
       saw_control_prefix = !saw_control_prefix;
       break;
     case 'A':
-      add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdinfo),
+      add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdinfo), 
                                               MAX_ALBUM_LEN));
       break;
 
@@ -275,15 +275,16 @@
     vcdinfo_offset_t *off = vcdinfo_get_offset_t(p_vcdinfo, ofs);
     if (off != NULL) {
       *entry = off->lid;
-      dbg_print(INPUT_DBG_PBC, "%s: %d\n", label, off->lid);
+      dbg_print(INPUT_DBG_PBC, "%s: LID %d\n", label, off->lid);
     } else
       *entry = VCDINFO_INVALID_ENTRY;
   }
 }
 
 /*!
-  Update next/prev/return/default navigation buttons (via p_vcdplayer->i_lid).
-  Update size of play-item (via p_vcdplayer->play_item).
+  Update next/prev/return/default navigation buttons 
+  (via p_vcdplayer->i_lid). Update size of play-item 
+  (via p_vcdplayer->play_item).
 */
 void
 vcdplayer_update_nav(vcdplayer_t *p_vcdplayer)
@@ -314,6 +315,10 @@
                               vcdinf_psd_get_return_offset(p_vcdplayer->pxd.psd),
                               &(p_vcdplayer->return_entry), "return");
 
+      _vcdplayer_update_entry(p_vcdinfo, 
+                              vcdinfo_get_default_offset(p_vcdinfo, 
+                                                         p_vcdplayer->i_lid),
+                              &(p_vcdplayer->default_entry), "default");
       break;
     case PSD_TYPE_PLAY_LIST:
       if (p_vcdplayer->pxd.pld == NULL) return;
@@ -328,15 +333,16 @@
       _vcdplayer_update_entry(p_vcdinfo, 
                               vcdinf_pld_get_return_offset(p_vcdplayer->pxd.pld),
                               &(p_vcdplayer->return_entry), "return");
+      p_vcdplayer->default_entry = VCDINFO_INVALID_ENTRY;
       break;
     case PSD_TYPE_END_LIST:
-      p_vcdplayer->origin_lsn = p_vcdplayer->i_lsn 
-        = p_vcdplayer->end_lsn = VCDINFO_NULL_LSN;
+      p_vcdplayer->origin_lsn = p_vcdplayer->i_lsn = p_vcdplayer->end_lsn 
+        = VCDINFO_NULL_LSN;
       /* Fall through */
     case PSD_TYPE_COMMAND_LIST:
       p_vcdplayer->next_entry = p_vcdplayer->prev_entry 
-        = p_vcdplayer->return_entry =
-      VCDINFO_INVALID_ENTRY;
+        = p_vcdplayer->return_entry = VCDINFO_INVALID_ENTRY;
+      p_vcdplayer->default_entry = VCDINFO_INVALID_ENTRY;
       break;
     }
 
@@ -356,13 +362,13 @@
     case VCDINFO_ITEM_TYPE_ENTRY: 
       max_entry = p_vcdplayer->i_entries;
       min_entry = 0; /* Can remove when Entries start at 1. */
-      p_vcdplayer->i_track   = vcdinfo_get_track(p_vcdinfo, play_item);
+      p_vcdplayer->i_track = vcdinfo_get_track(p_vcdinfo, play_item);
       p_vcdplayer->track_lsn = vcdinfo_get_track_lsn(p_vcdinfo, 
                                                      p_vcdplayer->i_track);
       break;
     case VCDINFO_ITEM_TYPE_SEGMENT: 
-      max_entry       = p_vcdplayer->i_segments;
-      p_vcdplayer->i_track   = VCDINFO_INVALID_TRACK;
+      max_entry            = p_vcdplayer->i_segments;
+      p_vcdplayer->i_track = VCDINFO_INVALID_TRACK;
       
       break;
     case VCDINFO_ITEM_TYPE_TRACK: 
@@ -388,6 +394,7 @@
     else 
       p_vcdplayer->prev_entry = VCDINFO_INVALID_ENTRY;
     
+    p_vcdplayer->default_entry = play_item;
     p_vcdplayer->return_entry  = min_entry;
     break;
 
@@ -405,20 +412,20 @@
   Set reading to play an entire track.
 */
 static void
-_vcdplayer_set_track(vcdplayer_t *p_vcdplayer, unsigned int track_num) 
+_vcdplayer_set_track(vcdplayer_t *p_vcdplayer, unsigned int i_track) 
 {
-  if (track_num < 1 || track_num > p_vcdplayer->i_tracks) 
+  if (i_track < 1 || i_track > p_vcdplayer->i_tracks) 
     return;
   else {
     vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd;
     vcdinfo_itemid_t itemid;
 
-    itemid.num             = track_num;
+    itemid.num             = i_track;
     itemid.type            = VCDINFO_ITEM_TYPE_TRACK;
-    p_vcdplayer->in_still  = 0;
-    p_vcdplayer->i_lsn     = vcdinfo_get_track_lsn(p_vcdinfo, track_num);
+    p_vcdplayer->i_still   = 0;
+    p_vcdplayer->i_lsn     = vcdinfo_get_track_lsn(p_vcdinfo, i_track);
     p_vcdplayer->play_item = itemid;
-    p_vcdplayer->i_track   = track_num;
+    p_vcdplayer->i_track   = i_track;
     p_vcdplayer->track_lsn = p_vcdplayer->i_lsn;
 
     _vcdplayer_set_origin(p_vcdplayer);
@@ -444,12 +451,12 @@
 
     itemid.num             = num;
     itemid.type            = VCDINFO_ITEM_TYPE_ENTRY;
-    p_vcdplayer->in_still  = 0;
+    p_vcdplayer->i_still   = 0;
     p_vcdplayer->i_lsn     = vcdinfo_get_entry_lsn(p_vcdinfo, num);
     p_vcdplayer->play_item = itemid;
     p_vcdplayer->i_track   = vcdinfo_get_track(p_vcdinfo, num);
     p_vcdplayer->track_lsn = vcdinfo_get_track_lsn(p_vcdinfo, 
-                                                       p_vcdplayer->i_track);
+                                                   p_vcdplayer->i_track);
     p_vcdplayer->track_end_lsn = p_vcdplayer->track_lsn + 
       p_vcdplayer->track[p_vcdplayer->i_track-1].size;
 
@@ -475,7 +482,7 @@
   } else {
     vcdinfo_itemid_t itemid;
 
-    p_vcdplayer->i_lsn = vcdinfo_get_seg_lsn(p_vcdinfo, num);
+    p_vcdplayer->i_lsn   = vcdinfo_get_seg_lsn(p_vcdinfo, num);
     p_vcdplayer->i_track = 0;
 
     if (VCDINFO_NULL_LSN==p_vcdplayer->i_lsn) {
@@ -504,7 +511,7 @@
   dbg_print(INPUT_DBG_CALL, "called itemid.num: %d, itemid.type: %d\n", 
             itemid.num, itemid.type);
 
-  p_vcdplayer->in_still = 0;
+  p_vcdplayer->i_still = 0;
 
   switch (itemid.type) {
   case VCDINFO_ITEM_TYPE_SEGMENT: 
@@ -529,10 +536,10 @@
           /* Note that we are reading a still frame but haven't
              got to the end.
            */
-          p_vcdplayer->in_still = -5;
+          p_vcdplayer->i_still = STILL_READING;
           break;
         default:
-          p_vcdplayer->in_still = 0;
+          p_vcdplayer->i_still = 0;
         }
       
       break;
@@ -646,8 +653,8 @@
       if (p_vcdplayer->pxd.psd == NULL) return;
       trans_itemid_num  = vcdinf_psd_get_itemid(p_vcdplayer->pxd.psd);
       vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);
-      p_vcdplayer->i_loop      = 1;
-      p_vcdplayer->loop_item   = trans_itemid;
+      p_vcdplayer->i_loop    = 1;
+      p_vcdplayer->loop_item = trans_itemid;
       vcdplayer_play_single_item(p_vcdplayer, trans_itemid);
       break;
     }
@@ -685,9 +692,15 @@
             p_vcdplayer->end_lsn);
 }
 
+#define RETURN_NULL_STILL                       \
+  p_vcdplayer->i_still = 127;                   \
+  memset (p_buf, 0, M2F2_SECTOR_SIZE);          \
+  p_buf[0] = 0;  p_buf[1] = 0; p_buf[2] = 0x01; \
+  return READ_STILL_FRAME
+
 /* Handles PBC navigation when reaching the end of a play item. */
 static vcdplayer_read_status_t
-vcdplayer_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *wait_time)
+vcdplayer_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *p_buf)
 {
   /* We are in playback control. */
   vcdinfo_itemid_t itemid;
@@ -711,46 +724,48 @@
     return READ_END;
     break;
   case PSD_TYPE_PLAY_LIST: {
-    *wait_time = vcdinf_get_wait_time(p_vcdplayer->pxd.pld);
+    int wait_time = vcdinf_get_wait_time(p_vcdplayer->pxd.pld);
     
-    dbg_print(INPUT_DBG_PBC, "playlist wait_time: %d\n", *wait_time);
+    dbg_print(INPUT_DBG_PBC, "playlist wait_time: %d\n", wait_time);
     
     if (_vcdplayer_inc_play_item(p_vcdplayer))
       return READ_BLOCK;
 
-    /* Set caller to handle any wait time given. */
-    if (-5 == p_vcdplayer->in_still) {
-      if (*wait_time != 0) {
-        return READ_STILL_FRAME;
-      }
+    /* This needs to be improved in libvcdinfo when I get around to it.
+     */
+    if (-1 == wait_time) wait_time = STILL_INDEFINITE_WAIT;
+
+    /* Set caller to handle wait time given. */
+    if (STILL_READING == p_vcdplayer->i_still && wait_time > 0) {
+      p_vcdplayer->i_still = wait_time;
+      return READ_STILL_FRAME;
     }
     break;
   }
   case PSD_TYPE_SELECTION_LIST:     /* Selection List (+Ext. for SVCD) */
   case PSD_TYPE_EXT_SELECTION_LIST: /* Extended Selection List (VCD2.0) */
     {
+      int wait_time         = vcdinf_get_timeout_time(p_vcdplayer->pxd.psd);
       uint16_t timeout_offs = vcdinf_get_timeout_offset(p_vcdplayer->pxd.psd);
       uint16_t max_loop     = vcdinf_get_loop_count(p_vcdplayer->pxd.psd);
       vcdinfo_offset_t *offset_timeout_LID = 
         vcdinfo_get_offset_t(p_vcdplayer->vcd, timeout_offs);
       
-      *wait_time = vcdinf_get_timeout_time(p_vcdplayer->pxd.psd);
       dbg_print(INPUT_DBG_PBC, "wait_time: %d, looped: %d, max_loop %d\n", 
-                *wait_time, p_vcdplayer->i_loop, max_loop);
+                wait_time, p_vcdplayer->i_loop, max_loop);
       
-      /* Set caller to handle any wait time given */
-      if (-5 == p_vcdplayer->in_still && *wait_time) {
-        p_vcdplayer->in_still = *wait_time;
+      /* Set caller to handle wait time given. */
+      if (STILL_READING == p_vcdplayer->i_still && wait_time > 0) {
+        p_vcdplayer->i_still = wait_time;
         return READ_STILL_FRAME;
       }
       
-      /* Wait time has been processed; continue with next entry. */
-      /* Handle any looping given. max_loop == 0 means indefinite
-         looping. */
+      /* Handle any looping given. */
       if ( max_loop == 0 || p_vcdplayer->i_loop < max_loop ) {
         p_vcdplayer->i_loop++;
-        if (p_vcdplayer->i_loop == 0x7f) p_vcdplayer->i_loop = 0;
+        if (p_vcdplayer->i_loop == 0x7fff) p_vcdplayer->i_loop = 0;
         vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->loop_item);
+        if (p_vcdplayer->i_still) p_vcdplayer->force_redisplay();
         return READ_BLOCK;
       }
       
@@ -780,10 +795,9 @@
                     rand_selection - bsn, rand_lid);
           vcdplayer_play(p_vcdplayer, itemid);
           return READ_BLOCK;
-        } else if (p_vcdplayer->in_still) {
+        } else if (p_vcdplayer->i_still > 0) {
           /* Hack: Just go back and do still again */
-          *wait_time = 0x7f;
-          return READ_STILL_FRAME ;
+          RETURN_NULL_STILL ;
         }
       }
       
@@ -814,7 +828,7 @@
    is to do something that's probably right or helpful.
 */
 static vcdplayer_read_status_t
-vcdplayer_non_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *wait_time)
+vcdplayer_non_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *p_buf)
 {
   /* Not in playback control. Do we advance automatically or stop? */
   switch (p_vcdplayer->play_item.type) {
@@ -828,41 +842,26 @@
       return READ_END;
     break;
   case VCDINFO_ITEM_TYPE_SPAREID2:  
-    if (p_vcdplayer->in_still) {
-      vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->play_item);
-      return READ_BLOCK;
-    } 
-    return READ_END;
+    RETURN_NULL_STILL ;
 
   case VCDINFO_ITEM_TYPE_NOTFOUND:  
     LOG_ERR(p_vcdplayer, "NOTFOUND outside PBC -- not supposed to happen\n");
-    if (p_vcdplayer->in_still) {
-      /* Hack: force infinite still. */
-      vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->play_item);
-      return READ_BLOCK;
-    } else 
-      return READ_END;
+    return READ_END;
     break;
 
   case VCDINFO_ITEM_TYPE_LID:  
     LOG_ERR(p_vcdplayer, "LID outside PBC -- not supposed to happen\n");
-    if (p_vcdplayer->in_still) {
-      vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->play_item);
-      return READ_BLOCK;
-    } else 
-      return READ_END;
+    return READ_END;
     break;
 
   case VCDINFO_ITEM_TYPE_SEGMENT:
-    if (p_vcdplayer->in_still) {
-      vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->play_item);
-      return READ_BLOCK;
-    }
-    return READ_END;
+    /* Hack: Just go back and do still again */
+    RETURN_NULL_STILL ;
   }
   return READ_BLOCK;
 }
 
+
 /*!
   Read nlen bytes into buf and return the status back.
 
@@ -871,29 +870,27 @@
   interpret the next item in the playback-control list.
 */
 vcdplayer_read_status_t
-vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, const off_t nlen) 
+vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, 
+                const off_t nlen) 
 {
-  uint8_t wait_time;
-  
+
   if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) {
     vcdplayer_read_status_t read_status;
-
+    
     /* 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, end: %u\n", p_vcdplayer->i_lsn, 
-               p_vcdplayer->end_lsn);
+              "end reached, cur: %u, end: %u\n", 
+               p_vcdplayer->i_lsn, p_vcdplayer->end_lsn);
 
   handle_item_continuation:
-
-    read_status = vcdplayer_pbc_is_on(p_vcdplayer)
-      ? vcdplayer_pbc_nav(p_vcdplayer, &wait_time) 
-      : vcdplayer_non_pbc_nav(p_vcdplayer, &wait_time);
+    read_status = vcdplayer_pbc_is_on(p_vcdplayer) 
+      ? vcdplayer_pbc_nav(p_vcdplayer, p_buf) 
+      : vcdplayer_non_pbc_nav(p_vcdplayer, p_buf);
 
     if (READ_STILL_FRAME == read_status) {
-      *p_buf = p_vcdplayer->in_still = wait_time;
+      *p_buf = p_vcdplayer->i_still;
       return READ_STILL_FRAME;
     }
-
     if (READ_BLOCK != read_status) return read_status;
   }
 
@@ -906,8 +903,8 @@
     a little bit as well.
   */
 
-    {
-    CdIo *img = vcdinfo_get_cd_image(p_vcdplayer->vcd);
+  {
+    CdIo *p_img = vcdinfo_get_cd_image(p_vcdplayer->vcd);
     typedef struct {
       uint8_t subheader	[CDIO_CD_SUBHEADER_SIZE];
       uint8_t data	[M2F2_SECTOR_SIZE];
@@ -916,10 +913,10 @@
     vcdsector_t vcd_sector;
 
     do {
-      dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcdplayer->i_lsn);
-      if ( cdio_read_mode2_sector(img, &vcd_sector, p_vcdplayer->i_lsn, 
-                                  true) != 0 ) {
+      if (cdio_read_mode2_sector(p_img, &vcd_sector, 
+				 p_vcdplayer->i_lsn, true)!=0) {
         dbg_print(INPUT_DBG_LSN, "read error\n");
+	p_vcdplayer->i_lsn++;
         return READ_ERROR;
       }
       p_vcdplayer->i_lsn++;

Index: vcdplayer.h
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/vcdplayer.h,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -r1.65 -r1.66
--- vcdplayer.h	28 Dec 2004 09:15:49 -0000	1.65
+++ vcdplayer.h	30 Jan 2005 04:15:39 -0000	1.66
@@ -1,7 +1,7 @@
 /* 
   $Id$
 
-  Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
+  Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
   
   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
@@ -93,6 +93,15 @@
 
 typedef int (*generic_fn)();
 
+/* The maximim wait time that can be encoded in a VCD still frame is
+   2,000 seconds (33.33 minutes).  We'll use a number larger than this
+   to signal indefinite wait.
+*/
+#define STILL_INDEFINITE_WAIT  3000 
+
+/* Value when we have yet to finish reading blocks of a frame. */
+#define STILL_READING          -5
+
 typedef struct vcdplayer_input_s {
   void             *user_data;  /* environment. Passed to called routines. */
   int32_t           buttonN;
@@ -104,11 +113,6 @@
   unsigned int      i_debug;           /* Debugging mask */
   unsigned int      i_blocks_per_read; /* number of blocks per read */
 
-  int               in_still;   /*  0 if not in still, 
-                                   -2 if in infinite loop
-                                   -5 if a still but haven't read wait time yet
-                                   >0 number of seconds yet to wait */
-
   /*------------------------------------------------------------------
     Callback functions - players and higher-level routines can use
     this to customize their behavior when using this player-independent
@@ -122,7 +126,7 @@
   /* Function to flush any audio or  video buffers */
   void (*flush_buffers) (void); 
 
-  /* Function to flush sleep for a number of milliseconds. */
+  /* Function to force a redisplay. */
   void (*force_redisplay) (void); 
 
   /* Function to update title of selection. */
@@ -131,6 +135,11 @@
   /*-------------------------------------------------------------
      Playback control fields 
    --------------------------------------------------------------*/
+  int                 i_still;    /*  0 if not in still, 
+                                      STILL_INDEFINITE_WAIT if indefinite time,
+                                      STILL_READING if don't have full picture,
+                                      else number of seconds yet to wait */
+
   int                 i_lid;      /* LID that play item is in. Implies PBC is.
                                      on. VCDPLAYER_BAD_ENTRY if not none or 
                                      not in PBC */
@@ -154,6 +163,7 @@
   uint16_t   prev_entry;    /* where to fo if prev is pressed, 
                                VCDPLAYER_BAD_ENTRY if none */
   uint16_t   return_entry;  /* Entry index to use if return is pressed */
+  uint16_t   default_entry; /* Default selection entry. */
 
   lsn_t      i_lsn;         /* LSN of where we are right now */
   lsn_t      end_lsn;       /* LSN of end of current entry/segment/track.
@@ -167,8 +177,8 @@
   /*--------------------------------------------------------------
     (S)VCD Medium information
    ---------------------------------------------------------------*/
-  char       *psz_source;   /* VCD device currently open */
-  bool       opened;                /* true if initialized */
+  char         *psz_source; /* VCD device currently open */
+  bool          opened;     /* true if initialized */
 
   track_t       i_tracks;   /* # of playable MPEG tracks. This is 
                                 generally one less than the number

Index: xineplug_inp_cd.c
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/xineplug_inp_cd.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- xineplug_inp_cd.c	17 Dec 2004 23:55:42 -0000	1.49
+++ xineplug_inp_cd.c	30 Jan 2005 04:15:39 -0000	1.50
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2004 Rocky Bernstein
+ * Copyright (C) 2003, 2004, 2005 Rocky Bernstein
  *
  * This file is part of xine, a free video player.
  *
@@ -27,6 +27,7 @@
  * to use *LIBRARIES* 
  *    libcdio - for disc reading and CD control
  *    libcddb - for CDDB processing 
+ *    libcdio_paranoia libcdio_cdda - for cd paranoia jitter/error correction
  *
  * If you find yourself adding OS-specific code here, you are probably
  * doing something wrong.
@@ -66,9 +67,9 @@
 #include <xine-extra.h>
 
 #include <cdio/cdio.h>
+#include <cdio/cdda.h>
 #include <cdio/logging.h>
 #include <cdio/cd_types.h>
-#include <cdio/cdtext.h>
 
 #ifdef HAVE_LIBCDDB
 #include <cddb/cddb.h>
@@ -133,11 +134,13 @@
 					title when CDDB not enabled. */
   char         *comment_format;      /* Format string of stream comment 
 					meta when CDDB not enabled.*/
-  bool         b_cdtext_enabled;     /* Use CD-Text at all? If not,
+  bool         b_cdtext;             /* Use CD-Text at all? If not,
 					cdtext_preferred is meaningless. */
   bool         b_cdtext_prefer;      /* Prefer CD-Text info over
 					CDDB? If no CDDB, the issue
 					is moot. */
+  bool         b_paranoia;           /* Use CD paranoia for reads? */
+
 } cdda_config_t;
 
     
@@ -159,22 +162,28 @@
 
   cdda_config_t      v_config;       /* Config stuff initially inherited   */
                                      /* from (copied) from parent          */
-  track_t            cur_track;      /* The track we are currently playing */
   track_t            i_tracks;       /* The number of tracks on this CD    */
-  track_t            first_track;    /* The number of first track of CD.
+  track_t            i_first_track;  /* The number of first track of CD.
 					This is usually 1. 	           */
-  char              *psz_mrl;            /* The MRL for the current play item  */
+
+  char              *psz_mrl;        /* The MRL for the current play item  */
+
+  /* Current position */
+  track_t            i_track;        /* The track we are currently playing */
+  lsn_t              i_lsn;          /* LSN of current frame to read       */
+
   lsn_t              first_frame;    /* LSN of first frame of this track   */
-  lsn_t              current_frame;  /* LSN of current frame to read       */
   lsn_t              last_frame;     /* LSN of last frame of this track    */
   lsn_t              last_disk_frame;/* LSN of last frame on disk          */
   unsigned int       disk_size;      /* Size in bytes of disk              */
+  const cdtext_t    *p_cdtext;       /* CD-Text info                       */
+
+  /* Disc info */
   char *             psz_mcn;        /* Media Catalog Number               */
   char              *psz_discid;
   char              *psz_disc_artist;/* These will be either from ...      */
   char              *psz_disc_title; /* .. CD-Text or from CDDB or from... */
   char              *psz_disc_genre; /* .. somewhere else                  */
-  const cdtext_t    *p_cdtext;       /* CD-Text info                       */
 
   struct  {
     bool             b_info;         /* True if we have any info */
@@ -209,27 +218,32 @@
   config_values_t     *x_conf;
   cdda_input_plugin_t *ip;                       
 
-  cdda_config_t        v_config;    /* config stuff passed to child */
-  xine_mrl_t         **mrls;        /* MRLs in media */
-  int                  i_mrls;      /* count of above */
+  cdda_config_t        v_config;      /* config stuff passed to child */
+  xine_mrl_t         **mrls;          /* MRLs in media */
+  int                  i_mrls;        /* count of above */
 
   char                *autoplaylist[CDIO_CD_MAX_TRACKS];
 
-  char                *cdda_device; /* Device name to use when
-				       none specified in MRL
-						  */
-  CdIo *              p_cdio;       /* libcdio uses this to read          */
+  char                *cdda_device;   /* Device name to use when
+					 none specified in MRL   */
+  CdIo_t              *p_cdio;        /* libcdio uses this to read          */
+
+  /* CD Paranoia support */
+  cdrom_drive_t *paranoia_cd;        /* Place to store drive
+					handle given by paranoia. */
+  cdrom_paranoia_t *paranoia;
+
   struct  {
-    bool              b_enabled;    /* Do we use CDDB at all? If not,
-				       fields below are meaningless. */
-    char            *email;         /* Email we report back to CDDB. Can
-				       be bogus to hide information. 	   */
-    char            *server;        /* CDDB Server to contact */
-    int              port;          /* Port number for server above */
-    bool             http;          /* Contact using HTTP protocol? */
-    int              timeout;       /* network timeout value in seconds. */
-    bool             enable_cache;  /* If false, the below is meaningless. */
-    char            *cachedir;
+    bool               b_enabled;     /* Do we use CDDB at all? If not,
+					 fields below are meaningless. */
+    char              *psz_email;     /* Email we report back to CDDB. Can
+					 be bogus to hide information. 	   */
+    char              *server;        /* CDDB Server to contact */
+    int                i_port;        /* Port number for server above */
+    bool               b_http;        /* Contact using HTTP protocol? */
+    int                i_timeout;     /* network timeout value in seconds. */
+    bool               b_cache;       /* If false, the below is meaningless. */
+    char              *cachedir;
   } cddb;
 
 
@@ -238,11 +252,11 @@
 
 /**************** Static prototypes **************/
 
-static bool  cdda_handle_events(cdda_input_plugin_t *this);
-static bool  cdda_play_track (cdda_input_plugin_t *this, track_t track_num);
-static void  cdda_update_title(cdda_input_plugin_t *this);
-static off_t cdda_plugin_get_current_pos (input_plugin_t *this_gen);
-static void  cdda_close (cdda_input_class_t *class);
+static bool  _cdda_handle_events(cdda_input_plugin_t *this);
+static bool  _cdda_play_track (cdda_input_plugin_t *this, track_t track_num);
+static void  _cdda_update_title(cdda_input_plugin_t *this);
+static off_t _cdda_plugin_get_current_pos (input_plugin_t *this_gen);
+static void  _cdda_close (cdda_input_class_t *class);
 
 /*
  * Config callbacks
@@ -284,7 +298,7 @@
 	    str_value);
 IP_CALLBACK(cddb_comment_format_changed_cb,v_config.comment_format,
 	    str_value);
-IP_CALLBACK(cdtext_enabled_changed_cb,     v_config.b_cdtext_enabled,
+IP_CALLBACK(cdtext_enabled_changed_cb,     v_config.b_cdtext,
 	    num_value);
 IP_CALLBACK(cdtext_prefer_changed_cb,      v_config.b_cdtext_prefer, 
 	    num_value);
@@ -298,12 +312,12 @@
 
 CHANGED_CALLBACK(cddb_enabled_changed_cb,  cddb.b_enabled, num_value);
 CHANGED_CALLBACK(cddb_server_changed_cb,   cddb.server,    str_value);
-CHANGED_CALLBACK(cddb_port_changed_cb,     cddb.port,      num_value);
-CHANGED_CALLBACK(cddb_timeout_changed_cb,  cddb.timeout,   num_value);
-CHANGED_CALLBACK(cddb_http_changed_cb,     cddb.http,      num_value);
-CHANGED_CALLBACK(cddb_enable_cache_cb,     cddb.enable_cache,  num_value);
+CHANGED_CALLBACK(cddb_port_changed_cb,     cddb.i_port,    num_value);
+CHANGED_CALLBACK(cddb_timeout_changed_cb,  cddb.i_timeout, num_value);
+CHANGED_CALLBACK(cddb_http_changed_cb,     cddb.b_http,    num_value);
+CHANGED_CALLBACK(cddb_enable_cache_cb,     cddb.b_cache,   num_value);
 CHANGED_CALLBACK(cddb_cachedir_changed_cb, cddb.cachedir,  str_value);
-CHANGED_CALLBACK(cddb_email_changed_cb,    cddb.email,     str_value);
+CHANGED_CALLBACK(cddb_email_changed_cb,    cddb.psz_email, str_value);
 
 /*
  * **************** CDDB *********************
@@ -493,7 +507,7 @@
   char        *psz_mrl;
   CdIo        *p_cdio;
   bool         destroy_cdio = false;
-  track_t      first_track, i;
+  track_t      i_first_track, i;
   track_t      i_tracks;
   unsigned int size;
   bool         mrl_list_success = false;
@@ -542,12 +556,12 @@
   }
 
   /* Record MRL's for tracks */
-  first_track = cdio_get_first_track_num(p_cdio);
+  i_first_track = cdio_get_first_track_num(p_cdio);
   for ( i= 0; i < class->i_mrls; i++ ) { 
     memset(psz_mrl, 0, sizeof (psz_mrl));
-    MRL_FORMAT(psz_mrl, class->cdda_device, first_track+i);
+    MRL_FORMAT(psz_mrl, class->cdda_device, i_first_track+i);
     cdda_add_mrl_slot(class, psz_mrl, 
-		      cdio_get_track_sec_count(p_cdio, first_track+i), i);
+		      cdio_get_track_sec_count(p_cdio, i_first_track+i), i);
   }
 
   free(psz_mrl);
@@ -717,8 +731,8 @@
   cdda_input_class_t *class = (cdda_input_class_t *) this_gen;
   char track_mrl[200];
   int i;
-  track_t first_track;
-  CdIo *p_cdio;
+  track_t i_first_track;
+  CdIo_t *p_cdio;
 
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
 
@@ -741,7 +755,7 @@
     return NULL;
   }
   
-  first_track = cdio_get_first_track_num(p_cdio);
+  i_first_track = cdio_get_first_track_num(p_cdio);
   *num_files = cdio_get_num_tracks(p_cdio);
   if (CDIO_INVALID_TRACK == *num_files) {
     LOG_MSG("%s", _("error retrieving number of tracks"));
@@ -750,10 +764,10 @@
   }
   for( i = 0; i <= *num_files; i++ ) {
     /* We only want to process audio CDs. */
-    if (cdio_get_track_format(p_cdio, first_track+i) != TRACK_FORMAT_AUDIO) {
-      LOG_MSG("track %d is not an audio track", first_track+i);
+    if (cdio_get_track_format(p_cdio, i_first_track+i) != TRACK_FORMAT_AUDIO) {
+      LOG_MSG("track %d is not an audio track", i_first_track+i);
     } else {
-      MRL_FORMAT(track_mrl, class->cdda_device, first_track+i);
+      MRL_FORMAT(track_mrl, class->cdda_device, i_first_track+i);
       class->autoplaylist[i] = strdup(track_mrl);    
     }
   }
@@ -873,7 +887,7 @@
 
   uint32_t ret = INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_CHAPTERS;
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "returning %d\n", ret);
-  cdda_handle_events((cdda_input_plugin_t *) this_gen);
+  _cdda_handle_events((cdda_input_plugin_t *) this_gen);
   return ret;
 }
 
@@ -899,27 +913,44 @@
   unsigned char frame_data[CDIO_CD_FRAMESIZE_RAW];
 
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_LSN), "called %d\n", 
-	    this->current_frame);
+	    this->i_lsn);
 
   if (nlen != CDIO_CD_FRAMESIZE_RAW)
     return NULL;
 
-  cdda_handle_events(this);
+  _cdda_handle_events(this);
 
-  if (this->current_frame > this->last_frame) {
+  if (this->i_lsn > this->last_frame) {
     dbg_print( INPUT_DBG_LSN, 
-              "end reached, cur: %u, end: %u\n", this->current_frame, 
+              "end reached, cur: %u, end: %u\n", this->i_lsn, 
 	       this->last_frame);
     if (this->v_config.disk_mode==track_mode) goto end_of_cd;
-    if (this->cur_track - this->first_track < this->i_tracks-1) 
-      cdda_play_track(this, this->cur_track+1);
+    if (this->i_track - this->i_first_track < this->i_tracks-1) 
+      _cdda_play_track(this, this->i_track+1);
     else 
       goto end_of_cd;
   }
-
-  if (cdio_read_audio_sector(this->class->p_cdio, frame_data, 
-			     this->current_frame++)) {
-    return NULL;
+  
+  if ( this->v_config.b_paranoia && this->class->paranoia ) {
+    uint16_t *p_data = (uint16_t *) frame_data;
+    p_data = cdio_paranoia_read(this->class->paranoia, NULL);
+    char *psz_err = cdio_cddap_errors(this->class->paranoia_cd);
+    char *psz_mes = cdio_cddap_messages(this->class->paranoia_cd);
+    
+    if (psz_mes || psz_err)
+      LOG_ERR( "%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: "" );
+    
+    if (psz_err) free(psz_err);
+    if (psz_mes) free(psz_mes);
+    if( !frame_data ) {
+      LOG_ERR( "paranoia read error on frame %i\n", this->i_lsn++ );
+      return NULL;
+    }
+  } else {
+    if (cdio_read_audio_sector(this->class->p_cdio, frame_data, 
+			       this->i_lsn++)) {
+      return NULL;
+    }
   }
 
   buf = fifo->buffer_pool_alloc(fifo);
@@ -929,7 +960,7 @@
   memcpy(buf->mem, frame_data, CDIO_CD_FRAMESIZE_RAW);
 
   if (this->b_jumped) {
-    int64_t pts = cdda_plugin_get_current_pos(this_gen);
+    int64_t pts = _cdda_plugin_get_current_pos(this_gen);
     pts = (pts * 90000) / CD_BYTES_PER_SECOND;
     _x_demux_control_newpts(this->stream, pts, 0);
     this->b_jumped = false;
@@ -937,7 +968,7 @@
 
   return buf;
  end_of_cd: 
-  cdda_close (this->class);
+  _cdda_close (this->class);
   return NULL;
 }
 
@@ -958,18 +989,18 @@
   if (frame >= this->first_frame && frame <= this->last_frame)
     return true;
 
-  last_lsn = cdio_get_track_lsn(this->class->p_cdio, this->first_track);
+  last_lsn = cdio_get_track_lsn(this->class->p_cdio, this->i_first_track);
   for (t=1; t<this->i_tracks; t++) {
-    this_lsn = cdio_get_track_lsn(this->class->p_cdio, t+this->first_track);
+    this_lsn = cdio_get_track_lsn(this->class->p_cdio, t+this->i_first_track);
     if ( frame < this_lsn ) {
       this->first_frame = last_lsn;
       this->last_frame  = this_lsn;
-      this->cur_track   = t+this->first_track-1;
+      this->i_track     = t+this->i_first_track-1;
       this->psz_mrl     = this->class->mrls[t]->mrl;
-      cdda_update_title(this);
+      _cdda_update_title(this);
       return true;
     }
-    last_lsn = cdio_get_track_lsn(this->class->p_cdio, t+this->first_track);
+    last_lsn = cdio_get_track_lsn(this->class->p_cdio, t+this->i_first_track);
   }
 
   return false;
@@ -1000,26 +1031,29 @@
     seek_to_frame = this->first_frame + offset_frames;
   else if (origin == SEEK_CUR)
     /* Set relative to current position. */
-    seek_to_frame = this->current_frame + offset_frames;
+    seek_to_frame = this->i_lsn + offset_frames;
   else
     /* Set to be an invalid frame */
     seek_to_frame = last_frame + 1;
   
   if ((seek_to_frame >= first_frame) &&
       (seek_to_frame <= last_frame)) {
-    this->current_frame = seek_to_frame;
+    this->i_lsn = seek_to_frame;
     cdda_find_track(this, seek_to_frame);
   }
 
-  return (this->current_frame - first_frame) * CDIO_CD_FRAMESIZE_RAW;
+  if (this->class->v_config.b_paranoia && this->class->paranoia)
+    cdio_paranoia_seek(this->class->paranoia, this->i_lsn, SEEK_SET);
+
+  return (this->i_lsn - first_frame) * CDIO_CD_FRAMESIZE_RAW;
 }
 
 static off_t 
-cdda_plugin_get_current_pos (input_plugin_t *this_gen){
+_cdda_plugin_get_current_pos (input_plugin_t *this_gen){
   cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen;
   off_t frame_offset = (this->v_config.disk_mode == disk_mode)
-    ? this->current_frame
-    : this->current_frame - this->first_frame;
+    ? this->i_lsn
+    : this->i_lsn - this->first_frame;
 
   return frame_offset * CDIO_CD_FRAMESIZE_RAW;
 }
@@ -1032,7 +1066,7 @@
 static off_t cdda_plugin_get_length (input_plugin_t *this_gen) {
   cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen;
 
-  cdda_handle_events(this);
+  _cdda_handle_events(this);
   if (this->v_config.disk_mode == disk_mode) return this->disk_size;
   return  (this->last_frame - this->first_frame + 1) * CDIO_CD_FRAMESIZE_RAW;
 }
@@ -1054,7 +1088,7 @@
 */
 
 static bool
-cdda_handle_events (cdda_input_plugin_t *this) 
+_cdda_handle_events (cdda_input_plugin_t *this) 
 {
   xine_event_t *event;
   int digit_entered=0;
@@ -1125,7 +1159,7 @@
         dbg_print(INPUT_DBG_EVENT, "NEXT/PREV iteration count %d\n", num);
 
 	cdda_flush_buffers(this);
-	return cdda_play_track(this, this->cur_track+num);
+	return _cdda_play_track(this, this->i_track+num);
         break;
       }
     case XINE_EVENT_INPUT_SELECT:
@@ -1139,7 +1173,7 @@
         if (num == 0) num++;
 
 	cdda_flush_buffers(this);
-	return cdda_play_track(this, num);
+	return _cdda_play_track(this, num);
         break;
       }
 
@@ -1265,17 +1299,17 @@
 #ifdef HAVE_LIBCDDB      
 	if (this->class->cddb.b_enabled) {
 	  cddb_track_t *t = cddb_disc_get_track(this->cddb.disc, 
-						this->cur_track 
-						- this->first_track);
+						this->i_track 
+						- this->i_first_track);
 	  if (t != NULL && t->title != NULL) 
 	    psz_title = t->title;
 	}
 #endif /*HAVE_LIBCDDB*/	  
 	  
-	if (this->class->v_config.b_cdtext_enabled) {
+	if (this->class->v_config.b_cdtext) {
 	  
 	  const cdtext_t *p_cdtext = cdio_get_cdtext(this->class->p_cdio, 
-						     this->cur_track);
+						     this->i_track);
 	  
 	  if ( p_cdtext && p_cdtext->field[CDTEXT_TITLE] && 
 		 (this->class->v_config.b_cdtext_prefer || !psz_title) ) {
@@ -1297,16 +1331,16 @@
 #ifdef HAVE_LIBCDDB      
 	if (this->class->cddb.b_enabled) {
 	  cddb_track_t *t=cddb_disc_get_track(this->cddb.disc, 
-					      this->cur_track-1);
+					      this->i_track-1);
 	  if (t != NULL && t->artist != NULL) 
 	    psz_performer = t->artist;
 	}
 #endif /*HAVE_LIBCDDB*/	  
 	  
-	if (this->class->v_config.b_cdtext_enabled) {
+	if (this->class->v_config.b_cdtext) {
 	  
 	  const cdtext_t *p_cdtext = cdio_get_cdtext(this->class->p_cdio, 
-						     this->cur_track);
+						     this->i_track);
 	  
 	  if ( p_cdtext && p_cdtext->field[CDTEXT_PERFORMER] && 
 	       (this->class->v_config.b_cdtext_prefer || !psz_performer) ) {
@@ -1327,16 +1361,16 @@
 #ifdef HAVE_LIBCDDB      
 	if (this->class->cddb.b_enabled) {
 	  cddb_track_t *t=cddb_disc_get_track(this->cddb.disc, 
-					      this->cur_track-1);
+					      this->i_track-1);
 	  if (t != NULL && t->ext_data != NULL) 
 	    psz_ext_msg = t->ext_data;
 	}
 #endif /*HAVE_LIBCDDB*/	  
 	  
-	if (this->class->v_config.b_cdtext_enabled) {
+	if (this->class->v_config.b_cdtext) {
 	  
 	  const cdtext_t *p_cdtext = cdio_get_cdtext(this->class->p_cdio, 
-						     this->cur_track);
+						     this->i_track);
 	  
 	  if ( p_cdtext && p_cdtext->field[CDTEXT_ISRC] && 
 		 (this->class->v_config.b_cdtext_prefer || !psz_ext_msg) ) {
@@ -1366,11 +1400,11 @@
 #endif
 
     case 's':
-      if ( CDIO_INVALID_TRACK != this->cur_track )
+      if ( CDIO_INVALID_TRACK != this->i_track )
 	{
 	  unsigned int i_track_frames = 
 	    cdio_get_track_sec_count(this->class->p_cdio, 
-				     this->cur_track);
+				     this->i_track);
 	  unsigned int i_duration = 
 	    i_track_frames / CDIO_CD_FRAMES_PER_SEC;
 	  add_format_str_info( secstotimestr( temp_str, i_duration ) );
@@ -1398,7 +1432,7 @@
       add_format_num_info(this->i_tracks, "%d");
       break;
     case 'T':
-      add_format_num_info(this->cur_track, "%d");
+      add_format_num_info(this->i_track, "%d");
       break;
 #ifdef HAVE_LIBCDDB      
     not_special:
@@ -1424,7 +1458,7 @@
 
 /* Update the xine player title text. */
 static void 
-cdda_update_title(cdda_input_plugin_t *this) 
+_cdda_update_title(cdda_input_plugin_t *this) 
 {
   xine_event_t uevent;
   xine_ui_data_t data;
@@ -1468,7 +1502,7 @@
   Set up internal state so that we play a given track.
  */
 static bool
-cdda_play_track (cdda_input_plugin_t *this, track_t track_num) 
+_cdda_play_track (cdda_input_plugin_t *this, track_t track_num) 
 {
   dbg_print((INPUT_DBG_CALL), "called track: %d\n", track_num);
 
@@ -1478,16 +1512,16 @@
     return false;
   }
 
-  this->cur_track = track_num;
+  this->i_track = track_num;
 
   /* set up the frame boundaries for this particular track */
-  this->first_frame = this->current_frame = 
+  this->first_frame = this->i_lsn = 
     cdio_get_track_lsn(this->class->p_cdio, track_num);
   this->last_frame  = cdio_get_track_lsn(this->class->p_cdio, track_num+1) - 1;
   this->b_jumped    = true;
 
   /*xine_demux_flush_engine (this->stream);*/
-  cdda_update_title(this);
+  _cdda_update_title(this);
   
   return true;
 }
@@ -1498,7 +1532,8 @@
    when we have an actual MRL we want to deal with.
 */
 static int 
-cdda_plugin_open (input_plugin_t *this_gen ) {
+cdda_plugin_open (input_plugin_t *this_gen ) 
+{
   cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen;
 
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
@@ -1565,7 +1600,7 @@
   this->b_jumped       = false;
   this->event_queue    = xine_event_new_queue (stream);
   this->i_tracks       = cdio_get_num_tracks(p_cdio);
-  this->first_track    = cdio_get_first_track_num(p_cdio);
+  this->i_first_track  = cdio_get_first_track_num(p_cdio);
   this->disk_size      = cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
     * CDIO_CD_FRAMESIZE_RAW;
   this->last_disk_frame= cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK);
@@ -1579,7 +1614,7 @@
   
   if (class->i_mrls == 0) cdda_build_mrl_list(class);
 
-  if (track_num-this->first_track >= this->i_tracks || track_num == 0) {
+  if (track_num-this->i_first_track >= this->i_tracks || track_num == 0) {
     LOG_ERR("CD has %d tracks, and you requested track %d", 
 	    this->i_tracks, track_num);
     cdio_destroy(p_cdio);
@@ -1594,7 +1629,7 @@
     goto free_and_return;
   }
   
-  if (this->class->v_config.b_cdtext_enabled) {
+  if (this->class->v_config.b_cdtext) {
     this->p_cdtext = cdio_get_cdtext(p_cdio, 0);
   }
 
@@ -1618,21 +1653,21 @@
       goto cddb_destroy;
     }
     
-    cddb_set_email_address(conn, class->cddb.email);
+    cddb_set_email_address(conn, class->cddb.psz_email);
     cddb_set_server_name(conn, class->cddb.server);
-    cddb_set_server_port(conn, class->cddb.port);
+    cddb_set_server_port(conn, class->cddb.i_port);
 
     /* Set the location of the local CDDB cache directory.
        The default location of this directory is */
 
-    if (!class->cddb.enable_cache)
+    if (!class->cddb.b_cache)
       cddb_cache_disable(conn);
 
     cddb_cache_set_dir(conn, class->cddb.cachedir);
 
-    cddb_set_timeout(conn, class->cddb.timeout);
+    cddb_set_timeout(conn, class->cddb.i_timeout);
 
-    if (class->cddb.http)
+    if (class->cddb.b_http)
       cddb_http_enable(conn);
     else
       cddb_http_disable(conn);
@@ -1687,11 +1722,28 @@
   
 #endif /*HAVE_LIBCDDB*/
 
+  if (class->v_config.b_paranoia) {
+    class->paranoia_cd = cdio_cddap_identify_cdio(p_cdio, 1, NULL);
+    /* We'll set for verbose paranoia messages. */
+    cdio_cddap_verbose_set(class->paranoia_cd, CDDA_MESSAGE_PRINTIT, 
+			   CDDA_MESSAGE_PRINTIT);
+    if ( 0 != cdio_cddap_open(class->paranoia_cd) ) {
+      LOG_MSG( "Unable to get paranoia support - continuing without it." );
+      class->v_config.b_paranoia = false;
+    } else {
+      class->paranoia = cdio_paranoia_init(class->paranoia_cd);
+      
+      /* Set reading mode for full paranoia, but allow skipping sectors. */
+      cdio_paranoia_modeset(class->paranoia, 
+			    PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
+    }
+  }
+      
   this->psz_disc_title  = this->cddb.psz_disc_title;
   this->psz_disc_artist = this->cddb.psz_disc_artist;
   this->psz_disc_genre  = this->cddb.psz_disc_genre;
     
-  if (this->p_cdtext && this->class->v_config.b_cdtext_enabled) {
+  if (this->p_cdtext && this->class->v_config.b_cdtext) {
     
     if ( this->p_cdtext->field[CDTEXT_TITLE] && 
 	 (this->class->v_config.b_cdtext_prefer || !this->psz_disc_title) ) {
@@ -1727,7 +1779,7 @@
   this->input_plugin.read               = cdda_plugin_read;
   this->input_plugin.read_block         = cdda_plugin_read_block;
   this->input_plugin.seek               = cdda_plugin_seek;
-  this->input_plugin.get_current_pos    = cdda_plugin_get_current_pos;
+  this->input_plugin.get_current_pos    = _cdda_plugin_get_current_pos;
   this->input_plugin.get_length         = cdda_plugin_get_length;
   this->input_plugin.get_blocksize      = cdda_plugin_get_blocksize;
   this->input_plugin.get_mrl            = cdda_plugin_get_mrl;
@@ -1737,7 +1789,7 @@
 
   this->psz_mrl = strdup(psz_mrl);
 
-  cdda_play_track(this, track_num);
+  _cdda_play_track(this, track_num);
 
   free (device_str);
   free (check_mrl);
@@ -1808,7 +1860,7 @@
 }
 
 static void 
-cdda_close (cdda_input_class_t *class) {
+_cdda_close (cdda_input_class_t *class) {
   dbg_print((INPUT_DBG_CALL), "called\n");
 
   gl_default_cdio_log_handler = cdio_log_set_handler (uninit_log_handler);
@@ -1824,6 +1876,14 @@
     cdio_destroy(class->p_cdio);
     class->p_cdio = NULL;
   }
+
+  if (class->v_config.b_paranoia) {
+    cdio_paranoia_free(class->paranoia);
+    if (class->paranoia_cd) 
+      cdio_cddap_close_no_free_cdio(class->paranoia_cd);
+  }
+  
+
 }
 
 
@@ -1833,7 +1893,7 @@
 
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
   if (NULL == class) return;
-  cdda_close(class);
+  _cdda_close(class);
   free (class);
 }
 
@@ -1920,7 +1980,7 @@
 			  0,
 			  cddb_disk_mode_changed_cb, (void *) class);
   
-  class->v_config.b_cdtext_enabled =
+  class->v_config.b_cdtext =
     x_conf->register_bool(x_conf, "cdda.cdtext_enabled", 1,
 			  _("Use CD-Text information if available?"), 
 			  NULL, 0,
@@ -1932,22 +1992,27 @@
 			  NULL, 0,
 			  cdtext_prefer_changed_cb, (void *) class);
   
+  class->v_config.b_paranoia =
+    x_conf->register_bool(x_conf, "cdda.enable_paranoia", 0,
+			  _("Use CD paranoia jitter/error correction"), 
+			  NULL, 0, NULL, NULL);
+  
 #ifdef HAVE_LIBCDDB
   class->cddb.b_enabled =
     x_conf->register_bool(x_conf, "cdda.cddb_enabled", 1,
-			  _("Do we use CDDB to retrieve CD information?"), 
+			  _("Use CDDB to retrieve CD information"), 
 			  NULL, 0,
 			  cddb_enabled_changed_cb, (void *) class);
   
-  class->cddb.enable_cache =
+  class->cddb.b_cache =
     x_conf->register_bool(x_conf, "cdda.cddb_enable_cache", 1,
-			  _("Do we cache CDDB requests?"), 
+			  _("Cache CDDB requests"), 
 			  NULL, 0,
 			  cddb_enable_cache_cb, (void *) class);
   
-  class->cddb.http =
+  class->cddb.b_http =
     x_conf->register_bool(x_conf, "cdda.cddb_http", 0,
-			  _("Contact CDDB via the HTTP protocol?"), NULL, 0,
+			  _("Contact CDDB via the HTTP protocol"), NULL, 0,
 			  cddb_http_changed_cb, (void *) class);
 
   class->cddb.server =
@@ -1956,24 +2021,24 @@
 			  _("The server CDDB contacts to get CD info"), 
 				   (void *) class, 10,
 				   cddb_server_changed_cb, (void *) class));
-  class->cddb.port =
+  class->cddb.i_port =
     x_conf->register_num(x_conf, "cdda.cddb_port", CDDB_PORT,
 			 _("CDDB server port"), (void *) class, 10,
 			 cddb_port_changed_cb, (void *) class);
 
-  class->cddb.timeout =
+  class->cddb.i_timeout =
     x_conf->register_num(x_conf, "cdda.timeout", 7,
-			 _("cddb timeout value (in seconds)"), 
+			 _("CDDB timeout value (in seconds)"), 
 			 (void *) class, 10,
 			 cddb_timeout_changed_cb, (void *) class);
 
   class->cddb.cachedir = 
     strdup(x_conf->register_string(x_conf, "cdda.cddb_cachedir", 
 				   "~/.cddbslave",
-				   _("cddb cache directory"), NULL, 20, 
+				   _("CDDB cache directory"), NULL, 20, 
 				   cddb_cachedir_changed_cb, (void *) class));
 
-  class->cddb.email =
+  class->cddb.psz_email =
     strdup(x_conf->register_string(x_conf, "cdda.cddb_email", 
 				   "me@home",
 				   _("email given on cddb requests"), 
@@ -1999,7 +2064,7 @@
     strdup(x_conf->register_string(x_conf,
 				   "cdda.cddb_comment_format",
 				   "MRL %M, MCN: %m",
-_("format for stream comment field (when CDDB info not available)"),
+_("Format for stream comment field (when CDDB info not available)"),
 _("Format used in the GUI Title. Similar to the Unix date "
 "command. Format specifiers that start with a percent sign. Specifiers are "
 "same as the cddb_title_format string."),
@@ -2011,7 +2076,7 @@
     strdup(x_conf->register_string(x_conf,
 				   "cdda.cddb_cddb_title_format",
                                _("Track %T: %t Artist: %a, Title %t, Performer %p, \
                %e, Album %A, %C (%Y)"),
-_("format string for display banner (when CDDB info available)"),
+_("Format string for display banner (when CDDB info available)"),
 "Format used in the GUI Title. Similar to the Unix date "
 "command. Format specifiers that start with a percent sign. Specifiers are "
 			  "%a, %A, %e, %C, %G, %I %M, %m, %n, %p, %T, %Y and %%.",
@@ -2037,36 +2102,9 @@
   return class;
 }
 
-/* 
-   Exported plugin catalog entries.
-
-   All plugins listing only the current API number break when the API
-   number is increased. This is by design. 
-
-   Sometimes in the rush to get out a buggy release, the API number is
-   increased without communication let alone a concern for whether it
-   is necessary or how many plugins it might break. And that is
-   precisely when what happened between API release 12 and API
-   13. Input plugin API numbers 12 and 13 are functionally identical.
-
-   Because of problems like this, we'll just put in a future API
-   release. If the number was increased for a reason that doesn't
-   affect us (such as for nor reason at all), then this plugin will
-   work unmodified that future APIs. If on the other hand there was
-   incompatible change, we are no worse off than if we hadn't entered
-   the next API number since in both cases the plugin is broken.
- */
 const plugin_info_t xine_plugin_info[] = {
   /* type, API, "name", version, special_info, init_function */
-  { PLUGIN_INPUT, 11, (char *) SHORT_PLUGIN_NAME, XINE_VERSION_CODE, 
-    NULL, cdda_init },
-  { PLUGIN_INPUT, 12, (char *) SHORT_PLUGIN_NAME, XINE_VERSION_CODE, 
-    NULL, cdda_init },
-  { PLUGIN_INPUT, 13, (char *) SHORT_PLUGIN_NAME, XINE_VERSION_CODE, 
-    NULL, cdda_init }, 
-  { PLUGIN_INPUT, 14, (char *) SHORT_PLUGIN_NAME, XINE_VERSION_CODE, 
-    NULL, cdda_init }, /* This is the current API */
   { PLUGIN_INPUT, 15, (char *) SHORT_PLUGIN_NAME, XINE_VERSION_CODE, 
-    NULL, cdda_init }, /* This is possibly the next API */
+    NULL, cdda_init },
   { PLUGIN_NONE, 0, (char *) "", 0, NULL, NULL }
 };

Index: xineplug_inp_vcd.c
===================================================================
RCS file: /cvsroot/xine/xine-vcdnav/input/xineplug_inp_vcd.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -r1.117 -r1.118
--- xineplug_inp_vcd.c	28 Dec 2004 09:15:49 -0000	1.117
+++ xineplug_inp_vcd.c	30 Jan 2005 04:15:39 -0000	1.118
@@ -1,9 +1,9 @@
 /*
   $Id$
  
-  Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
+  Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
   
-  Program is free software; you can redistribute it and/or modify
+  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
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
@@ -112,8 +112,8 @@
     into "mrls" array 
    ---------------------------------------------------------------*/
   int        mrl_track_offset;    /* perhaps -1 for tracks staring with 1*/
-  int        mrl_entry_offset;    /* # tracks for entries starting with 0 */
-  int        mrl_play_offset;     /* # tracks for entries starting with 0 */
+  int        mrl_entry_offset;    /* i_tracks for entries starting with 0 */
+  int        mrl_play_offset;     /* i_tracks for entries starting with 0 */
   int        mrl_segment_offset;  /* i_tracks + i_entries if segs start 1*/
 
 
@@ -130,6 +130,13 @@
   xine_stream_t      *stream;
   xine_event_queue_t *event_queue;
 
+  time_t	      pause_end_time;
+  int                 i_old_still; /* Value of player-i_still before next read.
+                                      See also i_still in vcdplayer structure.
+                                    */
+  int                 i_old_deinterlace; /* value of deinterlace before
+                                            entering a still. */
+
   vcd_input_class_t  *class;
   vcd_config_t        v_config;    /* Config stuff initially inherited   */
   bool                jumped;      /* True if we changed tracks or any
@@ -188,16 +195,16 @@
 static void
 vcd_set_meta_info (vcd_input_plugin_t *xine_vcd) 
 {
-  vcdinfo_obj_t *obj= xine_vcd->player.vcd;
+  vcdinfo_obj_t *p_vcdinfo= xine_vcd->player.vcd;
   meta_info_assign(XINE_META_INFO_ALBUM, xine_vcd->stream, 
-                   vcdinfo_get_album_id(obj));
+                   vcdinfo_get_album_id(p_vcdinfo));
   meta_info_assign(XINE_META_INFO_ARTIST,  xine_vcd->stream,
-                   vcdinfo_get_preparer_id(obj));
+                   vcdinfo_get_preparer_id(p_vcdinfo));
   meta_info_assign(XINE_META_INFO_COMMENT, xine_vcd->stream,
                    vcdplayer_format_str(&xine_vcd->player,
                                    xine_vcd->v_config.comment_format));
   meta_info_assign(XINE_META_INFO_GENRE, xine_vcd->stream,
-                   vcdinfo_get_format_version_str(obj));
+                   vcdinfo_get_format_version_str(p_vcdinfo));
 }
 
 static void
@@ -282,20 +289,20 @@
 {
 
   char mrl[strlen(MRL_PREFIX)+MAX_DEVICE_LEN+sizeof("@E")-1+12];
-  vcdplayer_t *player;
+  vcdplayer_t *vcdplayer;
   unsigned int n, i=0;
   unsigned int i_entries;
-  vcdinfo_obj_t *obj;
+  vcdinfo_obj_t *p_vcdinfo;
 
   if (NULL == class) {
     LOG_MSG("%s", _("was passed a null class parameter"));
     return false;
   }
 
-  player = &(my_vcd.player);
+  vcdplayer = &(my_vcd.player);
 
   /* If VCD already open, we gotta close and stop it. */
-  if (player->opened) {
+  if (vcdplayer->opened) {
     vcd_close(class);
   }
 
@@ -304,16 +311,16 @@
     vcd_device = class->vcd_device;
   }
   
-  if (!vcdio_open(player, vcd_device)) {
+  if (!vcdio_open(vcdplayer, vcd_device)) {
     /* Error should have been logged  in vcdio_open. If not do the below:
-    LOG_ERR(player, "%s: %s.\n", _("unable to open"), 
+    LOG_ERR(vcdplayer, "%s: %s.\n", _("unable to open"), 
             class->vcd_device, strerror(errno));
     */
     return false;
   }
   
-  obj                     = player->vcd;
-  i_entries               = player->i_entries;
+  p_vcdinfo               = vcdplayer->vcd;
+  i_entries               = vcdplayer->i_entries;
   class->mrl_track_offset = -1;
 
   xine_free_mrls(&(class->num_mrls), class->mrls);
@@ -322,13 +329,13 @@
      didn't have to possibly remove rejected LIDs from list done in the
      loop below.
    */
-  class->num_mrls = player->i_tracks + player->i_entries 
-    + player->i_segments + player->i_lids;
+  class->num_mrls = vcdplayer->i_tracks + vcdplayer->i_entries 
+    + vcdplayer->i_segments + vcdplayer->i_lids;
 
-  if (!player->show_rejected && vcdinfo_get_lot(player->vcd)) {
+  if (!vcdplayer->show_rejected && vcdinfo_get_lot(vcdplayer->vcd)) {
     /* Remove rejected LIDs from count. */
-    for (n=0; n<player->i_lids; n++) {
-      if ( vcdinf_get_lot_offset(vcdinfo_get_lot(player->vcd), n) 
+    for (n=0; n<vcdplayer->i_lids; n++) {
+      if ( vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n) 
            == PSD_OFS_DISABLED )
         class->num_mrls--;
     }
@@ -342,13 +349,13 @@
   }
 
   /* Record MRL's for tracks */
-  for (n=1; n<=player->i_tracks; n++) { 
+  for (n=1; n<=vcdplayer->i_tracks; n++) { 
     memset(&mrl, 0, sizeof (mrl));
     snprintf(mrl, sizeof(mrl), "%s%s@T%u", MRL_PREFIX, vcd_device, n);
-    vcd_add_mrl_slot(class, mrl, player->track[n-1].size, &i);
+    vcd_add_mrl_slot(class, mrl, vcdplayer->track[n-1].size, &i);
   }
     
-  class->mrl_entry_offset = player->i_tracks;
+  class->mrl_entry_offset = vcdplayer->i_tracks;
   class->mrl_play_offset  = class->mrl_entry_offset + i_entries - 1;
 
   /* Record MRL's for entries */
@@ -356,16 +363,16 @@
     for (n=0; n<i_entries; n++) { 
       memset(&mrl, 0, sizeof (mrl));
       snprintf(mrl, sizeof(mrl), "%s%s@E%u", MRL_PREFIX, vcd_device, n);
-      vcd_add_mrl_slot(class, mrl, player->entry[n].size, &i);
+      vcd_add_mrl_slot(class, mrl, vcdplayer->entry[n].size, &i);
     }
   }
   
   /* Record MRL's for LID entries or selection entries*/
   class->mrl_segment_offset = class->mrl_play_offset;
-  if (vcdinfo_get_lot(player->vcd)) {
-    for (n=0; n<player->i_lids; n++) {
-      uint16_t ofs = vcdinf_get_lot_offset(vcdinfo_get_lot(player->vcd), n);
-      if (ofs != PSD_OFS_DISABLED || player->show_rejected) {
+  if (vcdinfo_get_lot(vcdplayer->vcd)) {
+    for (n=0; n<vcdplayer->i_lids; n++) {
+      uint16_t ofs = vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n);
+      if (ofs != PSD_OFS_DISABLED || vcdplayer->show_rejected) {
         memset(&mrl, 0, sizeof (mrl));
         snprintf(mrl, sizeof(mrl), "%s%s@P%u%s", MRL_PREFIX, vcd_device, n+1, 
                 ofs == PSD_OFS_DISABLED ? "*" : "");
@@ -377,10 +384,10 @@
 
   /* Record MRL's for segments */
   {
-    segnum_t i_segments = player->i_segments;
+    segnum_t i_segments = vcdplayer->i_segments;
     for (n=0; n<i_segments; n++) {
       vcdinfo_video_segment_type_t segtype 
-        = vcdinfo_get_video_type(obj, n);
+        = vcdinfo_get_video_type(p_vcdinfo, n);
       char c='S';
       switch (segtype) {
         {
@@ -400,7 +407,7 @@
 
       memset(&mrl, 0, sizeof (mrl));
       snprintf(mrl, sizeof(mrl), "%s%s@%c%u", MRL_PREFIX, vcd_device, c, n);
-      vcd_add_mrl_slot(class, mrl, player->segment[n].size, &i);
+      vcd_add_mrl_slot(class, mrl, vcdplayer->segment[n].size, &i);
     }
   }
   
@@ -560,11 +567,7 @@
   uint32_t ret = 
     INPUT_CAP_AUDIOLANG | INPUT_CAP_BLOCK     | 
     INPUT_CAP_CHAPTERS  | INPUT_CAP_PREVIEW   |
-#if 0
-    (my_vcd.player.in_still ? 0: INPUT_CAP_SEEKABLE) |
-#else
-    INPUT_CAP_SEEKABLE |
-#endif
+    (my_vcd.player.i_still ? 0: INPUT_CAP_SEEKABLE) |
     INPUT_CAP_SPULANG;
 
   dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "returning %d\n", ret);
@@ -607,18 +610,22 @@
   return (off_t) 1;
 }
 
-/* This code needs to be replaced with better code */
-#ifndef STILL_FIXED
-#define SLEEP_1_SEC_AND_HANDLE_EVENTS              \
-  if (vcd_handle_events()) goto read;              \
-  xine_usec_sleep(250000);                         \
-  if (vcd_handle_events()) goto read;              \
-  xine_usec_sleep(250000);                         \
-  if (vcd_handle_events()) goto read;              \
-  xine_usec_sleep(250000);                         \
-  if (vcd_handle_events()) goto read;              \
-  xine_usec_sleep(250000);
-#endif
+/* Allocate and return a no-op buffer. This signals the outside
+   to do nothing, but in contrast to returning NULL, it doesn't 
+   mean the stream has ended. We use this say for still frames.
+ */
+#define RETURN_NOOP_BUF                                    \
+  p_buf = fifo->buffer_pool_alloc (fifo);                  \
+  p_buf->type = BUF_CONTROL_NOP;                           \
+  return p_buf
+
+/* Handle keyboard events and if there were non which might affect
+   playback, then sleep a little bit and return;
+ */
+#define SLEEP_AND_HANDLE_EVENTS                          \
+  xine_usec_sleep(50000);                                \
+  if (vcd_handle_events()) goto read_block;              \
+  RETURN_NOOP_BUF
 
 /*!
   From xine plugin spec:
@@ -632,6 +639,7 @@
 vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, 
                        const off_t nlen) 
 {
+  vcd_input_plugin_t *vcd_input_plugin= (vcd_input_plugin_t *) this_gen;
   vcdplayer_t   *p_vcdplayer = &my_vcd.player;
   buf_element_t *p_buf;
   uint8_t        data[M2F2_SECTOR_SIZE] = {0};
@@ -646,20 +654,25 @@
   /* Should we change this to <= instead of !=? */
   if (nlen != M2F2_SECTOR_SIZE) return NULL;
 
-#ifndef STILL_FIXED
-  vcd_handle_events();
-  if (0 != p_vcdplayer->in_still && p_vcdplayer->in_still != -5) {
-    dbg_print(INPUT_DBG_STILL, "Handled still event\n");
-    p_buf = fifo->buffer_pool_alloc (fifo);
-    SLEEP_1_SEC_AND_HANDLE_EVENTS;
-    if (p_vcdplayer->in_still > 0) p_vcdplayer->in_still--;
-    p_buf = fifo->buffer_pool_alloc (fifo);
-    p_buf->type = BUF_CONTROL_NOP;
-    return p_buf;
+  if (vcd_handle_events()) goto read_block;
+
+  if (p_vcdplayer->i_still > 0) {
+    if ( time(NULL) >= vcd_input_plugin->pause_end_time ) {
+      if (STILL_INDEFINITE_WAIT == p_vcdplayer->i_still) {
+        dbg_print(INPUT_DBG_STILL, "Continuing still indefinite wait time\n");
+        vcd_input_plugin->pause_end_time = time(NULL) + p_vcdplayer->i_still;
+        SLEEP_AND_HANDLE_EVENTS;
+      } else {
+        dbg_print(INPUT_DBG_STILL, "Still time ended\n");
+        p_vcdplayer->i_still = 0;
+      }
+    } else {
+      SLEEP_AND_HANDLE_EVENTS;
+    }
   }
-#endif
+  
 
- read:
+ read_block:
   switch (vcdplayer_read(p_vcdplayer, data, nlen)) {
   case READ_END:
     /* End reached. Return NULL to indicated this. */
@@ -669,26 +682,10 @@
     return NULL;
   case READ_STILL_FRAME: 
     {
-      /* We have reached the *end* of reading an entire still frame.
-         The wait time is given in data[0] and also p_vcdplayer->in_still
-         has been set to the wait time.
-       */
-#ifndef STILL_FIXED
-      dbg_print(INPUT_DBG_STILL, "Handled still event\n");
-      p_buf = fifo->buffer_pool_alloc (fifo);
-      SLEEP_1_SEC_AND_HANDLE_EVENTS;
-      if (data[0] > 0 && p_vcdplayer->in_still > 0) {
-        p_vcdplayer->in_still--;
-      }
-      p_buf = fifo->buffer_pool_alloc (fifo);
-      p_buf->type = BUF_CONTROL_NOP;
-      return p_buf;
-#endif
-  
-      dbg_print(INPUT_DBG_STILL, "Handled still event\n");
-      p_buf = fifo->buffer_pool_alloc (fifo);
-      p_buf->type = BUF_CONTROL_NOP;
-      break;
+      dbg_print(INPUT_DBG_STILL, "Handled still event wait time %u\n",
+                p_vcdplayer->i_still);
+      vcd_input_plugin->pause_end_time = time(NULL) + p_vcdplayer->i_still;
+      RETURN_NOOP_BUF;
     }
     
   default:
@@ -700,6 +697,20 @@
   
   p_buf->content = p_buf->mem;
 
+  if (STILL_READING == p_vcdplayer->i_still && 0 == my_vcd.i_old_still) {
+    my_vcd.i_old_deinterlace = xine_get_param(my_vcd.stream, 
+                                              XINE_PARAM_VO_DEINTERLACE);
+    xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE, 0);
+    dbg_print(INPUT_DBG_STILL, "going into still, saving deinterlace %d\n", 
+              my_vcd.i_old_deinterlace);
+  } else if (0 == p_vcdplayer->i_still && 0 != my_vcd.i_old_still) {
+    dbg_print(INPUT_DBG_STILL, 
+              "going out of still, restoring deinterlace\n");
+    xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE,
+                   my_vcd.i_old_deinterlace);
+  }
+  my_vcd.i_old_still = p_vcdplayer->i_still;
+  
   /* Ideally this should probably be nlen.  */
   memcpy (p_buf->mem, data, M2F2_SECTOR_SIZE);
 
@@ -737,27 +748,27 @@
 vcd_plugin_get_length (input_plugin_t *this_gen) {
 
   vcd_input_plugin_t *ip= (vcd_input_plugin_t *) this_gen;
-  vcdplayer_t  *this = &(ip->player);
+  vcdplayer_t        *vcdplayer = &(ip->player);
 
-  int n = this->play_item.num;
+  int n = vcdplayer->play_item.num;
 
-  if (this->play_item.num == old_play_item.num
-      && this->play_item.type == old_play_item.type 
-      && this->slider_length == old_slider_length)
+  if (vcdplayer->play_item.num == old_play_item.num
+      && vcdplayer->play_item.type == old_play_item.type 
+      && vcdplayer->slider_length == old_slider_length)
     return old_get_length;
 
-  old_slider_length = this->slider_length;
-  old_play_item     = this->play_item;
+  old_slider_length = vcdplayer->slider_length;
+  old_play_item     = vcdplayer->play_item;
 
-  switch (this->play_item.type) {
+  switch (vcdplayer->play_item.type) {
   case VCDINFO_ITEM_TYPE_ENTRY:
-    switch (this->slider_length) {
+    switch (vcdplayer->slider_length) {
     case VCDPLAYER_SLIDER_LENGTH_AUTO:
     case VCDPLAYER_SLIDER_LENGTH_ENTRY:
       n += ip->class->mrl_entry_offset;
       break;
     case VCDPLAYER_SLIDER_LENGTH_TRACK:
-      n = vcdinfo_get_track(this->vcd, n) + ip->class->mrl_track_offset;
+      n = vcdinfo_get_track(vcdplayer->vcd, n) + ip->class->mrl_track_offset;
       break;
     default:
       /* FIXME? */
@@ -774,7 +785,7 @@
     /* This is the only situation where the size of the current play item
        is not static. It depends what the current play-item is.
      */
-    old_get_length = (this->end_lsn - this->origin_lsn) * 
+    old_get_length = (vcdplayer->end_lsn - vcdplayer->origin_lsn) * 
       M2F2_SECTOR_SIZE;
     return old_get_length;
     break;
@@ -788,7 +799,7 @@
   if (n >= 0 && n < ip->class->num_mrls) {
     old_get_length = ip->class->mrls[n]->size;
     dbg_print(INPUT_DBG_MRL, "item: %u, slot %u, size %ld\n", 
-              this->play_item.num, 
+              vcdplayer->play_item.num, 
               (unsigned int) n,  (long int) old_get_length);
   }
   return old_get_length;
@@ -833,7 +844,7 @@
   vcdinfo_itemid_t itemid;
 
   vcd_input_class_t *class = (vcd_input_class_t *) this_gen;
-  vcdplayer_t       *player = &my_vcd.player;
+  vcdplayer_t       *vcdplayer= &my_vcd.player;
 
   bool used_default;
 
@@ -842,7 +853,7 @@
               "called with NULL\n");
     if ( class->mrls != NULL && NULL != class->mrls[0] ) goto have_mrls;
 
-    if ( !vcd_build_mrl_list(class, player->psz_source) ) {
+    if ( !vcd_build_mrl_list(class, vcdplayer->psz_source) ) {
       goto no_mrls;
     }
   } else {
@@ -852,7 +863,7 @@
     if (!vcd_get_default_device(class, true)) goto no_mrls;
     if (!vcd_parse_mrl(class->vcd_device, mrl, 
                        intended_vcd_device, &itemid, 
-                       player->default_autoplay, &used_default)) { 
+                       vcdplayer->default_autoplay, &used_default)) { 
       free (mrl);
       goto no_mrls;
     }
@@ -908,24 +919,24 @@
 static char * 
 vcd_plugin_get_mrl (input_plugin_t *this_gen) 
 {
-  vcd_input_plugin_t *t    = (vcd_input_plugin_t *) this_gen;
-  vcdplayer_t        *this = &my_vcd.player;
+  vcd_input_plugin_t *t         = (vcd_input_plugin_t *) this_gen;
+  vcdplayer_t        *vcdplayer = &my_vcd.player;
   unsigned int n;
   int size; /* need something to feed get_mrl_type_offset */
   int offset;
 
-  if (vcdplayer_pbc_is_on(this)) {
-    n = this->i_lid;
+  if (vcdplayer_pbc_is_on(vcdplayer)) {
+    n = vcdplayer->i_lid;
     offset = vcd_get_mrl_type_offset(t, VCDINFO_ITEM_TYPE_LID, &size);
   } else {
-    n = this->play_item.num;
-    offset = vcd_get_mrl_type_offset(t, this->play_item.type, &size);
+    n = vcdplayer->play_item.num;
+    offset = vcd_get_mrl_type_offset(t, vcdplayer->play_item.type, &size);
   }
 
   if (-2 == offset) {
     /* Bad type. */
     LOG_ERR("%s %d", _("Invalid current entry type"), 
-                  this->play_item.type);
+                  vcdplayer->play_item.type);
     return strdup("");
   } else {
     n += offset;
@@ -1187,12 +1198,12 @@
       if (-1 == channel) {
         sprintf(data, " %s", "auto");
       } else {
-        const vcdinfo_obj_t *obj= my_vcd.player.vcd;
+        const vcdinfo_obj_t *p_vcdinfo= my_vcd.player.vcd;
         unsigned int audio_type;
         unsigned int num_channels;
         unsigned int track_num = my_vcd.player.i_track;
-        audio_type = vcdinfo_get_track_audio_type(obj, track_num);
-        num_channels = vcdinfo_audio_type_num_channels(obj, audio_type);
+        audio_type = vcdinfo_get_track_audio_type(p_vcdinfo, track_num);
+        num_channels = vcdinfo_audio_type_num_channels(p_vcdinfo, audio_type);
 
         if (channel >= num_channels) {
           sprintf(data, "%d ERR", channel);
@@ -1420,7 +1431,7 @@
                    vcdplayer_format_str(&my_vcd.player, 
                                         my_vcd.v_config.comment_format));
   stream_info_assign(XINE_STREAM_INFO_VIDEO_HAS_STILL, my_vcd.stream, 
-                     my_vcd.player.in_still);
+                     my_vcd.player.i_still);
 
   /* Set_str title/chapter display */
   dbg_print((INPUT_DBG_MRL|INPUT_DBG_CALL),
@@ -1437,7 +1448,7 @@
 }
 
 /* 
-   No special initialization needed here. All of the initialization 
+   Not much special initialization needed here. All of the initialization 
    is either done in the class or when we have an actual MRL we want
    to deal with.
 */
@@ -1450,7 +1461,8 @@
 
   /* actually, this is also done by class initialization. But just in 
      case... */
-  class->ip                  = &my_vcd; 
+  class->ip          = &my_vcd; 
+  my_vcd.i_old_still = 0;
 
   return 1;
 }
@@ -1653,6 +1665,7 @@
   my_vcd.player.next_entry             = -1;
   my_vcd.player.prev_entry             = -1;
   my_vcd.player.return_entry           = -1;
+  my_vcd.player.default_entry          = -1;
   
   /*--------------------------------------------------------------
     Configuration variables



-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
_______________________________________________
Xine-cvslog mailing list
Xine-cvslog@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xine-cvslog


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic