summaryrefslogtreecommitdiff
path: root/src/libxineadec
diff options
context:
space:
mode:
Diffstat (limited to 'src/libxineadec')
-rw-r--r--src/libxineadec/Makefile.am3
-rw-r--r--src/libxineadec/fooaudio.c26
-rw-r--r--src/libxineadec/gsm610.c6
-rw-r--r--src/libxineadec/gsm610/long_term.c4
-rw-r--r--src/libxineadec/gsm610/lpc.c4
-rw-r--r--src/libxineadec/gsm610/rpe.c4
-rw-r--r--src/libxineadec/gsm610/short_term.c4
-rw-r--r--src/libxineadec/nosefart/Makefile.am2
-rw-r--r--src/libxineadec/nsf.c18
-rw-r--r--src/libxineadec/xine_lpcm_decoder.c217
-rw-r--r--src/libxineadec/xine_speex_decoder.c63
-rw-r--r--src/libxineadec/xine_vorbis_decoder.c270
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 }
};