summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input/vcd/vcdplayer.c12
-rw-r--r--src/input/vcd/vcdplayer.h18
-rw-r--r--src/input/vcd/xineplug_inp_vcd.c60
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