summaryrefslogtreecommitdiff
path: root/src/demuxers/demux_real.c
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 /src/demuxers/demux_real.c
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
Diffstat (limited to 'src/demuxers/demux_real.c')
-rw-r--r--src/demuxers/demux_real.c151
1 files changed, 149 insertions, 2 deletions
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);