summaryrefslogtreecommitdiff
path: root/src/demuxers/demux_wc3movie.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers/demux_wc3movie.c')
-rw-r--r--src/demuxers/demux_wc3movie.c379
1 files changed, 137 insertions, 242 deletions
diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c
index 8c1ec6b24..bf40a1728 100644
--- a/src/demuxers/demux_wc3movie.c
+++ b/src/demuxers/demux_wc3movie.c
@@ -22,7 +22,7 @@
* For more information on the MVE file format, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: demux_wc3movie.c,v 1.20 2002/10/27 16:14:31 tmmm Exp $
+ * $Id: demux_wc3movie.c,v 1.21 2002/10/28 03:24:43 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -32,8 +32,6 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
-#include <pthread.h>
-#include <sched.h>
#include <string.h>
#include <stdlib.h>
@@ -85,11 +83,6 @@ typedef struct {
input_plugin_t *input;
- pthread_t thread;
- int thread_running;
- pthread_mutex_t mutex;
- int send_end_buffers;
-
int status;
unsigned int fps;
@@ -157,7 +150,7 @@ const unsigned char wc3_pal_lookup[] = {
0xFD, 0xFD, 0xFD
};
-static void *demux_mve_loop (void *this_gen) {
+static int demux_mve_send_chunk(demux_plugin_t *this_gen) {
demux_mve_t *this = (demux_mve_t *) this_gen;
buf_element_t *buf = NULL;
@@ -170,186 +163,146 @@ static void *demux_mve_loop (void *this_gen) {
off_t current_file_pos;
unsigned int palette_number;
- pthread_mutex_lock( &this->mutex );
- this->seek_flag = 0;
+ /* compensate for the initial data in the file */
+ current_file_pos = this->input->get_current_pos(this->input) -
+ this->data_start;
- /* do-while needed to seek after demux finished */
- do {
- /* main demuxer loop */
- while (this->status == DEMUX_OK) {
+ if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
+ PREAMBLE_SIZE)
+ this->status = DEMUX_FINISHED;
+ else {
+ chunk_tag = BE_32(&preamble[0]);
+ /* round up to the nearest even size */
+ chunk_size = (BE_32(&preamble[4]) + 1) & (~1);
- /* someone may want to interrupt us */
- pthread_mutex_unlock( &this->mutex );
- /* give demux_*_stop a chance to interrupt us */
- sched_yield();
- pthread_mutex_lock( &this->mutex );
+ if (chunk_tag == BRCH_TAG) {
- /* compensate for the initial data in the file */
- current_file_pos = this->input->get_current_pos(this->input) -
- this->data_start;
+ /* empty chunk; do nothing */
- if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
- PREAMBLE_SIZE)
- this->status = DEMUX_FINISHED;
- else {
- chunk_tag = BE_32(&preamble[0]);
- /* round up to the nearest even size */
- chunk_size = (BE_32(&preamble[4]) + 1) & (~1);
+ } else if (chunk_tag == SHOT_TAG) {
- if (chunk_tag == BRCH_TAG) {
-
- /* empty chunk; do nothing */
-
- } else if (chunk_tag == SHOT_TAG) {
-
- if (this->seek_flag) {
-
- /* reset pts */
- video_pts = 0;
- xine_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK);
- this->seek_flag = 0;
-
- } else {
-
- /* record the offset of the SHOT chunk */
- this->shot_offsets[this->current_shot] =
- this->input->get_current_pos(this->input) - PREAMBLE_SIZE;
- }
-
- this->current_shot++;
-
- /* this is the start of a new shot; send a new palette */
- if (this->input->read(this->input, preamble, 4) != 4) {
- this->status = DEMUX_FINISHED;
- break;
- }
- palette_number = LE_32(&preamble[0]);
-
- if (palette_number >= this->number_of_shots) {
- xine_log(this->stream->xine, XINE_LOG_MSG,
- _("demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n"),
- palette_number, this->number_of_shots);
- this->status = DEMUX_FINISHED;
- break;
- }
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->decoder_flags = BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_PALETTE;
- buf->decoder_info[2] = PALETTE_SIZE;
- buf->decoder_info[3] =
- (unsigned int)&this->palettes[PALETTE_SIZE * palette_number];
- buf->size = 0;
- buf->type = BUF_VIDEO_WC3;
- this->video_fifo->put (this->video_fifo, buf);
-
- } else if (chunk_tag == AUDI_TAG) {
-
- audio_pts = video_pts - WC3_PTS_INC;
-
- while (chunk_size) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_AUDIO_LPCM_LE;
- buf->input_pos = current_file_pos;
- buf->input_length = this->data_size;
- buf->input_time = audio_pts / 90000;
- buf->pts = audio_pts;
-
- if (chunk_size > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = chunk_size;
- chunk_size -= buf->size;
-
- if (this->input->read(this->input, buf->content, buf->size) !=
- buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
- }
-
- if (!chunk_size)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
-
- this->audio_fifo->put (this->audio_fifo, buf);
- }
-
- } else if (chunk_tag == VGA_TAG) {
-
- while (chunk_size) {
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_VIDEO_WC3;
- buf->input_pos = current_file_pos;
- buf->input_length = this->data_size;
- buf->input_time = video_pts / 90000;
- buf->pts = video_pts;
-
- if (chunk_size > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = chunk_size;
- chunk_size -= buf->size;
-
- if (this->input->read(this->input, buf->content, buf->size) !=
- buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
- }
-
- if (!chunk_size)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
-
- this->video_fifo->put (this->video_fifo, buf);
- }
- video_pts += WC3_PTS_INC;
-
- } else if (chunk_tag == TEXT_TAG) {
-
- text_pts = video_pts - WC3_PTS_INC;
-
- /* unhandled thus far */
- this->input->seek(this->input, chunk_size, SEEK_CUR);
+ if (this->seek_flag) {
- } else {
+ /* reset pts */
+ video_pts = 0;
+ xine_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK);
+ this->seek_flag = 0;
- /* report an unknown chunk and skip it */
- printf (_("demux_wc3movie: encountered unknown chunk: %c%c%c%c\n"),
- (chunk_tag >> 24) & 0xFF,
- (chunk_tag >> 16) & 0xFF,
- (chunk_tag >> 8) & 0xFF,
- (chunk_tag >> 0) & 0xFF);
- this->input->seek(this->input, chunk_size, SEEK_CUR);
+ } else {
+
+ /* record the offset of the SHOT chunk */
+ this->shot_offsets[this->current_shot] =
+ this->input->get_current_pos(this->input) - PREAMBLE_SIZE;
+ }
+
+ this->current_shot++;
+
+ /* this is the start of a new shot; send a new palette */
+ if (this->input->read(this->input, preamble, 4) != 4) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ palette_number = LE_32(&preamble[0]);
+
+ if (palette_number >= this->number_of_shots) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n"),
+ palette_number, this->number_of_shots);
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->decoder_flags = BUF_FLAG_SPECIAL;
+ buf->decoder_info[1] = BUF_SPECIAL_PALETTE;
+ buf->decoder_info[2] = PALETTE_SIZE;
+ buf->decoder_info[3] =
+ (unsigned int)&this->palettes[PALETTE_SIZE * palette_number];
+ buf->size = 0;
+ buf->type = BUF_VIDEO_WC3;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ } else if (chunk_tag == AUDI_TAG) {
+
+ audio_pts = video_pts - WC3_PTS_INC;
+
+ while (chunk_size) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_AUDIO_LPCM_LE;
+ buf->input_pos = current_file_pos;
+ buf->input_length = this->data_size;
+ buf->input_time = audio_pts / 90000;
+ buf->pts = audio_pts;
+
+ if (chunk_size > buf->max_size)
+ buf->size = buf->max_size;
+ else
+ buf->size = chunk_size;
+ chunk_size -= buf->size;
+
+ if (this->input->read(this->input, buf->content, buf->size) !=
+ buf->size) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
}
+
+ if (!chunk_size)
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
+
+ this->audio_fifo->put (this->audio_fifo, buf);
}
- }
- /* wait before sending end buffers: user might want to do a new seek */
- while(this->send_end_buffers && this->audio_fifo->size(this->audio_fifo) &&
- this->status != DEMUX_OK){
- pthread_mutex_unlock( &this->mutex );
- xine_usec_sleep(100000);
- pthread_mutex_lock( &this->mutex );
- }
+ } else if (chunk_tag == VGA_TAG) {
+
+ while (chunk_size) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_VIDEO_WC3;
+ buf->input_pos = current_file_pos;
+ buf->input_length = this->data_size;
+ buf->input_time = video_pts / 90000;
+ buf->pts = video_pts;
+
+ if (chunk_size > buf->max_size)
+ buf->size = buf->max_size;
+ else
+ buf->size = chunk_size;
+ chunk_size -= buf->size;
+
+ if (this->input->read(this->input, buf->content, buf->size) !=
+ buf->size) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ }
- } while (this->status == DEMUX_OK);
+ if (!chunk_size)
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
- printf ("demux_wc3movie: demux loop finished (status: %d)\n",
- this->status);
+ this->video_fifo->put (this->video_fifo, buf);
+ }
+ video_pts += WC3_PTS_INC;
- /* seek back to the beginning of the data in preparation for another
- * start */
- this->input->seek(this->input, this->data_start, SEEK_SET);
+ } else if (chunk_tag == TEXT_TAG) {
- this->status = DEMUX_FINISHED;
+ text_pts = video_pts - WC3_PTS_INC;
+
+ /* unhandled thus far */
+ this->input->seek(this->input, chunk_size, SEEK_CUR);
+
+ } else {
- if (this->send_end_buffers) {
- xine_demux_control_end(this->stream, BUF_FLAG_END_STREAM);
+ /* report an unknown chunk and skip it */
+ printf (_("demux_wc3movie: encountered unknown chunk: %c%c%c%c\n"),
+ (chunk_tag >> 24) & 0xFF,
+ (chunk_tag >> 16) & 0xFF,
+ (chunk_tag >> 8) & 0xFF,
+ (chunk_tag >> 0) & 0xFF);
+ this->input->seek(this->input, chunk_size, SEEK_CUR);
+ }
}
- this->thread_running = 0;
- pthread_mutex_unlock(&this->mutex);
- return NULL;
+ return this->status;
}
static void demux_mve_send_headers(demux_plugin_t *this_gen) {
@@ -357,8 +310,6 @@ static void demux_mve_send_headers(demux_plugin_t *this_gen) {
demux_mve_t *this = (demux_mve_t *) this_gen;
buf_element_t *buf;
- pthread_mutex_lock(&this->mutex);
-
this->video_fifo = this->stream->video_fifo;
this->audio_fifo = this->stream->audio_fifo;
@@ -417,8 +368,6 @@ static void demux_mve_send_headers(demux_plugin_t *this_gen) {
}
xine_demux_control_headers_done (this->stream);
-
- pthread_mutex_unlock (&this->mutex);
}
/* returns 1 if the MVE file was opened successfully, 0 otherwise */
@@ -559,38 +508,6 @@ static int open_mve_file(demux_mve_t *this) {
}
static int demux_mve_seek (demux_plugin_t *this_gen,
- off_t start_pos, int start_time);
-
-static int demux_mve_start (demux_plugin_t *this_gen,
- off_t start_pos, int start_time) {
-
- demux_mve_t *this = (demux_mve_t *) this_gen;
- int err;
-
- demux_mve_seek(this_gen, start_pos, start_time);
-
- /* if thread is not running, initialize demuxer */
- if (!this->thread_running) {
-
- /* send new pts */
- xine_demux_control_newpts(this->stream, 0, 0);
-
- this->status = DEMUX_OK;
- this->send_end_buffers = 1;
- this->thread_running = 1;
-
- if ((err = pthread_create (&this->thread, NULL, demux_mve_loop, this)) != 0) {
- printf ("demux_wc3movie: can't create new thread (%s)\n", strerror(err));
- abort();
- }
- }
-
- pthread_mutex_unlock(&this->mutex);
-
- return DEMUX_OK;
-}
-
-static int demux_mve_seek (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
/*
@@ -612,8 +529,6 @@ static int demux_mve_seek (demux_plugin_t *this_gen,
unsigned int chunk_size;
int new_shot = -1;
- pthread_mutex_lock(&this->mutex);
-
/* make sure the first shot has been recorded */
if (this->shot_offsets[0] == 0) {
@@ -622,8 +537,7 @@ static int demux_mve_seek (demux_plugin_t *this_gen,
if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
PREAMBLE_SIZE) {
this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return 1;
+ return this->status;
}
chunk_tag = BE_32(&preamble[0]);
@@ -655,8 +569,7 @@ static int demux_mve_seek (demux_plugin_t *this_gen,
if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
PREAMBLE_SIZE) {
this->status = DEMUX_FINISHED;
- pthread_mutex_unlock(&this->mutex);
- return 1;
+ return this->status;
}
chunk_tag = BE_32(&preamble[0]);
@@ -698,39 +611,23 @@ static int demux_mve_seek (demux_plugin_t *this_gen,
this->status = DEMUX_OK;
xine_demux_flush_engine(this->stream);
- pthread_mutex_unlock(&this->mutex);
-
- return 0;
-}
-
-static void demux_mve_stop (demux_plugin_t *this_gen) {
-
- demux_mve_t *this = (demux_mve_t *) this_gen;
- void *p;
+
+ /* if thread is not running, initialize demuxer */
+ if( !this->stream->demux_thread_running ) {
- pthread_mutex_lock( &this->mutex );
+ /* send new pts */
+ xine_demux_control_newpts(this->stream, 0, 0);
- if (!this->thread_running) {
- pthread_mutex_unlock( &this->mutex );
- return;
+ this->status = DEMUX_OK;
+ this->seek_flag = 0;
}
- this->send_end_buffers = 0;
- this->status = DEMUX_FINISHED;
-
- pthread_mutex_unlock( &this->mutex );
- pthread_join (this->thread, &p);
-
- xine_demux_flush_engine(this->stream);
-
- xine_demux_control_end(this->stream, BUF_FLAG_END_USER);
+ return 0;
}
static void demux_mve_dispose (demux_plugin_t *this_gen) {
demux_mve_t *this = (demux_mve_t *) this_gen;
- demux_mve_stop(this_gen);
-
free(this->palettes);
free(this);
}
@@ -763,16 +660,14 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
this->input = input;
this->demux_plugin.send_headers = demux_mve_send_headers;
- this->demux_plugin.start = demux_mve_start;
+ this->demux_plugin.send_chunk = demux_mve_send_chunk;
this->demux_plugin.seek = demux_mve_seek;
- this->demux_plugin.stop = demux_mve_stop;
this->demux_plugin.dispose = demux_mve_dispose;
this->demux_plugin.get_status = demux_mve_get_status;
this->demux_plugin.get_stream_length = demux_mve_get_stream_length;
this->demux_plugin.demux_class = class_gen;
this->status = DEMUX_FINISHED;
- pthread_mutex_init (&this->mutex, NULL);
switch (stream->content_detection_method) {
@@ -879,6 +774,6 @@ static void *init_plugin (xine_t *xine, void *data) {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_DEMUX, 14, "wc3movie", XINE_VERSION_CODE, NULL, init_plugin },
+ { PLUGIN_DEMUX, 15, "wc3movie", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};