From 9ef1fab0025505f09e135789f4bec80b48850c84 Mon Sep 17 00:00:00 2001 From: Christopher Martin Date: Wed, 5 Aug 2009 19:15:49 +0100 Subject: Fix reading of CDDB information (ref. cset a470c338149c) This fixes the reading of CDDB information by not setting INPUT_CAP_BLOCK for the CDDA plugin (and therefore also setting CD_RAW_FRAME_SIZE to 0), and allow reading in non-block sized chunks as per http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=a470c338149c;style=gitweb Explanation: At some point a number of releases ago, a codepath in Xine related to the reading of block devices which had been bypassed was fixed, which meant that when certain frontends asked Xine to provide CDDB information for a disc, querying the name, length, etc. of each track, Xine would actually cause a seek to the starting block of each track, which meant that before starting to play, the player would pause for 5-10 seconds, seeking through each track. This is unnecessary, since Xine should have simply used the CD TOC information from the CD audio header at the start of the disc. Other frontends handle CDDB differently and don't query Xine for information track by track, and so never triggered this problem. But for those with the problem, it made loading a disc rather slow. It turns out that the root of the problem is that the CDDA plugin shouldn't be setting INPUT_CAP_BLOCK, since Audio CDs are not block devices _in the sense that Xine intends_. Simply turning this off fixes the problem, with no other side effects (tested locally, for some time now, on xine-ui, kscd, kaffeine, amarok, etc.). This change pairs nicely with a patch originally committed years ago (cset a470c338149c) but which was reverted as it inadvertently triggered the same problem as is now (properly) fixed by the simple above-mentioned change. Now that a better fix is in, it can be re-committed. --- src/input/input_cdda.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index 33ba0b299..70bd34f35 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -2158,26 +2158,18 @@ static int cdda_close(cdda_input_plugin_t *this_gen) { static uint32_t cdda_plugin_get_capabilities (input_plugin_t *this_gen) { - return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK; + return INPUT_CAP_SEEKABLE; } static off_t cdda_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { - /* only allow reading in block-sized chunks */ - - return 0; -} - -static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, - off_t nlen) { - cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; - buf_element_t *buf; - unsigned char frame_data[CD_RAW_FRAME_SIZE]; int err = 0; - if (nlen != CD_RAW_FRAME_SIZE) + /* only allow reading in block-sized chunks */ + + if (len != CD_RAW_FRAME_SIZE) return 0; if (this->current_frame > this->last_frame) @@ -2211,14 +2203,26 @@ static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buf if( err < 0 ) return 0; - memcpy(frame_data, this->cache[this->current_frame-this->cache_first], CD_RAW_FRAME_SIZE); + memcpy(buf, this->cache[this->current_frame-this->cache_first], CD_RAW_FRAME_SIZE); this->current_frame++; + return CD_RAW_FRAME_SIZE; +} + +static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, + off_t nlen) { + + buf_element_t *buf; + buf = fifo->buffer_pool_alloc(fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; - buf->size = CD_RAW_FRAME_SIZE; - memcpy(buf->mem, frame_data, CD_RAW_FRAME_SIZE); + + buf->size = cdda_plugin_read(this_gen, buf->content, nlen); + if (buf->size == 0) { + buf->free_buffer(buf); + buf = NULL; + } return buf; } @@ -2256,7 +2260,7 @@ static off_t cdda_plugin_get_length (input_plugin_t *this_gen) { static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) { - return CD_RAW_FRAME_SIZE; + return 0; } static const char* cdda_plugin_get_mrl (input_plugin_t *this_gen) { -- cgit v1.2.3