summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-08 01:00:10 +0100
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-08 01:00:10 +0100
commit628c4cbd9d023e74a7c6805d7ec0f163f2c172d1 (patch)
treeb74ddd76dc7fb3080ea269c6d3776f84aca36837
parent3f255412a55880c7323debef2bff0fc2dd5ed554 (diff)
parent964f55aef546a1f1574c9f6ec10b3410fe390c34 (diff)
downloadxine-lib-628c4cbd9d023e74a7c6805d7ec0f163f2c172d1.tar.gz
xine-lib-628c4cbd9d023e74a7c6805d7ec0f163f2c172d1.tar.bz2
Merge from 1.1.
--HG-- rename : src/xine-engine/buffer.h => include/xine/buffer.h rename : src/libmad/xine_mad_decoder.c => src/audio_dec/xine_mad_decoder.c rename : src/combined/combined_wavpack.c => src/combined/wavpack_combined.c
-rw-r--r--ChangeLog3
-rw-r--r--doc/man/en/Makefile.am4
-rw-r--r--include/Makefile.am3
-rw-r--r--include/xine/buffer.h1
-rw-r--r--src/audio_dec/xine_mad_decoder.c2
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c81
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c20
-rw-r--r--src/combined/wavpack_combined.c2
-rw-r--r--src/demuxers/Makefile.am2
-rw-r--r--src/demuxers/demux_matroska.c4
-rw-r--r--src/demuxers/demux_real.c151
-rw-r--r--src/demuxers/demux_realaudio.c88
-rw-r--r--src/demuxers/real_common.h56
-rw-r--r--src/libreal/xine_real_audio_decoder.c166
-rw-r--r--src/libreal/xine_real_video_decoder.c46
-rw-r--r--src/video_out/video_out_macosx.m2
-rw-r--r--src/xine-engine/buffer_types.c8
17 files changed, 459 insertions, 180 deletions
diff --git a/ChangeLog b/ChangeLog
index 25565e72a..5a4583d71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -70,6 +70,9 @@ xine-lib (1.1.12) 2008-??-??
* And another, this time in the Matroska demuxer.
* Added a tool to assist with generating front ends' desktop files. It
lists MIME types & filename extensions known to the installed xine-lib.
+ * Various Real codec improvements, including:
+ - RV20 no longer causes segfaults (observed on amd64);
+ - Cook is now handled by ffmpeg.
xine-lib (1.1.11.1) 2008-03-30
* Security fixes:
diff --git a/doc/man/en/Makefile.am b/doc/man/en/Makefile.am
index 8cdf212a6..9fe87cc11 100644
--- a/doc/man/en/Makefile.am
+++ b/doc/man/en/Makefile.am
@@ -7,7 +7,7 @@ man_MANS = $(STATICMANS) $(DYNAMICMANS)
BUILT_SOURCES = $(DYNAMICMANS)
DISTCLEANFILES = $(DYNAMICMANS)
-EXTRA_DIST = $(STATICMANS) $(suffix .in,$(DYNAMICMANS))
+EXTRA_DIST = $(STATICMANS) xine-list.1.in
xine-list-@XINE_SERIES@.1: xine-list.1.in
- (echo '.ds xl xine\-list\-@XINE_MAJOR@.@XINE_MINOR@'; cat $<) >$@
+ (echo '.ds xl xine\-list\-@XINE_SERIES@'; cat $<) >$@
diff --git a/include/Makefile.am b/include/Makefile.am
index 7f569f498..aa26094a6 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -46,7 +46,8 @@ nobase_include_HEADERS = xine.h \
xine/xmllexer.h \
xine/xmlparser.h
-noinst_HEADERS = config.h configure.h
+noinst_HEADERS = config.h
+nodist_noinst_HEADERS = configure.h
nodist_include_HEADERS = $(inttypes_h)
diff --git a/include/xine/buffer.h b/include/xine/buffer.h
index 9401f8852..a53b99db3 100644
--- a/include/xine/buffer.h
+++ b/include/xine/buffer.h
@@ -264,6 +264,7 @@ extern "C" {
#define BUF_AUDIO_SMACKER 0x033B0000
#define BUF_AUDIO_FLVADPCM 0x033C0000
#define BUF_AUDIO_WAVPACK 0x033D0000
+#define BUF_AUDIO_MP3ADU 0x033E0000
/*@}*/
/**
diff --git a/src/audio_dec/xine_mad_decoder.c b/src/audio_dec/xine_mad_decoder.c
index 74c04924f..abad70f4f 100644
--- a/src/audio_dec/xine_mad_decoder.c
+++ b/src/audio_dec/xine_mad_decoder.c
@@ -393,7 +393,7 @@ static const uint32_t audio_types[] = {
static const decoder_info_t dec_info_audio = {
audio_types, /* supported types */
- 7 /* priority */
+ 8 /* priority */
};
const plugin_info_t xine_plugin_info[] EXPORTED = {
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index f79014fde..2b42cfb33 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -81,6 +81,7 @@ static const ff_codec_t ff_audio_lookup[] = {
{BUF_AUDIO_14_4, CODEC_ID_RA_144, "Real 14.4 (ffmpeg)"},
{BUF_AUDIO_28_8, CODEC_ID_RA_288, "Real 28.8 (ffmpeg)"},
{BUF_AUDIO_MPEG, CODEC_ID_MP3, "MP3 (ffmpeg)"},
+ {BUF_AUDIO_MP3ADU, CODEC_ID_MP3ADU, "MPEG-3 adu (ffmpeg)"},
{BUF_AUDIO_MSADPCM, CODEC_ID_ADPCM_MS, "MS ADPCM (ffmpeg)"},
{BUF_AUDIO_QTIMAADPCM, CODEC_ID_ADPCM_IMA_QT, "QT IMA ADPCM (ffmpeg)"},
{BUF_AUDIO_MSIMAADPCM, CODEC_ID_ADPCM_IMA_WAV, "MS IMA ADPCM (ffmpeg)"},
@@ -201,8 +202,8 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->audio_channels = this->buf[0x37];
/* this->audio_bits = buf->content[0x35] */
- this->context->block_align = _X_BE_16(&this->buf[0x2A]);
-
+ this->context->block_align = _X_BE_32(&this->buf[0x18]);
+
this->context->extradata_size = 5*sizeof(short);
this->context->extradata = xine_xmalloc(this->context->extradata_size);
@@ -213,7 +214,49 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
ptr[2] = _X_BE_16(&this->buf[0x16]); /* subpacket flavour */
ptr[3] = _X_BE_32(&this->buf[0x18]); /* coded frame size */
ptr[4] = 0; /* codec's data length */
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: 28_8 audio channels %d bits %d sample rate %d block align %d\n",
+ this->audio_channels, this->audio_bits, this->audio_sample_rate,
+ this->context->block_align);
break;
+ case BUF_AUDIO_COOK:
+ {
+ int version;
+ int data_len;
+ int extradata;
+
+ version = _X_BE_16 (this->buf+4);
+ if (version == 4) {
+ this->audio_sample_rate = _X_BE_16 (this->buf+48);
+ this->audio_bits = _X_BE_16 (this->buf+52);
+ this->audio_channels = _X_BE_16 (this->buf+54);
+ data_len = _X_BE_32 (this->buf+67);
+ extradata = 71;
+ } else {
+ this->audio_sample_rate = _X_BE_16 (this->buf+54);
+ this->audio_bits = _X_BE_16 (this->buf+58);
+ this->audio_channels = _X_BE_16 (this->buf+60);
+ data_len = _X_BE_32 (this->buf+74);
+ extradata = 78;
+ }
+ this->context->block_align = _X_BE_16 (this->buf+44);
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: cook audio channels %d bits %d sample rate %d block align %d\n",
+ this->audio_channels, this->audio_bits, this->audio_sample_rate,
+ this->context->block_align);
+
+ if (extradata + data_len > this->size)
+ break; /* abort early - extradata length is bad */
+
+ this->context->extradata_size = data_len;
+ this->context->extradata = xine_xmalloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ xine_fast_memcpy (this->context->extradata, this->buf + extradata,
+ this->context->extradata_size);
+ break;
+ }
default:
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type);
@@ -230,6 +273,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->context->sample_rate = this->audio_sample_rate;
this->context->channels = this->audio_channels;
this->context->codec_id = this->codec->id;
+ this->context->codec_type = this->codec->type;
this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
this->size = 0;
@@ -269,7 +313,26 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->decoder_ok = 1;
}
+ if( buf->decoder_flags & BUF_FLAG_PREVIEW )
+ return;
+
+ ff_audio_ensure_buffer_size(this, this->size + buf->size);
+ xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
+ this->size += buf->size;
+
if (!this->output_open) {
+ if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) {
+ avcodec_decode_audio (this->context,
+ (int16_t *)this->decode_buffer,
+ &decode_buffer_size,
+ &this->buf[0],
+ this->size);
+ this->audio_bits = this->context->bits_per_sample;
+ this->audio_sample_rate = this->context->sample_rate;
+ this->audio_channels = this->context->channels;
+ if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels)
+ return;
+ }
this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
this->stream, this->audio_bits, this->audio_sample_rate,
_x_ao_channels2mode(this->audio_channels));
@@ -279,13 +342,6 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
if (!this->output_open)
return;
- if( buf->decoder_flags & BUF_FLAG_PREVIEW )
- return;
-
- ff_audio_ensure_buffer_size(this, this->size + buf->size);
- xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
- this->size += buf->size;
-
if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
offset = 0;
@@ -326,7 +382,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
/* fill up this buffer */
xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out],
- bytes_to_send);
+ bytes_to_send);
/* byte count / 2 (bytes / sample) / channels */
audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels;
@@ -357,7 +413,8 @@ static void ff_audio_reset (audio_decoder_t *this_gen) {
if( this->context && this->decoder_ok ) {
pthread_mutex_lock (&ffmpeg_lock);
avcodec_close (this->context);
- avcodec_open (this->context, this->codec);
+ if (avcodec_open (this->context, this->codec) < 0)
+ this->decoder_ok = 0;
pthread_mutex_unlock (&ffmpeg_lock);
}
}
@@ -537,5 +594,5 @@ static const uint32_t supported_audio_types[] = {
decoder_info_t dec_info_ffmpeg_audio = {
supported_audio_types, /* supported types */
- 6 /* priority */
+ 7 /* priority */
};
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
index 58305aa13..10b326d45 100644
--- a/src/combined/ffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -946,6 +946,26 @@ static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *bu
this->context->slice_offset = xine_xmalloc(sizeof(int)*SLICE_OFFSET_SIZE);
this->slice_offset_size = SLICE_OFFSET_SIZE;
+ this->context->extradata_size = this->size - 26;
+ if (this->context->extradata_size < 8) {
+ this->context->extradata_size= 8;
+ this->context->extradata = malloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ ((uint32_t *)this->context->extradata)[0] = 0;
+ if (codec_type == BUF_VIDEO_RV10)
+ ((uint32_t *)this->context->extradata)[1] = 0x10000000;
+ else
+ ((uint32_t *)this->context->extradata)[1] = 0x10003001;
+ } else {
+ this->context->extradata = malloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(this->context->extradata, this->buf + 26,
+ this->context->extradata_size);
+ }
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_video_dec: buf size %d\n", this->size);
+
lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight);
break;
diff --git a/src/combined/wavpack_combined.c b/src/combined/wavpack_combined.c
index 8a4b488ae..ca54635e7 100644
--- a/src/combined/wavpack_combined.c
+++ b/src/combined/wavpack_combined.c
@@ -33,7 +33,7 @@ static const uint32_t audio_types[] = {
static const decoder_info_t decoder_info_wv = {
audio_types, /* supported types */
- 7 /* priority */
+ 8 /* priority */
};
const plugin_info_t xine_plugin_info[] EXPORTED = {
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index 276505521..876b64f7a 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -8,7 +8,7 @@ AM_LDFLAGS = $(xineplug_ldflags)
# ---------
# All of xine demuxer plugins should be named like the scheme "xineplug_dmx_"
-noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h
+noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h real_common.h
if ENABLE_ASF
asf_module = xineplug_dmx_asf.la
diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c
index e0e8c9e78..713995e97 100644
--- a/src/demuxers/demux_matroska.c
+++ b/src/demuxers/demux_matroska.c
@@ -635,9 +635,7 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) {
}
buf->size = frame[i];
- buf->decoder_flags = BUF_FLAG_HEADER;
- if (i == 2)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
+ buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_START | BUF_FLAG_FRAME_END;
buf->type = track->buf_type;
buf->pts = 0;
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 7b5f7530d..cc6a214e0 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -55,6 +55,8 @@
#include <xine/demux.h>
#include "bswap.h"
+#include "real_common.h"
+
#define FOURCC_TAG BE_FOURCC
#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F')
#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P')
@@ -113,6 +115,12 @@ typedef struct {
int index_entries;
mdpr_t *mdpr;
+ int sps, cfs, w, h;
+ int block_align;
+ int frame_size;
+ uint8_t *frame_buffer;
+ uint32_t frame_num_bytes;
+ uint32_t sub_packet_cnt;
} real_stream_t;
typedef struct {
@@ -168,7 +176,6 @@ typedef struct {
demux_class_t demux_class;
} demux_real_class_t;
-
static void real_parse_index(demux_real_t *this) {
off_t next_index_chunk = this->index_start;
@@ -310,6 +317,64 @@ static void real_free_mdpr (mdpr_t *mdpr) {
free (mdpr);
}
+static void real_parse_audio_specific_data (demux_real_t *this,
+ real_stream_t * stream,
+ uint8_t * data, int len)
+{
+ int coded_frame_size;
+ int codec_data_length;
+ int coded_frame_size2;
+ int subpacket_size;
+
+ coded_frame_size = _X_BE_32 (data+24);
+ codec_data_length = _X_BE_16 (data+40);
+ coded_frame_size2 = _X_BE_16 (data+42);
+ subpacket_size = _X_BE_16 (data+44);
+
+ stream->sps = subpacket_size;
+ stream->w = coded_frame_size2;
+ stream->h = codec_data_length;
+ stream->block_align = coded_frame_size2;
+ stream->cfs = coded_frame_size;
+
+ switch (stream->buf_type) {
+ case BUF_AUDIO_COOK:
+ case BUF_AUDIO_ATRK:
+ stream->block_align = subpacket_size;
+ break;
+
+ case BUF_AUDIO_14_4:
+ break;
+
+ case BUF_AUDIO_28_8:
+ stream->block_align = stream->cfs;
+ break;
+
+ case BUF_AUDIO_SIPRO:
+ /* this->block_align = 19; */
+ break;
+
+ default:
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: error, i don't handle buf type 0x%08x\n", stream->buf_type);
+ }
+
+ if (stream->sps) {
+ stream->frame_size = stream->w / stream->sps * stream->h * stream->sps;
+ stream->frame_buffer = xine_xmalloc (stream->frame_size);
+ stream->frame_num_bytes = 0;
+ } else {
+ stream->frame_size = stream->w * stream->h;
+ stream->frame_buffer = xine_xmalloc (stream->frame_size);
+ stream->frame_num_bytes = 0;
+ }
+ stream->sub_packet_cnt = 0;
+
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_real: buf type 0x%08x frame size %dblock align %d\n", stream->buf_type,
+ stream->frame_size, stream->block_align);
+
+}
static void real_parse_headers (demux_real_t *this) {
@@ -420,8 +485,16 @@ static void real_parse_headers (demux_real_t *this) {
mdpr = real_parse_mdpr (chunk_buffer);
lprintf ("parsing type specific data...\n");
+ if(!strcmp(mdpr->mime_type, "audio/X-MP3-draft-00")) {
+ lprintf ("mpeg layer 3 audio detected...\n");
- if(_X_BE_32(mdpr->type_specific_data) == RA_TAG) {
+ fourcc = ME_FOURCC('a', 'd', 'u', 0x55);
+ this->audio_streams[this->num_audio_streams].fourcc = fourcc;
+ this->audio_streams[this->num_audio_streams].buf_type = _x_formattag_to_buf_audio(fourcc);
+ this->audio_streams[this->num_audio_streams].index = NULL;
+ this->audio_streams[this->num_audio_streams].mdpr = mdpr;
+ this->num_audio_streams++;
+ } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG) {
int version, len;
if(this->num_audio_streams == MAX_AUDIO_STREAMS) {
@@ -459,6 +532,10 @@ static void real_parse_headers (demux_real_t *this) {
this->audio_streams[this->num_audio_streams].index = NULL;
this->audio_streams[this->num_audio_streams].mdpr = mdpr;
+ real_parse_audio_specific_data (this,
+ &this->audio_streams[this->num_audio_streams],
+ mdpr->type_specific_data,
+ mdpr->type_specific_len);
this->num_audio_streams++;
if (!this->audio_streams[this->num_audio_streams].buf_type)
@@ -747,6 +824,13 @@ unknown:
memcpy(buf->content, mdpr->type_specific_data + 79,
buf->decoder_info[2]);
+ } else if(buf->type == BUF_AUDIO_MP3ADU) {
+ buf->decoder_flags |= BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END;
+ buf->size = 0;
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = 0;
+ buf->decoder_info[2] = 0;
+ buf->decoder_info[3] = 0;
} else {
memcpy(buf->content, mdpr->type_specific_data,
mdpr->type_specific_len);
@@ -985,6 +1069,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
off_t offset, input_length = 0;
int normpos = 0;
+ read_next_packet:
if(this->reference_mode)
return demux_real_parse_references(this);
@@ -1322,6 +1407,64 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
}
free(sizes);
+ } else if (this->audio_stream->buf_type == BUF_AUDIO_COOK ||
+ this->audio_stream->buf_type == BUF_AUDIO_ATRK ||
+ this->audio_stream->buf_type == BUF_AUDIO_28_8 ||
+ this->audio_stream->buf_type == BUF_AUDIO_SIPRO) {
+ /* reorder */
+ uint8_t * buffer = this->audio_stream->frame_buffer;
+ int sps = this->audio_stream->sps;
+ int sph = this->audio_stream->h;
+ int cfs = this->audio_stream->cfs;
+ int w = this->audio_stream->w;
+ int spc = this->audio_stream->sub_packet_cnt;
+ int x, pos;
+
+ switch (this->audio_stream->buf_type) {
+ case BUF_AUDIO_28_8:
+ for (x = 0; x < sph / 2; x++) {
+ pos = x * 2 * w + spc * cfs;
+ if(this->input->read(this->input, buffer + pos, cfs) < cfs) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ break;
+ case BUF_AUDIO_COOK:
+ case BUF_AUDIO_ATRK:
+ for (x = 0; x < w / sps; x++) {
+ pos = sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1));
+ if(this->input->read(this->input, buffer + pos, sps) < sps) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ break;
+ case BUF_AUDIO_SIPRO:
+ pos = spc * w;
+ if(this->input->read(this->input, buffer + pos, w) < w) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ if (spc == sph - 1)
+ demux_real_sipro_swap (buffer, sph * w * 2 / 96);
+ break;
+ }
+ if(++this->audio_stream->sub_packet_cnt == sph) {
+ this->audio_stream->sub_packet_cnt = 0;
+ _x_demux_send_data(this->audio_fifo, buffer, this->audio_stream->frame_size,
+ pts, this->audio_stream->buf_type, 0, normpos, input_time,
+ this->duration, 0);
+ }
} else {
if(_x_demux_read_send_data(this->audio_fifo, this->input, size, pts,
this->audio_stream->buf_type, 0, normpos,
@@ -1471,6 +1614,9 @@ static int demux_real_seek (demux_plugin_t *this_gen,
this->input->seek(this->input, index[i].offset, SEEK_SET);
if(playing) {
+ if(this->audio_stream)
+ this->audio_stream->sub_packet_cnt = 0;
+
this->buf_flag_seek = 1;
_x_demux_flush_engine(this->stream);
}
@@ -1507,6 +1653,7 @@ static void demux_real_dispose (demux_plugin_t *this_gen) {
for(i = 0; i < this->num_audio_streams; i++) {
real_free_mdpr(this->audio_streams[i].mdpr);
free(this->audio_streams[i].index);
+ free(this->audio_streams[i].frame_buffer);
}
free(this->fragment_tab);
diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c
index 7ee608c83..2873a522e 100644
--- a/src/demuxers/demux_realaudio.c
+++ b/src/demuxers/demux_realaudio.c
@@ -41,6 +41,8 @@
#include "bswap.h"
#include "group_audio.h"
+#include "real_common.h"
+
#define RA_FILE_HEADER_PREV_SIZE 22
typedef struct {
@@ -62,6 +64,10 @@ typedef struct {
off_t data_start;
off_t data_size;
+ int sps, cfs, w, h;
+ int frame_size;
+ uint8_t *frame_buffer;
+
unsigned char *header;
unsigned int header_size;
} demux_ra_t;
@@ -70,6 +76,9 @@ typedef struct {
demux_class_t demux_class;
} demux_ra_class_t;
+/* Map flavour to bytes per second */
+static int sipr_fl2bps[4] = {813, 1062, 625, 2000}; // 6.5, 8.5, 5, 16 kbit per second
+
/* returns 1 if the RealAudio file was opened successfully, 0 otherwise */
static int open_ra_file(demux_ra_t *this) {
unsigned char file_header[RA_FILE_HEADER_PREV_SIZE], len;
@@ -165,20 +174,41 @@ static int open_ra_file(demux_ra_t *this) {
offset++;
/* Fourcc for version 3 comes after meta info */
- if((version == 3) && ((offset+7) <= this->header_size)) {
- if(this->header[offset+2] == 4)
- this->fourcc = _X_ME_32(&this->header[offset+3]);
- else {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]);
- free(this->header);
- return 0;
+ if(version == 3) {
+ if (((offset+7) <= this->header_size)) {
+ if(this->header[offset+2] == 4)
+ this->fourcc = _X_ME_32(&this->header[offset+3]);
+ else {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]);
+ free(this->header);
+ return 0;
+ }
+ } else {
+ this->fourcc = ME_FOURCC('l', 'p', 'c', 'J');
}
}
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc);
this->audio_type = _x_formattag_to_buf_audio(this->fourcc);
+ if (version == 4) {
+ this->sps = _X_BE_16 (this->header+44);
+ this->w = _X_BE_16 (this->header+42);
+ this->h = _X_BE_16 (this->header+40);
+ this->cfs = _X_BE_32 (this->header+24);
+ if (this->sps) {
+ this->frame_size = this->sps * this->h * this->sps;
+ this->frame_buffer = xine_xmalloc (this->frame_size);
+ } else {
+ this->frame_size = this->w * this->h;
+ this->frame_buffer = xine_xmalloc (this->frame_size);
+ }
+
+ if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO)
+ this->block_align = this->cfs;
+ }
+
/* seek to start of data */
this->data_start = this->header_size;
if (this->input->seek(this->input, this->data_start, SEEK_SET) !=
@@ -212,7 +242,45 @@ static int demux_ra_send_chunk(demux_plugin_t *this_gen) {
this->seek_flag = 0;
}
- if(_x_demux_read_send_data(this->audio_fifo, this->input, this->block_align,
+ if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) {
+ int x;
+ uint8_t * buffer;
+
+ buffer = this->frame_buffer;
+ if (this->audio_type == BUF_AUDIO_SIPRO) {
+ int n;
+ int len = this->h * this->w;
+ if(this->input->read(this->input, this->frame_buffer, len) < len) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ demux_real_sipro_swap (this->frame_buffer, len * 2 / 96);
+ } else {
+ int x, y;
+ int pos;
+
+ for (y = 0; y < this->h; y++)
+ for (x = 0; x < this->h / 2; x++) {
+ pos = x * 2 * this->w + y * this->cfs;
+ if(this->input->read(this->input, this->frame_buffer + pos,
+ this->cfs) < this->cfs) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ }
+
+ _x_demux_send_data(this->audio_fifo,
+ buffer, this->frame_size,
+ current_pts, this->audio_type, 0,
+ current_normpos, current_pts / 90, 0, 0);
+ } else if(_x_demux_read_send_data(this->audio_fifo, this->input, this->block_align,
current_pts, this->audio_type, 0, current_normpos,
current_pts / 90, 0, 0) < 0) {
this->status = DEMUX_FINISHED;
@@ -298,6 +366,7 @@ static void demux_ra_dispose (demux_plugin_t *this_gen) {
demux_ra_t *this = (demux_ra_t *) this_gen;
free(this->header);
+ free(this->frame_buffer);
free(this);
}
@@ -329,6 +398,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
this = xine_xmalloc (sizeof (demux_ra_t));
this->stream = stream;
this->input = input;
+ this->frame_buffer = NULL;
this->demux_plugin.send_headers = demux_ra_send_headers;
this->demux_plugin.send_chunk = demux_ra_send_chunk;
diff --git a/src/demuxers/real_common.h b/src/demuxers/real_common.h
new file mode 100644
index 000000000..4945a65ff
--- /dev/null
+++ b/src/demuxers/real_common.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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
+ */
+
+static inline void demux_real_sipro_swap (char buffer[], int bs)
+{
+ /* bs = nybbles per subpacket */
+ static const unsigned char sipr_swaps[38][2] = {
+ {0, 63}, {1, 22}, {2, 44}, {3, 90}, {5, 81}, {7, 31}, {8, 86}, {9, 58},
+ {10, 36}, {12, 68}, {13, 39}, {14, 73}, {15, 53}, {16, 69}, {17, 57},
+ {19, 88}, {20, 34}, {21, 71}, {24, 46}, {25, 94}, {26, 54}, {28, 75},
+ {29, 50}, {32, 70}, {33, 92}, {35, 74}, {38, 85}, {40, 56}, {42, 87},
+ {43, 65}, {45, 59}, {48, 79}, {49, 93}, {51, 89}, {55, 95}, {61, 76},
+ {67, 83}, {77, 80}
+ };
+ int n;
+
+ for (n = 0; n < 38; ++n)
+ {
+ int j;
+ int i = bs * sipr_swaps[n][0];
+ int o = bs * sipr_swaps[n][1];
+ /* swap nibbles of block 'i' with 'o' TODO: optimize */
+ for (j = 0; j < bs; ++j)
+ {
+ int x = (i & 1) ? (buffer[i >> 1] >> 4) : (buffer[i >> 1] & 0x0F);
+ int y = (o & 1) ? (buffer[o >> 1] >> 4) : (buffer[o >> 1] & 0x0F);
+ if (o & 1)
+ buffer[o >> 1] = (buffer[o >> 1] & 0x0F) | (x << 4);
+ else
+ buffer[o >> 1] = (buffer[o >> 1] & 0xF0) | x;
+ if (i & 1)
+ buffer[i >> 1] = (buffer[i >> 1] & 0x0F) | (y << 4);
+ else
+ buffer[i >> 1] = (buffer[i >> 1] & 0xF0) | y;
+ ++i;
+ ++o;
+ }
+ }
+}
diff --git a/src/libreal/xine_real_audio_decoder.c b/src/libreal/xine_real_audio_decoder.c
index b9231a2b7..a12518c1e 100644
--- a/src/libreal/xine_real_audio_decoder.c
+++ b/src/libreal/xine_real_audio_decoder.c
@@ -51,6 +51,8 @@ typedef struct {
/* empty so far */
} real_class_t;
+typedef void * ra_codec_t;
+
typedef struct realdec_decoder_s {
audio_decoder_t audio_decoder;
@@ -60,18 +62,18 @@ typedef struct realdec_decoder_s {
void *ra_handle;
- unsigned long (*raCloseCodec)(void*);
- unsigned long (*raDecode)(void*, char*,unsigned long,char*,unsigned int*,long);
- unsigned long (*raFlush)(unsigned long,unsigned long,unsigned long);
- unsigned long (*raFreeDecoder)(void*);
- void* (*raGetFlavorProperty)(void*,unsigned long,unsigned long,int*);
- unsigned long (*raInitDecoder)(void*, void*);
- unsigned long (*raOpenCodec2)(void*);
- unsigned long (*raSetFlavor)(void*,unsigned long);
- void (*raSetDLLAccessPath)(char*);
- void (*raSetPwd)(char*,char*);
+ uint32_t (*raCloseCodec)(ra_codec_t);
+ uint32_t (*raDecode)(ra_codec_t, char *, uint32_t, char *, uint32_t *, uint32_t);
+ uint32_t (*raFlush)(ra_codec_t, char *, uint32_t *);
+ uint32_t (*raFreeDecoder)(ra_codec_t);
+ void * (*raGetFlavorProperty)(ra_codec_t, uint16_t, uint16_t, uint16_t *);
+ uint32_t (*raInitDecoder)(ra_codec_t, void *);
+ uint32_t (*raOpenCodec2)(ra_codec_t *, const char *);
+ uint32_t (*raSetFlavor)(ra_codec_t, uint16_t);
+ void (*raSetDLLAccessPath)(char *);
+ void (*raSetPwd)(ra_codec_t, char *);
- void *context;
+ ra_codec_t context;
int sps, w, h;
int block_align;
@@ -92,14 +94,14 @@ typedef struct realdec_decoder_s {
} realdec_decoder_t;
typedef struct {
- int samplerate;
- short bits;
- short channels;
- int unk1;
- int subpacket_size;
- int coded_frame_size;
- int codec_data_length;
- void *extras;
+ uint32_t samplerate;
+ uint16_t bits;
+ uint16_t channels;
+ uint16_t quality;
+ uint32_t subpacket_size;
+ uint32_t coded_frame_size;
+ uint32_t codec_data_length;
+ void *extras;
} ra_init_t;
static int load_syms_linux (realdec_decoder_t *this, const char *const codec_name, const char *const codec_alternate) {
@@ -216,13 +218,14 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Cook");
if (!load_syms_linux (this, "cook.so", "cook.so.6.0"))
return 0;
+ this->block_align = subpacket_size;
break;
case BUF_AUDIO_ATRK:
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Atrac");
if (!load_syms_linux (this, "atrc.so", "atrc.so.6.0"))
return 0;
- this->block_align = 384;
+ this->block_align = subpacket_size;
break;
case BUF_AUDIO_14_4:
@@ -254,7 +257,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
* init codec
*/
- result = this->raOpenCodec2 (&this->context);
+ result = this->raOpenCodec2 (&this->context, NULL);
if (result) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: error in raOpenCodec2: %d\n", result);
return 0;
@@ -266,7 +269,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
init_data.samplerate = samples_per_sec;
init_data.bits = bits_per_sample;
init_data.channels = num_channels;
- init_data.unk1 = 100; /* ??? */
+ init_data.quality = 100; /* ??? */
init_data.subpacket_size = subpacket_size; /* subpacket size */
init_data.coded_frame_size = coded_frame_size; /* coded frame size */
init_data.codec_data_length = data_len; /* codec data length */
@@ -350,13 +353,6 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
return 1;
}
-static const unsigned char sipr_swaps[38][2]={
- {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
- {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46},
- {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56},
- {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83},
- {77,80} };
-
static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
@@ -383,116 +379,32 @@ static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->pts = buf->pts;
size = buf->size;
-
while (size) {
+ int need;
- int needed;
-
- needed = this->frame_size - this->frame_num_bytes;
-
- if (needed>size) {
-
- memcpy (this->frame_buffer+this->frame_num_bytes, buf->content, size);
+ need = this->frame_size - this->frame_num_bytes;
+ if (size < need) {
+ memcpy (this->frame_buffer + this->frame_num_bytes,
+ buf->content + buf->size - size, size);
this->frame_num_bytes += size;
-
- lprintf ("buffering %d/%d bytes\n", this->frame_num_bytes, this->frame_size);
-
size = 0;
-
} else {
-
- int result;
- int len =-1;
- int n;
- int sps = this->sps;
- int w = this->w;
- int h = this->h;
audio_buffer_t *audio_buffer;
+ int n, len;
+ int result;
- lprintf ("buffering %d bytes\n", needed);
-
- memcpy (this->frame_buffer+this->frame_num_bytes, buf->content, needed);
-
- size -= needed;
+ memcpy (this->frame_buffer + this->frame_num_bytes,
+ buf->content + buf->size - size, need);
+ size -= need;
this->frame_num_bytes = 0;
- lprintf ("frame completed. reordering...\n");
- lprintf ("bs=%d sps=%d w=%d h=%d \n",/*sh->wf->nBlockAlign*/-1,sps,w,h);
-
- if (!sps) {
-
- int j,n;
- int bs=h*w*2/96; /* nibbles per subpacket */
- unsigned char *p=this->frame_buffer;
-
- /* 'sipr' way */
- /* demux_read_data(sh->ds, p, h*w); */
- for (n=0;n<38;n++){
- int i=bs*sipr_swaps[n][0];
- int o=bs*sipr_swaps[n][1];
- /* swap nibbles of block 'i' with 'o' TODO: optimize */
- for (j=0;j<bs;j++) {
- int x=(i&1) ? (p[(i>>1)]>>4) : (p[(i>>1)]&15);
- int y=(o&1) ? (p[(o>>1)]>>4) : (p[(o>>1)]&15);
- if (o&1)
- p[(o>>1)]=(p[(o>>1)]&0x0F)|(x<<4);
- else
- p[(o>>1)]=(p[(o>>1)]&0xF0)|x;
-
- if (i&1)
- p[(i>>1)]=(p[(i>>1)]&0x0F)|(y<<4);
- else
- p[(i>>1)]=(p[(i>>1)]&0xF0)|y;
-
- ++i;
- ++o;
- }
- }
- /*
- sh->a_in_buffer_size=
- sh->a_in_buffer_len=w*h;
- */
-
- } else {
- int x, y;
- uint8_t *s;
-
- /* 'cook' way */
-
- w /= sps; s = this->frame_buffer;
-
- for (y=0; y<h; y++)
-
- for (x=0; x<w; x++) {
-
- lprintf ("x=%d, y=%d, off %d\n",
- x, y, sps*(h*x+((h+1)/2)*(y&1)+(y>>1)));
-
- memcpy (this->frame_reordered+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)),
- s, sps);
- s+=sps;
-
- /* demux_read_data(sh->ds, sh->a_in_buffer+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)),
- sps); */
-
- }
- /*
- sh->a_in_buffer_size=
- sh->a_in_buffer_len=w*h*sps;
- */
- }
-
-#ifdef LOG
- xine_hexdump (this->frame_reordered, buf->size);
-#endif
-
n = 0;
- while (n<this->frame_size) {
+ while (n < this->frame_size) {
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
result = this->raDecode (this->context,
- this->frame_reordered+n,
+ this->frame_buffer + n,
this->block_align,
(char *) audio_buffer->mem, &len, -1);
@@ -506,7 +418,7 @@ static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->stream->audio_out->put_buffer (this->stream->audio_out,
audio_buffer, this->stream);
- n+=this->block_align;
+ n += this->block_align;
}
}
}
@@ -609,5 +521,5 @@ static const uint32_t audio_types[] = {
const decoder_info_t dec_info_realaudio = {
audio_types, /* supported types */
- 7 /* priority */
+ 6 /* priority */
};
diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c
index 28fddafda..2b5eafa16 100644
--- a/src/libreal/xine_real_video_decoder.c
+++ b/src/libreal/xine_real_video_decoder.c
@@ -63,9 +63,9 @@ typedef struct realdec_decoder_s {
uint32_t (*rvyuv_custom_message)(void*, void*);
uint32_t (*rvyuv_free)(void*);
- uint32_t (*rvyuv_hive_message)(uint32_t, uint32_t);
+ uint32_t (*rvyuv_hive_message)(uint32_t, void*);
uint32_t (*rvyuv_init)(void*, void*); /* initdata,context */
- uint32_t (*rvyuv_transform)(char*, char*, void*, uint32_t*,void*);
+ uint32_t (*rvyuv_transform)(char*, char*, void*, void*, void*);
void *context;
@@ -113,13 +113,21 @@ typedef struct cmsg_data_s {
typedef struct transform_in_s {
uint32_t len;
- uint32_t unknown1;
- uint32_t chunks;
- uint32_t* extra;
- uint32_t unknown2;
+ uint32_t interpolate;
+ uint32_t nsegments;
+ void *segments;
+ uint32_t flags;
uint32_t timestamp;
} transform_in_t;
+typedef struct {
+ uint32_t frames;
+ uint32_t notes;
+ uint32_t timestamp;
+ uint32_t width;
+ uint32_t height;
+} transform_out_t;
+
/*
* real codec loader
*/
@@ -169,7 +177,6 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
int result;
rv_init_t init_data = {11, 0, 0, 0, 0, 0, 1, 0}; /* rv30 */
-
switch (buf->type) {
case BUF_VIDEO_RV20:
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 2.0");
@@ -258,7 +265,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
#ifdef LOG
printf ("libreal: CustomMessage cmsg_data:\n");
- xine_hexdump ((uint8_t *) cmsg_data, sizeof (cmsg_data));
+ xine_hexdump ((uint8_t *) &cmsg_data, sizeof (cmsg_data));
printf ("libreal: cmsg24:\n");
xine_hexdump ((uint8_t *) cmsg24, (buf->size - 34 + 2) * sizeof(uint32_t));
#endif
@@ -342,7 +349,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
int result;
vo_frame_t *img;
- uint32_t transform_out[5];
+ transform_out_t transform_out;
transform_in_t transform_in = {
this->chunk_buffer_size,
/* length of the packet (sub-packets appended) */
@@ -369,7 +376,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
xine_hexdump (this->chunk_buffer, this->chunk_buffer_size);
printf ("libreal: transform_in:\n");
- xine_hexdump ((uint8_t *) transform_in, 6 * 4);
+ xine_hexdump ((uint8_t *) &transform_in, sizeof(rv_xform_in_t));
printf ("libreal: chunk_table:\n");
xine_hexdump ((uint8_t *) buf->decoder_info_ptr[2],
@@ -379,21 +386,21 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
result = this->rvyuv_transform (this->chunk_buffer,
this->frame_buffer,
&transform_in,
- transform_out,
+ &transform_out,
this->context);
lprintf ("transform result: %08x\n", result);
lprintf ("transform_out:\n");
- #ifdef LOG
- xine_hexdump ((uint8_t *) transform_out, 5 * 4);
- #endif
+#ifdef LOG
+ xine_hexdump ((uint8_t *) &transform_out, 5 * 4);
+#endif
/* Sometimes the stream contains video of a different size
* to that specified in the realmedia header */
- if(transform_out[0] && ((transform_out[3] != this->width) ||
- (transform_out[4] != this->height))) {
- this->width = transform_out[3];
- this->height = transform_out[4];
+ if(transform_out.frames && ((transform_out.width != this->width) ||
+ (transform_out.height != this->height))) {
+ this->width = transform_out.width;
+ this->height = transform_out.height;
this->frame_size = this->width * this->height;
@@ -531,8 +538,7 @@ void *init_realvdec (xine_t *xine, void *data) {
* exported plugin catalog entry
*/
-static const uint32_t supported_types[] = { BUF_VIDEO_RV20,
- BUF_VIDEO_RV30,
+static const uint32_t supported_types[] = { BUF_VIDEO_RV30,
BUF_VIDEO_RV40,
0 };
diff --git a/src/video_out/video_out_macosx.m b/src/video_out/video_out_macosx.m
index 70cffaeb8..085387a44 100644
--- a/src/video_out/video_out_macosx.m
+++ b/src/video_out/video_out_macosx.m
@@ -207,7 +207,7 @@ static void macosx_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) {
break;
case XINE_IMGFMT_YUY2:
xine_fast_memcpy (texture_buffer, vo_frame->base[0],
- vo_frame->pitches[0] * vo_frame->height * 2);
+ vo_frame->pitches[0] * vo_frame->height);
[driver->view updateTexture];
break;
default:
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index b0e01db31..15b5ff952 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -808,6 +808,14 @@ static const audio_db_t audio_db[] = {
},
{
{
+ ME_FOURCC('a', 'd', 'u', 0x55),
+ 0
+ },
+ BUF_AUDIO_MP3ADU,
+ "MPEG layer-3 adu"
+},
+{
+ {
ME_FOURCC('t','w','o','s'),
ME_FOURCC('i','n','2','4'),
0