diff options
author | Reinhard Nißl <rnissl@gmx.de> | 2008-03-02 21:12:01 +0100 |
---|---|---|
committer | Reinhard Nißl <rnissl@gmx.de> | 2008-03-02 21:12:01 +0100 |
commit | a33991c82965b1cf40c175b7bc9d13488e14cae6 (patch) | |
tree | f5fac4e5bf8c2080f47ced0e3f8686ad39b72d63 | |
parent | e32eab57b9c6d869cdfa41b988e76184f2c5e41b (diff) | |
download | xine-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.h | 3 | ||||
-rw-r--r-- | src/vdr/input_vdr.c | 63 |
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; |