summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Stembridge <jstembridge@users.sourceforge.net>2004-03-14 21:37:52 +0000
committerJames Stembridge <jstembridge@users.sourceforge.net>2004-03-14 21:37:52 +0000
commit0ddc2a72f2f5fc22c60a38d42cead2c9451c0fdb (patch)
tree25417f7bba1885c4a93eee97ca9467c457a6074d
parent4e87a4ca26966875271d476a77bcd5486b808c60 (diff)
downloadxine-lib-0ddc2a72f2f5fc22c60a38d42cead2c9451c0fdb.tar.gz
xine-lib-0ddc2a72f2f5fc22c60a38d42cead2c9451c0fdb.tar.bz2
Move real 14.4 and 28.8 header parsing to ffmpeg decoder
CVS patchset: 6259 CVS date: 2004/03/14 21:37:52
-rw-r--r--src/demuxers/demux_real.c15
-rw-r--r--src/demuxers/demux_realaudio.c139
-rw-r--r--src/libffmpeg/audio_decoder.c75
3 files changed, 121 insertions, 108 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 44798f371..cc61387ef 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -31,7 +31,7 @@
*
* Based on FFmpeg's libav/rm.c.
*
- * $Id: demux_real.c,v 1.94 2004/03/01 22:33:52 jstembridge Exp $
+ * $Id: demux_real.c,v 1.95 2004/03/14 21:37:52 jstembridge Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -741,19 +741,6 @@ unknown:
memcpy(buf->content, mdpr->type_specific_data + 79,
buf->decoder_info[2]);
- } else if(buf->type == BUF_AUDIO_14_4) {
- xine_waveformatex wave;
-
- wave.nSamplesPerSec = buf->decoder_info[1] = 8000;
- wave.wBitsPerSample = buf->decoder_info[2] = 16;
- wave.nChannels = buf->decoder_info[3] = 1;
- wave.nBlockAlign = 240;
-
- buf->decoder_flags |= BUF_FLAG_STDHEADER;
- buf->size = sizeof(xine_waveformatex);
-
- memcpy(buf->content, &wave, sizeof(xine_waveformatex));
-
} else {
memcpy(buf->content, mdpr->type_specific_data,
mdpr->type_specific_len);
diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c
index d1bab47f2..ff7518811 100644
--- a/src/demuxers/demux_realaudio.c
+++ b/src/demuxers/demux_realaudio.c
@@ -22,7 +22,7 @@
* RealAudio File Demuxer by Mike Melanson (melanson@pcisys.net)
* improved by James Stembridge (jstembridge@users.sourceforge.net)
*
- * $Id: demux_realaudio.c,v 1.29 2004/01/09 01:26:33 miguelfreitas Exp $
+ * $Id: demux_realaudio.c,v 1.30 2004/03/14 21:37:52 jstembridge Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -54,20 +54,18 @@ typedef struct {
input_plugin_t *input;
int status;
- xine_waveformatex wave;
+ unsigned int fourcc;
unsigned int audio_type;
off_t data_start;
off_t data_size;
-
-#if 0
- /* Needed by ffmpeg 28.8 decoder */
- unsigned short sub_packet_size;
- unsigned short sub_packet_height;
- unsigned short sub_packet_flavour;
- unsigned int coded_frame_size;
-#endif
+ unsigned short block_align;
+ unsigned int bytes_per_sec;
+
+ unsigned char *header;
+ unsigned int header_size;
+
int seek_flag; /* this is set when a seek just occurred */
} demux_ra_t;
@@ -78,8 +76,6 @@ typedef struct {
/* 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;
- unsigned char *audio_header;
- unsigned int audio_fourcc = 0, hdr_size;
unsigned short version;
off_t offset;
@@ -99,108 +95,95 @@ static int open_ra_file(demux_ra_t *this) {
/* read header size according to version */
if (version == 3)
- hdr_size = BE_16(&file_header[0x06]) + 8;
+ this->header_size = BE_16(&file_header[0x06]) + 8;
else if (version == 4)
- hdr_size = BE_32(&file_header[0x12]) + 16;
+ this->header_size = BE_32(&file_header[0x12]) + 16;
else {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unknown version number %d\n", version);
return 0;
}
/* allocate for and read header data */
- audio_header = xine_xmalloc(hdr_size);
+ this->header = xine_xmalloc(this->header_size);
- if (_x_demux_read_header(this->input, audio_header, hdr_size) != hdr_size) {
+ if (_x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to read header\n");
- free(audio_header);
+ free(this->header);
return 0;
}
/* read header data according to version */
- if((version == 3) && (hdr_size >= 32)) {
- this->data_size = BE_32(&audio_header[0x12]);
+ if((version == 3) && (this->header_size >= 32)) {
+ this->data_size = BE_32(&this->header[0x12]);
+
+ this->block_align = 240;
- this->wave.nChannels = 1;
- this->wave.nSamplesPerSec = 8000;
- this->wave.nBlockAlign = 240;
- this->wave.wBitsPerSample = 16;
-
offset = 0x16;
- } else if(hdr_size >= 72) {
- this->data_size = BE_32(&audio_header[0x1C]);
+ } else if(this->header_size >= 72) {
+ this->data_size = BE_32(&this->header[0x1C]);
- this->wave.nBlockAlign = BE_16(&audio_header[0x2A]);
- this->wave.nSamplesPerSec = BE_16(&audio_header[0x30]);
- this->wave.wBitsPerSample = audio_header[0x35];
- this->wave.nChannels = audio_header[0x37];
-
-#if 0
- this->sub_packet_size = BE_16(&audio_header[0x2C]);
- this->sub_packet_height = BE_16(&audio_header[0x28]);
- this->sub_packet_flavour = BE_16(&audio_header[0x16]);
- this->coded_frame_size = BE_32(&audio_header[0x18]);
-#endif
-
- if(audio_header[0x3D] == 4)
- audio_fourcc = ME_32(&audio_header[0x3E]);
+ this->block_align = BE_16(&this->header[0x2A]);
+
+ if(this->header[0x3D] == 4)
+ this->fourcc = ME_32(&this->header[0x3E]);
else {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_realaudio: invalid fourcc size %d\n", audio_header[0x3D]);
- free(audio_header);
+ "demux_realaudio: invalid fourcc size %d\n", this->header[0x3D]);
+ free(this->header);
return 0;
}
offset = 0x45;
} else {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: header too small\n");
- free(audio_header);
+ free(this->header);
return 0;
}
/* Read title */
- len = audio_header[offset];
- if(len && ((offset+len+2) < hdr_size)) {
+ len = this->header[offset];
+ if(len && ((offset+len+2) < this->header_size)) {
_x_meta_info_n_set(this->stream, XINE_META_INFO_TITLE,
- &audio_header[offset+1], len);
+ &this->header[offset+1], len);
offset += len+1;
} else
offset++;
/* Author */
- len = audio_header[offset];
- if(len && ((offset+len+1) < hdr_size)) {
+ len = this->header[offset];
+ if(len && ((offset+len+1) < this->header_size)) {
_x_meta_info_n_set(this->stream, XINE_META_INFO_ARTIST,
- &audio_header[offset+1], len);
+ &this->header[offset+1], len);
offset += len+1;
} else
offset++;
/* Copyright/Date */
- len = audio_header[offset];
- if(len && ((offset+len) <= hdr_size)) {
+ len = this->header[offset];
+ if(len && ((offset+len) <= this->header_size)) {
_x_meta_info_n_set(this->stream, XINE_META_INFO_YEAR,
- &audio_header[offset+1], len);
+ &this->header[offset+1], len);
offset += len+1;
} else
offset++;
/* Fourcc for version 3 comes after meta info */
- if((version == 3) && ((offset+7) <= hdr_size)) {
- if(audio_header[offset+2] == 4)
- audio_fourcc = ME_32(&audio_header[offset+3]);
+ if((version == 3) && ((offset+7) <= this->header_size)) {
+ if(this->header[offset+2] == 4)
+ this->fourcc = ME_32(&this->header[offset+3]);
else {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_realaudio: invalid fourcc size %d\n", audio_header[offset+2]);
- free(audio_header);
+ "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]);
+ free(this->header);
return 0;
}
}
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, audio_fourcc);
- this->audio_type = _x_formattag_to_buf_audio(audio_fourcc);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc);
+ this->audio_type = _x_formattag_to_buf_audio(this->fourcc);
/* seek to start of data */
- this->data_start = hdr_size;
+ this->data_start = this->header_size;
if (this->input->seek(this->input, this->data_start, SEEK_SET) !=
this->data_start) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to seek to data start\n");
@@ -223,7 +206,7 @@ static int demux_ra_send_chunk(demux_plugin_t *this_gen) {
/* just load data chunks from wherever the stream happens to be
* pointing; issue a DEMUX_FINISHED status if EOF is reached */
- remaining_sample_bytes = this->wave.nBlockAlign;
+ remaining_sample_bytes = this->block_align;
current_file_pos =
this->input->get_current_pos(this->input) - this->data_start;
@@ -279,12 +262,7 @@ static void demux_ra_send_headers(demux_plugin_t *this_gen) {
/* load stream information */
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS,
- this->wave.nChannels);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE,
- this->wave.nSamplesPerSec);
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS,
- this->wave.wBitsPerSample);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc);
/* send start buffers */
_x_demux_control_start(this->stream);
@@ -293,13 +271,15 @@ static void demux_ra_send_headers(demux_plugin_t *this_gen) {
if (this->audio_fifo && this->audio_type) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->type = this->audio_type;
- buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
- buf->decoder_info[0] = 0;
- buf->decoder_info[1] = this->wave.nSamplesPerSec;
- buf->decoder_info[2] = this->wave.wBitsPerSample;
- buf->decoder_info[3] = this->wave.nChannels;
- memcpy(buf->content, &this->wave, sizeof(this->wave));
- buf->size = sizeof(this->wave);
+ buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
+
+ if(this->header_size > buf->max_size)
+ buf->size = buf->max_size;
+ else
+ buf->size = this->header_size;
+
+ memcpy(buf->content, this->header, buf->size);
+
this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -330,8 +310,8 @@ static int demux_ra_seek (demux_plugin_t *this_gen,
* the block alignment integer-wise, and multiply the quotient by the
* block alignment to get the new aligned offset. Add the data start
* offset and seek to the new position. */
- start_pos /= this->wave.nBlockAlign;
- start_pos *= this->wave.nBlockAlign;
+ start_pos /= this->block_align;
+ start_pos *= this->block_align;
start_pos += this->data_start;
this->input->seek(this->input, start_pos, SEEK_SET);
@@ -343,6 +323,9 @@ static int demux_ra_seek (demux_plugin_t *this_gen,
static void demux_ra_dispose (demux_plugin_t *this_gen) {
demux_ra_t *this = (demux_ra_t *) this_gen;
+
+ if(this->header)
+ free(this->header);
free(this);
}
@@ -357,8 +340,8 @@ static int demux_ra_get_status (demux_plugin_t *this_gen) {
static int demux_ra_get_stream_length (demux_plugin_t *this_gen) {
demux_ra_t *this = (demux_ra_t *) this_gen;
- if(this->wave.nAvgBytesPerSec)
- return (int)((int64_t) this->data_size * 1000 / this->wave.nAvgBytesPerSec);
+ if(this->bytes_per_sec)
+ return (int)((int64_t) this->data_size * 1000 / this->bytes_per_sec);
else
return 0;
}
diff --git a/src/libffmpeg/audio_decoder.c b/src/libffmpeg/audio_decoder.c
index 26a04ff9c..38a5b1a73 100644
--- a/src/libffmpeg/audio_decoder.c
+++ b/src/libffmpeg/audio_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_decoder.c,v 1.5 2004/03/13 19:42:22 jstembridge Exp $
+ * $Id: audio_decoder.c,v 1.6 2004/03/14 21:37:52 jstembridge Exp $
*
* xine audio decoder plugin using ffmpeg
*
@@ -43,6 +43,7 @@
#include "xine_internal.h"
#include "buffer.h"
#include "xineutils.h"
+#include "bswap.h"
#include "xine_decoder.h"
#define AUDIOBUFSIZE 128*1024
@@ -112,7 +113,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
audio_buffer_t *audio_buffer;
int bytes_to_send;
- if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
int i, codec_type;
xine_waveformatex *audio_header = (xine_waveformatex *)buf->content;
@@ -137,24 +138,65 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
}
this->context = avcodec_alloc_context();
+
+ if(buf->decoder_flags & BUF_FLAG_STDHEADER) {
+ this->audio_sample_rate = buf->decoder_info[1];
+ this->audio_channels = buf->decoder_info[3];
+
+ this->context->block_align = audio_header->nBlockAlign;
+ this->context->bit_rate = audio_header->nAvgBytesPerSec * 8;
+
+ if(audio_header->cbSize > 0) {
+ this->context->extradata = xine_xmalloc(audio_header->cbSize);
+ this->context->extradata_size = audio_header->cbSize;
+ memcpy( this->context->extradata,
+ (uint8_t *)audio_header + sizeof(xine_waveformatex),
+ audio_header->cbSize );
+ }
+ } else {
+ short *ptr;
+
+ switch(codec_type) {
+ case BUF_AUDIO_14_4:
+ this->audio_sample_rate = 8000;
+ this->audio_channels = 1;
+
+ this->context->block_align = 240;
+ break;
+ case BUF_AUDIO_28_8:
+ this->audio_sample_rate = BE_16(&buf->content[0x30]);
+ this->audio_channels = buf->content[0x37];
+ /* this->audio_bits = buf->content[0x35] */
+
+ this->context->block_align = BE_16(&buf->content[0x2A]);
+
+ this->context->extradata_size = 5*sizeof(short);
+ this->context->extradata = xine_xmalloc(this->context->extradata_size);
+
+ ptr = (short *) this->context->extradata;
+
+ ptr[0] = BE_16(&buf->content[0x2C]); /* subpacket size */
+ ptr[1] = BE_16(&buf->content[0x28]); /* subpacket height */
+ ptr[2] = BE_16(&buf->content[0x16]); /* subpacket flavour */
+ ptr[3] = BE_32(&buf->content[0x18]); /* coded frame size */
+ ptr[4] = 0; /* codec's data length */
+ break;
+ default:
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type);
+ break;
+ }
+ }
- this->context->sample_rate = this->audio_sample_rate = buf->decoder_info[1];
/* Current ffmpeg audio decoders always use 16 bits/sample
* buf->decoder_info[2] can't be used as it doesn't refer to the output
* bits/sample for some codecs (e.g. MS ADPCM) */
this->audio_bits = 16;
- this->context->channels = this->audio_channels = buf->decoder_info[3];
- this->context->block_align = audio_header->nBlockAlign;
- this->context->bit_rate = audio_header->nAvgBytesPerSec * 8;
- this->context->codec_id = this->codec->id;
- this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
- if( audio_header->cbSize > 0 ) {
- this->context->extradata = malloc(audio_header->cbSize);
- this->context->extradata_size = audio_header->cbSize;
- memcpy( this->context->extradata,
- (uint8_t *)audio_header + sizeof(xine_waveformatex),
- audio_header->cbSize );
- }
+
+ this->context->sample_rate = this->audio_sample_rate;
+ this->context->channels = this->audio_channels;
+ this->context->codec_id = this->codec->id;
+ this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
this->buf = xine_xmalloc(AUDIOBUFSIZE);
this->bufsize = AUDIOBUFSIZE;
@@ -222,7 +264,8 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
"ffmpeg_audio_dec: error decompressing audio frame\n");
this->size=0;
return;
- }
+ } else if (bytes_consumed == 0)
+ return;
/* dispatch the decoded audio */
out = 0;