From 38bb6ceabb38fd8dbcac974be9a1aa3a1a74c4fe Mon Sep 17 00:00:00 2001 From: Kelvie Wong Date: Fri, 11 Dec 2009 19:28:39 -0800 Subject: TTA demux: don't read past the last frame. I don't think whoever wrote this played a TTA file all the way to the end. --- src/demuxers/demux_tta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index d5217477d..ebb51b100 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -115,7 +115,7 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; uint32_t bytes_to_read; - if ( this->currentframe > this->totalframes ) { + if ( this->currentframe >= this->totalframes ) { this->status = DEMUX_FINISHED; return this->status; } -- cgit v1.2.3 From 49e7fb6bf0115e2895bd2234eabb271b35a923a6 Mon Sep 17 00:00:00 2001 From: Kelvie Wong Date: Fri, 11 Dec 2009 19:28:37 -0800 Subject: TTA demux: fix buffer->extra_info->total_time Supposed to be in milliseconds; totalframes is only approx. total seconds. --- src/demuxers/demux_tta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index ebb51b100..1b50edcd4 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -130,7 +130,7 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) { buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_TTA; buf->pts = 0; - buf->extra_info->total_time = this->totalframes; + buf->extra_info->total_time = (int)(FRAME_TIME * this->totalframes)*1000; buf->decoder_flags = 0; /* Set normalised position */ -- cgit v1.2.3 From 55e59f17a96caf51cdad116e5990a79df75d2339 Mon Sep 17 00:00:00 2001 From: Kelvie Wong Date: Sun, 13 Dec 2009 03:28:16 -0800 Subject: TTA demux: Fix a buffer overflow It can be the case that the header is larger than buf->max_size (8 kilobytes), especially for slightly larger files. This sends them in parts so we don't overfill the buffer. --- src/demuxers/demux_tta.c | 58 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index 1b50edcd4..3158a9ed6 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -164,6 +164,12 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) { static void demux_tta_send_headers(demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; buf_element_t *buf; + xine_waveformatex wave; + uint32_t total_size = sizeof(xine_waveformatex) + sizeof(this->header) + + sizeof(uint32_t)*this->totalframes; + unsigned char *header; + + header = malloc(total_size); this->audio_fifo = this->stream->audio_fifo; @@ -181,27 +187,43 @@ static void demux_tta_send_headers(demux_plugin_t *this_gen) { /* send start buffers */ _x_demux_control_start(this->stream); - /* send init info to decoders */ - if (this->audio_fifo) { - xine_waveformatex wave; - - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_TTA; - buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; - buf->decoder_info[0] = 0; - buf->decoder_info[1] = le2me_32(this->header.tta.samplerate); - buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample); - buf->decoder_info[3] = le2me_16(this->header.tta.channels); + /* create header */ + wave.cbSize = total_size - sizeof(xine_waveformatex); - buf->size = sizeof(xine_waveformatex) + sizeof(this->header) + sizeof(uint32_t)*this->totalframes; - memcpy(buf->content+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header)); - memcpy(buf->content+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes); + memcpy(header, &wave, sizeof(wave)); + memcpy(header+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header)); + memcpy(header+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes); - wave.cbSize = buf->size - sizeof(xine_waveformatex); - memcpy(buf->content, &wave, sizeof(wave)); - - this->audio_fifo->put (this->audio_fifo, buf); + /* send init info to decoders */ + if (this->audio_fifo) { + uint32_t bytes_left = total_size; + + /* We are sending the seektable as well, and this may be larger than + buf->max_size */ + while (bytes_left) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER; + buf->type = BUF_AUDIO_TTA; + + /* Copy min(bytes_left, max_size) bytes */ + buf->size = bytes_left < buf->max_size ? bytes_left : buf->max_size; + memcpy(buf->content, header+(total_size-bytes_left), buf->size); + + bytes_left -= buf->size; + + /* The decoder information only needs the decoder information on the last + buffer element. */ + if (!bytes_left) { + buf->decoder_flags |= BUF_FLAG_FRAME_END; + buf->decoder_info[0] = 0; + buf->decoder_info[1] = le2me_32(this->header.tta.samplerate); + buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample); + buf->decoder_info[3] = le2me_16(this->header.tta.channels); + } + this->audio_fifo->put (this->audio_fifo, buf); + } } + free(header); } static int demux_tta_seek (demux_plugin_t *this_gen, -- cgit v1.2.3 From bf59cde213a99c76fd6d8740d1f819b45e2ae984 Mon Sep 17 00:00:00 2001 From: Kelvie Wong Date: Tue, 15 Dec 2009 20:49:16 -0800 Subject: TTA demux: Fix the calculation of the stream length. Its resolution was in frames (+/- ~1 second), now it is calculated from the number of samples, as it should be. --- src/demuxers/demux_tta.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index 3158a9ed6..7462cd874 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -64,7 +64,7 @@ typedef struct { uint16_t channels; uint16_t bits_per_sample; uint32_t samplerate; - uint32_t data_length; + uint32_t data_length; /* Number of samples */ uint32_t crc32; } XINE_PACKED tta; uint8_t buffer[22]; /* This is the size of the header */ @@ -130,7 +130,7 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) { buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_TTA; buf->pts = 0; - buf->extra_info->total_time = (int)(FRAME_TIME * this->totalframes)*1000; + buf->extra_info->total_time = (int)(le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate)); /* milliseconds */ buf->decoder_flags = 0; /* Set normalised position */ @@ -281,7 +281,7 @@ static int demux_tta_get_status (demux_plugin_t *this_gen) { static int demux_tta_get_stream_length (demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; - return (int)(FRAME_TIME * this->totalframes * 1000); + return le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate); /* milliseconds */ } static uint32_t demux_tta_get_capabilities(demux_plugin_t *this_gen) { -- cgit v1.2.3 From 682ea4a0a64795c864c992fa09f795df0ec8f3ec Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 4 Jan 2010 18:16:48 +0000 Subject: Minor cleanup. --- m4/video_out.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/m4/video_out.m4 b/m4/video_out.m4 index 6f8bedfba..2a0867b5f 100644 --- a/m4/video_out.m4 +++ b/m4/video_out.m4 @@ -515,4 +515,3 @@ AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [ AM_CONDITIONAL([ENABLE_VDPAU], test x"$have_vdpau" = x"yes") ])dnl XINE_VIDEO_OUT_PLUGIN -S -- cgit v1.2.3 From 0adb81a5aad4e763c08c0ac1771f8c234ca2ef94 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:38:22 +0200 Subject: Added some debug logging --- src/libxineadec/xine_lpcm_decoder.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index b7c0f8d1a..8280af89e 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -94,6 +94,8 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { unsigned int sample_rate = 0; unsigned int num_channels; + lprintf("lpcm_decoder: config data 0x%x\n", buf->decoder_info[2]); + num_channels = (buf->decoder_info[2] & 0x7) + 1; switch ((buf->decoder_info[2]>>4) & 3) { case 0: sample_rate = 48000; break; @@ -115,6 +117,10 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->number_of_channels = num_channels; this->rate = sample_rate; format_changed++; + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "lpcm_decoder: format changed to %d channels, %d bits per sample, %d Hz, %d kbit/s\n", + num_channels, bits_per_sample, sample_rate, (num_channels * sample_rate * bits_per_sample)/1024); } } -- cgit v1.2.3 From 87280324dd572b715a47bee75511ef60f687f4f9 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:38:51 +0200 Subject: Decode BluRay PCM header --- src/libxineadec/xine_lpcm_decoder.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 8280af89e..f1cf84480 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -96,6 +96,31 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { lprintf("lpcm_decoder: config data 0x%x\n", buf->decoder_info[2]); + /* BluRay PCM header is 4 bytes */ + if (buf->decoder_info[2] & 0xffffff00) { + static const uint8_t channels[16] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0}; + + num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f]; + switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { + case 1: bits_per_sample = 16; break; + case 2: bits_per_sample = 20; break; + case 3: bits_per_sample = 24; break; + default: bits_per_sample = 0; break; + } + switch ((buf->decoder_info[2] >> 16) & 0x0f) { + case 1: sample_rate = 48000; break; + case 4: sample_rate = 96000; break; + case 5: sample_rate = 192000; break; + default: sample_rate = 0; break; + } + + if (!num_channels || !sample_rate || !bits_per_sample) + xine_log (this->stream->xine, XINE_LOG_MSG, + "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]); + + } else { + + /* MPEG2/DVD PCM header is one byte */ num_channels = (buf->decoder_info[2] & 0x7) + 1; switch ((buf->decoder_info[2]>>4) & 3) { case 0: sample_rate = 48000; break; @@ -108,6 +133,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { case 1: bits_per_sample = 20; break; case 2: bits_per_sample = 24; break; } + } if( this->bits_per_sample != bits_per_sample || this->number_of_channels != num_channels || -- cgit v1.2.3 From 79f1a707976d40332b23dd1bb1d66fe8320066a6 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:39:56 +0200 Subject: Cosmetics --- src/libxineadec/xine_lpcm_decoder.c | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index f1cf84480..626329569 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -102,16 +102,16 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f]; switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { - case 1: bits_per_sample = 16; break; - case 2: bits_per_sample = 20; break; - case 3: bits_per_sample = 24; break; - default: bits_per_sample = 0; break; + case 1: bits_per_sample = 16; break; + case 2: bits_per_sample = 20; break; + case 3: bits_per_sample = 24; break; + default: bits_per_sample = 0; break; } switch ((buf->decoder_info[2] >> 16) & 0x0f) { - case 1: sample_rate = 48000; break; - case 4: sample_rate = 96000; break; - case 5: sample_rate = 192000; break; - default: sample_rate = 0; break; + case 1: sample_rate = 48000; break; + case 4: sample_rate = 96000; break; + case 5: sample_rate = 192000; break; + default: sample_rate = 0; break; } if (!num_channels || !sample_rate || !bits_per_sample) @@ -120,19 +120,19 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { } else { - /* MPEG2/DVD PCM header is one byte */ - num_channels = (buf->decoder_info[2] & 0x7) + 1; - switch ((buf->decoder_info[2]>>4) & 3) { - case 0: sample_rate = 48000; break; - case 1: sample_rate = 96000; break; - case 2: sample_rate = 44100; break; - case 3: sample_rate = 32000; break; - } - switch ((buf->decoder_info[2]>>6) & 3) { - case 0: bits_per_sample = 16; break; - case 1: bits_per_sample = 20; break; - case 2: bits_per_sample = 24; break; - } + /* MPEG2/DVD PCM header is one byte */ + num_channels = (buf->decoder_info[2] & 0x7) + 1; + switch ((buf->decoder_info[2]>>4) & 3) { + case 0: sample_rate = 48000; break; + case 1: sample_rate = 96000; break; + case 2: sample_rate = 44100; break; + case 3: sample_rate = 32000; break; + } + switch ((buf->decoder_info[2]>>6) & 3) { + case 0: bits_per_sample = 16; break; + case 1: bits_per_sample = 20; break; + case 2: bits_per_sample = 24; break; + } } if( this->bits_per_sample != bits_per_sample || @@ -152,8 +152,8 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if( buf->decoder_flags & BUF_FLAG_STDHEADER ) { this->rate=buf->decoder_info[1]; - this->bits_per_sample=buf->decoder_info[2] ; - this->number_of_channels=buf->decoder_info[3] ; + this->bits_per_sample=buf->decoder_info[2]; + this->number_of_channels=buf->decoder_info[3]; format_changed++; } -- cgit v1.2.3 From 864eaab92f7aa3c2dc9b59bfc0518a11d0141fc0 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:40:22 +0200 Subject: Use local variable for buffer size --- src/libxineadec/xine_lpcm_decoder.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 626329569..56d44c84d 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -79,6 +79,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; int16_t *sample_buffer=(int16_t *)buf->content; + int buf_size = buf->size; int stream_be; audio_buffer_t *audio_buffer; int format_changed = 0; @@ -195,14 +196,14 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if( this->bits_per_sample == 16 ){ if (stream_be != this->cpu_be) - swab (sample_buffer, audio_buffer->mem, buf->size); + swab (sample_buffer, audio_buffer->mem, buf_size); else - memcpy (audio_buffer->mem, sample_buffer, buf->size); + memcpy (audio_buffer->mem, sample_buffer, buf_size); } else if( this->bits_per_sample == 20 ) { uint8_t *s = (uint8_t *)sample_buffer; uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf->size; + int n = buf_size; if (stream_be != this->cpu_be) { while( n >= 0 ) { @@ -222,7 +223,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { } else if( this->bits_per_sample == 24 ) { uint8_t *s = (uint8_t *)sample_buffer; uint8_t *d = (uint8_t *)audio_buffer->mem; - int n = buf->size; + int n = buf_size; while (n >= 3) { if ( stream_be ) { @@ -249,15 +250,15 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { n -= 3; } - if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf->size ) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf->size - (d - (uint8_t*)audio_buffer->mem))/2*3); + if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size ) + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem))/2*3); } else { - memcpy (audio_buffer->mem, sample_buffer, buf->size); + memcpy (audio_buffer->mem, sample_buffer, buf_size); } audio_buffer->vpts = buf->pts; - audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample); + audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); -- cgit v1.2.3 From 84375d46d6d1203732f1c03454f6b8159e45abaf Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:40:52 +0200 Subject: Join multiple chunks before passing to audio out (data is lost if PCM frames are splitted in the middle) --- src/libxineadec/xine_lpcm_decoder.c | 51 +++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 56d44c84d..630d5a120 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -64,15 +64,26 @@ typedef struct lpcm_decoder_s { int output_open; int cpu_be; /* TRUE, if we're a Big endian CPU */ + + int64_t pts; + + uint8_t *buf; + size_t buffered_bytes; + size_t buf_size; + } lpcm_decoder_t; static void lpcm_reset (audio_decoder_t *this_gen) { - /* lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; */ + lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; + free (this->buf); + this->buf = NULL; } static void lpcm_discontinuity (audio_decoder_t *this_gen) { + + lpcm_reset(this_gen); } static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { @@ -119,6 +130,15 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]); + if (this->buffered_bytes) + xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: %zd bytes lost !\n", this->buffered_bytes); + + if (!this->buf) { + this->buffered_bytes = 0; + this->buf_size = 8128; + this->buf = malloc(this->buf_size); + } + } else { /* MPEG2/DVD PCM header is one byte */ @@ -188,6 +208,30 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) return; + if (buf->pts && !this->pts) + this->pts = buf->pts; + + /* data accumulation */ + if (this->buf) { + int frame_end = buf->decoder_flags & BUF_FLAG_FRAME_END; + if (this->buffered_bytes || !frame_end) { + if (this->buf_size < this->buffered_bytes + buf->size) { + this->buf_size *= 2; + this->buf = realloc(this->buf, this->buf_size); + } + + memcpy(this->buf + this->buffered_bytes, buf->content, buf->size); + this->buffered_bytes += buf->size; + + if (!frame_end) + return; + + sample_buffer = (int16_t*)this->buf; + buf_size = this->buffered_bytes; + this->buffered_bytes = 0; + } + } + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); /* Swap LPCM samples into native byte order, if necessary */ @@ -257,11 +301,12 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { memcpy (audio_buffer->mem, sample_buffer, buf_size); } - audio_buffer->vpts = buf->pts; + audio_buffer->vpts = this->pts; audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + this->pts = 0; } static void lpcm_dispose (audio_decoder_t *this_gen) { @@ -271,6 +316,8 @@ static void lpcm_dispose (audio_decoder_t *this_gen) { this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; + free (this->buf); + free (this_gen); } -- cgit v1.2.3 From f717a1a9d3191948f79e6f67a76f8010671dc992 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Wed, 6 Jan 2010 14:44:22 +0200 Subject: Demux BluRay PCM audio --- src/demuxers/demux_ts.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index cedcbb4a1..6844f6a01 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -821,6 +821,18 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->type |= BUF_AUDIO_DTS; return 1; + } else if (m->descriptor_tag == HDMV_AUDIO_80_PCM) { + + m->content = p + 4; + m->size = packet_len - 4; + m->type |= BUF_AUDIO_LPCM_BE; + + m->buf->decoder_flags |= BUF_FLAG_SPECIAL; + m->buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; + m->buf->decoder_info[2] = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0]; + + return 1; + } else if (m->descriptor_tag == ISO_13818_PES_PRIVATE && p[0] == 0x20 && p[1] == 0x00) { /* DVBSUB */ @@ -1539,7 +1551,10 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num demux_ts_get_reg_desc(this, &format_identifier, stream + 5, stream_info_length); /* If no format identifier, assume A52 */ - if ((format_identifier == 0x41432d33) || (format_identifier == 0)) { + if (( format_identifier == 0x41432d33) || + ( format_identifier == 0) || + ((format_identifier == 0x48444d56 || this->hdmv>0) && stream[0] == HDMV_AUDIO_80_PCM) /* BluRay PCM */) { + demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]); this->audio_tracks[this->audio_tracks_count].pid = pid; this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; -- cgit v1.2.3 From 9a472d6a7f6f24dce5ff9a66aeed99662359ad4e Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 6 Jan 2010 21:15:59 +0000 Subject: Update to libxdg-basedir 1.0.2; adapt accordingly, and default to external. --- configure.ac | 8 +- contrib/libxdg-basedir/Makefile.am | 2 +- contrib/libxdg-basedir/basedir.c | 251 ++++++++++++++++++++++++------------ contrib/libxdg-basedir/basedir.h | 146 +++++++-------------- contrib/libxdg-basedir/basedir_fs.h | 100 ++++++++++++++ include/xine/xine_internal.h | 9 +- src/input/input_cdda.c | 4 +- src/input/input_dvb.c | 2 +- src/libw32dll/wine/registry.c | 7 +- src/xine-engine/load_plugins.c | 2 +- src/xine-engine/osd.c | 4 +- src/xine-engine/xine.c | 4 +- 12 files changed, 338 insertions(+), 201 deletions(-) create mode 100644 contrib/libxdg-basedir/basedir_fs.h diff --git a/configure.ac b/configure.ac index 181fd8dd5..615f2c04c 100644 --- a/configure.ac +++ b/configure.ac @@ -239,10 +239,10 @@ AC_CHECK_LIB([c], [dlopen], [DYNAMIC_LD_LIBS=""], AC_SUBST([DYNAMIC_LD_LIBS]) AC_ARG_WITH([external-libxdg-basedir], - [AS_HELP_STRING([--with-external-libxdg-basedir], [use external copy of libxdg-basedir])]) + [AS_HELP_STRING([--without-external-libxdg-basedir], [use internal copy of libxdg-basedir])]) -if test x"$with_external_libxdg_basedir" = x"yes"; then - PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 0.1.3]) +if test x"$with_external_libxdg_basedir" != x"no"; then + PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 1]) XDG_BASEDIR_REQUIRES="libxdg-basedir" else XDG_BASEDIR_CPPFLAGS='-I$(top_srcdir)/contrib/libxdg-basedir' @@ -255,7 +255,7 @@ AC_SUBST([XDG_BASEDIR_CPPFLAGS]) AC_SUBST([XDG_BASEDIR_LIBS]) AC_SUBST([XDG_BASEDIR_DEPS]) -AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$with_external_libxdg_basedir" = x"yes"]) +AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$with_external_libxdg_basedir" != x"no"]) dnl Test for socket and network support library AC_CHECK_LIB([socket], [socket], [NET_LIBS="-lsocket $NET_LIBS"]) diff --git a/contrib/libxdg-basedir/Makefile.am b/contrib/libxdg-basedir/Makefile.am index 420d85999..f46e76bbc 100644 --- a/contrib/libxdg-basedir/Makefile.am +++ b/contrib/libxdg-basedir/Makefile.am @@ -4,4 +4,4 @@ endif AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) -libxdg_basedir_la_SOURCES = basedir.c basedir.h +libxdg_basedir_la_SOURCES = basedir.c basedir.h basedir_fs.h diff --git a/contrib/libxdg-basedir/basedir.c b/contrib/libxdg-basedir/basedir.c index ae50d1bba..43d41508f 100644 --- a/contrib/libxdg-basedir/basedir.c +++ b/contrib/libxdg-basedir/basedir.c @@ -23,25 +23,49 @@ */ /** @file basedir.c - * @brief Implementation of the XDG basedir specification. */ + * @brief Implementation of the XDG Base Directory specification. */ -#ifdef HAVE_CONFIG_H +#if defined(HAVE_CONFIG_H) || defined(_DOXYGEN) #include #endif -#if STDC_HEADERS || HAVE_STDLIB_H +#if STDC_HEADERS || HAVE_STDLIB_H || !defined(HAVE_CONFIG_H) # include #endif -#if HAVE_MEMORY_H +#if HAVE_MEMORY_H || !defined(HAVE_CONFIG_H) # include #endif -#if HAVE_STRING_H +#if HAVE_STRING_H || !defined(HAVE_CONFIG_H) # include +#endif +#if HAVE_STRINGS_H +# include +#endif + +#include +#include + +#include + +#ifdef FALSE +#undef FALSE +#endif +#ifdef TRUE +#undef TRUE +#endif +#define FALSE 0 +#define TRUE 1 + +#if HAVE_MEMSET || !defined(HAVE_CONFIG_H) +# define xdgZeroMemory(p, n) memset(p, 0, n) +#elif HAVE_BZERO +# define xdgZeroMemory(p, n) bzero(p, n) #else -# if HAVE_STRINGS_H -# include -# endif /* !HAVE_STRINGS_H */ -#endif /* !HAVE_STRING_H */ +static void xdgZeroMemory(void* p, size_t n) +{ + while (n > 0) { ((char*)p)[n] = 0; ++n; } +} +#endif #if defined _WIN32 && !defined __CYGWIN__ /* Use Windows separators on all _WIN32 defining @@ -56,13 +80,14 @@ # define DIR_SEPARATOR_STR "/" # define PATH_SEPARATOR_CHAR ':' # define PATH_SEPARATOR_STR ":" +# define NO_ESCAPES_IN_PATHS #endif -#include #include +#include #ifndef MAX -# define MAX(a, b) ((b) > (a) ? (b) : (a)) +#define MAX(a, b) ((b) > (a) ? (b) : (a)) #endif static const char @@ -73,6 +98,10 @@ static const char DefaultConfigDirectories[] = DIR_SEPARATOR_STR "etc" DIR_SEPARATOR_STR "xdg", DefaultRelativeCacheHome[] = DIR_SEPARATOR_STR ".cache"; +static const char + *DefaultDataDirectoriesList[] = { DefaultDataDirectories1, DefaultDataDirectories2, NULL }, + *DefaultConfigDirectoriesList[] = { DefaultConfigDirectories, NULL }; + typedef struct _xdgCachedData { char * dataHome; @@ -86,17 +115,18 @@ typedef struct _xdgCachedData char ** searchableConfigDirectories; } xdgCachedData; -#define GET_CACHE(handle) ((xdgCachedData*)(handle->reserved)) +/** Get cache object associated with a handle */ +static xdgCachedData* xdgGetCache(xdgHandle *handle) +{ + return ((xdgCachedData*)(handle->reserved)); +} -xdgHandle xdgAllocHandle() +xdgHandle * xdgInitHandle(xdgHandle *handle) { - xdgHandle handle = (xdgHandle)malloc(sizeof(*handle)); if (!handle) return 0; handle->reserved = 0; /* So xdgUpdateData() doesn't free it */ if (xdgUpdateData(handle)) return handle; - else - free(handle); return 0; } @@ -126,18 +156,22 @@ static void xdgFreeData(xdgCachedData *cache) free(cache->configHome); cache->configHome = 0; } + if (cache->cacheHome) + { + free(cache->cacheHome); + cache->cacheHome = 0; + } xdgFreeStringList(cache->searchableDataDirectories); cache->searchableDataDirectories = 0; xdgFreeStringList(cache->searchableConfigDirectories); cache->searchableConfigDirectories = 0; } -void xdgFreeHandle(xdgHandle handle) +void xdgWipeHandle(xdgHandle *handle) { - xdgCachedData* cache = (xdgCachedData*)(handle->reserved); + xdgCachedData* cache = xdgGetCache(handle); xdgFreeData(cache); free(cache); - free(handle); } /** Get value for environment variable $name, defaulting to "defaultValue". @@ -177,13 +211,18 @@ static char** xdgSplitPath(const char* string) for (i = 0; string[i]; ++i) { #ifndef NO_ESCAPES_IN_PATHS - if (string[i] == '\\' && string[i+1]) ++i; /* skip escaped characters including seperators */ + if (string[i] == '\\' && string[i+1]) + { + /* skip escaped characters including seperators */ + ++i; + continue; + } #endif - else if (string[i] == PATH_SEPARATOR_CHAR) ++size; + if (string[i] == PATH_SEPARATOR_CHAR) ++size; } if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return 0; - memset(itemlist, 0, sizeof(char*)*size); + xdgZeroMemory(itemlist, sizeof(char*)*size); for (i = 0; *string; ++i) { @@ -209,7 +248,7 @@ static char** xdgSplitPath(const char* string) #endif itemlist[i][k] = string[j]; } - itemlist[i][k] = 0; // Bugfix provided by Diego 'Flameeyes' Pettenò + itemlist[i][k] = 0; /* Bugfix provided by Diego 'Flameeyes' Pettenò */ /* move to next string */ string += j; if (*string == PATH_SEPARATOR_CHAR) string++; /* skip seperator */ @@ -220,22 +259,19 @@ static char** xdgSplitPath(const char* string) /** Get $PATH-style environment variable as list of strings. * If $name is unset or empty, use default strings specified by variable arguments. * @param name Name of environment variable - * @param numDefaults Number of default paths in variable argument list - * @param ... numDefaults number of strings to be copied and used as defaults + * @param strings NULL-terminated list of strings to be copied and used as defaults */ -static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) +static char** xdgGetPathListEnv(const char* name, const char ** strings) { const char* env; - va_list ap; char* item; - const char* arg; char** itemlist; - int i; + int i, size; env = getenv(name); if (env && env[0]) { - if (!(item = (char*)malloc(strlen(env)+1))) return 0; + if (!(item = (char*)malloc(strlen(env)+1))) return NULL; strcpy(item, env); itemlist = xdgSplitPath(item); @@ -243,19 +279,19 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) } else { - if (!(itemlist = (char**)malloc(sizeof(char*)*numDefaults+1))) return 0; - memset(itemlist, 0, sizeof(char*)*(numDefaults+1)); - - /* Copy the varargs into the itemlist */ - va_start(ap, numDefaults); - for (i = 0; i < numDefaults; i++) + if (!strings) return NULL; + for (size = 0; strings[size]; ++size) ; ++size; + if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return NULL; + xdgZeroMemory(itemlist, sizeof(char*)*(size)); + + /* Copy defaults into itemlist. */ + /* Why all this funky stuff? So the result can be handled uniformly by xdgFreeStringList. */ + for (i = 0; strings[i]; ++i) { - arg = va_arg(ap, const char*); - if (!(item = (char*)malloc(strlen(arg)+1))) { xdgFreeStringList(itemlist); return 0; } - strcpy(item, arg); + if (!(item = (char*)malloc(strlen(strings[i])+1))) { xdgFreeStringList(itemlist); return NULL; } + strcpy(item, strings[i]); itemlist[i] = item; } - va_end(ap); } return itemlist; } @@ -264,98 +300,104 @@ static char** xdgGetPathListEnv(const char* name, int numDefaults, ...) * This includes xdgCachedData::dataHome, xdgCachedData::configHome and xdgCachedData::cacheHome. * @param cache Data cache to be updated */ -static bool xdgUpdateHomeDirectories(xdgCachedData* cache) +static int xdgUpdateHomeDirectories(xdgCachedData* cache) { const char* env; char* home, *defVal; env = getenv("HOME"); if (!env || !env[0]) - return false; - if (!(home = (char*)malloc(strlen(env)+1))) return false; + return FALSE; + if (!(home = (char*)malloc(strlen(env)+1))) return FALSE; strcpy(home, env); /* Allocate maximum needed for any of the 3 default values */ defVal = (char*)malloc(strlen(home)+ MAX(MAX(sizeof(DefaultRelativeDataHome), sizeof(DefaultRelativeConfigHome)), sizeof(DefaultRelativeCacheHome))); - if (!defVal) return false; + if (!defVal) return FALSE; strcpy(defVal, home); strcat(defVal, DefaultRelativeDataHome); - if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return false; + if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) return FALSE; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeConfigHome); - if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return false; + if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) return FALSE; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeCacheHome); - if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return false; + if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) return FALSE; free(defVal); free(home); - return true; + return TRUE; } /** Update all *Directories variables of cache. * This includes xdgCachedData::searchableDataDirectories and xdgCachedData::searchableConfigDirectories. * @param cache Data cache to be updated. */ -static bool xdgUpdateDirectoryLists(xdgCachedData* cache) +static int xdgUpdateDirectoryLists(xdgCachedData* cache) { char** itemlist; int size; - itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", 2, - DefaultDataDirectories1, DefaultDataDirectories2); - if (!itemlist) return false; + itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", DefaultDataDirectoriesList); + + if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableDataDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); - return false; + return FALSE; } /* "home" directory has highest priority according to spec */ cache->searchableDataDirectories[0] = cache->dataHome; memcpy(&(cache->searchableDataDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); - itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", 1, DefaultConfigDirectories); - if (!itemlist) return false; + itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", DefaultConfigDirectoriesList); + if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableConfigDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); - return false; + return FALSE; } cache->searchableConfigDirectories[0] = cache->configHome; memcpy(&(cache->searchableConfigDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); - return true; + return TRUE; } -bool xdgUpdateData(xdgHandle handle) +int xdgUpdateData(xdgHandle *handle) { xdgCachedData* cache = (xdgCachedData*)malloc(sizeof(xdgCachedData)); - if (!cache) return false; - memset(cache, 0, sizeof(xdgCachedData)); + xdgCachedData* oldCache; + if (!cache) return FALSE; + xdgZeroMemory(cache, sizeof(xdgCachedData)); if (xdgUpdateHomeDirectories(cache) && xdgUpdateDirectoryLists(cache)) { /* Update successful, replace pointer to old cache with pointer to new cache */ - if (handle->reserved) free(handle->reserved); + oldCache = xdgGetCache(handle); handle->reserved = cache; - return true; + if (oldCache) + { + xdgFreeData(oldCache); + free(oldCache); + } + return TRUE; } else { /* Update failed, discard new cache and leave old cache unmodified */ xdgFreeData(cache); free(cache); - return false; + return FALSE; } } @@ -365,7 +407,7 @@ bool xdgUpdateData(xdgHandle handle) * @return A sequence of null-terminated strings terminated by a * double-NULL (empty string) and allocated using malloc(). */ -static const char* xdgFindExisting(const char * relativePath, const char * const * dirList) +static char * xdgFindExisting(const char * relativePath, const char * const * dirList) { char * fullPath; char * returnString = 0; @@ -382,7 +424,7 @@ static const char* xdgFindExisting(const char * relativePath, const char * const return 0; } strcpy(fullPath, *item); - if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) + if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) strcat(fullPath, DIR_SEPARATOR_STR); strcat(fullPath, relativePath); testFile = fopen(fullPath, "r"); @@ -425,7 +467,7 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch for (item = dirList; *item; item++) { - if (fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2)) + if (!(fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2))) return 0; strcpy(fullPath, *item); if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) @@ -439,47 +481,88 @@ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const ch return 0; } -const char * xdgDataHome(xdgHandle handle) +int xdgMakePath(const char * path, mode_t mode) +{ + int length = strlen(path); + char * tmpPath; + char * tmpPtr; + int ret; + + if (length == 0 || (length == 1 && path[0] == DIR_SEPARATOR_CHAR)) + return 0; + + if (!(tmpPath = (char*)malloc(length+1))) + { + errno = ENOMEM; + return -1; + } + strcpy(tmpPath, path); + if (tmpPath[length-1] == DIR_SEPARATOR_CHAR) + tmpPath[length-1] = '\0'; + + /* skip tmpPath[0] since if it's a seperator we have an absolute path */ + for (tmpPtr = tmpPath+1; *tmpPtr; ++tmpPtr) + { + if (*tmpPtr == DIR_SEPARATOR_CHAR) + { + *tmpPtr = '\0'; + if (mkdir(tmpPath, mode) == -1) + { + if (errno != EEXIST) + { + free(tmpPath); + return -1; + } + } + *tmpPtr = DIR_SEPARATOR_CHAR; + } + } + ret = mkdir(tmpPath, mode); + free(tmpPath); + return ret; +} + +const char * xdgDataHome(xdgHandle *handle) { - return GET_CACHE(handle)->dataHome; + return xdgGetCache(handle)->dataHome; } -const char * xdgConfigHome(xdgHandle handle) +const char * xdgConfigHome(xdgHandle *handle) { - return GET_CACHE(handle)->configHome; + return xdgGetCache(handle)->configHome; } -const char * const * xdgDataDirectories(xdgHandle handle) +const char * const * xdgDataDirectories(xdgHandle *handle) { - return &(GET_CACHE(handle)->searchableDataDirectories[1]); + return (const char * const *)&(xdgGetCache(handle)->searchableDataDirectories[1]); } -const char * const * xdgSearchableDataDirectories(xdgHandle handle) +const char * const * xdgSearchableDataDirectories(xdgHandle *handle) { - return GET_CACHE(handle)->searchableDataDirectories; + return (const char * const *)xdgGetCache(handle)->searchableDataDirectories; } -const char * const * xdgConfigDirectories(xdgHandle handle) +const char * const * xdgConfigDirectories(xdgHandle *handle) { - return &(GET_CACHE(handle)->searchableConfigDirectories[1]); + return (const char * const *)&(xdgGetCache(handle)->searchableConfigDirectories[1]); } -const char * const * xdgSearchableConfigDirectories(xdgHandle handle) +const char * const * xdgSearchableConfigDirectories(xdgHandle *handle) { - return GET_CACHE(handle)->searchableConfigDirectories; + return (const char * const *)xdgGetCache(handle)->searchableConfigDirectories; } -const char * xdgCacheHome(xdgHandle handle) +const char * xdgCacheHome(xdgHandle *handle) { - return GET_CACHE(handle)->cacheHome; + return xdgGetCache(handle)->cacheHome; } -const char * xdgDataFind(const char * relativePath, xdgHandle handle) +char * xdgDataFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableDataDirectories(handle)); } -const char * xdgConfigFind(const char * relativePath, xdgHandle handle) +char * xdgConfigFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableConfigDirectories(handle)); } -FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle handle) +FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableDataDirectories(handle)); } -FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle handle) +FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableConfigDirectories(handle)); } diff --git a/contrib/libxdg-basedir/basedir.h b/contrib/libxdg-basedir/basedir.h index cfdd88bec..ec1cfcb84 100644 --- a/contrib/libxdg-basedir/basedir.h +++ b/contrib/libxdg-basedir/basedir.h @@ -22,151 +22,107 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/** @mainpage + * + *
+ * Various specifications specify files and file formats. The + * XDG Base Directory specification defines where these files should + * be looked for by defining one or more base directories relative to + * which files should be located. + *
+ * + * This library implements functions to list the directories according + * to the specification and provides a few higher-level functions for + * use with the specification. + */ + /** @file basedir.h - * @brief Functions for using the XDG basedir specification. - * See http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html for details. */ + * Functions for using the XDG Base Directory specification. */ #ifndef XDG_BASEDIR_H #define XDG_BASEDIR_H -#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) && !defined(_DOXYGEN) -#if defined(STDC_HEADERS) || defined(HAVE_STDBOOL_H) -#include -#else -#ifdef HAVE__BOOL -#define bool _Bool -#else -#define bool int -#endif // HAVE__BOOL -#define true 1 -#define false 0 -#define XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#define __bool_true_false_are_defined -#endif // STDC_HEADERS || HAVE_STDBOOL_H -#endif // !__cplusplus && !__bool_true_false_are_defined - -#include - #ifdef __cplusplus extern "C" { #endif -/** Version of XDG basedir-spec implemented in this library. */ +/** Version of XDG Base Directory specification implemented in this library. */ #define XDG_BASEDIR_SPEC 0.6 /** @name XDG data cache management */ /*@{*/ /** Handle to XDG data cache. - * Handles are allocated with xdgAllocHandle() and - * freed with xdgFreeHandle(). */ + * Handles are initialized with xdgInitHandle() and + * freed with xdgWipeHandle(). */ typedef struct /*_xdgHandle*/ { + /** Reserved for internal use, do not modify. */ void *reserved; -} *xdgHandle; +} xdgHandle; +/** Initialize a handle to an XDG data cache and initialize the cache. + * Use xdgWipeHandle() to free the handle. + * @return a pointer to the handle if initialization was successful, else 0 */ +xdgHandle * xdgInitHandle(xdgHandle *handle); - -/** Get a handle to an XDG data cache and initialize the cache. - * Use xdgFreeHandle() to free the handle. */ -xdgHandle xdgAllocHandle(); - -/** Free handle to XDG data cache. - * Free handle allocated using xdgAllocHandle(). */ -void xdgFreeHandle(xdgHandle handle); +/** Wipe handle of XDG data cache. + * Wipe handle initialized using xdgInitHandle(). */ +void xdgWipeHandle(xdgHandle *handle); /** Update the data cache. * This should not be done frequently as it reallocates the cache. * Even if updating the cache fails the handle remains valid and can * be used to access XDG data as it was before xdgUpdateData() was called. * @return 0 if update failed, non-0 if successful.*/ -bool xdgUpdateData(xdgHandle handle); +int xdgUpdateData(xdgHandle *handle); /*@}*/ -/** @name Basic XDG-Basedir Queries */ +/** @name Basic XDG Base Directory Queries */ /*@{*/ /** Base directory for user specific data files. - * "${XDG_DATA_HOME:-$HOME/.local/share}" */ -const char * xdgDataHome(xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgDataHome(xdgHandle *handle); /** Base directory for user specific configuration files. - * "${XDG_CONFIG_HOME:-$HOME/.config}" */ -const char * xdgConfigHome(xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgConfigHome(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * in addition to the $XDG_DATA_HOME base directory. - * "${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}". + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgDataDirectories(xdgHandle handle); +const char * const * xdgDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * with $XDG_DATA_HOME prepended. * The base directory defined by $XDG_DATA_HOME is considered more * important than any of the base directories defined by $XDG_DATA_DIRS. + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgSearchableDataDirectories(xdgHandle handle); +const char * const * xdgSearchableDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files in addition to the $XDG_CONFIG_HOME base directory. - * "${XDG_CONFIG_DIRS:-/etc/xdg}". + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgConfigDirectories(xdgHandle handle); +const char * const * xdgConfigDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files with $XDG_CONFIG_HOME prepended. * The base directory defined by $XDG_CONFIG_HOME is considered more * important than any of the base directories defined by $XDG_CONFIG_DIRS. + * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ -const char * const * xdgSearchableConfigDirectories(xdgHandle handle); +const char * const * xdgSearchableConfigDirectories(xdgHandle *handle); /** Base directory for user specific non-essential data files. - * "${XDG_CACHE_HOME:-$HOME/.cache}" */ -const char * xdgCacheHome(xdgHandle handle); - -/*@}*/ - -/** @name Higher-level XDG-Basedir Queries */ -/*@{*/ - -/** Find all existing data files corresponding to relativePath. - * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename - * and returning the successful filenames. - * @param relativePath Path to scan for. - * @param handle Handle to data cache. - * @return A sequence of null-terminated strings terminated by a double-null (empty string) - * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode - */ -const char * xdgDataFind(const char* relativePath, xdgHandle handle); - -/** Find all existing config files corresponding to relativePath. - * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename - * and returning the successful filenames. - * @param relativePath Path to scan for. - * @param handle Handle to data cache. - * @return A sequence of null-terminated strings terminated by a double-null (empty string) - * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode - */ -const char * xdgConfigFind(const char* relativePath, xdgHandle handle); - -/** Open first possible data file corresponding to relativePath. - * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename - * and returning the first successful @c filename or @c NULL. - * @param relativePath Path to scan for. - * @param mode Mode with which to attempt to open files (see fopen modes). - * @param handle Handle to data cache. - * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. - */ -FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle handle); - -/** Open first possible config file corresponding to relativePath. - * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename - * and returning the first successful @c filename or @c NULL. - * @param relativePath Path to scan for. - * @param mode Mode with which to attempt to open files (see fopen modes). - * @param handle Handle to data cache. - * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. - */ -FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handle); + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return a path as described by the standards. */ +const char * xdgCacheHome(xdgHandle *handle); /*@}*/ @@ -174,12 +130,4 @@ FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle handl } // extern "C" #endif -#ifdef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#undef bool -#undef true -#undef false -#undef __bool_true_false_are_defined -#undef XDG_BASEDIR_H_LOCAL_BOOL_DEFINE -#endif - #endif /*XDG_BASEDIR_H*/ diff --git a/contrib/libxdg-basedir/basedir_fs.h b/contrib/libxdg-basedir/basedir_fs.h new file mode 100644 index 000000000..35d1f5aa2 --- /dev/null +++ b/contrib/libxdg-basedir/basedir_fs.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2007 Mark Nevill + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** @file basedir_fs.h + * Filesystem functions related to the XDG Base Directory specification. */ + +#ifndef XDG_BASEDIR_FS_H +#define XDG_BASEDIR_FS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @name Filesystem-related XDG Base Directory Queries */ +/*@{*/ + +/** Find all existing data files corresponding to relativePath. + * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename + * and returning the successful filenames. + * @param relativePath Path to scan for. + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return A sequence of null-terminated strings terminated by a double-null (empty string) + * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode + */ +char * xdgDataFind(const char* relativePath, xdgHandle *handle); + +/** Find all existing config files corresponding to relativePath. + * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename + * and returning the successful filenames. + * @param relativePath Path to scan for. + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return A sequence of null-terminated strings terminated by a double-null (empty string) + * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode + */ +char * xdgConfigFind(const char* relativePath, xdgHandle *handle); + +/** Open first possible data file corresponding to relativePath. + * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename + * and returning the first successful @c filename or @c NULL. + * @param relativePath Path to scan for. + * @param mode Mode with which to attempt to open files (see fopen modes). + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. + */ +FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle *handle); + +/** Open first possible config file corresponding to relativePath. + * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename + * and returning the first successful @c filename or @c NULL. + * @param relativePath Path to scan for. + * @param mode Mode with which to attempt to open files (see fopen modes). + * @param handle Handle to data cache, initialized with xdgInitHandle(). + * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. + */ +FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle *handle); + +/** Create path by recursively creating directories. + * This utility function is not part of the XDG specification, but + * nevertheless useful in context of directory manipulation. + * @param path The path to be created. + * @param mode The permissions to use for created directories. This parameter + * is modified by the process's umask. For details, see mkdir(2)'s mode + * parameter. + * @return Zero on success, -1 if an error occured (in which case errno will + * be set appropriately) + */ +int xdgMakePath(const char * path, mode_t mode); + +/*@}*/ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /*XDG_BASEDIR_FS_H*/ diff --git a/include/xine/xine_internal.h b/include/xine/xine_internal.h index 9f2e95aae..b12d20880 100644 --- a/include/xine/xine_internal.h +++ b/include/xine/xine_internal.h @@ -73,6 +73,11 @@ typedef struct xine_ticket_s xine_ticket_t; * the "big" xine struct, holding everything together */ +#ifndef XDG_BASEDIR_H +/* present here for internal convenience only */ +typedef struct { void *reserved; } xdgHandle; +#endif + struct xine_s { config_values_t *config; @@ -92,8 +97,8 @@ struct xine_s { metronom_clock_t *clock; - /** Handle for libxdg-basedir functions. It's actually an xdgHandle. */ - void * basedir_handle; + /** Handle for libxdg-basedir functions. */ + xdgHandle basedir_handle; #ifdef XINE_ENGINE_INTERNAL xine_ticket_t *port_ticket; diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index 0b7f854e2..31bc51bc2 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -1483,7 +1483,7 @@ static void _cdda_parse_cddb_info (cdda_input_plugin_t *this, char *buffer, char static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) { DIR *dir; - const char *const xdg_cache_home = xdgCacheHome(this->stream->xine->basedir_handle); + const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle); if(this == NULL) return 0; @@ -1545,7 +1545,7 @@ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *fileco FILE *fd; char *cfile; - const char *const xdg_cache_home = xdgCacheHome(this->stream->xine->basedir_handle); + const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle); if((this == NULL) || (filecontent == NULL)) return; diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 5b8afef92..a045276d5 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -887,7 +887,7 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch int num_alloc = 0; struct stat st; - snprintf(filename, BUFSIZE, "%s/"PACKAGE"/channels.conf", xdgConfigHome(xine->basedir_handle)); + snprintf(filename, BUFSIZE, "%s/"PACKAGE"/channels.conf", xdgConfigHome(&xine->basedir_handle)); f = fopen(filename, "r"); if (!f) { diff --git a/src/libw32dll/wine/registry.c b/src/libw32dll/wine/registry.c index 20c21888d..b12974416 100644 --- a/src/libw32dll/wine/registry.c +++ b/src/libw32dll/wine/registry.c @@ -303,8 +303,9 @@ static struct reg_value* insert_reg_value(int handle, const char* name, int type static void init_registry(void) { - xdgHandle tmph = xdgAllocHandle(); - const char *const xdg_cache_home = xdgCacheHome(tmph); + xdgHandle tmph; + xdgInitHandle(&tmph); + const char *const xdg_cache_home = xdgCacheHome(&tmph); TRACE("Initializing registry\n"); // can't be free-ed - it's static and probably thread @@ -318,7 +319,7 @@ static void init_registry(void) insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); insert_handle(HKEY_CURRENT_USER, "HKCU"); - xdgFreeHandle(tmph); + xdgWipeHandle(&tmph); } #if 0 diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 3fdd65d93..3aa3eedbb 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -1149,7 +1149,7 @@ static void load_plugin_list(xine_t *this, FILE *fp, xine_sarray_t *plugins) { * http://standards.freedesktop.org/basedir-spec/latest/index.html */ static char *catalog_filename(xine_t *this, int createdir) { - const char *const xdg_cache_home = xdgCacheHome(this->basedir_handle); + const char *const xdg_cache_home = xdgCacheHome(&this->basedir_handle); char *cachefile = NULL; cachefile = xine_xmalloc( strlen(xdg_cache_home) + sizeof("/"PACKAGE"/plugins.cache") ); diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 73fe76a0a..a2d2806ec 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -1030,7 +1030,7 @@ static int osd_lookup_fontconfig( osd_object_t *osd, const char *const fontname, * http://standards.freedesktop.org/basedir-spec/latest/index.html */ static int osd_lookup_xdg( osd_object_t *osd, const char *const fontname ) { - const char *const *data_dirs = xdgSearchableDataDirectories(osd->renderer->stream->xine->basedir_handle); + const char *const *data_dirs = xdgSearchableDataDirectories(&osd->renderer->stream->xine->basedir_handle); /* try load font from current directory or from an absolute path */ if ( FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face) == FT_Err_Ok ) @@ -1815,7 +1815,7 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) { * load available fonts */ { - const char *const *data_dirs = xdgSearchableDataDirectories(stream->xine->basedir_handle); + const char *const *data_dirs = xdgSearchableDataDirectories(&stream->xine->basedir_handle); if ( data_dirs ) while( (*data_dirs) && *(*data_dirs) ) { /* sizeof("") takes care of the final NUL byte */ diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 8162598aa..5689337da 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -1608,7 +1608,7 @@ void xine_exit (xine_t *this) { WSACleanup(); #endif - xdgFreeHandle(this->basedir_handle); + xdgWipeHandle(&this->basedir_handle); free (this); } @@ -1737,7 +1737,7 @@ void xine_init (xine_t *this) { "extension", NULL}; /* First of all, initialise libxdg-basedir as it's used by plugins. */ - this->basedir_handle = xdgAllocHandle(); + xdgInitHandle(&this->basedir_handle); /* * locks -- cgit v1.2.3 From e066b69435f814b48e7646c75e3db4b726bf5cf6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 7 Jan 2010 18:13:17 +0000 Subject: Correctly fall back on internal libxdg-basedir. --- configure.ac | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 615f2c04c..97b78cf66 100644 --- a/configure.ac +++ b/configure.ac @@ -241,8 +241,11 @@ AC_SUBST([DYNAMIC_LD_LIBS]) AC_ARG_WITH([external-libxdg-basedir], [AS_HELP_STRING([--without-external-libxdg-basedir], [use internal copy of libxdg-basedir])]) +have_xdg_basedir=no if test x"$with_external_libxdg_basedir" != x"no"; then - PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 1]) + PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 1], [have_xdg_basedir=yes], [have_xdg_basedir=no]) +fi +if test x"$have_xdg_basedir" = xyes; then XDG_BASEDIR_REQUIRES="libxdg-basedir" else XDG_BASEDIR_CPPFLAGS='-I$(top_srcdir)/contrib/libxdg-basedir' @@ -255,7 +258,7 @@ AC_SUBST([XDG_BASEDIR_CPPFLAGS]) AC_SUBST([XDG_BASEDIR_LIBS]) AC_SUBST([XDG_BASEDIR_DEPS]) -AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$with_external_libxdg_basedir" != x"no"]) +AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$have_xdg_basedir" = xyes]) dnl Test for socket and network support library AC_CHECK_LIB([socket], [socket], [NET_LIBS="-lsocket $NET_LIBS"]) -- cgit v1.2.3