diff options
-rw-r--r-- | src/input/vcd/vcdplayer.c | 12 | ||||
-rw-r--r-- | src/input/vcd/vcdplayer.h | 18 | ||||
-rw-r--r-- | src/input/vcd/xineplug_inp_vcd.c | 60 |
3 files changed, 58 insertions, 32 deletions
diff --git a/src/input/vcd/vcdplayer.c b/src/input/vcd/vcdplayer.c index 2d2659600..7a0c220b0 100644 --- a/src/input/vcd/vcdplayer.c +++ b/src/input/vcd/vcdplayer.c @@ -1,5 +1,5 @@ /* - $Id: vcdplayer.c,v 1.13 2005/01/02 13:51:01 rockyb Exp $ + $Id: vcdplayer.c,v 1.14 2005/01/08 11:59:27 rockyb Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> @@ -733,6 +733,10 @@ vcdplayer_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *p_buf) if (_vcdplayer_inc_play_item(p_vcdplayer)) goto skip_next_play; + /* 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; @@ -875,8 +879,6 @@ vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, const off_t nlen) { - p_vcdplayer->handle_events (); - if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) { vcdplayer_read_status_t read_status; @@ -890,6 +892,10 @@ vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, ? 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->i_still; + return READ_STILL_FRAME; + } if (READ_BLOCK != read_status) return read_status; } diff --git a/src/input/vcd/vcdplayer.h b/src/input/vcd/vcdplayer.h index d2f40a3ea..67b0c95fd 100644 --- a/src/input/vcd/vcdplayer.h +++ b/src/input/vcd/vcdplayer.h @@ -1,7 +1,7 @@ /* - $Id: vcdplayer.h,v 1.6 2005/01/01 02:43:57 rockyb Exp $ + $Id: vcdplayer.h,v 1.7 2005/01/08 11:59:27 rockyb Exp $ - 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 @@ -97,8 +97,12 @@ typedef struct { typedef int (*generic_fn)(); -/* Value for indefinite wait period on a still frame */ -#define STILL_INDEFINITE_WAIT 255 +/* 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 @@ -126,15 +130,9 @@ typedef struct vcdplayer_input_s { /* Function to flush any audio or video buffers */ void (*flush_buffers) (void); - /* Function to flush sleep for a number of milliseconds. */ - void (*sleep) (unsigned int usecs); - /* Function to force a redisplay. */ void (*force_redisplay) (void); - /* Function to handle player events. Returns true if play item changed. */ - bool (*handle_events) (void); - /* Function to update title of selection. */ void (*update_title) (); diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c index e32c4dc20..023632930 100644 --- a/src/input/vcd/xineplug_inp_vcd.c +++ b/src/input/vcd/xineplug_inp_vcd.c @@ -1,5 +1,5 @@ /* - $Id: xineplug_inp_vcd.c,v 1.31 2005/01/02 13:51:01 rockyb Exp $ + $Id: xineplug_inp_vcd.c,v 1.32 2005/01/08 11:59:27 rockyb Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> @@ -619,15 +619,22 @@ vcd_plugin_read (input_plugin_t *this_gen, char *buf, const off_t nlen) return (off_t) 1; } -#define SLEEP_1_SEC_AND_HANDLE_EVENTS \ - if (p_vcdplayer->handle_events()) goto read_block; \ - p_vcdplayer->sleep(250000); \ - if (p_vcdplayer->handle_events()) goto read_block; \ - p_vcdplayer->sleep(250000); \ - if (p_vcdplayer->handle_events()) goto read_block; \ - p_vcdplayer->sleep(250000); \ - if (p_vcdplayer->handle_events()) goto read_block; \ - p_vcdplayer->sleep(250000); +/* 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 \ + buf = fifo->buffer_pool_alloc (fifo); \ + buf->type = BUF_CONTROL_NOP; \ + return 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: @@ -641,6 +648,7 @@ static buf_element_t * 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 *buf; uint8_t data[M2F2_SECTOR_SIZE]; @@ -655,7 +663,23 @@ vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, /* Should we change this to <= instead of !=? */ if (nlen != M2F2_SECTOR_SIZE) return NULL; - if (p_vcdplayer->i_still > 0) goto read_still; + 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; + } + } + read_block: switch (vcdplayer_read(p_vcdplayer, data, nlen)) { @@ -665,15 +689,15 @@ vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, case READ_ERROR: /* Some sort of error. */ return NULL; +#if INACCURATE_STILL_TIME read_still: +#endif /* INACCURATE_STILL_TIME */ case READ_STILL_FRAME: { - p_vcdplayer->i_still--; - SLEEP_1_SEC_AND_HANDLE_EVENTS ; - dbg_print(INPUT_DBG_STILL, "Handled still event\n"); - buf = fifo->buffer_pool_alloc (fifo); - 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: @@ -1637,9 +1661,7 @@ vcd_init (xine_t *xine, void *data) my_vcd.player.update_title = &vcd_update_title; my_vcd.player.log_err = (generic_fn) &xine_log_err; my_vcd.player.log_msg = (generic_fn) &xine_log_msg; - my_vcd.player.sleep = &xine_usec_sleep; my_vcd.player.force_redisplay = &vcd_force_redisplay; - my_vcd.player.handle_events = &vcd_handle_events; /*------------------------------------------------------------- Playback control-specific fields |