summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhard Nißl <rnissl@gmx.de>2008-03-02 21:12:01 +0100
committerReinhard Nißl <rnissl@gmx.de>2008-03-02 21:12:01 +0100
commita33991c82965b1cf40c175b7bc9d13488e14cae6 (patch)
treef5fac4e5bf8c2080f47ced0e3f8686ad39b72d63
parente32eab57b9c6d869cdfa41b988e76184f2c5e41b (diff)
downloadxine-lib-a33991c82965b1cf40c175b7bc9d13488e14cae6.tar.gz
xine-lib-a33991c82965b1cf40c175b7bc9d13488e14cae6.tar.bz2
Fix "clear" implementation by introducing sync points in data stream.vdr-xine-version-802
vdr-xine used a padding packet to push out any remaining data before input_vdr executed "clear" to drop that data. But depending on the way how input_vdr is connected to vdr-xine it could happen that the padding packet reached input_vdr after executing "clear" and therefore "clear" didn't work as expected. To fix this issue, sync points are introduced by making the padding packets "unique" in the stream. input_vdr will now drop all data up to the sync point packet. So even if the padding packet arrives later than the "clear" command, only data following the sync point will be fed to the demuxer. --HG-- extra : transplant_source : %A1%5E%8C%E1vmW%98D%1EW%A7%AF%B4V%5D%84%26%D0%DA
-rw-r--r--include/xine/vdr.h3
-rw-r--r--src/vdr/input_vdr.c63
2 files changed, 62 insertions, 4 deletions
diff --git a/include/xine/vdr.h b/include/xine/vdr.h
index 5102d7f77..a2a3e800f 100644
--- a/include/xine/vdr.h
+++ b/include/xine/vdr.h
@@ -22,7 +22,7 @@
#define __VDR_H
-#define XINE_VDR_VERSION 801
+#define XINE_VDR_VERSION 802
enum funcs
@@ -270,6 +270,7 @@ typedef struct __attribute__((packed)) data_clear_s
int32_t n;
int8_t s;
+ uint8_t i;
}
data_clear_t;
diff --git a/src/vdr/input_vdr.c b/src/vdr/input_vdr.c
index 863a2cc45..32cef6395 100644
--- a/src/vdr/input_vdr.c
+++ b/src/vdr/input_vdr.c
@@ -111,6 +111,8 @@ typedef struct
uint16_t image16_9_zoom_x;
uint16_t image16_9_zoom_y;
+ uint8_t find_sync_point;
+ pthread_mutex_t find_sync_point_lock;
}
vdr_input_plugin_t;
@@ -581,7 +583,13 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
int orig_speed = xine_get_param(this->stream, XINE_PARAM_FINE_SPEED);
if (orig_speed <= 0)
xine_set_param(this->stream, XINE_PARAM_FINE_SPEED, XINE_FINE_SPEED_NORMAL);
-fprintf(stderr, "+++ CLEAR(%d%c)\n", data->n, data->s ? 'b' : 'a');
+fprintf(stderr, "+++ CLEAR(%d%c): sync point: %02x\n", data->n, data->s ? 'b' : 'a', data->i);
+ if (!data->s)
+ {
+ pthread_mutex_lock(&this->find_sync_point_lock);
+ this->find_sync_point = data->i;
+ pthread_mutex_unlock(&this->find_sync_point_lock);
+ }
/*
if (!this->dont_change_xine_volume)
xine_set_param(this->stream, XINE_PARAM_AUDIO_VOLUME, 0);
@@ -1311,7 +1319,7 @@ static off_t vdr_plugin_read(input_plugin_t *this_gen,
void *buf_gen, off_t len)
{
vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen;
- char *buf = (char *)buf_gen;
+ uint8_t *buf = (uint8_t *)buf_gen;
off_t n, total;
#ifdef LOG_READ
lprintf ("reading %lld bytes...\n", len);
@@ -1336,7 +1344,7 @@ static off_t vdr_plugin_read(input_plugin_t *this_gen,
int retries = 0;
do
{
- n = vdr_read_abort (this->stream, this->fh, &buf[total], len-total);
+ n = vdr_read_abort (this->stream, this->fh, (char *)&buf[total], len-total);
if (0 == n)
lprintf("read 0, retries: %d\n", retries);
}
@@ -1357,6 +1365,53 @@ static off_t vdr_plugin_read(input_plugin_t *this_gen,
this->curpos += n;
total += n;
}
+
+ if (this->find_sync_point
+ && total == 6)
+ {
+ pthread_mutex_lock(&this->find_sync_point_lock);
+
+ while (this->find_sync_point
+ && total == 6
+ && buf[0] == 0x00
+ && buf[1] == 0x00
+ && buf[2] == 0x01)
+ {
+ int l, sp;
+
+ if (buf[3] == 0xbe
+ && buf[4] == 0xff)
+ {
+//fprintf(stderr, "------- seen sync point: %02x, waiting for: %02x\n", buf[5], this->find_sync_point);
+ if (buf[5] == this->find_sync_point)
+ {
+ this->find_sync_point = 0;
+ break;
+ }
+ }
+
+ if ((buf[3] & 0xf0) != 0xe0
+ && (buf[3] & 0xe0) != 0xc0
+ && buf[3] != 0xbd
+ && buf[3] != 0xbe)
+ {
+ break;
+ }
+
+ l = buf[4] * 256 + buf[5];
+ if (l <= 0)
+ break;
+
+ sp = this->find_sync_point;
+ this->find_sync_point = 0;
+ this_gen->seek(this_gen, l, SEEK_CUR);
+ total = this_gen->read(this_gen, buf, 6);
+ this->find_sync_point = sp;
+ }
+
+ pthread_mutex_unlock(&this->find_sync_point_lock);
+ }
+
return total;
}
@@ -1512,6 +1567,7 @@ static void vdr_plugin_dispose(input_plugin_t *this_gen)
pthread_cond_destroy(&this->rpc_thread_shutdown_cond);
pthread_mutex_destroy(&this->rpc_thread_shutdown_lock);
+ pthread_mutex_destroy(&this->find_sync_point_lock);
pthread_mutex_destroy(&this->adjust_zoom_lock);
if (this->fh_result != -1)
@@ -2017,6 +2073,7 @@ static input_plugin_t *vdr_class_get_instance(input_class_t *cls_gen, xine_strea
pthread_mutex_init(&this->rpc_thread_shutdown_lock, 0);
pthread_cond_init(&this->rpc_thread_shutdown_cond, 0);
+ pthread_mutex_init(&this->find_sync_point_lock, 0);
pthread_mutex_init(&this->adjust_zoom_lock, 0);
this->image4_3_zoom_x = 0;
this->image4_3_zoom_y = 0;