diff options
author | Mike Melanson <mike@multimedia.cx> | 2002-09-21 18:18:45 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2002-09-21 18:18:45 +0000 |
commit | cbd8394189b0125cee8af14eac8d2c516825598d (patch) | |
tree | 884a9635cba1dbeca23df79ffe9fac41713daa32 | |
parent | 4b8f6c82ee1928267af462a6b7fdcd0f36019689 (diff) | |
download | xine-lib-cbd8394189b0125cee8af14eac8d2c516825598d.tar.gz xine-lib-cbd8394189b0125cee8af14eac8d2c516825598d.tar.bz2 |
bring the audio-only demuxers (WAV, AIFF, VOC, SND) up to the new API
spec
CVS patchset: 2730
CVS date: 2002/09/21 18:18:45
-rw-r--r-- | src/demuxers/Makefile.am | 28 | ||||
-rw-r--r-- | src/demuxers/demux_aiff.c | 185 | ||||
-rw-r--r-- | src/demuxers/demux_snd.c | 184 | ||||
-rw-r--r-- | src/demuxers/demux_voc.c | 122 | ||||
-rw-r--r-- | src/demuxers/demux_wav.c | 154 |
5 files changed, 407 insertions, 266 deletions
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index 4c84651ca..e50ce5977 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -37,7 +37,9 @@ endif lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(qt_modules) xineplug_dmx_avi.la\ xineplug_dmx_mpeg_block.la xineplug_dmx_mpeg.la \ xineplug_dmx_mpeg_elem.la xineplug_dmx_mpeg_audio.la \ - xineplug_dmx_film.la + xineplug_dmx_film.la xineplug_dmx_wav.la \ + xineplug_dmx_aiff.la xineplug_dmx_voc.la \ + xineplug_dmx_snd.la xineplug_dmx_ogg_la_SOURCES = demux_ogg.c xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\ @@ -100,9 +102,9 @@ xineplug_dmx_film_la_LDFLAGS = -avoid-version -module #xineplug_dmx_smjpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la #xineplug_dmx_smjpeg_la_LDFLAGS = -avoid-version -module -#xineplug_dmx_wav_la_SOURCES = demux_wav.c -#xineplug_dmx_wav_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la -#xineplug_dmx_wav_la_LDFLAGS = -avoid-version -module +xineplug_dmx_wav_la_SOURCES = demux_wav.c +xineplug_dmx_wav_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la +xineplug_dmx_wav_la_LDFLAGS = -avoid-version -module #xineplug_dmx_idcin_la_SOURCES = demux_idcin.c #xineplug_dmx_idcin_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la @@ -116,17 +118,17 @@ xineplug_dmx_film_la_LDFLAGS = -avoid-version -module #xineplug_dmx_vqa_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la #xineplug_dmx_vqa_la_LDFLAGS = -avoid-version -module -#xineplug_dmx_voc_la_SOURCES = demux_voc.c -#xineplug_dmx_voc_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la -#xineplug_dmx_voc_la_LDFLAGS = -avoid-version -module +xineplug_dmx_voc_la_SOURCES = demux_voc.c +xineplug_dmx_voc_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la +xineplug_dmx_voc_la_LDFLAGS = -avoid-version -module -#xineplug_dmx_aiff_la_SOURCES = demux_aiff.c -#xineplug_dmx_aiff_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la -#xineplug_dmx_aiff_la_LDFLAGS = -avoid-version -module +xineplug_dmx_aiff_la_SOURCES = demux_aiff.c +xineplug_dmx_aiff_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la +xineplug_dmx_aiff_la_LDFLAGS = -avoid-version -module -#xineplug_dmx_snd_la_SOURCES = demux_snd.c -#xineplug_dmx_snd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la -#xineplug_dmx_snd_la_LDFLAGS = -avoid-version -module +xineplug_dmx_snd_la_SOURCES = demux_snd.c +xineplug_dmx_snd_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la +xineplug_dmx_snd_la_LDFLAGS = -avoid-version -module include_HEADERS = demux.h qtpalette.h diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index a2af652e1..73b5debea 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -19,7 +19,7 @@ * * AIFF File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_aiff.c,v 1.5 2002/09/10 15:07:13 mroi Exp $ + * $Id: demux_aiff.c,v 1.6 2002/09/21 18:18:46 tmmm Exp $ * */ @@ -189,6 +189,99 @@ static void *demux_aiff_loop (void *this_gen) { return NULL; } +static int load_aiff_and_send_headers(demux_aiff_t *this) { + + unsigned char preamble[PREAMBLE_SIZE]; + unsigned int chunk_type; + unsigned int chunk_size; + unsigned char buffer[100]; + + pthread_mutex_lock(&this->mutex); + + this->video_fifo = this->xine->video_fifo; + this->audio_fifo = this->xine->audio_fifo; + + this->status = DEMUX_OK; + + /* audio type is PCM unless proven otherwise */ + this->audio_type = BUF_AUDIO_LPCM_BE; + this->audio_frames = 0; + this->audio_channels = 0; + this->audio_bits = 0; + this->audio_sample_rate = 0; + this->audio_bytes_per_second = 0; + + /* skip past the file header and traverse the chunks */ + this->input->seek(this->input, 12, SEEK_SET); + while (1) { + if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != + PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + pthread_mutex_lock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + chunk_type = BE_32(&preamble[0]); + chunk_size = BE_32(&preamble[4]); + + if (chunk_type == COMM_TAG) { + if (this->input->read(this->input, buffer, chunk_size) != + chunk_size) { + this->status = DEMUX_FINISHED; + pthread_mutex_lock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + this->audio_channels = BE_16(&buffer[0]); + this->audio_frames = BE_32(&buffer[2]); + this->audio_bits = BE_16(&buffer[6]); + this->audio_sample_rate = BE_16(&buffer[0x0A]); + this->audio_bytes_per_second = this->audio_channels * + (this->audio_bits / 8) * this->audio_sample_rate; + + } else if ((chunk_type == SSND_TAG) || + (chunk_type == APCM_TAG)) { + + /* audio data has been located; proceed to demux loop after + * skipping 8 more bytes (2 more 4-byte numbers) */ + this->input->seek(this->input, 8, SEEK_CUR); + this->data_start = this->input->get_current_pos(this->input); + this->data_size = this->audio_frames * this->audio_channels * + (this->audio_bits / 8); + this->running_time = this->audio_frames / this->audio_sample_rate; + this->data_end = this->data_start + this->data_size; + + this->audio_block_align = PCM_BLOCK_ALIGN; + + break; + + } else { + /* unrecognized; skip it */ + this->input->seek(this->input, chunk_size, SEEK_CUR); + } + } + + /* the audio parameters should have been set at this point */ + if (!this->audio_channels) { + this->status = DEMUX_FINISHED; + pthread_mutex_lock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + /* load stream information */ + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = + this->audio_channels; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = + this->audio_sample_rate; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = + this->audio_bits; + + xine_demux_control_headers_done (this->xine); + + pthread_mutex_unlock (&this->mutex); + + return DEMUX_CAN_HANDLE; +} + static int demux_aiff_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) { @@ -210,7 +303,7 @@ static int demux_aiff_open(demux_plugin_t *this_gen, /* check the signature */ if ((BE_32(&signature[0]) == FORM_TAG) && (BE_32(&signature[8]) == AIFF_TAG)) - return DEMUX_CAN_HANDLE; + return load_aiff_and_send_headers(this); return DEMUX_CANNOT_HANDLE; } @@ -236,10 +329,8 @@ static int demux_aiff_open(demux_plugin_t *this_gen, while(*m == ' ' || *m == '\t') m++; - if(!strcasecmp((suffix + 1), m)) { - this->input = input; - return DEMUX_CAN_HANDLE; - } + if(!strcasecmp((suffix + 1), m)) + return load_aiff_and_send_headers(this); } return DEMUX_CANNOT_HANDLE; } @@ -254,97 +345,25 @@ static int demux_aiff_open(demux_plugin_t *this_gen, } static int demux_aiff_start (demux_plugin_t *this_gen, - fifo_buffer_t *video_fifo, - fifo_buffer_t *audio_fifo, off_t start_pos, int start_time) { demux_aiff_t *this = (demux_aiff_t *) this_gen; buf_element_t *buf; int err; - unsigned char preamble[PREAMBLE_SIZE]; - unsigned int chunk_type; - unsigned int chunk_size; - unsigned char buffer[100]; pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ if (!this->thread_running) { - this->video_fifo = video_fifo; - this->audio_fifo = audio_fifo; - - /* audio type is PCM unless proven otherwise */ - this->audio_type = BUF_AUDIO_LPCM_BE; - this->audio_frames = 0; - this->audio_channels = 0; - this->audio_bits = 0; - this->audio_sample_rate = 0; - this->audio_bytes_per_second = 0; - - /* skip past the file header and traverse the chunks */ - this->input->seek(this->input, 12, SEEK_SET); - while (1) { - if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != - PREAMBLE_SIZE) { - this->status = DEMUX_FINISHED; - pthread_mutex_lock(&this->mutex); - return DEMUX_FINISHED; - } - chunk_type = BE_32(&preamble[0]); - chunk_size = BE_32(&preamble[4]); - - if (chunk_type == COMM_TAG) { - if (this->input->read(this->input, buffer, chunk_size) != - chunk_size) { - this->status = DEMUX_FINISHED; - pthread_mutex_lock(&this->mutex); - return DEMUX_FINISHED; - } - - this->audio_channels = BE_16(&buffer[0]); - this->audio_frames = BE_32(&buffer[2]); - this->audio_bits = BE_16(&buffer[6]); - this->audio_sample_rate = BE_16(&buffer[0x0A]); - this->audio_bytes_per_second = this->audio_channels * - (this->audio_bits / 8) * this->audio_sample_rate; - - } else if ((chunk_type == SSND_TAG) || - (chunk_type == APCM_TAG)) { - - /* audio data has been located; proceed to demux loop after - * skipping 8 more bytes (2 more 4-byte numbers) */ - this->input->seek(this->input, 8, SEEK_CUR); - this->data_start = this->input->get_current_pos(this->input); - this->data_size = this->audio_frames * this->audio_channels * - (this->audio_bits / 8); - this->running_time = this->audio_frames / this->audio_sample_rate; - this->data_end = this->data_start + this->data_size; - - this->audio_block_align = PCM_BLOCK_ALIGN; - - break; - - } else { - /* unrecognized; skip it */ - this->input->seek(this->input, chunk_size, SEEK_CUR); - } - } - - /* the audio parameters should have been set at this point */ - if (!this->audio_channels) { - this->status = DEMUX_FINISHED; - pthread_mutex_lock(&this->mutex); - return DEMUX_FINISHED; - } /* print vital stats */ - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_aiff: %d Hz, %d channels, %d bits, %d frames\n"), this->audio_sample_rate, this->audio_channels, this->audio_bits, this->audio_frames); - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_aiff: running time: %d min, %d sec\n"), this->running_time / 60, this->running_time % 60); @@ -446,7 +465,7 @@ static void demux_aiff_stop (demux_plugin_t *this_gen) { xine_demux_control_end(this->xine, BUF_FLAG_END_USER); } -static void demux_aiff_close (demux_plugin_t *this_gen) { +static void demux_aiff_dispose (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; pthread_mutex_destroy (&this->mutex); @@ -492,7 +511,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { this->demux_plugin.start = demux_aiff_start; this->demux_plugin.seek = demux_aiff_seek; this->demux_plugin.stop = demux_aiff_stop; - this->demux_plugin.close = demux_aiff_close; + this->demux_plugin.dispose = demux_aiff_dispose; this->demux_plugin.get_status = demux_aiff_get_status; this->demux_plugin.get_identifier = demux_aiff_get_id; this->demux_plugin.get_stream_length = demux_aiff_get_stream_length; @@ -510,6 +529,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 10, "aiff", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, + { PLUGIN_DEMUX, 11, "aiff", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_snd.c b/src/demuxers/demux_snd.c index 59b02cbc3..1f47d9cea 100644 --- a/src/demuxers/demux_snd.c +++ b/src/demuxers/demux_snd.c @@ -19,7 +19,7 @@ * * SND/AU File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_snd.c,v 1.6 2002/09/10 15:07:14 mroi Exp $ + * $Id: demux_snd.c,v 1.7 2002/09/21 18:18:46 tmmm Exp $ * */ @@ -179,6 +179,98 @@ static void *demux_snd_loop (void *this_gen) { return NULL; } +static int load_snd_and_send_headers(demux_snd_t *this) { + + unsigned char header[SND_HEADER_SIZE]; + unsigned int encoding; + + pthread_mutex_lock(&this->mutex); + + this->video_fifo = this->xine->video_fifo; + this->audio_fifo = this->xine->audio_fifo; + + this->status = DEMUX_OK; + + this->input->seek(this->input, 0, SEEK_SET); + if (this->input->read(this->input, header, SND_HEADER_SIZE) != + SND_HEADER_SIZE) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + this->data_start = BE_32(&header[0x04]); + this->data_size = BE_32(&header[0x08]); + encoding = BE_32(&header[0x0C]); + this->audio_sample_rate = BE_32(&header[0x10]); + this->audio_channels = BE_32(&header[0x14]); + this->data_end = this->data_start + this->data_size; + + /* basic sanity checks on the loaded audio parameters */ + if ((!this->audio_sample_rate) || + (!this->audio_channels)) { + xine_log(this->xine, XINE_LOG_MSG, + _("demux_snd: bad header parameters\n")); + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + switch (encoding) { + case 1: + this->audio_type = BUF_AUDIO_MULAW; + this->audio_bits = 16; + this->audio_frames = this->data_size / this->audio_channels; + this->audio_block_align = PCM_BLOCK_ALIGN; + this->audio_bytes_per_second = this->audio_channels * + this->audio_sample_rate; + break; + + case 3: + this->audio_type = BUF_AUDIO_LPCM_BE; + this->audio_bits = 16; + this->audio_frames = this->data_size / + (this->audio_channels * this->audio_bits / 8); + this->audio_block_align = PCM_BLOCK_ALIGN; + this->audio_bytes_per_second = this->audio_channels * + (this->audio_bits / 8) * this->audio_sample_rate; + break; + + case 27: + this->audio_type = BUF_AUDIO_ALAW; + this->audio_bits = 16; + this->audio_frames = this->data_size / this->audio_channels; + this->audio_block_align = PCM_BLOCK_ALIGN; + this->audio_bytes_per_second = this->audio_channels * + this->audio_sample_rate; + break; + + default: + xine_log(this->xine, XINE_LOG_MSG, + _("demux_snd: unsupported audio type: %d\n"), encoding); + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + break; + } + + this->running_time = this->audio_frames / this->audio_sample_rate; + + /* load stream information */ + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = + this->audio_channels; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = + this->audio_sample_rate; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = + this->audio_bits; + + xine_demux_control_headers_done (this->xine); + + pthread_mutex_unlock (&this->mutex); + + return DEMUX_CAN_HANDLE; +} + static int demux_snd_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) { @@ -198,7 +290,7 @@ static int demux_snd_open(demux_plugin_t *this_gen, /* check the signature */ if (BE_32(&header[0]) == snd_TAG) - return DEMUX_CAN_HANDLE; + return load_snd_and_send_headers(this); return DEMUX_CANNOT_HANDLE; } @@ -224,10 +316,8 @@ static int demux_snd_open(demux_plugin_t *this_gen, while(*m == ' ' || *m == '\t') m++; - if(!strcasecmp((suffix + 1), m)) { - this->input = input; - return DEMUX_CAN_HANDLE; - } + if(!strcasecmp((suffix + 1), m)) + return load_snd_and_send_headers(this); } return DEMUX_CANNOT_HANDLE; } @@ -242,94 +332,22 @@ static int demux_snd_open(demux_plugin_t *this_gen, } static int demux_snd_start (demux_plugin_t *this_gen, - fifo_buffer_t *video_fifo, - fifo_buffer_t *audio_fifo, off_t start_pos, int start_time) { demux_snd_t *this = (demux_snd_t *) this_gen; buf_element_t *buf; int err; - unsigned char header[SND_HEADER_SIZE]; - unsigned int encoding; /* if thread is not running, initialize demuxer */ if (!this->thread_running) { - this->video_fifo = video_fifo; - this->audio_fifo = audio_fifo; - - this->input->seek(this->input, 0, SEEK_SET); - if (this->input->read(this->input, header, SND_HEADER_SIZE) != - SND_HEADER_SIZE) { - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return DEMUX_FINISHED; - } - - this->data_start = BE_32(&header[0x04]); - this->data_size = BE_32(&header[0x08]); - encoding = BE_32(&header[0x0C]); - this->audio_sample_rate = BE_32(&header[0x10]); - this->audio_channels = BE_32(&header[0x14]); - this->data_end = this->data_start + this->data_size; - - /* basic sanity checks on the loaded audio parameters */ - if ((!this->audio_sample_rate) || - (!this->audio_channels)) { - xine_log(this->xine, XINE_LOG_FORMAT, - _("demux_snd: bad header parameters\n")); - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return DEMUX_FINISHED; - } - - switch (encoding) { - case 1: - this->audio_type = BUF_AUDIO_MULAW; - this->audio_bits = 16; - this->audio_frames = this->data_size / this->audio_channels; - this->audio_block_align = PCM_BLOCK_ALIGN; - this->audio_bytes_per_second = this->audio_channels * - this->audio_sample_rate; - break; - - case 3: - this->audio_type = BUF_AUDIO_LPCM_BE; - this->audio_bits = 16; - this->audio_frames = this->data_size / - (this->audio_channels * this->audio_bits / 8); - this->audio_block_align = PCM_BLOCK_ALIGN; - this->audio_bytes_per_second = this->audio_channels * - (this->audio_bits / 8) * this->audio_sample_rate; - break; - - case 27: - this->audio_type = BUF_AUDIO_ALAW; - this->audio_bits = 16; - this->audio_frames = this->data_size / this->audio_channels; - this->audio_block_align = PCM_BLOCK_ALIGN; - this->audio_bytes_per_second = this->audio_channels * - this->audio_sample_rate; - break; - - default: - xine_log(this->xine, XINE_LOG_FORMAT, - _("demux_snd: unsupported audio type: %d\n"), encoding); - this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return DEMUX_FINISHED; - break; - } - - this->running_time = this->audio_frames / this->audio_sample_rate; - /* print vital stats */ - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_snd: %d Hz, %d channels, %d bits, %d frames\n"), this->audio_sample_rate, this->audio_channels, this->audio_bits, this->audio_frames); - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_snd: running time: %d min, %d sec\n"), this->running_time / 60, this->running_time % 60); @@ -431,7 +449,7 @@ static void demux_snd_stop (demux_plugin_t *this_gen) { xine_demux_control_end(this->xine, BUF_FLAG_END_USER); } -static void demux_snd_close (demux_plugin_t *this_gen) { +static void demux_snd_dispose (demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; pthread_mutex_destroy (&this->mutex); @@ -477,7 +495,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { this->demux_plugin.start = demux_snd_start; this->demux_plugin.seek = demux_snd_seek; this->demux_plugin.stop = demux_snd_stop; - this->demux_plugin.close = demux_snd_close; + this->demux_plugin.dispose = demux_snd_dispose; this->demux_plugin.get_status = demux_snd_get_status; this->demux_plugin.get_identifier = demux_snd_get_id; this->demux_plugin.get_stream_length = demux_snd_get_stream_length; @@ -495,6 +513,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 10, "snd", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, + { PLUGIN_DEMUX, 11, "snd", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_voc.c b/src/demuxers/demux_voc.c index 9448cae4c..2d669c494 100644 --- a/src/demuxers/demux_voc.c +++ b/src/demuxers/demux_voc.c @@ -23,7 +23,7 @@ * It will only play that block if it is PCM data. More variations will be * supported as they are encountered. * - * $Id: demux_voc.c,v 1.6 2002/09/10 15:07:14 mroi Exp $ + * $Id: demux_voc.c,v 1.7 2002/09/21 18:18:46 tmmm Exp $ * */ @@ -73,6 +73,7 @@ typedef struct { int send_end_buffers; int status; + unsigned int voc_audio_type; unsigned int audio_type; unsigned int audio_sample_rate; unsigned int audio_bits; @@ -178,6 +179,95 @@ static void *demux_voc_loop (void *this_gen) { return NULL; } +static int load_voc_and_send_headers(demux_voc_t *this) { + + unsigned char header[VOC_HEADER_SIZE]; + unsigned char preamble[BLOCK_PREAMBLE_SIZE]; + off_t first_block_offset; + signed char sample_rate_divisor; + + pthread_mutex_lock(&this->mutex); + + this->video_fifo = this->xine->video_fifo; + this->audio_fifo = this->xine->audio_fifo; + + this->status = DEMUX_OK; + + /* load the header */ + this->input->seek(this->input, 0, SEEK_SET); + if (this->input->read(this->input, header, VOC_HEADER_SIZE) != + VOC_HEADER_SIZE) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + first_block_offset = LE_16(&header[0x14]); + this->input->seek(this->input, first_block_offset, SEEK_SET); + + /* load the block preamble */ + if (this->input->read(this->input, preamble, BLOCK_PREAMBLE_SIZE) != + BLOCK_PREAMBLE_SIZE) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + /* so far, this demuxer only cares about type 1 blocks */ + if (preamble[0] != 1) { + xine_log(this->xine, XINE_LOG_MSG, + _("unknown VOC block type (0x%02X); please report to xine developers\n"), + preamble[0]); + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + /* assemble 24-bit, little endian length */ + this->data_size = preamble[1] | (preamble[2] << 8) | (preamble[3] << 16); + + /* get the next 2 bytes (re-use preamble bytes) */ + if (this->input->read(this->input, preamble, 2) != 2) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + /* this app only knows how to deal with format 0 data (raw PCM) */ + this->voc_audio_type = preamble[1]; + if (preamble[1] != 0) { + xine_log(this->xine, XINE_LOG_MSG, + _("unknown VOC compression type (0x%02X); please report to xine developers\n"), + preamble[1]); + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + this->audio_type = BUF_AUDIO_LPCM_BE; + sample_rate_divisor = preamble[0]; + this->audio_sample_rate = 256 - (1000000 / sample_rate_divisor); + this->data_start = this->input->get_current_pos(this->input); + this->data_end = this->data_start + this->data_size; + this->audio_bits = 8; + this->audio_channels = 1; + this->running_time = this->data_size / this->audio_sample_rate; + + /* load stream information */ + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = + this->audio_channels; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = + this->audio_sample_rate; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = + this->audio_bits; + + xine_demux_control_headers_done (this->xine); + + pthread_mutex_unlock (&this->mutex); + + return DEMUX_CAN_HANDLE; +} + static int demux_voc_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) { @@ -197,7 +287,7 @@ static int demux_voc_open(demux_plugin_t *this_gen, /* check the signature */ if (strncmp(header, VOC_SIGNATURE, strlen(VOC_SIGNATURE)) == 0) - return DEMUX_CAN_HANDLE; + return load_voc_and_send_headers(this); return DEMUX_CANNOT_HANDLE; } @@ -223,10 +313,8 @@ static int demux_voc_open(demux_plugin_t *this_gen, while(*m == ' ' || *m == '\t') m++; - if(!strcasecmp((suffix + 1), m)) { - this->input = input; - return DEMUX_CAN_HANDLE; - } + if(!strcasecmp((suffix + 1), m)) + return load_voc_and_send_headers(this); } return DEMUX_CANNOT_HANDLE; } @@ -241,22 +329,17 @@ static int demux_voc_open(demux_plugin_t *this_gen, } static int demux_voc_start (demux_plugin_t *this_gen, - fifo_buffer_t *video_fifo, - fifo_buffer_t *audio_fifo, off_t start_pos, int start_time) { demux_voc_t *this = (demux_voc_t *) this_gen; buf_element_t *buf; int err; - unsigned char header[VOC_HEADER_SIZE]; - unsigned char preamble[BLOCK_PREAMBLE_SIZE]; - off_t first_block_offset; - signed char sample_rate_divisor; pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ if (!this->thread_running) { +#if 0 this->video_fifo = video_fifo; this->audio_fifo = audio_fifo; @@ -282,7 +365,7 @@ static int demux_voc_start (demux_plugin_t *this_gen, /* so far, this demuxer only cares about type 1 blocks */ if (preamble[0] != 1) { - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("unknown VOC block type (0x%02X); please report to xine developers\n"), preamble[0]); this->status = DEMUX_FINISHED; @@ -302,7 +385,7 @@ static int demux_voc_start (demux_plugin_t *this_gen, /* this app only knows how to deal with format 0 data (raw PCM) */ if (preamble[1] != 0) { - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("unknown VOC compression type (0x%02X); please report to xine developers\n"), preamble[1]); this->status = DEMUX_FINISHED; @@ -318,11 +401,12 @@ static int demux_voc_start (demux_plugin_t *this_gen, this->audio_bits = 8; this->audio_channels = 1; this->running_time = this->data_size / this->audio_sample_rate; +#endif /* print vital stats */ - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_voc: VOC format 0x%X audio, %d Hz, running time: %d min, %d sec\n"), - preamble[1], + this->voc_audio_type, this->audio_sample_rate, this->running_time / 60, this->running_time % 60); @@ -423,7 +507,7 @@ static void demux_voc_stop (demux_plugin_t *this_gen) { xine_demux_control_end(this->xine, BUF_FLAG_END_USER); } -static void demux_voc_close (demux_plugin_t *this_gen) { +static void demux_voc_dispose (demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; pthread_mutex_destroy (&this->mutex); @@ -469,7 +553,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { this->demux_plugin.start = demux_voc_start; this->demux_plugin.seek = demux_voc_seek; this->demux_plugin.stop = demux_voc_stop; - this->demux_plugin.close = demux_voc_close; + this->demux_plugin.dispose = demux_voc_dispose; this->demux_plugin.get_status = demux_voc_get_status; this->demux_plugin.get_identifier = demux_voc_get_id; this->demux_plugin.get_stream_length = demux_voc_get_stream_length; @@ -487,6 +571,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 10, "voc", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, + { PLUGIN_DEMUX, 11, "voc", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index 9a9cafd07..c57ba4fde 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -20,7 +20,7 @@ * MS WAV File Demuxer by Mike Melanson (melanson@pcisys.net) * based on WAV specs that are available far and wide * - * $Id: demux_wav.c,v 1.12 2002/09/10 15:07:14 mroi Exp $ + * $Id: demux_wav.c,v 1.13 2002/09/21 18:18:45 tmmm Exp $ * */ @@ -102,7 +102,7 @@ static void *demux_wav_loop (void *this_gen) { pthread_mutex_lock( &this->mutex ); /* just load data chunks from wherever the stream happens to be - * pointing; issue a DEMUX_FINISHED status is EOF is reached */ + * pointing; issue a DEMUX_FINISHED status if EOF is reached */ remaining_sample_bytes = this->wave->nBlockAlign; current_file_pos = this->input->get_current_pos(this->input); @@ -172,6 +172,81 @@ static void *demux_wav_loop (void *this_gen) { return NULL; } +static int load_wav_and_send_headers(demux_wav_t *this) { + + unsigned int chunk_tag; + unsigned int chunk_size; + unsigned char chunk_preamble[8]; + + pthread_mutex_lock(&this->mutex); + + this->video_fifo = this->xine->video_fifo; + this->audio_fifo = this->xine->audio_fifo; + + this->status = DEMUX_OK; + + /* go straight for the format structure */ + this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET); + if (this->input->read(this->input, + (unsigned char *)&this->wave_size, 4) != 4) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + this->wave_size = le2me_32(this->wave_size); + this->wave = (xine_waveformatex *) malloc( this->wave_size ); + + if (this->input->read(this->input, (void *)this->wave, this->wave_size) != + this->wave_size) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + xine_waveformatex_le2me(this->wave); + this->audio_type = formattag_to_buf_audio(this->wave->wFormatTag); + if(!this->audio_type) { + xine_report_codec( this->xine, XINE_CODEC_AUDIO, this->audio_type, 0, 0); + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + + /* traverse through the chunks to find the 'data' chunk */ + this->data_start = this->data_size = this->data_end = 0; + while (this->data_start == 0) { + + if (this->input->read(this->input, chunk_preamble, 8) != 8) { + this->status = DEMUX_FINISHED; + pthread_mutex_unlock(&this->mutex); + return DEMUX_CANNOT_HANDLE; + } + chunk_tag = LE_32(&chunk_preamble[0]); + chunk_size = LE_32(&chunk_preamble[4]); + + if (chunk_tag == data_TAG) { + this->data_start = this->input->get_current_pos(this->input); + this->data_size = chunk_size; + this->data_end = this->data_start + chunk_size; + } else { + this->input->seek(this->input, chunk_size, SEEK_CUR); + } + } + + /* load stream information */ + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = + this->wave->nChannels; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = + this->wave->nSamplesPerSec; + this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = + this->wave->wBitsPerSample; + + xine_demux_control_headers_done (this->xine); + + pthread_mutex_unlock (&this->mutex); + + return DEMUX_CAN_HANDLE; +} + static int demux_wav_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) { @@ -203,7 +278,7 @@ static int demux_wav_open(demux_plugin_t *this_gen, (signature[13] == 'm') && (signature[14] == 't') && (signature[15] == ' ')) - return DEMUX_CAN_HANDLE; + return load_wav_and_send_headers(this); return DEMUX_CANNOT_HANDLE; } @@ -228,10 +303,8 @@ static int demux_wav_open(demux_plugin_t *this_gen, while(*m == ' ' || *m == '\t') m++; - if(!strcasecmp((suffix + 1), m)) { - this->input = input; - return DEMUX_CAN_HANDLE; - } + if(!strcasecmp((suffix + 1), m)) + return load_wav_and_send_headers(this); } return DEMUX_CANNOT_HANDLE; } @@ -246,85 +319,30 @@ static int demux_wav_open(demux_plugin_t *this_gen, } static int demux_wav_start (demux_plugin_t *this_gen, - fifo_buffer_t *video_fifo, - fifo_buffer_t *audio_fifo, off_t start_pos, int start_time) { demux_wav_t *this = (demux_wav_t *) this_gen; buf_element_t *buf; int err; - unsigned int chunk_tag; - unsigned int chunk_size; - unsigned char chunk_preamble[8]; - int status; pthread_mutex_lock(&this->mutex); /* if thread is not running, initialize demuxer */ if (!this->thread_running) { - this->video_fifo = video_fifo; - this->audio_fifo = audio_fifo; - - /* go straight for the format structure */ - this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET); - if (this->input->read(this->input, - (unsigned char *)&this->wave_size, 4) != 4) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; - } - this->wave_size = le2me_32(this->wave_size); - this->wave = (xine_waveformatex *) malloc( this->wave_size ); - - if (this->input->read(this->input, (void *)this->wave, this->wave_size) != - this->wave_size) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; - } - xine_waveformatex_le2me(this->wave); - this->audio_type = formattag_to_buf_audio(this->wave->wFormatTag); - if(!this->audio_type) { - xine_report_codec( this->xine, XINE_CODEC_AUDIO, this->audio_type, 0, 0); - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; - } - - /* traverse through the chunks to find the 'data' chunk */ - this->data_start = this->data_size = this->data_end = 0; - while (this->data_start == 0) { - - if (this->input->read(this->input, chunk_preamble, 8) != 8) { - status = this->status = DEMUX_FINISHED; - pthread_mutex_unlock(&this->mutex); - return status; - } - chunk_tag = LE_32(&chunk_preamble[0]); - chunk_size = LE_32(&chunk_preamble[4]); - - if (chunk_tag == data_TAG) { - this->data_start = this->input->get_current_pos(this->input); - this->data_size = chunk_size; - this->data_end = this->data_start + chunk_size; - } else { - this->input->seek(this->input, chunk_size, SEEK_CUR); - } - } /* print vital stats */ - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_wav: format 0x%X audio, %d Hz, %d bits/sample, %d %s\n"), this->wave->wFormatTag, this->wave->nSamplesPerSec, this->wave->wBitsPerSample, this->wave->nChannels, ngettext("channel", "channels", this->wave->nChannels)); - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_wav: running time = %lld min, %lld sec\n"), this->data_size / this->wave->nAvgBytesPerSec / 60, this->data_size / this->wave->nAvgBytesPerSec % 60); - xine_log(this->xine, XINE_LOG_FORMAT, + xine_log(this->xine, XINE_LOG_MSG, _("demux_wav: average bytes/sec = %d, block alignment = %d\n"), this->wave->nAvgBytesPerSec, this->wave->nBlockAlign); @@ -432,7 +450,7 @@ static void demux_wav_stop (demux_plugin_t *this_gen) { xine_demux_control_end(this->xine, BUF_FLAG_END_USER); } -static void demux_wav_close (demux_plugin_t *this_gen) { +static void demux_wav_dispose (demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; pthread_mutex_destroy (&this->mutex); @@ -478,7 +496,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { this->demux_plugin.start = demux_wav_start; this->demux_plugin.seek = demux_wav_seek; this->demux_plugin.stop = demux_wav_stop; - this->demux_plugin.close = demux_wav_close; + this->demux_plugin.dispose = demux_wav_dispose; this->demux_plugin.get_status = demux_wav_get_status; this->demux_plugin.get_identifier = demux_wav_get_id; this->demux_plugin.get_stream_length = demux_wav_get_stream_length; @@ -496,6 +514,6 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 10, "wav", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, + { PLUGIN_DEMUX, 11, "wav", XINE_VERSION_CODE, NULL, init_demuxer_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |