summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/Makefile.am15
-rw-r--r--src/demuxers/demux_fli.c123
-rw-r--r--src/demuxers/demux_roq.c217
3 files changed, 194 insertions, 161 deletions
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index 7792faae6..8aed0cb13 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -40,7 +40,8 @@ lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(qt_modules) xineplug_dmx_avi.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_wc3movie.la xineplug_dmx_fli.la \
+ xineplug_dmx_roq.la
xineplug_dmx_ogg_la_SOURCES = demux_ogg.c
xineplug_dmx_ogg_la_LIBADD = $(OGG_LIBS) $(VORBIS_LIBS)\
@@ -91,13 +92,13 @@ xineplug_dmx_film_la_SOURCES = demux_film.c
xineplug_dmx_film_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
xineplug_dmx_film_la_LDFLAGS = -avoid-version -module
-#xineplug_dmx_roq_la_SOURCES = demux_roq.c
-#xineplug_dmx_roq_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
-#xineplug_dmx_roq_la_LDFLAGS = -avoid-version -module
+xineplug_dmx_roq_la_SOURCES = demux_roq.c
+xineplug_dmx_roq_la_LIBADD = $(top_builddir)/src/xine-engine/libxine.la
+xineplug_dmx_roq_la_LDFLAGS = -avoid-version -module
-#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_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
diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c
index c80e36f11..99e880711 100644
--- a/src/demuxers/demux_fli.c
+++ b/src/demuxers/demux_fli.c
@@ -22,7 +22,7 @@
* avoid while programming a FLI decoder, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: demux_fli.c,v 1.10 2002/09/10 15:07:14 mroi Exp $
+ * $Id: demux_fli.c,v 1.11 2002/09/21 19:47:11 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -76,6 +76,7 @@ typedef struct {
/* video information */
unsigned int width;
unsigned int height;
+ unsigned char fli_header[FLI_HEADER_SIZE];
/* playback info */
unsigned int magic_number;
@@ -183,6 +184,64 @@ static void *demux_fli_loop (void *this_gen) {
return NULL;
}
+static int load_fli_and_send_headers(demux_fli_t *this) {
+
+ pthread_mutex_lock(&this->mutex);
+
+ this->video_fifo = this->xine->video_fifo;
+ /* video-only format, don't worry about audio_fifo */
+
+ this->status = DEMUX_OK;
+
+ /* read the whole header */
+ this->input->seek(this->input, 0, SEEK_SET);
+ if (this->input->read(this->input, this->fli_header, FLI_HEADER_SIZE) !=
+ FLI_HEADER_SIZE) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock (&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ this->magic_number = LE_16(&this->fli_header[4]);
+ this->frame_count = LE_16(&this->fli_header[6]);
+ this->width = LE_16(&this->fli_header[8]);
+ this->height = LE_16(&this->fli_header[10]);
+ this->speed = LE_32(&this->fli_header[16]);
+ if (this->magic_number == 0xAF11) {
+ /*
+ * in this case, the speed (n) is number of 1/70s ticks between frames:
+ *
+ * xine pts n * frame #
+ * -------- = ----------- => xine pts = n * (90000/70) * frame #
+ * 90000 70
+ *
+ * therefore, the frame pts increment = n * 1285.7
+ */
+ this->frame_pts_inc = this->speed * 1285.7;
+ } else {
+ /*
+ * in this case, the speed (n) is number of milliseconds between frames:
+ *
+ * xine pts n * frame #
+ * -------- = ----------- => xine pts = n * 90 * frame #
+ * 90000 1000
+ *
+ * therefore, the frame pts increment = n * 90
+ */
+ this->frame_pts_inc = this->speed * 90;
+ }
+
+ /* load stream information */
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
+
+ xine_demux_control_headers_done (this->xine);
+
+ pthread_mutex_unlock (&this->mutex);
+
+ return DEMUX_CAN_HANDLE;
+}
+
static int demux_fli_open(demux_plugin_t *this_gen, input_plugin_t *input,
int stage) {
@@ -204,7 +263,7 @@ static int demux_fli_open(demux_plugin_t *this_gen, input_plugin_t *input,
magic_number = LE_16(&sig[0]);
if ((magic_number == FLI_FILE_MAGIC_1) ||
(magic_number == FLI_FILE_MAGIC_2))
- return DEMUX_CAN_HANDLE;
+ return load_fli_and_send_headers(this);
return DEMUX_CANNOT_HANDLE;
}
@@ -230,10 +289,8 @@ static int demux_fli_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_fli_and_send_headers(this);
}
return DEMUX_CANNOT_HANDLE;
}
@@ -249,66 +306,26 @@ static int demux_fli_open(demux_plugin_t *this_gen, input_plugin_t *input,
}
static int demux_fli_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_fli_t *this = (demux_fli_t *) this_gen;
buf_element_t *buf;
int err;
- unsigned char fli_header[FLI_HEADER_SIZE];
pthread_mutex_lock(&this->mutex);
/* if thread is not running, initialize demuxer */
if (!this->thread_running) {
- this->video_fifo = video_fifo;
-
- /* read the whole header */
- this->input->seek(this->input, 0, SEEK_SET);
- if (this->input->read(this->input, fli_header, FLI_HEADER_SIZE) !=
- FLI_HEADER_SIZE) {
- return DEMUX_FINISHED;
- }
-
- this->magic_number = LE_16(&fli_header[4]);
- this->frame_count = LE_16(&fli_header[6]);
- this->width = LE_16(&fli_header[8]);
- this->height = LE_16(&fli_header[10]);
- this->speed = LE_32(&fli_header[16]);
- if (this->magic_number == 0xAF11) {
- /*
- * in this case, the speed (n) is number of 1/70s ticks between frames:
- *
- * xine pts n * frame #
- * -------- = ----------- => xine pts = n * (90000/70) * frame #
- * 90000 70
- *
- * therefore, the frame pts increment = n * 1285.7
- */
- this->frame_pts_inc = this->speed * 1285.7;
- } else {
- /*
- * in this case, the speed (n) is number of milliseconds between frames:
- *
- * xine pts n * frame #
- * -------- = ----------- => xine pts = n * 90 * frame #
- * 90000 1000
- *
- * therefore, the frame pts increment = n * 90
- */
- this->frame_pts_inc = this->speed * 90;
- }
/* print vital stats */
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_fli: FLI type: %04X, speed: %d/%d\n"),
this->magic_number, this->speed,
(this->magic_number == FLI_FILE_MAGIC_1) ? 70 : 1000);
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_fli: %d frames, %dx%d\n"),
this->frame_count, this->width, this->height);
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_fli: running time: %d min, %d sec\n"),
this->frame_count * this->frame_pts_inc / 90000 / 60,
this->frame_count * this->frame_pts_inc / 90000 % 60);
@@ -325,7 +342,7 @@ static int demux_fli_start (demux_plugin_t *this_gen,
buf->decoder_info[0] = 0;
buf->decoder_info[1] = this->frame_pts_inc; /* initial video_step */
/* be a rebel and send the FLI header instead of the bih */
- memcpy(buf->content, fli_header, FLI_HEADER_SIZE);
+ memcpy(buf->content, this->fli_header, FLI_HEADER_SIZE);
buf->size = FLI_HEADER_SIZE;
buf->type = BUF_VIDEO_FLI;
this->video_fifo->put (this->video_fifo, buf);
@@ -378,7 +395,7 @@ static void demux_fli_stop (demux_plugin_t *this_gen) {
xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
}
-static void demux_fli_close (demux_plugin_t *this) {
+static void demux_fli_dispose (demux_plugin_t *this) {
free(this);
}
@@ -417,7 +434,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
this->demux_plugin.start = demux_fli_start;
this->demux_plugin.seek = demux_fli_seek;
this->demux_plugin.stop = demux_fli_stop;
- this->demux_plugin.close = demux_fli_close;
+ this->demux_plugin.dispose = demux_fli_dispose;
this->demux_plugin.get_status = demux_fli_get_status;
this->demux_plugin.get_identifier = demux_fli_get_id;
this->demux_plugin.get_stream_length = demux_fli_get_stream_length;
@@ -432,6 +449,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, "fli", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 11, "fli", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c
index 5e90198c6..c0904acc2 100644
--- a/src/demuxers/demux_roq.c
+++ b/src/demuxers/demux_roq.c
@@ -21,7 +21,7 @@
* For more information regarding the RoQ file format, visit:
* http://www.csse.monash.edu.au/~timf/
*
- * $Id: demux_roq.c,v 1.14 2002/09/10 15:07:14 mroi Exp $
+ * $Id: demux_roq.c,v 1.15 2002/09/21 19:47:11 tmmm Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -124,7 +124,6 @@ static void *demux_roq_loop (void *this_gen) {
/* adjust the chunk size */
chunk_size += RoQ_CHUNK_PREAMBLE_SIZE;
-
if( this->audio_fifo ) {
/* do this calculation carefully because I can't trust the
@@ -158,7 +157,6 @@ static void *demux_roq_loop (void *this_gen) {
if (!chunk_size)
buf->decoder_flags |= BUF_FLAG_FRAME_END;
this->audio_fifo->put(this->audio_fifo, buf);
-//printf ("audio packet pts = %lld\n", buf->pts);
}
} else {
/* no audio -> skip chunk */
@@ -191,7 +189,6 @@ static void *demux_roq_loop (void *this_gen) {
}
/* packetize the video chunk and route it to the video fifo */
-//printf ("total video chunk size = %X\n", chunk_size);
while (chunk_size) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_VIDEO_ROQ;
@@ -213,8 +210,6 @@ static void *demux_roq_loop (void *this_gen) {
if (!chunk_size)
buf->decoder_flags |= BUF_FLAG_FRAME_END;
this->video_fifo->put(this->video_fifo, buf);
-//printf ("loaded video packet with %X bytes, pts = %lld\n",
-// buf->size, buf->pts);
}
video_pts_counter += this->frame_pts_inc;
} else {
@@ -250,6 +245,113 @@ static void *demux_roq_loop (void *this_gen) {
return NULL;
}
+static int load_roq_and_send_headers(demux_roq_t *this) {
+
+ char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
+ int i;
+ unsigned int chunk_type;
+ unsigned int chunk_size;
+
+ 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, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
+ RoQ_CHUNK_PREAMBLE_SIZE) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ this->width = this->height = 0;
+ this->audio_channels = 0; /* assume no audio at first */
+
+ /*
+ * RoQ files enjoy a constant framerate; pts calculation:
+ *
+ * xine pts frame #
+ * -------- = ------- => xine pts = 90000 * frame # / fps
+ * 90000 fps
+ *
+ * therefore, the frame pts increment is 90000 / fps
+ */
+ this->fps = LE_16(&preamble[6]);
+ this->frame_pts_inc = 90000 / this->fps;
+
+ /* iterate through the first 2 seconds worth of chunks searching for
+ * the RoQ_INFO chunk and an audio chunk */
+ i = this->fps * 2;
+ while (i-- > 0) {
+ /* if this read fails, then maybe it's just a really small RoQ file
+ * (even less than 2 seconds) */
+ if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
+ RoQ_CHUNK_PREAMBLE_SIZE)
+ break;
+ chunk_type = LE_16(&preamble[0]);
+ chunk_size = LE_32(&preamble[2]);
+
+ if (chunk_type == RoQ_INFO) {
+ /* fetch the width and height; reuse the preamble bytes */
+ if (this->input->read(this->input, preamble, 8) != 8)
+ break;
+
+ this->width = LE_16(&preamble[0]);
+ this->height = LE_16(&preamble[2]);
+
+ /* if an audio chunk was already found, search is done */
+ if (this->audio_channels)
+ break;
+
+ /* prep the size for a seek */
+ chunk_size -= 8;
+ } else {
+ /* if it was an audio chunk and the info chunk has already been
+ * found (as indicated by width and height) then break */
+ if (chunk_type == RoQ_SOUND_MONO) {
+ this->audio_channels = 1;
+ if (this->width && this->height)
+ break;
+ } else if (chunk_type == RoQ_SOUND_STEREO) {
+ this->audio_channels = 2;
+ if (this->width && this->height)
+ break;
+ }
+ }
+
+ /* skip the rest of the chunk */
+ this->input->seek(this->input, chunk_size, SEEK_CUR);
+ }
+
+ /* after all is said and done, if there is a width and a height,
+ * regard it as being a valid file and reset to the first chunk */
+ if (this->width && this->height) {
+ this->input->seek(this->input, 8, SEEK_SET);
+ } else {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock(&this->mutex);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ /* load stream information */
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_WIDTH] = this->width;
+ this->xine->stream_info[XINE_STREAM_INFO_VIDEO_HEIGHT] = this->height;
+ this->xine->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] =
+ this->audio_channels;
+ this->xine->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] =
+ RoQ_AUDIO_SAMPLE_RATE;
+ 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_roq_open(demux_plugin_t *this_gen, input_plugin_t *input,
int stage) {
demux_roq_t *this = (demux_roq_t *) this_gen;
@@ -270,7 +372,7 @@ static int demux_roq_open(demux_plugin_t *this_gen, input_plugin_t *input,
/* check for the RoQ magic numbers */
if ((LE_16(&preamble[0]) == RoQ_MAGIC_NUMBER) &&
(LE_32(&preamble[2]) == 0xFFFFFFFF))
- return DEMUX_CAN_HANDLE;
+ return load_roq_and_send_headers(this);
return DEMUX_CANNOT_HANDLE;
}
@@ -296,10 +398,8 @@ static int demux_roq_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_roq_and_send_headers(this);
}
return DEMUX_CANNOT_HANDLE;
}
@@ -315,108 +415,23 @@ static int demux_roq_open(demux_plugin_t *this_gen, input_plugin_t *input,
}
static int demux_roq_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_roq_t *this = (demux_roq_t *) this_gen;
buf_element_t *buf;
int err;
- char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
- int i;
- unsigned int chunk_type;
- unsigned int chunk_size;
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;
-
- this->input->seek(this->input, 0, SEEK_SET);
- if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
- RoQ_CHUNK_PREAMBLE_SIZE) {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return this->status;
- }
-
- this->width = this->height = 0;
- this->audio_channels = 0; /* assume no audio at first */
-
- /*
- * RoQ files enjoy a constant framerate; pts calculation:
- *
- * xine pts frame #
- * -------- = ------- => xine pts = 90000 * frame # / fps
- * 90000 fps
- *
- * therefore, the frame pts increment is 90000 / fps
- */
- this->fps = LE_16(&preamble[6]);
- this->frame_pts_inc = 90000 / this->fps;
-
- /* iterate through the first 2 seconds worth of chunks searching for
- * the RoQ_INFO chunk and an audio chunk */
- i = this->fps * 2;
- while (i-- > 0) {
- /* if this read fails, then maybe it's just a really small RoQ file
- * (even less than 2 seconds) */
- if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
- RoQ_CHUNK_PREAMBLE_SIZE)
- break;
- chunk_type = LE_16(&preamble[0]);
- chunk_size = LE_32(&preamble[2]);
-
- if (chunk_type == RoQ_INFO) {
- /* fetch the width and height; reuse the preamble bytes */
- if (this->input->read(this->input, preamble, 8) != 8)
- break;
-
- this->width = LE_16(&preamble[0]);
- this->height = LE_16(&preamble[2]);
-
- /* if an audio chunk was already found, search is done */
- if (this->audio_channels)
- break;
-
- /* prep the size for a seek */
- chunk_size -= 8;
- } else {
- /* if it was an audio chunk and the info chunk has already been
- * found (as indicated by width and height) then break */
- if (chunk_type == RoQ_SOUND_MONO) {
- this->audio_channels = 1;
- if (this->width && this->height)
- break;
- } else if (chunk_type == RoQ_SOUND_STEREO) {
- this->audio_channels = 2;
- if (this->width && this->height)
- break;
- }
- }
-
- /* skip the rest of the chunk */
- this->input->seek(this->input, chunk_size, SEEK_CUR);
- }
-
- /* after all is said and done, if there is a width and a height,
- * regard it as being a valid file and reset to the first chunk */
- if (this->width && this->height) {
- this->input->seek(this->input, 8, SEEK_SET);
- } else {
- this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return this->status;
- }
/* print vital stats */
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_roq: RoQ file, video is %dx%d, %d frames/sec\n"),
this->width, this->height, this->fps);
if (this->audio_channels)
- xine_log (this->xine, XINE_LOG_FORMAT,
+ xine_log (this->xine, XINE_LOG_MSG,
_("demux_roq: 16-bit, 22050 Hz %s RoQ DPCM audio\n"),
(this->audio_channels == 1) ? "monaural" : "stereo");
@@ -500,7 +515,7 @@ static void demux_roq_stop (demux_plugin_t *this_gen) {
xine_demux_control_end(this->xine, BUF_FLAG_END_USER);
}
-static void demux_roq_close (demux_plugin_t *this) {
+static void demux_roq_dispose (demux_plugin_t *this) {
free(this);
}
@@ -540,7 +555,7 @@ static void *init_demuxer_plugin(xine_t *xine, void *data) {
this->demux_plugin.start = demux_roq_start;
this->demux_plugin.seek = demux_roq_seek;
this->demux_plugin.stop = demux_roq_stop;
- this->demux_plugin.close = demux_roq_close;
+ this->demux_plugin.dispose = demux_roq_dispose;
this->demux_plugin.get_status = demux_roq_get_status;
this->demux_plugin.get_identifier = demux_roq_get_id;
this->demux_plugin.get_stream_length = demux_roq_get_stream_length;
@@ -558,6 +573,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, "roq", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
+ { PLUGIN_DEMUX, 11, "roq", XINE_VERSION_CODE, NULL, init_demuxer_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};