diff options
Diffstat (limited to 'src/libxineadec')
-rw-r--r-- | src/libxineadec/Makefile.am | 3 | ||||
-rw-r--r-- | src/libxineadec/fooaudio.c | 26 | ||||
-rw-r--r-- | src/libxineadec/gsm610.c | 6 | ||||
-rw-r--r-- | src/libxineadec/gsm610/long_term.c | 4 | ||||
-rw-r--r-- | src/libxineadec/gsm610/lpc.c | 4 | ||||
-rw-r--r-- | src/libxineadec/gsm610/rpe.c | 4 | ||||
-rw-r--r-- | src/libxineadec/gsm610/short_term.c | 4 | ||||
-rw-r--r-- | src/libxineadec/nosefart/Makefile.am | 2 | ||||
-rw-r--r-- | src/libxineadec/nsf.c | 18 | ||||
-rw-r--r-- | src/libxineadec/xine_lpcm_decoder.c | 217 | ||||
-rw-r--r-- | src/libxineadec/xine_speex_decoder.c | 63 | ||||
-rw-r--r-- | src/libxineadec/xine_vorbis_decoder.c | 270 |
12 files changed, 392 insertions, 229 deletions
diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am index d502b7955..ae261e60c 100644 --- a/src/libxineadec/Makefile.am +++ b/src/libxineadec/Makefile.am @@ -1,3 +1,4 @@ +include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common EXTRA_DIST = fooaudio.c @@ -39,7 +40,7 @@ xineplug_decode_lpcm_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB) xineplug_decode_vorbis_la_SOURCES = xine_vorbis_decoder.c -xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS) +xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS) $(LTLIBINTL) xineplug_decode_vorbis_la_CFLAGS = $(VISIBILITY_FLAG) $(VORBIS_CFLAGS) xineplug_decode_speex_la_SOURCES = xine_speex_decoder.c diff --git a/src/libxineadec/fooaudio.c b/src/libxineadec/fooaudio.c index 5ab4fa1f6..776136fc2 100644 --- a/src/libxineadec/fooaudio.c +++ b/src/libxineadec/fooaudio.c @@ -22,6 +22,10 @@ * place of the data it should actually send. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -91,7 +95,7 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) this->channels = buf->decoder_info[3]; /* initialize the data accumulation buffer */ - this->buf = xine_xmalloc(AUDIOBUFSIZE); + this->buf = calloc(1, AUDIOBUFSIZE); this->bufsize = AUDIOBUFSIZE; this->size = 0; @@ -126,7 +130,7 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) * the accumulator buffer size as necessary */ if( this->size + buf->size > this->bufsize ) { this->bufsize = this->size + 2 * buf->size; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize); this->buf = realloc( this->buf, this->bufsize ); } @@ -147,8 +151,8 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) * This decoder generates a continuous sine pattern based on the pts * values sent by the xine engine. Two pts values are needed to know * how long to make the audio. Thus, If this is the first frame or - * a seek has occurred (indicated by this->last_pts = -1), - * log the pts but do not create any audio. + * a seek has occurred (indicated by this->last_pts = -1), + * log the pts but do not create any audio. * * When a valid pts delta is generated, create n audio samples, where * n is given as: @@ -177,7 +181,7 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) /* get an audio buffer */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "fooaudio: Help! Allocated audio buffer with nothing in it!\n"); return; } @@ -192,7 +196,7 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) #define WAVE_HZ 300 /* fill up the samples in the buffer */ for (i = 0; i < samples_to_send; i++) - audio_buffer->mem[i] = + audio_buffer->mem[i] = (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767); /* final prep for audio buffer dispatch */ @@ -255,7 +259,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre fooaudio_decoder_t *this ; - this = (fooaudio_decoder_t *) xine_xmalloc (sizeof (fooaudio_decoder_t)); + this = (fooaudio_decoder_t *) calloc(1, sizeof(fooaudio_decoder_t)); /* connect the member functions */ this->audio_decoder.decode_data = fooaudio_decode_data; @@ -304,7 +308,7 @@ static void dispose_class (audio_decoder_class_t *this_gen) { free (this); } -/* This function allocates a private audio decoder class and initializes +/* This function allocates a private audio decoder class and initializes * the class's member functions. */ static void *init_plugin (xine_t *xine, void *data) { @@ -320,18 +324,18 @@ static void *init_plugin (xine_t *xine, void *data) { return this; } -/* This is a list of all of the internal xine audio buffer types that +/* This is a list of all of the internal xine audio buffer types that * this decoder is able to handle. Check src/xine-engine/buffer.h for a * list of valid buffer types (and add a new one if the one you need does * not exist). Terminate the list with a 0. */ -static uint32_t audio_types[] = { +static uint32_t audio_types[] = { /* BUF_AUDIO_FOO, */ 0 }; /* This data structure combines the list of supported xine buffer types and * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) + * plugins that handle the same buffer type. A plugin with priority (n+1) * will be used instead of a plugin with priority (n). */ static const decoder_info_t dec_info_audio = { audio_types, /* supported types */ diff --git a/src/libxineadec/gsm610.c b/src/libxineadec/gsm610.c index 23c0d2104..c67382bc5 100644 --- a/src/libxineadec/gsm610.c +++ b/src/libxineadec/gsm610.c @@ -101,7 +101,7 @@ static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (buf->decoder_flags & BUF_FLAG_STDHEADER) { this->sample_rate = buf->decoder_info[1]; - this->buf = xine_xmalloc(AUDIOBUFSIZE); + this->buf = calloc(1, AUDIOBUFSIZE); this->bufsize = AUDIOBUFSIZE; this->size = 0; @@ -233,7 +233,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre gsm610_decoder_t *this ; - this = (gsm610_decoder_t *) xine_xmalloc (sizeof (gsm610_decoder_t)); + this = (gsm610_decoder_t *) calloc(1, sizeof(gsm610_decoder_t)); this->audio_decoder.decode_data = gsm610_decode_data; this->audio_decoder.reset = gsm610_reset; @@ -265,7 +265,7 @@ static void *init_plugin (xine_t *xine, void *data) { gsm610_class_t *this ; - this = (gsm610_class_t *) xine_xmalloc (sizeof (gsm610_class_t)); + this = (gsm610_class_t *) calloc(1, sizeof(gsm610_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.get_identifier = get_identifier; diff --git a/src/libxineadec/gsm610/long_term.c b/src/libxineadec/gsm610/long_term.c index 625662e1f..d3ef1b63d 100644 --- a/src/libxineadec/gsm610/long_term.c +++ b/src/libxineadec/gsm610/long_term.c @@ -6,6 +6,10 @@ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/long_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include "xineutils.h" diff --git a/src/libxineadec/gsm610/lpc.c b/src/libxineadec/gsm610/lpc.c index 0f51fa55f..7a8a8e2bc 100644 --- a/src/libxineadec/gsm610/lpc.c +++ b/src/libxineadec/gsm610/lpc.c @@ -6,6 +6,10 @@ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/lpc.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include "xineutils.h" diff --git a/src/libxineadec/gsm610/rpe.c b/src/libxineadec/gsm610/rpe.c index 67d94d30e..be1b1529b 100644 --- a/src/libxineadec/gsm610/rpe.c +++ b/src/libxineadec/gsm610/rpe.c @@ -6,6 +6,10 @@ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/rpe.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include "xineutils.h" #include "private.h" diff --git a/src/libxineadec/gsm610/short_term.c b/src/libxineadec/gsm610/short_term.c index 8222b2caa..c2d64853b 100644 --- a/src/libxineadec/gsm610/short_term.c +++ b/src/libxineadec/gsm610/short_term.c @@ -6,6 +6,10 @@ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/short_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include "xineutils.h" #include "private.h" diff --git a/src/libxineadec/nosefart/Makefile.am b/src/libxineadec/nosefart/Makefile.am index 51cc3f238..4ca4f75b6 100644 --- a/src/libxineadec/nosefart/Makefile.am +++ b/src/libxineadec/nosefart/Makefile.am @@ -13,7 +13,7 @@ libnosefart_la_SOURCES = \ memguard.c \ nes6502.c \ nsf.c \ - vrcvisnd.c + vrcvisnd.c libnosefart_la_CFLAGS = $(VISIBILITY_FLAG) -DNSF_PLAYER -fno-strict-aliasing diff --git a/src/libxineadec/nsf.c b/src/libxineadec/nsf.c index bdf523f1d..643d431a2 100644 --- a/src/libxineadec/nsf.c +++ b/src/libxineadec/nsf.c @@ -21,6 +21,10 @@ * http://www.baisoku.org/ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -90,7 +94,7 @@ static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->song_number = buf->content[4]; /* allocate a buffer for the file */ this->nsf_size = _X_BE_32(&buf->content[0]); - this->nsf_file = xine_xmalloc(this->nsf_size); + this->nsf_file = calloc(1, this->nsf_size); this->nsf_index = 0; /* peform any other required initialization */ @@ -205,7 +209,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre nsf_decoder_t *this ; - this = (nsf_decoder_t *) xine_xmalloc (sizeof (nsf_decoder_t)); + this = (nsf_decoder_t *) calloc(1, sizeof(nsf_decoder_t)); /* connect the member functions */ this->audio_decoder.decode_data = nsf_decode_data; @@ -249,13 +253,13 @@ static void dispose_class (audio_decoder_class_t *this_gen) { free (this); } -/* This function allocates a private audio decoder class and initializes +/* This function allocates a private audio decoder class and initializes * the class's member functions. */ static void *init_plugin (xine_t *xine, void *data) { nsf_class_t *this ; - this = (nsf_class_t *) xine_xmalloc (sizeof (nsf_class_t)); + this = (nsf_class_t *) calloc(1, sizeof(nsf_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.get_identifier = get_identifier; @@ -265,18 +269,18 @@ static void *init_plugin (xine_t *xine, void *data) { return this; } -/* This is a list of all of the internal xine audio buffer types that +/* This is a list of all of the internal xine audio buffer types that * this decoder is able to handle. Check src/xine-engine/buffer.h for a * list of valid buffer types (and add a new one if the one you need does * not exist). Terminate the list with a 0. */ -static uint32_t audio_types[] = { +static uint32_t audio_types[] = { BUF_AUDIO_NSF, 0 }; /* This data structure combines the list of supported xine buffer types and * the priority that the plugin should be given with respect to other - * plugins that handle the same buffer type. A plugin with priority (n+1) + * plugins that handle the same buffer type. A plugin with priority (n+1) * will be used instead of a plugin with priority (n). */ static const decoder_info_t dec_info_audio = { audio_types, /* supported types */ diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 8d8f23a05..630d5a120 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -1,18 +1,18 @@ -/* +/* * Copyright (C) 2000-2003 the xine project - * + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -20,6 +20,11 @@ * 31-8-2001 Added LPCM rate sensing. * (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef __sun #define _XOPEN_SOURCE 500 #endif @@ -53,31 +58,43 @@ typedef struct lpcm_decoder_s { xine_stream_t *stream; uint32_t rate; - uint32_t bits_per_sample; - uint32_t number_of_channels; - uint32_t ao_cap_mode; - + uint32_t bits_per_sample; + uint32_t number_of_channels; + uint32_t ao_cap_mode; + 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) { 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; - + /* Drop preview data */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; @@ -88,20 +105,57 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { unsigned int bits_per_sample = 16; unsigned int sample_rate = 0; unsigned int num_channels; - - 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; + + 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]); + + 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 */ + 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 || this->number_of_channels != num_channels || this->rate != sample_rate || @@ -110,16 +164,20 @@ 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); + } } - + 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++; } - + /* * (re-)open output device */ @@ -143,80 +201,123 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { /* stream/meta info */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Linear PCM"); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->bits_per_sample * this->rate * this->number_of_channels); } - if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) + 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 */ buf->type &= 0xffff0000; stream_be = ( buf->type == BUF_AUDIO_LPCM_BE ); - + 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 ) { swab( s, d, 8 ); s += 10; d += 8; - n -= 10; + n -= 10; } } else { while( n >= 0 ) { memcpy( d, s, 8 ); s += 10; d += 8; - n -= 10; + n -= 10; } } } 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 >= 0) { + while (n >= 3) { if ( stream_be ) { - *d++ = s[0]; - *d++ = s[1]; + if ( stream_be == this->cpu_be ) { + *d++ = s[0]; + *d++ = s[1]; + } else { + *d++ = s[1]; + *d++ = s[0]; + } } else { - *d++ = s[1]; - *d++ = s[2]; + if ( stream_be == this->cpu_be ) { + *d++ = s[1]; + *d++ = s[2]; + } + else + { + *d++ = s[2]; + *d++ = s[1]; + } } s += 3; 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); + } 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->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) { - lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; + lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; - if (this->output_open) + if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; + free (this->buf); + free (this_gen); } @@ -224,7 +325,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre lpcm_decoder_t *this ; - this = (lpcm_decoder_t *) xine_xmalloc (sizeof (lpcm_decoder_t)); + this = (lpcm_decoder_t *) calloc(1, sizeof(lpcm_decoder_t)); this->audio_decoder.decode_data = lpcm_decode_data; this->audio_decoder.reset = lpcm_reset; @@ -233,11 +334,11 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre this->output_open = 0; this->rate = 0; - this->bits_per_sample=0; - this->number_of_channels=0; - this->ao_cap_mode=0; + this->bits_per_sample=0; + this->number_of_channels=0; + this->ao_cap_mode=0; this->stream = stream; - + this->cpu_be = ( htons(1) == 1 ); return &this->audio_decoder; @@ -259,7 +360,7 @@ static void *init_plugin (xine_t *xine, void *data) { lpcm_class_t *this ; - this = (lpcm_class_t *) xine_xmalloc (sizeof (lpcm_class_t)); + this = (lpcm_class_t *) calloc(1, sizeof(lpcm_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.get_identifier = get_identifier; @@ -269,7 +370,7 @@ static void *init_plugin (xine_t *xine, void *data) { return this; } -static uint32_t audio_types[] = { +static uint32_t audio_types[] = { BUF_AUDIO_LPCM_BE, BUF_AUDIO_LPCM_LE, 0 }; @@ -279,7 +380,7 @@ static const decoder_info_t dec_info_audio = { }; const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ + /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 15, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/libxineadec/xine_speex_decoder.c b/src/libxineadec/xine_speex_decoder.c index aa8234385..9ae2e9718 100644 --- a/src/libxineadec/xine_speex_decoder.c +++ b/src/libxineadec/xine_speex_decoder.c @@ -1,18 +1,18 @@ -/* +/* * Copyright (C) 2000-2003 the xine project - * + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -170,16 +170,16 @@ void read_metadata (speex_decoder_t *this, char * comments, int length) #endif for (i = 0; speex_comment_keys[i].key != NULL; i++) { + size_t keylen = strlen(speex_comment_keys[i].key); if ( !strncasecmp (speex_comment_keys[i].key, c, - strlen(speex_comment_keys[i].key)) ) { - int keylen = strlen(speex_comment_keys[i].key); + keylen) ) { char meta_info[(len - keylen) + 1]; - + lprintf ("known metadata %d %d\n", i, speex_comment_keys[i].xine_metainfo_index); - - snprintf(meta_info, (len - keylen), "%s", c + keylen); + + strncpy(meta_info, &c[keylen], len-keylen); _x_meta_info_set_utf8(this->stream, speex_comment_keys[i].xine_metainfo_index, meta_info); } } @@ -204,7 +204,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (!this->st) { SpeexMode * spx_mode; SpeexHeader * spx_header; - int modeID; + unsigned int modeID; int bitrate; speex_bits_init (&this->bits); @@ -216,7 +216,12 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { return; } - modeID = spx_header->mode; + modeID = (unsigned int)spx_header->mode; + if (modeID >= SPEEX_NB_MODES) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid mode ID %u\n", modeID); + return; + } + spx_mode = (SpeexMode *) speex_mode_list[modeID]; if (spx_mode->bitstream_version != spx_header->mode_bitstream_version) { @@ -238,7 +243,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->channels = spx_header->nb_channels; if (this->channels == 2) { SpeexCallback callback; - + callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = &this->stereo; @@ -247,7 +252,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->nframes = spx_header->frames_per_packet; if (!this->nframes) this->nframes = 1; - + speex_decoder_ctl (this->st, SPEEX_GET_FRAME_SIZE, &this->frame_size); speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); @@ -266,10 +271,10 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (!this->header_count) { int mode = _x_ao_channels2mode(this->channels); - + if (!this->output_open) { this->output_open = - (this->stream->audio_out->open) (this->stream->audio_out, + (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->rate, @@ -278,9 +283,9 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { } } } - + } else if (this->output_open) { - int i, j; + int j; audio_buffer_t *audio_buffer; @@ -317,9 +322,9 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { audio_buffer->vpts = this->pts; this->pts=0; audio_buffer->num_frames = this->frame_size; - + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - + buf->pts=0; } @@ -331,26 +336,26 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { static void speex_dispose (audio_decoder_t *this_gen) { - speex_decoder_t *this = (speex_decoder_t *) this_gen; - + speex_decoder_t *this = (speex_decoder_t *) this_gen; + if (this->st) { speex_decoder_destroy (this->st); } speex_bits_destroy (&this->bits); - if (this->output_open) + if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); free (this_gen); } -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { speex_decoder_t *this ; static SpeexStereoState init_stereo = SPEEX_STEREO_STATE_INIT; - this = (speex_decoder_t *) xine_xmalloc (sizeof (speex_decoder_t)); + this = (speex_decoder_t *) calloc(1, sizeof(speex_decoder_t)); this->audio_decoder.decode_data = speex_decode_data; this->audio_decoder.reset = speex_reset; @@ -390,8 +395,8 @@ static void dispose_class (audio_decoder_class_t *this) { static void *init_plugin (xine_t *xine, void *data) { speex_class_t *this; - - this = (speex_class_t *) xine_xmalloc (sizeof (speex_class_t)); + + this = (speex_class_t *) calloc(1, sizeof(speex_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.get_identifier = get_identifier; @@ -401,7 +406,7 @@ static void *init_plugin (xine_t *xine, void *data) { return this; } -static uint32_t audio_types[] = { +static uint32_t audio_types[] = { BUF_AUDIO_SPEEX, 0 }; @@ -411,7 +416,7 @@ static const decoder_info_t dec_info_audio = { }; const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ + /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 15, "speex", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/libxineadec/xine_vorbis_decoder.c b/src/libxineadec/xine_vorbis_decoder.c index 4b7a6c15d..99012c40d 100644 --- a/src/libxineadec/xine_vorbis_decoder.c +++ b/src/libxineadec/xine_vorbis_decoder.c @@ -1,18 +1,18 @@ -/* +/* * Copyright (C) 2000-2003 the xine project - * + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -41,6 +41,7 @@ #include <vorbis/codec.h> #define MAX_NUM_SAMPLES 4096 +#define INIT_BUFSIZE 8192 typedef struct { audio_decoder_class_t decoder_class; @@ -70,6 +71,11 @@ typedef struct vorbis_decoder_s { xine_stream_t *stream; + /* data accumulation stuff */ + unsigned char *buf; + int bufsize; + int size; + } vorbis_decoder_t; @@ -78,10 +84,11 @@ static void vorbis_reset (audio_decoder_t *this_gen) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; if( this->header_count ) return; + this->size = 0; /* clear block first, as it might contain allocated data */ vorbis_block_clear(&this->vb); - vorbis_block_init(&this->vd,&this->vb); + vorbis_block_init(&this->vd,&this->vb); } static void vorbis_discontinuity (audio_decoder_t *this_gen) { @@ -136,132 +143,153 @@ static void get_metadata (vorbis_decoder_t *this) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "vorbis"); } +static void vorbis_check_bufsize (vorbis_decoder_t *this, int size) { + if (size > this->bufsize) { + this->bufsize = size + size / 2; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("vorbis: increasing buffer to %d to avoid overflow.\n"), + this->bufsize); + this->buf = realloc(this->buf, this->bufsize); + } +} + static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; memset( &this->op, 0, sizeof(this->op) ); - this->op.packet = buf->content; - this->op.bytes = buf->size; - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { - lprintf ("%d headers to go\n", this->header_count); + /* data accumulation */ + vorbis_check_bufsize(this, this->size + buf->size); + xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); + this->size += buf->size; - if (this->header_count) { - int res = 0; + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { + this->op.packet = this->buf; + this->op.bytes = this->size; - if (this->header_count == 3) - this->op.b_o_s = 1; + /* reset accumultaion buffer */ + this->size = 0; - - if( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ){ - /* error case; not a vorbis header */ - xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res); - xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64); - return; - } + if ( (buf->decoder_flags & BUF_FLAG_HEADER) && + !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { - this->header_count--; - - if (!this->header_count) { - - int mode = AO_CAP_MODE_MONO; - - get_metadata (this); - - mode = _x_ao_channels2mode(this->vi.channels); - - this->convsize=MAX_NUM_SAMPLES/this->vi.channels; - - if (!this->output_open) { - this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, - this->stream, - 16, - this->vi.rate, - mode) ; - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, - this->vi.bitrate_nominal); - - } - - /* OK, got and parsed all three headers. Initialize the Vorbis - * packet->PCM decoder. */ - lprintf("all three headers parsed. initializing decoder.\n"); - /* initialize central decode state */ - vorbis_synthesis_init(&this->vd,&this->vi); - /* initialize local state for most of the decode so multiple - * block decodes can proceed in parallel. We could init - * multiple vorbis_block structures for vd here */ - vorbis_block_init(&this->vd,&this->vb); - } - } - - } else if (this->output_open) { - - float **pcm; - int samples; - - if(vorbis_synthesis(&this->vb,&this->op)==0) - vorbis_synthesis_blockin(&this->vd,&this->vb); - - if (buf->pts!=0) - this->pts=buf->pts; - - while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){ - - /* **pcm is a multichannel float vector. In stereo, for - * example, pcm[0][...] is left, and pcm[1][...] is right. - * samples is the size of each channel. Convert the float - * values (-1.<=range<=1.) to whatever PCM format and write - * it out - */ - - int i,j; - int bout=(samples<this->convsize?samples:this->convsize); - audio_buffer_t *audio_buffer; - - audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); - - /* convert floats to 16 bit signed ints (host order) and - interleave */ - for(i=0;i<this->vi.channels;i++){ - ogg_int16_t *ptr=audio_buffer->mem+i; - float *mono=pcm[i]; - for(j=0;j<bout;j++){ - int val=(mono[j] + 1.0f) * 32768.f; - val -= 32768; - /* might as well guard against clipping */ - if(val>32767){ - val=32767; - } else if(val<-32768){ - val=-32768; - } - *ptr=val; - ptr+=this->vi.channels; - } - } + lprintf ("%d headers to go\n", this->header_count); + + if (this->header_count) { + int res = 0; - audio_buffer->vpts = this->pts; - this->pts=0; - audio_buffer->num_frames = bout; + if (this->header_count == 3) + this->op.b_o_s = 1; - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + if ( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ) { + /* error case; not a vorbis header */ + xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res); + xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64); + return; + } - buf->pts=0; + this->header_count--; - /* tell libvorbis how many samples we actually consumed */ - vorbis_synthesis_read(&this->vd,bout); + if (!this->header_count) { + + int mode = AO_CAP_MODE_MONO; + + get_metadata (this); + + mode = _x_ao_channels2mode(this->vi.channels); + + this->convsize=MAX_NUM_SAMPLES/this->vi.channels; + + if (!this->output_open) { + this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, + this->stream, + 16, + this->vi.rate, + mode) ; + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, + this->vi.bitrate_nominal); + + } + + /* OK, got and parsed all three headers. Initialize the Vorbis + * packet->PCM decoder. */ + lprintf("all three headers parsed. initializing decoder.\n"); + /* initialize central decode state */ + vorbis_synthesis_init(&this->vd,&this->vi); + /* initialize local state for most of the decode so multiple + * block decodes can proceed in parallel. We could init + * multiple vorbis_block structures for vd here */ + vorbis_block_init(&this->vd,&this->vb); + } + } + + } else if (this->output_open) { + + float **pcm; + int samples; + + if(vorbis_synthesis(&this->vb,&this->op)==0) + vorbis_synthesis_blockin(&this->vd,&this->vb); + + if (buf->pts!=0) + this->pts=buf->pts; + + while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){ + + /* **pcm is a multichannel float vector. In stereo, for + * example, pcm[0][...] is left, and pcm[1][...] is right. + * samples is the size of each channel. Convert the float + * values (-1.<=range<=1.) to whatever PCM format and write + * it out + */ + + int i,j; + int bout=(samples<this->convsize?samples:this->convsize); + audio_buffer_t *audio_buffer; + + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); + + /* convert floats to 16 bit signed ints (host order) and + interleave */ + for(i=0;i<this->vi.channels;i++){ + ogg_int16_t *ptr=audio_buffer->mem+i; + float *mono=pcm[i]; + for(j=0;j<bout;j++){ + int val=(mono[j] + 1.0f) * 32768.f; + val -= 32768; + /* might as well guard against clipping */ + if(val>32767){ + val=32767; + } else if(val<-32768){ + val=-32768; + } + *ptr=val; + ptr+=this->vi.channels; + } + } + + audio_buffer->vpts = this->pts; + this->pts=0; + audio_buffer->num_frames = bout; + + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + + buf->pts=0; + + /* tell libvorbis how many samples we actually consumed */ + vorbis_synthesis_read(&this->vd,bout); + } + } else { + lprintf("output not open\n"); } - } else { - lprintf("output not open\n"); } } static void vorbis_dispose (audio_decoder_t *this_gen) { - vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; + vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; if( !this->header_count ) { lprintf("deinitializing decoder\n"); @@ -274,7 +302,7 @@ static void vorbis_dispose (audio_decoder_t *this_gen) { vorbis_info_clear(&this->vi); /* must be called last */ - if (this->output_open) + if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); lprintf("libvorbis instance destroyed\n"); @@ -282,12 +310,12 @@ static void vorbis_dispose (audio_decoder_t *this_gen) { free (this_gen); } -static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { vorbis_decoder_t *this ; - this = (vorbis_decoder_t *) xine_xmalloc (sizeof (vorbis_decoder_t)); + this = (vorbis_decoder_t *) calloc(1, sizeof(vorbis_decoder_t)); this->audio_decoder.decode_data = vorbis_decode_data; this->audio_decoder.reset = vorbis_reset; @@ -299,6 +327,10 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, this->header_count = 3; this->convsize = 0; + this->bufsize = INIT_BUFSIZE; + this->buf = calloc(1, INIT_BUFSIZE); + this->size = 0; + vorbis_info_init(&this->vi); vorbis_comment_init(&this->vc); @@ -326,8 +358,8 @@ static void dispose_class (audio_decoder_class_t *this) { static void *init_plugin (xine_t *xine, void *data) { vorbis_class_t *this; - - this = (vorbis_class_t *) xine_xmalloc (sizeof (vorbis_class_t)); + + this = (vorbis_class_t *) calloc(1, sizeof(vorbis_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.get_identifier = get_identifier; @@ -337,7 +369,7 @@ static void *init_plugin (xine_t *xine, void *data) { return this; } -static uint32_t audio_types[] = { +static uint32_t audio_types[] = { BUF_AUDIO_VORBIS, 0 }; @@ -347,7 +379,7 @@ static const decoder_info_t dec_info_audio = { }; const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ + /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 15, "vorbis", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |