summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/Makefile.am29
-rw-r--r--src/demuxers/demux_cda.c42
-rw-r--r--src/demuxers/demux_smjpeg.c235
-rw-r--r--src/demuxers/demux_vqa.c225
4 files changed, 297 insertions, 234 deletions
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index 8aed0cb13..249afd797 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -37,11 +37,12 @@ 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_wav.la \
- xineplug_dmx_aiff.la xineplug_dmx_voc.la \
- xineplug_dmx_snd.la xineplug_dmx_idcin.la \
- xineplug_dmx_wc3movie.la xineplug_dmx_fli.la \
- xineplug_dmx_roq.la
+ xineplug_dmx_cda.la xineplug_dmx_film.la \
+ xineplug_dmx_roq.la xineplug_dmx_fli.la \
+ xineplug_dmx_smjpeg.la xineplug_dmx_wav.la \
+ xineplug_dmx_idcin.la xineplug_dmx_wc3movie.la \
+ xineplug_dmx_vqa.la xineplug_dmx_voc.la \
+ xineplug_dmx_aiff.la xineplug_dmx_snd.la
xineplug_dmx_ogg_la_SOURCES = demux_ogg.c
xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\
@@ -84,9 +85,9 @@ xineplug_dmx_asf_la_SOURCES = demux_asf.c
xineplug_dmx_asf_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_dmx_asf_la_LDFLAGS = -avoid-version -module
-#xineplug_dmx_cda_la_SOURCES = demux_cda.c
-#xineplug_dmx_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-#xineplug_dmx_cda_la_LDFLAGS = -avoid-version -module
+xineplug_dmx_cda_la_SOURCES = demux_cda.c
+xineplug_dmx_cda_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+xineplug_dmx_cda_la_LDFLAGS = -avoid-version -module
xineplug_dmx_film_la_SOURCES = demux_film.c
xineplug_dmx_film_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
@@ -100,9 +101,9 @@ xineplug_dmx_fli_la_SOURCES = demux_fli.c
xineplug_dmx_fli_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_dmx_fli_la_LDFLAGS = -avoid-version -module
-#xineplug_dmx_smjpeg_la_SOURCES = demux_smjpeg.c
-#xineplug_dmx_smjpeg_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-#xineplug_dmx_smjpeg_la_LDFLAGS = -avoid-version -module
+xineplug_dmx_smjpeg_la_SOURCES = demux_smjpeg.c
+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
@@ -116,9 +117,9 @@ xineplug_dmx_wc3movie_la_SOURCES = demux_wc3movie.c
xineplug_dmx_wc3movie_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_dmx_wc3movie_la_LDFLAGS = -avoid-version -module
-#xineplug_dmx_vqa_la_SOURCES = demux_vqa.c
-#xineplug_dmx_vqa_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-#xineplug_dmx_vqa_la_LDFLAGS = -avoid-version -module
+xineplug_dmx_vqa_la_SOURCES = demux_vqa.c
+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
diff --git a/src/demuxers/demux_cda.c b/src/demuxers/demux_cda.c
index 19311f007..efbb0d3b1 100644
--- a/src/demuxers/demux_cda.c
+++ b/src/demuxers/demux_cda.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: demux_cda.c,v 1.24 2002/09/10 15:07:13 mroi Exp $
+ * $Id: demux_cda.c,v 1.25 2002/09/21 20:27:02 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -170,8 +170,6 @@ static int demux_cda_get_status (demux_plugin_t *this_gen) {
*
*/
static int demux_cda_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_cda_t *this = (demux_cda_t *) this_gen;
int err;
@@ -184,9 +182,6 @@ static int demux_cda_start (demux_plugin_t *this_gen,
this->blocksize = this->input->get_blocksize(this->input);
if( !this->thread_running ) {
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
-
xine_demux_control_start(this->xine);
}
@@ -218,15 +213,38 @@ static int demux_cda_start (demux_plugin_t *this_gen,
static int demux_cda_seek (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
- demux_cda_t *this = (demux_cda_t *) this_gen;
- return demux_cda_start (this_gen, this->video_fifo, this->audio_fifo,
+ return demux_cda_start (this_gen,
start_pos, start_time);
}
/*
*
*/
+static int demux_cda_send_headers(demux_cda_t *this) {
+
+ pthread_mutex_lock(&this->mutex);
+
+ this->video_fifo = this->xine->video_fifo;
+ this->audio_fifo = this->xine->audio_fifo;
+
+ this->status = DEMUX_OK;
+
+ /* hardwired stream information */
+ this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = 2;
+ this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = 44100;
+ this->xine->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = 16;
+
+ xine_demux_control_headers_done (this->xine);
+
+ pthread_mutex_unlock (&this->mutex);
+
+ return DEMUX_CAN_HANDLE;
+}
+
+/*
+ *
+ */
static int demux_cda_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) {
demux_cda_t *this = (demux_cda_t *) this_gen;
@@ -244,7 +262,7 @@ static int demux_cda_open(demux_plugin_t *this_gen, input_plugin_t *input, int s
if(media) {
if(!strncasecmp(MRL, "cda", 3)) {
this->input = input;
- return DEMUX_CAN_HANDLE;
+ return demux_cda_send_headers(this);
}
}
}
@@ -275,7 +293,7 @@ static char *demux_cda_get_mimetypes(void) {
/*
*
*/
-static void demux_cda_close (demux_plugin_t *this) {
+static void demux_cda_dispose (demux_plugin_t *this) {
free (this);
}
@@ -301,7 +319,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
this->demux_plugin.start = demux_cda_start;
this->demux_plugin.seek = demux_cda_seek;
this->demux_plugin.stop = demux_cda_stop;
- this->demux_plugin.close = demux_cda_close;
+ this->demux_plugin.dispose = demux_cda_dispose;
this->demux_plugin.get_status = demux_cda_get_status;
this->demux_plugin.get_identifier = demux_cda_get_id;
this->demux_plugin.get_stream_length = demux_cda_get_stream_length;
@@ -319,6 +337,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, "cda", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 11, "cda", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/demuxers/demux_smjpeg.c b/src/demuxers/demux_smjpeg.c
index 2100959ee..ad3301bb2 100644
--- a/src/demuxers/demux_smjpeg.c
+++ b/src/demuxers/demux_smjpeg.c
@@ -21,7 +21,7 @@
* For more information on the SMJPEG file format, visit:
* http://www.lokigames.com/development/smjpeg.php3
*
- * $Id: demux_smjpeg.c,v 1.14 2002/09/10 15:07:14 mroi Exp $
+ * $Id: demux_smjpeg.c,v 1.15 2002/09/21 20:27:02 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -249,6 +249,124 @@ static void *demux_smjpeg_loop (void *this_gen) {
return NULL;
}
+static int load_smjpeg_and_send_headers(demux_smjpeg_t *this) {
+
+ unsigned int chunk_tag;
+ unsigned char header_chunk[SMJPEG_HEADER_CHUNK_MAX_SIZE];
+
+ pthread_mutex_lock(&this->mutex);
+
+ this->video_fifo = this->xine->video_fifo;
+ this->audio_fifo = this->xine->audio_fifo;
+
+ this->status = DEMUX_OK;
+
+ /* initial state: no video and no audio (until headers found) */
+ this->video_type = this->audio_type = 0;
+ this->input_length = this->input->get_length (this->input);
+
+ /* jump over the signature and version to the duration */
+ this->input->seek(this->input, 12, SEEK_SET);
+ if (this->input->read(this->input, header_chunk, 4) != 4) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+ this->duration = BE_32(&header_chunk[0]);
+
+ /* traverse the header chunks until the HEND tag is found */
+ chunk_tag = 0;
+ while (chunk_tag != HEND_TAG) {
+
+ if (this->input->read(this->input, header_chunk, 4) != 4) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_FINISHED;
+ }
+ chunk_tag = BE_32(&header_chunk[0]);
+
+ switch(chunk_tag) {
+
+ case HEND_TAG:
+ /* this indicates the end of the header; do nothing and fall
+ * out of the loop on the next iteration */
+ break;
+
+ case _VID_TAG:
+ if (this->input->read(this->input, header_chunk,
+ SMJPEG_VIDEO_HEADER_SIZE) != SMJPEG_VIDEO_HEADER_SIZE) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ this->bih.biWidth = BE_16(&header_chunk[8]);
+ this->bih.biHeight = BE_16(&header_chunk[10]);
+ this->bih.biCompression = *(uint32_t *)&header_chunk[12];
+ this->video_type = fourcc_to_buf_video(this->bih.biCompression);
+ break;
+
+ case _SND_TAG:
+ if (this->input->read(this->input, header_chunk,
+ SMJPEG_AUDIO_HEADER_SIZE) != SMJPEG_AUDIO_HEADER_SIZE) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ this->audio_sample_rate = BE_16(&header_chunk[4]);
+ this->audio_bits = header_chunk[6];
+ this->audio_channels = header_chunk[7];
+ /* ADPCM in these files is ID'd by 'APCM' which is used in other
+ * files to denote a slightly different format; thus, use the
+ * following special case */
+ if (BE_32(&header_chunk[8]) == APCM_TAG) {
+ this->audio_codec = be2me_32(APCM_TAG);
+ this->audio_type = BUF_AUDIO_SMJPEG_IMA;
+ } else {
+ this->audio_codec = *(uint32_t *)&header_chunk[8]&header_chunk[8];
+ this->audio_type = formattag_to_buf_audio(this->audio_codec);
+ }
+ break;
+
+ default:
+ /* for all other chunk types, read the length and skip the rest
+ * of the chunk */
+ if (this->input->read(this->input, header_chunk, 4) != 4) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+ this->input->seek(this->input, BE_32(&header_chunk[0]), SEEK_CUR);
+ break;
+ }
+ }
+
+ if(!this->video_type)
+ xine_report_codec(this->xine, XINE_CODEC_VIDEO,
+ this->bih.biCompression, 0, 0);
+
+ if(!this->audio_type && this->audio_codec)
+ xine_report_codec(this->xine, XINE_CODEC_AUDIO,
+ this->audio_codec, 0, 0);
+
+ /* load stream information */
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->bih.biWidth;
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->bih.biHeight;
+ 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_smjpeg_open(demux_plugin_t *this_gen, input_plugin_t *input,
int stage) {
demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen;
@@ -275,7 +393,7 @@ static int demux_smjpeg_open(demux_plugin_t *this_gen, input_plugin_t *input,
(signature[5] == 'P') &&
(signature[6] == 'E') &&
(signature[7] == 'G'))
- return DEMUX_CAN_HANDLE;
+ return load_smjpeg_and_send_headers(this);
return DEMUX_CANNOT_HANDLE;
}
@@ -301,10 +419,8 @@ static int demux_smjpeg_open(demux_plugin_t *this_gen, input_plugin_t *input,
while(*m == ' ' || *m == '\t') m++;
- if(!strcasecmp((suffix + 1), m)) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
- }
+ if(!strcasecmp((suffix + 1), m))
+ return load_smjpeg_and_send_headers(this);
}
return DEMUX_CANNOT_HANDLE;
}
@@ -320,13 +436,9 @@ static int demux_smjpeg_open(demux_plugin_t *this_gen, input_plugin_t *input,
}
static int demux_smjpeg_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen;
- unsigned int chunk_tag;
- unsigned char header_chunk[SMJPEG_HEADER_CHUNK_MAX_SIZE];
buf_element_t *buf;
int err;
@@ -334,105 +446,14 @@ static int demux_smjpeg_start (demux_plugin_t *this_gen,
/* if thread is not running, initialize demuxer */
if (!this->thread_running) {
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
-
- /* initial state: no video and no audio (until headers found) */
- this->video_type = this->audio_type = 0;
- this->input_length = this->input->get_length (this->input);
-
- /* jump over the signature and version to the duration */
- this->input->seek(this->input, 12, SEEK_SET);
- if (this->input->read(this->input, header_chunk, 4) != 4) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
- this->duration = BE_32(&header_chunk[0]);
-
- /* traverse the header chunks until the HEND tag is found */
- chunk_tag = 0;
- while (chunk_tag != HEND_TAG) {
-
- if (this->input->read(this->input, header_chunk, 4) != 4) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
- chunk_tag = BE_32(&header_chunk[0]);
-
- switch(chunk_tag) {
-
- case HEND_TAG:
- /* this indicates the end of the header; do nothing and fall
- * out of the loop on the next iteration */
- break;
-
- case _VID_TAG:
- if (this->input->read(this->input, header_chunk,
- SMJPEG_VIDEO_HEADER_SIZE) != SMJPEG_VIDEO_HEADER_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
-
- this->bih.biWidth = BE_16(&header_chunk[8]);
- this->bih.biHeight = BE_16(&header_chunk[10]);
- this->bih.biCompression = *(uint32_t *)&header_chunk[12];
- this->video_type = fourcc_to_buf_video(this->bih.biCompression);
- break;
-
- case _SND_TAG:
- if (this->input->read(this->input, header_chunk,
- SMJPEG_AUDIO_HEADER_SIZE) != SMJPEG_AUDIO_HEADER_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
-
- this->audio_sample_rate = BE_16(&header_chunk[4]);
- this->audio_bits = header_chunk[6];
- this->audio_channels = header_chunk[7];
- /* ADPCM in these files is ID'd by 'APCM' which is used in other
- * files to denote a slightly different format; thus, use the
- * following special case */
- if (BE_32(&header_chunk[8]) == APCM_TAG) {
- this->audio_codec = be2me_32(APCM_TAG);
- this->audio_type = BUF_AUDIO_SMJPEG_IMA;
- } else {
- this->audio_codec = *(uint32_t *)&header_chunk[8]&header_chunk[8];
- this->audio_type = formattag_to_buf_audio(this->audio_codec);
- }
- break;
-
- default:
- /* for all other chunk types, read the length and skip the rest
- * of the chunk */
- if (this->input->read(this->input, header_chunk, 4) != 4) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
- this->input->seek(this->input, BE_32(&header_chunk[0]), SEEK_CUR);
- break;
- }
- }
-
- if(!this->video_type)
- xine_report_codec(this->xine, XINE_CODEC_VIDEO,
- this->bih.biCompression, 0, 0);
-
- if(!this->audio_type && this->audio_codec)
- xine_report_codec(this->xine, XINE_CODEC_AUDIO,
- this->audio_codec, 0, 0);
/* print vital stats */
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_smjpeg: SMJPEG file, running time: %d min, %d sec\n"),
this->duration / 1000 / 60,
this->duration / 1000 % 60);
if (this->video_type)
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_smjpeg: '%c%c%c%c' video @ %dx%d\n"),
*((char *)&this->bih.biCompression + 0),
*((char *)&this->bih.biCompression + 1),
@@ -441,7 +462,7 @@ static int demux_smjpeg_start (demux_plugin_t *this_gen,
this->bih.biWidth,
this->bih.biHeight);
if (this->audio_type)
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_smjpeg: '%c%c%c%c' audio @ %d Hz, %d bits, %d %s\n"),
*((char *)&this->audio_codec + 0),
*((char *)&this->audio_codec + 1),
@@ -525,7 +546,7 @@ static void demux_smjpeg_stop (demux_plugin_t *this_gen) {
xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
}
-static void demux_smjpeg_close (demux_plugin_t *this_gen) {
+static void demux_smjpeg_dispose (demux_plugin_t *this_gen) {
demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen;
pthread_mutex_destroy (&this->mutex);
@@ -569,7 +590,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
this->demux_plugin.start = demux_smjpeg_start;
this->demux_plugin.seek = demux_smjpeg_seek;
this->demux_plugin.stop = demux_smjpeg_stop;
- this->demux_plugin.close = demux_smjpeg_close;
+ this->demux_plugin.dispose = demux_smjpeg_dispose;
this->demux_plugin.get_status = demux_smjpeg_get_status;
this->demux_plugin.get_identifier = demux_smjpeg_get_id;
this->demux_plugin.get_stream_length = demux_smjpeg_get_stream_length;
@@ -587,6 +608,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, "smjpeg", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 11, "smjpeg", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/demuxers/demux_vqa.c b/src/demuxers/demux_vqa.c
index e6599a80b..4d272498f 100644
--- a/src/demuxers/demux_vqa.c
+++ b/src/demuxers/demux_vqa.c
@@ -21,7 +21,7 @@
* For more information regarding the VQA file format, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: demux_vqa.c,v 1.6 2002/09/10 15:07:14 mroi Exp $
+ * $Id: demux_vqa.c,v 1.7 2002/09/21 20:27:02 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -257,6 +257,119 @@ static void *demux_vqa_loop (void *this_gen) {
return NULL;
}
+static int load_vqa_and_send_headers(demux_vqa_t *this) {
+
+ unsigned char header[VQA_HEADER_SIZE];
+ unsigned char *finf_chunk;
+ int i;
+ off_t last_offset;
+ uint64_t audio_pts_counter = 0;
+ uint64_t video_pts_counter = 0;
+
+ pthread_mutex_lock(&this->mutex);
+
+ this->video_fifo = this->xine->video_fifo;
+ this->audio_fifo = this->xine->audio_fifo;
+
+ this->status = DEMUX_OK;
+
+ /* get the file size (a.k.a., last offset) as reported by the file */
+ this->input->seek(this->input, 4, SEEK_SET);
+ if (this->input->read(this->input, header, 4) != 4) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+ last_offset = BE_32(&header[0]);
+
+ /* get the actual filesize */
+ this->filesize = this->input->get_length(this->input);
+
+ /* skip to the VQA header */
+ this->input->seek(this->input, 20, SEEK_SET);
+ if (this->input->read(this->input, header, VQA_HEADER_SIZE)
+ != VQA_HEADER_SIZE) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ /* fetch the interesting information */
+ this->total_frames = LE_16(&header[4]);
+ this->video_width = LE_16(&header[6]);
+ this->video_height = LE_16(&header[8]);
+ this->vector_width = header[10];
+ this->vector_height = header[11];
+ this->audio_sample_rate = LE_16(&header[24]);
+ this->audio_channels = header[26];
+
+ /* fetch the chunk table */
+ this->input->seek(this->input, 8, SEEK_CUR); /* skip FINF and length */
+ finf_chunk = xine_xmalloc(this->total_frames * 4);
+ this->frame_table = xine_xmalloc(this->total_frames * sizeof(vqa_frame_t));
+ if (this->input->read(this->input, finf_chunk, this->total_frames * 4) !=
+ this->total_frames * 4) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+ for (i = 0; i < this->total_frames; i++) {
+ this->frame_table[i].frame_offset = (LE_32(&finf_chunk[i * 4]) * 2) &
+ 0x03FFFFFF;
+ if (i < this->total_frames - 1)
+ this->frame_table[i].frame_size = LE_32(&finf_chunk[(i + 1) * 4]) * 2 -
+ this->frame_table[i].frame_offset;
+ else
+ this->frame_table[i].frame_size = last_offset -
+ this->frame_table[i].frame_offset;
+
+ /*
+ * VQA files play at a constant rate of 15 frames/second. The file data
+ * begins with 1/15 sec of compressed audio followed by 1 video frame
+ * that will be displayed for 1/15 sec.
+ *
+ * xine pts frame #
+ * -------- = ------- => xine pts = 90000 * frame # / 15
+ * 90000 15
+ *
+ * Thus, each frame has a duration of 90000 / 15 (VQA_PTS_INC, in
+ * this code).
+ *
+ * If this is the first frame in the file, it contains 1/2 sec
+ * of audio and no video. Each successive frame represents 1/15 sec.
+ */
+ if (i == 0) {
+ this->frame_table[i].audio_pts = 0;
+ this->frame_table[i].video_pts = 0;
+ audio_pts_counter += (90000 / 2);
+ } else {
+ this->frame_table[i].audio_pts = audio_pts_counter;
+ this->frame_table[i].video_pts = video_pts_counter;
+ audio_pts_counter += VQA_PTS_INC;
+ video_pts_counter += VQA_PTS_INC;
+ }
+ }
+
+ this->total_time = this->frame_table[this->total_frames - 1].video_pts /
+ 90000;
+
+ /* load stream information */
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->video_width;
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->video_height;
+ 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_vqa_open(demux_plugin_t *this_gen, input_plugin_t *input,
int stage) {
demux_vqa_t *this = (demux_vqa_t *) this_gen;
@@ -276,7 +389,7 @@ static int demux_vqa_open(demux_plugin_t *this_gen, input_plugin_t *input,
/* check for the VQA signatures */
if ((BE_32(&header[0]) == FORM_TAG) &&
(BE_32(&header[8]) == WVQA_TAG))
- return DEMUX_CAN_HANDLE;
+ return load_vqa_and_send_headers(this);
return DEMUX_CANNOT_HANDLE;
}
@@ -302,10 +415,8 @@ static int demux_vqa_open(demux_plugin_t *this_gen, input_plugin_t *input,
while(*m == ' ' || *m == '\t') m++;
- if(!strcasecmp((suffix + 1), m)) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
- }
+ if(!strcasecmp((suffix + 1), m))
+ return load_vqa_and_send_headers(this);
}
return DEMUX_CANNOT_HANDLE;
}
@@ -321,113 +432,23 @@ static int demux_vqa_open(demux_plugin_t *this_gen, input_plugin_t *input,
}
static int demux_vqa_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_vqa_t *this = (demux_vqa_t *) this_gen;
buf_element_t *buf;
int err;
- unsigned char header[VQA_HEADER_SIZE];
- unsigned char *finf_chunk;
- int i;
- off_t last_offset;
- uint64_t audio_pts_counter = 0;
- uint64_t video_pts_counter = 0;
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;
-
- /* get the file size (a.k.a., last offset) as reported by the file */
- this->input->seek(this->input, 4, SEEK_SET);
- if (this->input->read(this->input, header, 4) != 4) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
- last_offset = BE_32(&header[0]);
-
- /* get the actual filesize */
- this->filesize = this->input->get_length(this->input);
-
- /* skip to the VQA header */
- this->input->seek(this->input, 20, SEEK_SET);
- if (this->input->read(this->input, header, VQA_HEADER_SIZE)
- != VQA_HEADER_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
-
- /* fetch the interesting information */
- this->total_frames = LE_16(&header[4]);
- this->video_width = LE_16(&header[6]);
- this->video_height = LE_16(&header[8]);
- this->vector_width = header[10];
- this->vector_height = header[11];
- this->audio_sample_rate = LE_16(&header[24]);
- this->audio_channels = header[26];
-
- /* fetch the chunk table */
- this->input->seek(this->input, 8, SEEK_CUR); /* skip FINF and length */
- finf_chunk = xine_xmalloc(this->total_frames * 4);
- this->frame_table = xine_xmalloc(this->total_frames * sizeof(vqa_frame_t));
- if (this->input->read(this->input, finf_chunk, this->total_frames * 4) !=
- this->total_frames * 4) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return DEMUX_FINISHED;
- }
- for (i = 0; i < this->total_frames; i++) {
- this->frame_table[i].frame_offset = (LE_32(&finf_chunk[i * 4]) * 2) &
- 0x03FFFFFF;
- if (i < this->total_frames - 1)
- this->frame_table[i].frame_size = LE_32(&finf_chunk[(i + 1) * 4]) * 2 -
- this->frame_table[i].frame_offset;
- else
- this->frame_table[i].frame_size = last_offset -
- this->frame_table[i].frame_offset;
-
- /*
- * VQA files play at a constant rate of 15 frames/second. The file data
- * begins with 1/15 sec of compressed audio followed by 1 video frame
- * that will be displayed for 1/15 sec.
- *
- * xine pts frame #
- * -------- = ------- => xine pts = 90000 * frame # / 15
- * 90000 15
- *
- * Thus, each frame has a duration of 90000 / 15 (VQA_PTS_INC, in
- * this code).
- *
- * If this is the first frame in the file, it contains 1/2 sec
- * of audio and no video. Each successive frame represents 1/15 sec.
- */
- if (i == 0) {
- this->frame_table[i].audio_pts = 0;
- this->frame_table[i].video_pts = 0;
- audio_pts_counter += (90000 / 2);
- } else {
- this->frame_table[i].audio_pts = audio_pts_counter;
- this->frame_table[i].video_pts = video_pts_counter;
- audio_pts_counter += VQA_PTS_INC;
- video_pts_counter += VQA_PTS_INC;
- }
- }
-
- this->total_time = this->frame_table[this->total_frames - 1].video_pts /
- 90000;
/* print vital stats */
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_vqa: running time: %d min, %d sec\n"),
this->total_time / 60,
this->total_time % 60);
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_vqa: %dx%d VQA video; %d-channel %d Hz IMA ADPCM audio\n"),
this->video_width,
this->video_height,
@@ -496,6 +517,8 @@ static int demux_vqa_start (demux_plugin_t *this_gen,
static int demux_vqa_seek (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
+ /* VQA files are not built for seeking; don't even bother */
+
return 0;
}
@@ -522,7 +545,7 @@ static void demux_vqa_stop (demux_plugin_t *this_gen) {
xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
}
-static void demux_vqa_close (demux_plugin_t *this_gen) {
+static void demux_vqa_dispose (demux_plugin_t *this_gen) {
demux_vqa_t *this = (demux_vqa_t *) this_gen;
@@ -566,7 +589,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
this->demux_plugin.start = demux_vqa_start;
this->demux_plugin.seek = demux_vqa_seek;
this->demux_plugin.stop = demux_vqa_stop;
- this->demux_plugin.close = demux_vqa_close;
+ this->demux_plugin.dispose = demux_vqa_dispose;
this->demux_plugin.get_status = demux_vqa_get_status;
this->demux_plugin.get_identifier = demux_vqa_get_id;
this->demux_plugin.get_stream_length = demux_vqa_get_stream_length;
@@ -584,6 +607,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, "vqa", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 11, "vqa", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};