summaryrefslogtreecommitdiff
path: root/src/demuxers
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers')
-rw-r--r--src/demuxers/demux.h19
-rw-r--r--src/demuxers/demux_asf.c192
-rw-r--r--src/demuxers/demux_avi.c283
-rw-r--r--src/demuxers/demux_cda.c96
-rw-r--r--src/demuxers/demux_elem.c119
-rw-r--r--src/demuxers/demux_mpeg.c185
-rw-r--r--src/demuxers/demux_mpeg_block.c133
-rw-r--r--src/demuxers/demux_mpgaudio.c104
-rw-r--r--src/demuxers/demux_ogg.c111
-rw-r--r--src/demuxers/demux_pes.c181
-rw-r--r--src/demuxers/demux_qt.c229
-rw-r--r--src/demuxers/demux_ts.c211
12 files changed, 1219 insertions, 644 deletions
diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h
index a8228cd1b..8f7d9b480 100644
--- a/src/demuxers/demux.h
+++ b/src/demuxers/demux.h
@@ -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.h,v 1.12 2001/10/25 00:46:58 miguelfreitas Exp $
+ * $Id: demux.h,v 1.13 2002/04/09 03:37:59 miguelfreitas Exp $
*/
#ifndef HAVE_DEMUX_H
@@ -35,7 +35,7 @@ extern "C" {
#include "input_plugin.h"
#endif
-#define DEMUXER_PLUGIN_IFACE_VERSION 6
+#define DEMUXER_PLUGIN_IFACE_VERSION 7
#define DEMUX_OK 0
#define DEMUX_FINISHED 1
@@ -91,6 +91,21 @@ struct demux_plugin_s
void (*start) (demux_plugin_t *this, fifo_buffer_t *video_fifo,
fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time);
+
+ /*
+ * ask running demux thread to seek
+ *
+ * for seekable streams, a start position can be specified
+ *
+ * start_pos : position in input source
+ * start_time : position measured in seconds from stream start
+ *
+ * if both parameters are !=0 start_pos will be used
+ * for non-seekable streams both values will be ignored
+ */
+
+ void (*seek) (demux_plugin_t *this,
+ off_t start_pos, int start_time);
/*
* stop & kill demux thread, free resources associated with current
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 01a54c8c8..af147781a 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.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_asf.c,v 1.32 2002/03/26 18:23:35 miguelfreitas Exp $
+ * $Id: demux_asf.c,v 1.33 2002/04/09 03:37:59 miguelfreitas Exp $
*
* demultiplexer for asf streams
*
@@ -129,6 +129,7 @@ typedef struct demux_asf_s {
int frame;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -141,6 +142,7 @@ typedef struct demux_asf_s {
int reorder_w;
int reorder_b;
+ off_t header_size;
} demux_asf_t ;
@@ -671,13 +673,13 @@ static void asf_send_discontinuity (demux_asf_t *this, int64_t pts) {
buf_element_t *buf;
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->type = BUF_CONTROL_NEWPTS;
buf->disc_off = pts;
this->video_fifo->put (this->video_fifo, buf);
if(this->audio_fifo) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->type = BUF_CONTROL_NEWPTS;
buf->disc_off = pts;
this->audio_fifo->put (this->audio_fifo, buf);
}
@@ -1129,10 +1131,17 @@ static void *demux_asf_loop (void *this_gen) {
this->send_end_buffers = 1;
- while (this->status == DEMUX_OK) {
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
asf_read_packet (this);
-
+
+ pthread_mutex_unlock( &this->mutex );
+
}
/*
@@ -1156,6 +1165,8 @@ static void *demux_asf_loop (void *this_gen) {
}
}
+
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
@@ -1175,21 +1186,22 @@ static void demux_asf_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
int i;
void *p;
+
+ pthread_mutex_lock( &this->mutex );
if (this->status != DEMUX_OK) {
printf ("demux_asf: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
- pthread_cancel (this->thread);
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -1225,87 +1237,115 @@ static void demux_asf_start (demux_plugin_t *this_gen,
demux_asf_t *this = (demux_asf_t *) this_gen;
buf_element_t *buf;
int err;
+ int starting;
+
+ pthread_mutex_lock( &this->mutex );
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
-
- /*
- * send start buffer
- */
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ starting = (this->status != DEMUX_OK);
+ this->status = DEMUX_OK;
+
+ if( starting ) {
+ this->audio_fifo = audio_fifo;
+ this->video_fifo = video_fifo;
+
+ /*
+ * send start buffer
+ */
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- /*
- * initialize asf engine
- */
-
- this->num_streams = 0;
- this->num_audio_streams = 0;
- this->num_video_streams = 0;
- this->packet_size = 0;
- this->seqno = 0;
- this->send_discontinuity = 1;
- this->last_video_pts = 0;
- this->frame_duration = 3000;
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- if (this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE)
- this->input->seek (this->input, 0, SEEK_SET);
+ /*
+ * initialize asf engine
+ */
- if (!asf_read_header (this)) {
-
- this->status = DEMUX_FINISHED;
- return;
- }
+ this->num_streams = 0;
+ this->num_audio_streams = 0;
+ this->num_video_streams = 0;
+ this->packet_size = 0;
+ this->seqno = 0;
+ this->frame_duration = 3000;
+
+ if (this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE)
+ this->input->seek (this->input, 0, SEEK_SET);
- xine_log (this->xine, XINE_LOG_FORMAT,
- _("demux_asf: title : %s\n"), this->title);
- xine_log (this->xine, XINE_LOG_FORMAT,
- _("demux_asf: author : %s\n"), this->author);
- xine_log (this->xine, XINE_LOG_FORMAT,
- _("demux_asf: copyright : %s\n"), this->copyright);
- xine_log (this->xine, XINE_LOG_FORMAT,
- _("demux_asf: comment : %s\n"), this->comment);
+ if (!asf_read_header (this)) {
+
+ this->status = DEMUX_FINISHED;
+ } else {
+ this->header_size = this->input->get_current_pos (this->input);
- /*
- * seek to start position
- */
+ xine_log (this->xine, XINE_LOG_FORMAT,
+ _("demux_asf: title : %s\n"), this->title);
+ xine_log (this->xine, XINE_LOG_FORMAT,
+ _("demux_asf: author : %s\n"), this->author);
+ xine_log (this->xine, XINE_LOG_FORMAT,
+ _("demux_asf: copyright : %s\n"), this->copyright);
+ xine_log (this->xine, XINE_LOG_FORMAT,
+ _("demux_asf: comment : %s\n"), this->comment);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
+ }
+
+ if( this->status == DEMUX_OK )
+ /*
+ * seek to start position
+ */
+ this->send_discontinuity = 1;
+ this->last_video_pts = 0;
- if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) {
+ if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) {
- off_t cur_pos = this->input->get_current_pos (this->input);
-
- if ( (!start_pos) && (start_time))
- start_pos = start_time * this->rate;
+ if ( (!start_pos) && (start_time))
+ start_pos = start_time * this->rate;
- if (start_pos<cur_pos)
- start_pos = cur_pos;
+ if (start_pos < this->header_size)
+ start_pos = this->header_size;
- this->input->seek (this->input, start_pos, SEEK_SET);
- }
+ this->input->seek (this->input, start_pos, SEEK_SET);
+ }
- /*
- * now start demuxing
- */
+ /*
+ * now start demuxing
+ */
- this->keyframe_found = 0;
- this->status = DEMUX_OK;
+ this->keyframe_found = 0;
- if ((err = pthread_create (&this->thread,
- NULL, demux_asf_loop, this)) != 0) {
- printf ("demux_asf: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ if( starting ) {
+ if ((err = pthread_create (&this->thread,
+ NULL, demux_asf_loop, this)) != 0) {
+ printf ("demux_asf: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+
+ pthread_mutex_unlock( &this->mutex );
+
+ if( !starting && this->status != DEMUX_OK ) {
+ void *p;
+ pthread_join (this->thread, &p);
}
}
+static void demux_asf_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_asf_t *this = (demux_asf_t *) this_gen;
+
+ demux_asf_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
+}
+
+
static int demux_asf_open(demux_plugin_t *this_gen,
input_plugin_t *input, int stage) {
@@ -1387,7 +1427,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_asf_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_asf: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -1407,6 +1447,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_asf_open;
this->demux_plugin.start = demux_asf_start;
+ this->demux_plugin.seek = demux_asf_seek;
this->demux_plugin.stop = demux_asf_stop;
this->demux_plugin.close = demux_asf_close;
this->demux_plugin.get_status = demux_asf_get_status;
@@ -1414,5 +1455,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_asf_get_stream_length;
this->demux_plugin.get_mimetypes = demux_asf_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index 86c6ebeaa..8e8805ea5 100644
--- a/src/demuxers/demux_avi.c
+++ b/src/demuxers/demux_avi.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_avi.c,v 1.72 2002/03/31 20:38:40 jcdutton Exp $
+ * $Id: demux_avi.c,v 1.73 2002/04/09 03:37:59 miguelfreitas Exp $
*
* demultiplexer for avi streams
*
@@ -135,6 +135,7 @@ typedef struct demux_avi_s {
avi_t *avi;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -851,7 +852,10 @@ static int demux_avi_next (demux_avi_t *this) {
}
}
- return (buf->size>0);
+ if( buf )
+ return (buf->size>0);
+ else
+ return 0;
}
static void *demux_avi_loop (void *this_gen) {
@@ -861,14 +865,19 @@ static void *demux_avi_loop (void *this_gen) {
this->send_end_buffers = 1;
- do {
-
- /* printf ("avi loop (status %d)\n", this->status); */
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
if (!demux_avi_next(this))
this->status = DEMUX_FINISHED;
-
- } while (this->status == DEMUX_OK) ;
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -886,6 +895,7 @@ static void *demux_avi_loop (void *this_gen) {
printf ("demux_avi: demux loop finished.\n");
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
return NULL;
@@ -896,27 +906,27 @@ static void demux_avi_stop (demux_plugin_t *this_gen) {
demux_avi_t *this = (demux_avi_t *) this_gen;
buf_element_t *buf;
void *p;
+
+ pthread_mutex_lock( &this->mutex );
if (this->status != DEMUX_OK) {
printf ("demux_avi: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
- pthread_cancel (this->thread);
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
+ xine_flush_engine(this->xine);
/*
AVI_close (this->avi);
this->avi = NULL;
*/
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
-
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = BUF_FLAG_END_USER; /* user finished */
@@ -951,38 +961,44 @@ static void demux_avi_start (demux_plugin_t *this_gen,
uint32_t video_pts = 0;
int err;
unsigned char *sub;
+ int starting;
+
+ pthread_mutex_lock( &this->mutex );
- this->audio_fifo = audio_fifo;
- this->video_fifo = video_fifo;
-
- this->status = DEMUX_OK;
-
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video format = %s\n"),
- this->avi->compressor);
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video frame size %ld x %ld\n"),
- this->avi->width, this->avi->height);
- for(i=0; i < this->avi->n_audio; i++)
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: audio format[%d] = 0x%lx\n"),
- i, this->avi->audio[i]->a_fmt);
- this->no_audio = 0;
+ starting = (this->status != DEMUX_OK);
+ this->status = DEMUX_OK;
- for(i=0; i < this->avi->n_audio; i++) {
- this->avi->audio[i]->audio_type = formattag_to_buf_audio (this->avi->audio[i]->a_fmt);
+ if( starting ) {
+ this->audio_fifo = audio_fifo;
+ this->video_fifo = video_fifo;
+
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video format = %s\n"),
+ this->avi->compressor);
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video frame size %ld x %ld\n"),
+ this->avi->width, this->avi->height);
+ for(i=0; i < this->avi->n_audio; i++)
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: audio format[%d] = 0x%lx\n"),
+ i, this->avi->audio[i]->a_fmt);
+ this->no_audio = 0;
+
+ for(i=0; i < this->avi->n_audio; i++) {
+ this->avi->audio[i]->audio_type = formattag_to_buf_audio (this->avi->audio[i]->a_fmt);
- if( !this->avi->audio[i]->audio_type ) {
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: unknown audio type 0x%lx\n"),
- this->avi->audio[i]->a_fmt);
- this->no_audio = 1;
- this->avi->audio[i]->audio_type = BUF_CONTROL_NOP;
+ if( !this->avi->audio[i]->audio_type ) {
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: unknown audio type 0x%lx\n"),
+ this->avi->audio[i]->a_fmt);
+ this->no_audio = 1;
+ this->avi->audio[i]->audio_type = BUF_CONTROL_NOP;
+ }
+ else
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: audio type %s (wFormatTag 0x%x)\n"),
+ buf_audio_name(this->avi->audio[i]->audio_type),
+ (int)this->avi->audio[i]->a_fmt);
}
- else
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: audio type %s (wFormatTag 0x%x)\n"),
- buf_audio_name(this->avi->audio[i]->audio_type),
- (int)this->avi->audio[i]->a_fmt);
}
-
+
AVI_seek_start (this->avi);
-
+
/*
* seek to start pos / time
*/
@@ -998,7 +1014,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
this->status = DEMUX_FINISHED;
printf ("demux_avi: video seek to start failed\n");
- return;
+ break;
}
}
@@ -1015,7 +1031,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
this->status = DEMUX_FINISHED;
printf ("demux_avi: video seek to start failed\n");
- return;
+ break;
}
}
@@ -1024,7 +1040,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
}
/* seek audio */
- if (!this->no_audio) {
+ if (!this->no_audio && this->status == DEMUX_OK) {
for(i=0; i < this->avi->n_audio; i++) {
while (get_audio_pts (this, i, this->avi->audio[i]->audio_posc, 0) < video_pts) {
this->avi->audio[i]->audio_posc++;
@@ -1032,110 +1048,135 @@ static void demux_avi_start (demux_plugin_t *this_gen,
this->status = DEMUX_FINISHED;
printf ("demux_avi: audio seek to start failed\n");
- return;
+ break;
}
}
}
}
-
/*
* send start buffers
*/
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- buf->decoder_flags = 0;
- this->video_fifo->put (this->video_fifo, buf);
-
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if( starting && this->status == DEMUX_OK ) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
buf->decoder_flags = 0;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = video_pts;
- this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = 0;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
+ }
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
+ if( this->status == DEMUX_OK )
+ {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
buf->disc_off = video_pts;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->content = buf->mem;
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[1] = this->video_step;
- memcpy (buf->content, &this->avi->bih, sizeof (this->avi->bih));
- buf->size = sizeof (this->avi->bih);
-
- this->avi->video_type = fourcc_to_buf_video((void*)&this->avi->bih.biCompression);
-
- if ( !this->avi->video_type ) {
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: unknown video codec '%.4s'\n"),
- (char*)&this->avi->bih.biCompression);
-
- this->status = DEMUX_FINISHED;
- return;
- }
- buf->type = this->avi->video_type;
- xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video codec is '%s'\n"),
- buf_video_name(buf->type));
-
- this->video_fifo->put (this->video_fifo, buf);
-
- if(this->audio_fifo) {
- for(i=0; i<this->avi->n_audio; i++) {
- avi_audio_t *a = this->avi->audio[i];
+ this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->content = buf->mem;
- buf->decoder_flags = BUF_FLAG_HEADER;
- memcpy (buf->content, &a->wavex, sizeof (a->wavex));
- buf->size = sizeof (a->wavex);
- buf->type = a->audio_type | i;
- buf->decoder_info[0] = 0; /* first package, containing wavex */
- buf->decoder_info[1] = a->a_rate; /* Audio Rate */
- buf->decoder_info[2] = a->a_bits; /* Audio bits */
- buf->decoder_info[3] = a->a_chans; /* Audio bits */
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = video_pts;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
+
+ if( starting && this->status == DEMUX_OK ) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->content = buf->mem;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[1] = this->video_step;
+ memcpy (buf->content, &this->avi->bih, sizeof (this->avi->bih));
+ buf->size = sizeof (this->avi->bih);
- /*
- * send external spu file pointer, if present
- */
+ this->avi->video_type = fourcc_to_buf_video((void*)&this->avi->bih.biCompression);
+
+ if ( !this->avi->video_type ) {
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: unknown video codec '%.4s'\n"),
+ (char*)&this->avi->bih.biCompression);
+
+ this->status = DEMUX_FINISHED;
+ }
+ else {
+ buf->type = this->avi->video_type;
+ xine_log (this->xine, XINE_LOG_FORMAT, _("demux_avi: video codec is '%s'\n"),
+ buf_video_name(buf->type));
- if (this->input->get_optional_data (this->input, &sub, INPUT_OPTIONAL_DATA_TEXTSPU0)) {
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if(this->audio_fifo) {
+ for(i=0; i<this->avi->n_audio; i++) {
+ avi_audio_t *a = this->avi->audio[i];
+
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->content = buf->mem;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ memcpy (buf->content, &a->wavex, sizeof (a->wavex));
+ buf->size = sizeof (a->wavex);
+ buf->type = a->audio_type | i;
+ buf->decoder_info[0] = 0; /* first package, containing wavex */
+ buf->decoder_info[1] = a->a_rate; /* Audio Rate */
+ buf->decoder_info[2] = a->a_bits; /* Audio bits */
+ buf->decoder_info[3] = a->a_chans; /* Audio bits */
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+
+ /*
+ * send external spu file pointer, if present
+ */
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->content = sub;
+ if (this->input->get_optional_data (this->input, &sub, INPUT_OPTIONAL_DATA_TEXTSPU0)) {
- buf->type = BUF_SPU_TEXT;
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->content = sub;
+
+ buf->type = BUF_SPU_TEXT;
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[1] = this->avi->width;
- buf->decoder_info[2] = this->avi->height;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[1] = this->avi->width;
+ buf->decoder_info[2] = this->avi->height;
- this->video_fifo->put (this->video_fifo, buf);
+ this->video_fifo->put (this->video_fifo, buf);
- this->have_spu = 1;
+ this->have_spu = 1;
- printf ("demux_avi: text subtitle file available\n");
+ printf ("demux_avi: text subtitle file available\n");
+
+ } else
+ this->have_spu = 0;
+
+ if ((err = pthread_create (&this->thread, NULL, demux_avi_loop, this)) != 0) {
+ printf ("demux_avi: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+ }
+
+ pthread_mutex_unlock( &this->mutex );
+
+ if( !starting && this->status != DEMUX_OK ) {
+ void *p;
+ pthread_join (this->thread, &p);
+ }
+}
- } else
- this->have_spu = 0;
- if ((err = pthread_create (&this->thread, NULL, demux_avi_loop, this)) != 0) {
- printf ("demux_avi: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
- }
+static void demux_avi_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+
+ demux_avi_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static int demux_avi_open(demux_plugin_t *this_gen,
@@ -1250,7 +1291,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_avi_t *this;
- if (iface != 6) {
+ if (iface != 7) {
xine_log (xine, XINE_LOG_PLUGIN,
_("demux_avi: this plugin doesn't support plugin API version %d.\n"
"demux_avi: this means there's a version mismatch between xine and this "
@@ -1271,6 +1312,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_avi_open;
this->demux_plugin.start = demux_avi_start;
+ this->demux_plugin.seek = demux_avi_seek;
this->demux_plugin.stop = demux_avi_stop;
this->demux_plugin.close = demux_avi_close;
this->demux_plugin.get_status = demux_avi_get_status;
@@ -1278,5 +1320,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_avi_get_stream_length;
this->demux_plugin.get_mimetypes = demux_avi_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_cda.c b/src/demuxers/demux_cda.c
index 064e83b81..e7a5731a8 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.10 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: demux_cda.c,v 1.11 2002/04/09 03:38:00 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -52,7 +52,8 @@ typedef struct {
input_plugin_t *input;
pthread_t thread;
-
+ pthread_mutex_t mutex;
+
off_t start;
int status;
@@ -92,17 +93,22 @@ static void *demux_cda_loop (void *this_gen) {
this->send_end_buffers = 1;
- this->input->seek(this->input, this->start, SEEK_SET);
-
- do {
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
xine_usec_sleep(100000);
if (!demux_cda_next(this))
this->status = DEMUX_FINISHED;
-
- } while (this->status == DEMUX_OK) ;
-
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
+
this->status = DEMUX_FINISHED;
if (this->send_end_buffers) {
@@ -118,6 +124,8 @@ static void *demux_cda_loop (void *this_gen) {
this->audio_fifo->put (this->audio_fifo, buf);
}
}
+
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
}
@@ -130,23 +138,23 @@ static void demux_cda_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
printf ("demux_cda: stop...ignored\n");
return;
}
-
+
/* Force stop */
this->input->stop(this->input);
this->send_end_buffers = 0;
- this->status = DEMUX_FINISHED;
+ this->status = DEMUX_FINISHED;
- pthread_cancel(this->thread);
- pthread_join(this->thread, &p);
+ pthread_mutex_unlock( &this->mutex );
+ pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -182,33 +190,51 @@ static void demux_cda_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err;
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
-
- this->status = DEMUX_OK;
+ pthread_mutex_lock( &this->mutex );
+
this->start = start_pos;
this->blocksize = this->input->get_blocksize(this->input);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+
/*
* now start demuxing
*/
-
- if ((err = pthread_create (&this->thread,
- NULL, demux_cda_loop, this)) != 0) {
- printf ("demux_cda: can't create new thread (%s)\n", strerror(err));
- exit(1);
+ this->input->seek(this->input, this->start, SEEK_SET);
+
+ if( this->status != DEMUX_OK ) {
+
+ this->status = DEMUX_OK;
+ if ((err = pthread_create (&this->thread,
+ NULL, demux_cda_loop, this)) != 0) {
+ printf ("demux_cda: can't create new thread (%s)\n", strerror(err));
+ exit(1);
+ }
}
+ pthread_mutex_unlock( &this->mutex );
+}
+
+
+static void demux_cda_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_cda_t *this = (demux_cda_t *) this_gen;
+
+ demux_cda_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
/*
@@ -280,7 +306,7 @@ static int demux_cda_get_stream_length (demux_plugin_t *this_gen) {
demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_cda_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_cda: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -295,6 +321,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUX_CDA_IFACE_VERSION;
this->demux_plugin.open = demux_cda_open;
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.get_status = demux_cda_get_status;
@@ -302,5 +329,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_cda_get_stream_length;
this->demux_plugin.get_mimetypes = demux_cda_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return &this->demux_plugin;
}
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
index 78fe22025..9a46a175b 100644
--- a/src/demuxers/demux_elem.c
+++ b/src/demuxers/demux_elem.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_elem.c,v 1.36 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: demux_elem.c,v 1.37 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for elementary mpeg streams
*
@@ -43,7 +43,7 @@
#define DEMUX_MPEG_ELEM_IFACE_VERSION 1
-#define VALID_ENDS ".mpv"
+#define VALID_ENDS "mpv"
typedef struct {
@@ -59,6 +59,7 @@ typedef struct {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int blocksize;
int status;
@@ -83,10 +84,10 @@ static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) {
return 0;
}
- if(preview_mode)
- buf->decoder_info[0] = 0;
+ if (preview_mode)
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->pts = 0;
/*buf->scr = 0;*/
@@ -107,12 +108,19 @@ static void *demux_mpeg_elem_loop (void *this_gen) {
this->send_end_buffers = 1;
- do {
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
if (!demux_mpeg_elem_next(this, 0))
this->status = DEMUX_FINISHED;
-
- } while (this->status == DEMUX_OK) ;
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
this->status = DEMUX_FINISHED;
@@ -129,6 +137,7 @@ static void *demux_mpeg_elem_loop (void *this_gen) {
this->audio_fifo->put (this->audio_fifo, buf);
}
}
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
}
@@ -141,16 +150,16 @@ static void demux_mpeg_elem_stop (demux_plugin_t *this_gen) {
demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen;
buf_element_t *buf = NULL;
void *p;
+
+ pthread_mutex_lock( &this->mutex );
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
- pthread_cancel (this->thread);
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -186,53 +195,79 @@ static void demux_mpeg_elem_start (demux_plugin_t *this_gen,
demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen;
buf_element_t *buf;
int err;
+ int starting;
+
+ pthread_mutex_lock( &this->mutex );
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
-
- this->blocksize = this->input->get_blocksize(this->input);
- if (!this->blocksize)
- this->blocksize = 2048;
+ starting = (this->status != DEMUX_OK);
+ this->status = DEMUX_OK;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ if( starting ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
+
+ this->blocksize = this->input->get_blocksize(this->input);
+ if (!this->blocksize)
+ this->blocksize = 2048;
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
- int num_buffers = NUM_PREVIEW_BUFFERS;
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+
+ if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
+ int num_buffers = NUM_PREVIEW_BUFFERS;
- this->input->seek (this->input, 0, SEEK_SET);
+ this->input->seek (this->input, 0, SEEK_SET);
- this->status = DEMUX_OK ;
- while ((num_buffers > 0) && (this->status == DEMUX_OK)) {
- demux_mpeg_elem_next(this, 1);
- num_buffers--;
+ this->status = DEMUX_OK ;
+ while ((num_buffers > 0) && (this->status == DEMUX_OK)) {
+ demux_mpeg_elem_next(this, 1);
+ num_buffers--;
+ }
}
-
+ }
+ else {
+ xine_flush_engine(this->xine);
+ }
+
+ if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
+
/* FIXME: implement time seek */
this->input->seek (this->input, start_pos, SEEK_SET);
}
-
+
/*
* now start demuxing
*/
this->status = DEMUX_OK;
- if ((err = pthread_create (&this->thread,
+ if( starting ) {
+ if ((err = pthread_create (&this->thread,
NULL, demux_mpeg_elem_loop, this)) != 0) {
- printf ("demux_elem: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_elem: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
}
+ pthread_mutex_unlock( &this->mutex );
}
+static void demux_mpeg_elem_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen;
+
+ demux_mpeg_elem_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
+}
+
+
/*
*
*/
@@ -338,7 +373,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_mpeg_elem_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_elem: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -358,6 +393,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUX_MPEG_ELEM_IFACE_VERSION;
this->demux_plugin.open = demux_mpeg_elem_open;
this->demux_plugin.start = demux_mpeg_elem_start;
+ this->demux_plugin.seek = demux_mpeg_elem_seek;
this->demux_plugin.stop = demux_mpeg_elem_stop;
this->demux_plugin.close = demux_mpeg_elem_close;
this->demux_plugin.get_status = demux_mpeg_elem_get_status;
@@ -365,5 +401,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_mpeg_elem_get_stream_length;
this->demux_plugin.get_mimetypes = demux_mpeg_elem_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return &this->demux_plugin;
}
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index 80ae1a34f..60fc67b60 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.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_mpeg.c,v 1.52 2002/03/12 03:03:18 miguelfreitas Exp $
+ * $Id: demux_mpeg.c,v 1.53 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -61,6 +61,7 @@ typedef struct demux_mpeg_s {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
unsigned char dummy_space[100000];
@@ -72,7 +73,8 @@ typedef struct demux_mpeg_s {
int send_end_buffers;
int64_t last_scr;
-
+ int send_newpts;
+
} demux_mpeg_t;
static uint32_t read_bytes (demux_mpeg_t *this, int n) {
@@ -113,6 +115,28 @@ static uint32_t read_bytes (demux_mpeg_t *this, int n) {
return res;
}
+
+static void check_newpts( demux_mpeg_t *this, int64_t pts )
+{
+ if( this->send_newpts && !this->preview_mode && pts ) {
+
+ buf_element_t *buf;
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ this->send_newpts = 0;
+ }
+}
+
static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) {
int len, i;
@@ -143,7 +167,9 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
w = read_bytes(this, 2);
pts |= (w & 0xFFFE) >> 1;
- header_len -= 5 ;
+ header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -198,6 +224,8 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
pts |= (w & 0xFFFE) >> 1;
header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -245,6 +273,8 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
pts |= (w & 0xFFFE) >> 1;
header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -354,6 +384,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
}
}
+ check_newpts( this, pts );
if ((stream_id & 0xe0) == 0xc0) {
int track = stream_id & 0x1f;
@@ -384,7 +415,6 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
} else if ((stream_id & 0xf0) == 0xe0) {
-
buf = this->input->read_block (this->input, this->video_fifo, len);
if (buf == NULL) {
@@ -485,11 +515,12 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
}
/* discontinuity ? */
- if( scr )
+ if( scr && !this->preview_mode )
{
int64_t scr_diff = scr - this->last_scr;
- if (abs(scr_diff) > 60000 && !this->preview_mode) {
-
+
+ if (abs(scr_diff) > 60000 && !this->send_newpts) {
+
buf_element_t *buf;
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -617,15 +648,23 @@ static void *demux_mpeg_loop (void *this_gen) {
demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
buf_element_t *buf;
- uint32_t w;
+ uint32_t w=0;
- do {
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
w = parse_pack (this);
if (w != 0x000001ba)
demux_mpeg_resync (this, w);
- } while (this->status == DEMUX_OK) ;
+ pthread_mutex_unlock( &this->mutex );
+
+ }
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -644,6 +683,8 @@ static void *demux_mpeg_loop (void *this_gen) {
printf ("demux_mpeg: demux loop finished (status: %d, buf:%x)\n",
this->status, w);
+ pthread_mutex_unlock( &this->mutex );
+
pthread_exit(NULL);
return NULL;
@@ -655,26 +696,21 @@ static void demux_mpeg_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
- printf ("demux_mpeg: stop...\n");
-
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
-
- this->video_fifo->clear(this->video_fifo);
- if(this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
-
+ printf ("demux_mpeg: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
-
+
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if(this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -704,64 +740,93 @@ static void demux_mpeg_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err;
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
+ pthread_mutex_lock( &this->mutex );
- this->rate = 0; /* fixme */
- this->last_scr = 0;
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ if( this->status != DEMUX_OK ) {
+
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
+
+ this->rate = 0; /* fixme */
+ this->last_scr = 0;
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- uint32_t w;
- int num_buffers = NUM_PREVIEW_BUFFERS;
+ if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
- this->preview_mode = 1;
+ uint32_t w;
+ int num_buffers = NUM_PREVIEW_BUFFERS;
- this->input->seek (this->input, 4, SEEK_SET);
+ this->preview_mode = 1;
- this->status = DEMUX_OK ;
+ this->input->seek (this->input, 4, SEEK_SET);
- do {
+ this->status = DEMUX_OK ;
- w = parse_pack_preview (this, &num_buffers);
+ do {
+
+ w = parse_pack_preview (this, &num_buffers);
- if (w != 0x000001ba)
- demux_mpeg_resync (this, w);
+ if (w != 0x000001ba)
+ demux_mpeg_resync (this, w);
- num_buffers --;
-
- } while ( (this->status == DEMUX_OK) && (num_buffers>0)) ;
+ num_buffers --;
- /* printf ("demux_mpeg: rate %d\n", this->rate); */
+ } while ( (this->status == DEMUX_OK) && (num_buffers>0)) ;
+ /* printf ("demux_mpeg: rate %d\n", this->rate); */
+ this->status = DEMUX_FINISHED;
+ }
+ }
+
+ if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
+
if ( (!start_pos) && (start_time))
start_pos = start_time * this->rate * 50;
this->input->seek (this->input, start_pos+4, SEEK_SET);
+ if( start_pos )
+ demux_mpeg_resync (this, read_bytes(this, 4) );
+
} else
read_bytes(this, 4);
+
+ this->send_newpts = 1;
+
+ if( this->status != DEMUX_OK ) {
+ this->preview_mode = 0;
+ this->send_end_buffers = 1;
+ this->status = DEMUX_OK ;
- this->preview_mode = 0;
- this->send_end_buffers = 1;
- this->status = DEMUX_OK ;
-
- if ((err = pthread_create (&this->thread,
+ if ((err = pthread_create (&this->thread,
NULL, demux_mpeg_loop, this)) != 0) {
- printf ("demux_mpeg: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_mpeg: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
}
+ pthread_mutex_unlock( &this->mutex );
+
+}
+
+static void demux_mpeg_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+
+ demux_mpeg_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static int demux_mpeg_open(demux_plugin_t *this_gen,
@@ -910,7 +975,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_mpeg_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_mpeg: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -934,6 +999,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_mpeg_open;
this->demux_plugin.start = demux_mpeg_start;
+ this->demux_plugin.seek = demux_mpeg_seek;
this->demux_plugin.stop = demux_mpeg_stop;
this->demux_plugin.close = demux_mpeg_close;
this->demux_plugin.get_status = demux_mpeg_get_status;
@@ -941,6 +1007,9 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_mpeg_get_stream_length;
this->demux_plugin.get_mimetypes = demux_mpeg_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index 9d75c4e34..0314fbdca 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.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_mpeg_block.c,v 1.86 2002/04/06 02:23:38 miguelfreitas Exp $
+ * $Id: demux_mpeg_block.c,v 1.87 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -61,6 +61,7 @@ typedef struct demux_mpeg_block_s {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -341,7 +342,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
}
/* discontinuity ? */
- if (scr) {
+ if (scr && !preview_mode) {
int64_t scr_diff = scr - this->last_scr;
#ifdef LOG
@@ -349,7 +350,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr, this->last_scr, scr_diff);
#endif
- if ((abs(scr_diff) > DISC_TRESHOLD) && !preview_mode &&
+ if ( (abs(scr_diff) > DISC_TRESHOLD) &&
!this->ignore_scr_discont) {
buf_element_t *buf;
@@ -491,7 +492,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
}
if ((p[0]&0xF0) == 0x80) {
-
+
/* printf ( "ac3 PES packet, track %02x\n",track); */
buf->decoder_info[1] = p[1]; /* Number of frame headers */
buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
@@ -623,11 +624,18 @@ static void *demux_mpeg_block_loop (void *this_gen) {
this->send_end_buffers = 1;
- do {
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
demux_mpeg_block_parse_pack(this, 0);
-
- } while (this->status == DEMUX_OK) ;
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
/*
printf ("demux_mpeg_block: demux loop finished (status: %d)\n",
@@ -651,6 +659,8 @@ static void *demux_mpeg_block_loop (void *this_gen) {
}
+ pthread_mutex_unlock( &this->mutex );
+
pthread_exit(NULL);
return NULL;
@@ -805,21 +815,22 @@ static void demux_mpeg_block_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
printf ("demux_mpeg_block: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
-
+ xine_flush_engine(this->xine);
+
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = BUF_FLAG_END_USER;
@@ -849,44 +860,50 @@ static void demux_mpeg_block_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err;
+ pthread_mutex_lock( &this->mutex );
+
this->video_fifo = video_fifo;
this->audio_fifo = audio_fifo;
- /*
- * send start buffer
- */
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ if( this->status != DEMUX_OK ) {
+ /*
+ * send start buffer
+ */
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- if (!this->rate)
- this->rate = demux_mpeg_block_estimate_rate (this);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ if (!this->rate)
+ this->rate = demux_mpeg_block_estimate_rate (this);
- this->last_scr = 0;
- this->nav_last_end_pts = 0;
- this->ignore_scr_discont = 0;
+ this->last_scr = 0;
+ this->nav_last_end_pts = 0;
+ this->ignore_scr_discont = 0;
- if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
+ if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
- int num_buffers = NUM_PREVIEW_BUFFERS;
+ int num_buffers = NUM_PREVIEW_BUFFERS;
- this->input->seek (this->input, 0, SEEK_SET);
+ this->input->seek (this->input, 0, SEEK_SET);
- this->status = DEMUX_OK ;
- while ( (num_buffers>0) && (this->status == DEMUX_OK) ) {
+ this->status = DEMUX_OK ;
+ while ( (num_buffers>0) && (this->status == DEMUX_OK) ) {
- demux_mpeg_block_parse_pack(this, 1);
- num_buffers --;
+ demux_mpeg_block_parse_pack(this, 1);
+ num_buffers --;
+ }
}
-
+ this->status = DEMUX_FINISHED;
+ }
+
+ if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
if (start_pos) {
start_pos /= (off_t) this->blocksize;
start_pos *= (off_t) this->blocksize;
@@ -923,19 +940,35 @@ static void demux_mpeg_block_start (demux_plugin_t *this_gen,
* now start demuxing
*/
- this->status = DEMUX_OK ;
- this->last_scr = 0;
- this->nav_last_end_pts = 0;
- this->ignore_scr_discont = 0;
+ if( this->status != DEMUX_OK )
+ {
+ this->status = DEMUX_OK ;
+ this->last_scr = 0;
+ this->nav_last_end_pts = 0;
+ this->ignore_scr_discont = 0;
- if ((err = pthread_create (&this->thread,
+ if ((err = pthread_create (&this->thread,
NULL, demux_mpeg_block_loop, this)) != 0) {
- printf ("demux_mpeg_block: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_mpeg_block: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
}
+ pthread_mutex_unlock( &this->mutex );
+}
+
+static void demux_mpeg_block_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+
+ demux_mpeg_block_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
+
static void demux_mpeg_block_accept_input (demux_mpeg_block_t *this,
input_plugin_t *input) {
@@ -1094,6 +1127,9 @@ static char *demux_mpeg_block_get_mimetypes(void) {
static int demux_mpeg_block_get_stream_length (demux_plugin_t *this_gen) {
demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+ /*
+ * find input plugin
+ */
if (this->rate)
return this->input->get_length (this->input) / (this->rate * 50);
@@ -1106,7 +1142,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_mpeg_block_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_mpeg_block: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -1130,6 +1166,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_mpeg_block_open;
this->demux_plugin.start = demux_mpeg_block_start;
+ this->demux_plugin.seek = demux_mpeg_block_seek;
this->demux_plugin.stop = demux_mpeg_block_stop;
this->demux_plugin.close = demux_mpeg_block_close;
this->demux_plugin.get_status = demux_mpeg_block_get_status;
@@ -1138,6 +1175,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_mimetypes = demux_mpeg_block_get_mimetypes;
this->scratch = xine_xmalloc_aligned (512, 4096, (void**) &this->scratch_base);
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
index 4a3052c0f..b76ffc48e 100644
--- a/src/demuxers/demux_mpgaudio.c
+++ b/src/demuxers/demux_mpgaudio.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_mpgaudio.c,v 1.37 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: demux_mpgaudio.c,v 1.38 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for mpeg audio (i.e. mp3) streams
*
@@ -57,6 +57,7 @@ typedef struct {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -208,13 +209,20 @@ static void *demux_mpgaudio_loop (void *this_gen) {
this->send_end_buffers = 1;
- do {
-
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
if (!demux_mpgaudio_next(this))
this->status = DEMUX_FINISHED;
-
- } while (this->status == DEMUX_OK) ;
-
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
+
this->status = DEMUX_FINISHED;
if (this->send_end_buffers) {
@@ -231,6 +239,7 @@ static void *demux_mpgaudio_loop (void *this_gen) {
}
}
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
return NULL;
@@ -242,20 +251,21 @@ static void demux_mpgaudio_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
printf ("demux_mpgaudio_block: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -308,21 +318,26 @@ static void demux_mpgaudio_start (demux_plugin_t *this_gen,
demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen;
buf_element_t *buf;
int err;
+
+ pthread_mutex_lock( &this->mutex );
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
- this->status = DEMUX_OK;
- this->stream_length = 0;
+ this->stream_length = 0;
+ }
if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
uint32_t head;
- head = demux_mpgaudio_read_head(this->input);
-
- if (mpg123_head_check(head))
- mpg123_decode_header(this,head);
+ if( this->status != DEMUX_OK ) {
+ head = demux_mpgaudio_read_head(this->input);
+ if (mpg123_head_check(head))
+ mpg123_decode_header(this,head);
+ }
+
if (!start_pos && start_time && this->stream_length > 0)
start_pos = start_time * this->input->get_length(this->input) /
this->stream_length;
@@ -331,26 +346,41 @@ static void demux_mpgaudio_start (demux_plugin_t *this_gen,
this->input->seek (this->input, start_pos, SEEK_SET);
}
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
-
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ if( this->status != DEMUX_OK ) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- /*
- * now start demuxing
- */
+ /*
+ * now start demuxing
+ */
- if ((err = pthread_create (&this->thread,
+ this->status = DEMUX_OK;
+ if ((err = pthread_create (&this->thread,
NULL, demux_mpgaudio_loop, this)) != 0) {
- printf ("demux_mpgaudio: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_mpgaudio: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
}
+ else {
+ xine_flush_engine(this->xine);
+ }
+ pthread_mutex_unlock( &this->mutex );
+}
+
+static void demux_mpgaudio_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen;
+
+ demux_mpgaudio_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static int demux_mpgaudio_open(demux_plugin_t *this_gen,
@@ -444,7 +474,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_mpgaudio_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_mpeg: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -464,6 +494,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUX_MPGAUDIO_IFACE_VERSION;
this->demux_plugin.open = demux_mpgaudio_open;
this->demux_plugin.start = demux_mpgaudio_start;
+ this->demux_plugin.seek = demux_mpgaudio_seek;
this->demux_plugin.stop = demux_mpgaudio_stop;
this->demux_plugin.close = demux_mpgaudio_close;
this->demux_plugin.get_status = demux_mpgaudio_get_status;
@@ -471,5 +502,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_mpgaudio_get_stream_length;
this->demux_plugin.get_mimetypes = demux_mpgaudio_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return &this->demux_plugin;
}
diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c
index c4c7328a5..c910626e5 100644
--- a/src/demuxers/demux_ogg.c
+++ b/src/demuxers/demux_ogg.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_ogg.c,v 1.19 2002/04/04 10:36:35 guenter Exp $
+ * $Id: demux_ogg.c,v 1.20 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for ogg streams
*
@@ -94,6 +94,7 @@ typedef struct demux_ogg_s {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -289,8 +290,17 @@ static void *demux_ogg_loop (void *this_gen) {
this->send_end_buffers = 1;
- while (this->status == DEMUX_OK) {
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
demux_ogg_send_package (this);
+
+ pthread_mutex_unlock( &this->mutex );
+
}
/*
@@ -315,6 +325,7 @@ static void *demux_ogg_loop (void *this_gen) {
}
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
return NULL;
@@ -333,20 +344,21 @@ static void demux_ogg_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
printf ("demux_ogg: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -376,38 +388,41 @@ static void demux_ogg_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err, i;
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
+ pthread_mutex_lock( &this->mutex );
- /*
- * send start buffer
- */
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ /*
+ * send start buffer
+ */
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- /*
- * initialize ogg engine
- */
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- ogg_sync_init(&this->oy);
+ /*
+ * initialize ogg engine
+ */
- this->num_streams = 0;
+ ogg_sync_init(&this->oy);
- this->input->seek (this->input, 0, SEEK_SET);
+ this->num_streams = 0;
- /* send header */
- this->pkg_count = 0;
- for (i=0; i<5; i++)
- demux_ogg_send_package (this);
+ this->input->seek (this->input, 0, SEEK_SET);
+ /* send header */
+ this->pkg_count = 0;
+ for (i=0; i<5; i++)
+ demux_ogg_send_package (this);
+ }
/*
* seek to start position
@@ -428,18 +443,34 @@ static void demux_ogg_start (demux_plugin_t *this_gen,
this->input->seek (this->input, start_pos, SEEK_SET);
}
- /*
- * now start demuxing
- */
+
+ if( this->status != DEMUX_OK ) {
+ /*
+ * now start demuxing
+ */
- this->status = DEMUX_OK;
+ this->status = DEMUX_OK;
- if ((err = pthread_create (&this->thread,
+ if ((err = pthread_create (&this->thread,
NULL, demux_ogg_loop, this)) != 0) {
- printf ("demux_ogg: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_ogg: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
}
+
+ pthread_mutex_unlock( &this->mutex );
+}
+
+static void demux_ogg_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_ogg_t *this = (demux_ogg_t *) this_gen;
+
+ demux_ogg_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static int demux_ogg_open(demux_plugin_t *this_gen,
@@ -537,7 +568,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_ogg_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf( _("demux_ogg: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n"),
@@ -557,6 +588,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_ogg_open;
this->demux_plugin.start = demux_ogg_start;
+ this->demux_plugin.seek = demux_ogg_seek;
this->demux_plugin.stop = demux_ogg_stop;
this->demux_plugin.close = demux_ogg_close;
this->demux_plugin.get_status = demux_ogg_get_status;
@@ -564,5 +596,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_ogg_get_stream_length;
this->demux_plugin.get_mimetypes = demux_ogg_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_pes.c b/src/demuxers/demux_pes.c
index cba5ee10a..73383a934 100644
--- a/src/demuxers/demux_pes.c
+++ b/src/demuxers/demux_pes.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_pes.c,v 1.22 2002/03/31 20:38:40 jcdutton Exp $
+ * $Id: demux_pes.c,v 1.23 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for mpeg 2 PES (Packetized Elementary Streams)
* reads streams of variable blocksizes
@@ -60,6 +60,7 @@ typedef struct demux_pes_s {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
unsigned char dummy_space[100000];
@@ -67,7 +68,9 @@ typedef struct demux_pes_s {
int preview_mode;
int send_end_buffers;
-
+
+ int64_t last_scr;
+ int send_newpts;
} demux_pes_t ;
static uint32_t read_bytes (demux_pes_t *this, int n) {
@@ -87,7 +90,6 @@ static uint32_t read_bytes (demux_pes_t *this, int n) {
}
-
switch (n) {
case 1:
res = buf[0];
@@ -109,6 +111,28 @@ static uint32_t read_bytes (demux_pes_t *this, int n) {
return res;
}
+static void check_newpts( demux_pes_t *this, int64_t pts )
+{
+ if( this->send_newpts && !this->preview_mode && pts ) {
+
+ buf_element_t *buf;
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ this->send_newpts = 0;
+ }
+}
+
+
static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
int nLen, i;
@@ -141,6 +165,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
pts |= (w & 0xFFFE) >> 1;
header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -165,9 +191,9 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
buf->type = BUF_AUDIO_A52 + track;
buf->pts = pts;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos (this->input);
@@ -195,6 +221,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
pts |= (w & 0xFFFE) >> 1;
header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -210,9 +238,10 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
buf->type = BUF_AUDIO_MPEG + track;
buf->pts = pts;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
+
buf->input_pos = this->input->get_current_pos(this->input);
if(this->audio_fifo)
@@ -238,6 +267,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
pts |= (w & 0xFFFE) >> 1;
header_len -= 5 ;
+
+ check_newpts( this, pts );
}
/* read rest of header */
@@ -255,9 +286,10 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
buf->type = BUF_VIDEO_MPEG;
buf->pts = pts;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
+
buf->input_pos = this->input->get_current_pos(this->input);
this->video_fifo->put (this->video_fifo, buf);
@@ -299,15 +331,23 @@ static void *demux_pes_loop (void *this_gen) {
demux_pes_t *this = (demux_pes_t *) this_gen;
buf_element_t *buf;
- uint32_t w;
+ uint32_t w=0;
- do {
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
w = parse_pack (this);
if (w != 0x000001)
demux_pes_resync (this, w);
- } while (this->status == DEMUX_OK) ;
+ pthread_mutex_unlock( &this->mutex );
+
+ }
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -326,6 +366,7 @@ static void *demux_pes_loop (void *this_gen) {
printf ("demux_pes: demux loop finished (status: %d, buf:%x)\n",
this->status, w);
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
return NULL;
@@ -337,26 +378,21 @@ static void demux_pes_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
- printf ("demux_pes: stop...\n");
-
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
-
- this->video_fifo->clear(this->video_fifo);
- if(this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
-
+ printf ("demux_pes: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if(this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -386,57 +422,88 @@ static void demux_pes_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err;
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
+ pthread_mutex_lock( &this->mutex );
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ /*
+ * send start buffer
+ */
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
- if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- uint32_t w;
- int num_buffers = NUM_PREVIEW_BUFFERS;
+ if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
- this->preview_mode = 1;
+ uint32_t w;
+ int num_buffers = NUM_PREVIEW_BUFFERS;
- this->input->seek (this->input, 3, SEEK_SET);
+ this->preview_mode = 1;
- this->status = DEMUX_OK ;
+ this->input->seek (this->input, 3, SEEK_SET);
- do {
- w = parse_pack (this);
+ this->status = DEMUX_OK ;
+
+ do {
+ w = parse_pack (this);
- if (w != 0x000001)
- demux_pes_resync (this, w);
+ if (w != 0x000001)
+ demux_pes_resync (this, w);
- num_buffers --;
-
- } while ( (this->status == DEMUX_OK) && (num_buffers>0)) ;
+ num_buffers --;
+ } while ( (this->status == DEMUX_OK) && (num_buffers>0)) ;
+ this->status = DEMUX_FINISHED;
+ }
+ }
+
+ if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
+
+ /* FIXME: implement time seek */
this->input->seek (this->input, start_pos+3, SEEK_SET);
- /* FIXME: implement time seek */
+ if( start_pos )
+ demux_pes_resync (this, read_bytes(this, 3) );
} else
read_bytes(this, 3);
- this->preview_mode = 0;
- this->send_end_buffers = 1;
- this->status = DEMUX_OK ;
+ this->send_newpts = 1;
+
+ if( this->status != DEMUX_OK ) {
+ this->preview_mode = 0;
+ this->send_end_buffers = 1;
+ this->status = DEMUX_OK ;
- if ((err = pthread_create (&this->thread,
+ if ((err = pthread_create (&this->thread,
NULL, demux_pes_loop, this)) != 0) {
- printf ("demux_pes: can't create new thread (%s)\n",
- strerror(err));
- exit (1);
+ printf ("demux_pes: can't create new thread (%s)\n",
+ strerror(err));
+ exit (1);
+ }
+ }
+ else {
+ xine_flush_engine(this->xine);
}
+ pthread_mutex_unlock( &this->mutex );
+
+}
+
+static void demux_pes_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_pes_t *this = (demux_pes_t *) this_gen;
+
+ demux_pes_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static int demux_pes_open(demux_plugin_t *this_gen,
@@ -562,7 +629,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_pes_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_pes: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -585,6 +652,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_pes_open;
this->demux_plugin.start = demux_pes_start;
+ this->demux_plugin.seek = demux_pes_seek;
this->demux_plugin.stop = demux_pes_stop;
this->demux_plugin.close = demux_pes_close;
this->demux_plugin.get_status = demux_pes_get_status;
@@ -592,5 +660,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_pes_get_stream_length;
this->demux_plugin.get_mimetypes = demux_pes_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index 7ee9d5cd5..e247a9ecd 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.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_qt.c,v 1.24 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: demux_qt.c,v 1.25 2002/04/09 03:38:00 miguelfreitas Exp $
*
* demultiplexer for mpeg-4 system (aka quicktime) streams, based on:
*
@@ -54,12 +54,13 @@
#include "libw32dll/wine/vfw.h"
#include "libw32dll/wine/mmreg.h"
-
+/*
#define LOG
+*/
-
+/*
#define DBG_QT
-
+*/
#define VALID_ENDS "mov,mp4"
@@ -549,6 +550,7 @@ typedef struct demux_qt_s {
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
int send_end_buffers;
@@ -570,8 +572,32 @@ typedef struct demux_qt_s {
uint8_t scratch[64*1024];
+ int send_newpts;
} demux_qt_t ;
+
+static void check_newpts( demux_qt_t *this, int64_t pts )
+{
+ if( this->send_newpts && pts ) {
+
+ buf_element_t *buf;
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ this->send_newpts = 0;
+ }
+}
+
+
/*
* openquicktime stuff
*/
@@ -3747,9 +3773,13 @@ static void *demux_qt_loop (void *this_gen) {
idx = 0;
- do {
-
+ while(1) {
int is_audio, sample_num;
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
if (idx >= this->num_index_entries)
break;
@@ -3764,6 +3794,8 @@ static void *demux_qt_loop (void *this_gen) {
offset = this->index[idx].offset;
pts = this->index[idx].pts;
+ check_newpts( this, pts );
+
for (sample_num = this->index[idx].first_sample; sample_num <= this->index[idx].last_sample; sample_num++) {
todo = demux_qt_get_sample_size (this->index[idx].track, sample_num);
@@ -3816,8 +3848,10 @@ static void *demux_qt_loop (void *this_gen) {
}
idx++;
+
+ pthread_mutex_unlock( &this->mutex );
- } while (this->status == DEMUX_OK) ;
+ }
printf ("demux_qt: demux loop finished (status: %d)\n",
this->status);
@@ -3838,6 +3872,8 @@ static void *demux_qt_loop (void *this_gen) {
}
}
+
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
@@ -3861,20 +3897,21 @@ static void demux_qt_stop (demux_plugin_t *this_gen) {
buf_element_t *buf;
void *p;
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
printf ("demux_qt: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->video_fifo->clear(this->video_fifo);
- if (this->audio_fifo)
- this->audio_fifo->clear(this->audio_fifo);
+ xine_flush_engine(this->xine);
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -4038,8 +4075,9 @@ static void demux_qt_index_trak (demux_qt_t *this, quicktime_trak_t *trak, uint3
stts_pts = 0;
while (stsc_cur < stco->total_entries) {
-
+#ifdef LOG
printf ("demux_qt: chunk # is %d...\n", stsc_cur);
+#endif
chunk_offset = stco->table[stsc_cur-1].offset;
@@ -4082,8 +4120,9 @@ static void demux_qt_index_trak (demux_qt_t *this, quicktime_trak_t *trak, uint3
stsc_first_sample = stsc_last_sample + 1;
stsc_last_sample = stsc_first_sample + stsc_samples - 1;
+#ifdef LOG
printf ("demux_qt: chunk offset is %lld...\n", chunk_offset);
-
+#endif
/*
* find out about pts of sample
@@ -4144,26 +4183,29 @@ static void demux_qt_start (demux_plugin_t *this_gen,
buf_element_t *buf;
int err;
- this->video_fifo = video_fifo;
- this->audio_fifo = audio_fifo;
- this->send_end_buffers = 1;
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
#ifdef DBG_QT
- debug_fh = open ("/tmp/t.mp3", O_CREAT | O_WRONLY | O_TRUNC, 0644);
+ debug_fh = open ("/tmp/t.mp3", O_CREAT | O_WRONLY | O_TRUNC, 0644);
#endif
- /*
- * init quicktime parser
- */
+ /*
+ * init quicktime parser
+ */
- this->qt = quicktime_open (this->input, this->xine);
+ this->qt = quicktime_open (this->input, this->xine);
- if (!this->qt) {
- this->status = DEMUX_FINISHED;
- return;
- }
-
- xine_log (this->xine, XINE_LOG_FORMAT,
+ if (!this->qt) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock( &this->mutex );
+ return;
+ }
+
+ xine_log (this->xine, XINE_LOG_FORMAT,
_("demux_qt: video codec %s (%f fps), audio codec %s (%ld Hz, %d bits)\n"),
quicktime_video_compressor (this->qt,0),
quicktime_frame_rate (this->qt,0),
@@ -4171,35 +4213,36 @@ static void demux_qt_start (demux_plugin_t *this_gen,
quicktime_sample_rate (this->qt,0),
quicktime_audio_bits (this->qt,0));
- if (!demux_qt_detect_compressors (this)) {
- this->status = DEMUX_FINISHED;
- return;
- }
-
- /*
- * generate index
- */
+ if (!demux_qt_detect_compressors (this)) {
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_unlock( &this->mutex );
+ return;
+ }
- demux_qt_create_index (this);
+ /*
+ * generate index
+ */
- /*
- * send start buffer
- */
+ demux_qt_create_index (this);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
- this->video_fifo->put (this->video_fifo, buf);
+ /*
+ * send start buffer
+ */
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+ this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+
/*
* seek to start pos/time
*/
-
if (start_pos) {
double f = (double) start_pos / (double) this->input->get_length (this->input) ;
@@ -4212,52 +4255,68 @@ static void demux_qt_start (demux_plugin_t *this_gen,
quicktime_video_length (this->qt, 0) * f, 0);
}
+ this->send_newpts = 1;
+
+ if( this->status != DEMUX_OK ) {
+ /*
+ * send init info to decoders
+ */
- /*
- * send init info to decoders
- */
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->content = buf->mem;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[0] = 0; /* first package, containing bih */
+ buf->decoder_info[1] = this->video_step;
+ memcpy (buf->content, &this->bih, sizeof (this->bih));
+ buf->size = sizeof (this->bih);
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->content = buf->mem;
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[0] = 0; /* first package, containing bih */
- buf->decoder_info[1] = this->video_step;
- memcpy (buf->content, &this->bih, sizeof (this->bih));
- buf->size = sizeof (this->bih);
+ buf->type = this->video_type;
- buf->type = this->video_type;
+ this->video_fifo->put (this->video_fifo, buf);
- this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->content = buf->mem;
+ memcpy (buf->content, &this->wavex,
+ sizeof (this->wavex));
+ buf->size = sizeof (this->wavex);
+ buf->type = this->audio_type;
+ buf->decoder_flags = BUF_FLAG_HEADER;
+ buf->decoder_info[0] = 0; /* first package, containing wavex */
+ buf->decoder_info[1] = quicktime_sample_rate (this->qt, 0);
+ buf->decoder_info[2] = quicktime_audio_bits (this->qt, 0);
+ buf->decoder_info[3] = quicktime_track_channels (this->qt, 0);
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
- printf ("demux_qt: sent buffer %08x\n", buf);
+ /*
+ * now start demuxing
+ */
- if(this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->content = buf->mem;
- memcpy (buf->content, &this->wavex,
- sizeof (this->wavex));
- buf->size = sizeof (this->wavex);
- buf->type = this->audio_type;
- buf->decoder_flags = BUF_FLAG_HEADER;
- buf->decoder_info[0] = 0; /* first package, containing wavex */
- buf->decoder_info[1] = quicktime_sample_rate (this->qt, 0);
- buf->decoder_info[2] = quicktime_audio_bits (this->qt, 0);
- buf->decoder_info[3] = quicktime_track_channels (this->qt, 0);
- this->audio_fifo->put (this->audio_fifo, buf);
+ this->status = DEMUX_OK ;
+ this->send_end_buffers = 1;
+
+ if ((err = pthread_create (&this->thread, NULL, demux_qt_loop, this)) != 0) {
+ printf ("demux_qt: can't create new thread (%s)\n", strerror(err));
+ exit (1);
+ }
}
+ else {
+ xine_flush_engine(this->xine);
+ }
+ pthread_mutex_unlock( &this->mutex );
- /*
- * now start demuxing
- */
+}
- this->status = DEMUX_OK ;
+static void demux_qt_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_qt_t *this = (demux_qt_t *) this_gen;
- if ((err = pthread_create (&this->thread, NULL, demux_qt_loop, this)) != 0) {
- printf ("demux_qt: can't create new thread (%s)\n", strerror(err));
- exit (1);
- }
+ demux_qt_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
+
static int demux_qt_open(demux_plugin_t *this_gen,
input_plugin_t *input, int stage) {
@@ -4340,7 +4399,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_qt_t *this;
- if (iface != 6) {
+ if (iface != 7) {
printf ("demux_qt: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
" demuxer plugin.\nInstalling current demux plugins should help.\n",
@@ -4360,6 +4419,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_qt_open;
this->demux_plugin.start = demux_qt_start;
+ this->demux_plugin.seek = demux_qt_seek;
this->demux_plugin.stop = demux_qt_stop;
this->demux_plugin.close = demux_qt_close;
this->demux_plugin.get_status = demux_qt_get_status;
@@ -4367,5 +4427,8 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_stream_length = demux_qt_get_stream_length;
this->demux_plugin.get_mimetypes = demux_qt_get_mimetypes;
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
+
return (demux_plugin_t *) this;
}
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index eb0e3dcb0..9352c0724 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.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_ts.c,v 1.40 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: demux_ts.c,v 1.41 2002/04/09 03:38:00 miguelfreitas Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -154,12 +154,13 @@ typedef struct {
config_values_t *config;
- fifo_buffer_t *fifoAudio;
- fifo_buffer_t *fifoVideo;
+ fifo_buffer_t *audio_fifo;
+ fifo_buffer_t *video_fifo;
input_plugin_t *input;
pthread_t thread;
+ pthread_mutex_t mutex;
int status;
@@ -178,12 +179,17 @@ typedef struct {
*/
unsigned int programNumber;
unsigned int pcrPid;
- uint32_t PCR;
+ int64_t PCR;
+ int64_t last_PCR;
unsigned int pid;
unsigned int videoPid;
unsigned int audioPid;
unsigned int videoMedia;
unsigned int audioMedia;
+
+ int send_end_buffers;
+ int ignore_scr_discont;
+ int send_newpts;
} demux_ts;
static void demux_ts_build_crc32_table(demux_ts *this) {
@@ -208,6 +214,28 @@ static uint32_t demux_ts_compute_crc32(demux_ts *this, uint8_t *data, uint32_t l
return crc32;
}
+static void check_newpts( demux_ts *this, int64_t pts )
+{
+ if( this->send_newpts && pts ) {
+
+ buf_element_t *buf;
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = pts;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ this->send_newpts = 0;
+ this->ignore_scr_discont = 1;
+ }
+}
+
/*
* demux_ts_parse_pat
@@ -538,6 +566,8 @@ static void demux_ts_buffer_pes(demux_ts *this, unsigned char *ts,
m->broken_pes = 1;
LOG_MSG (this->xine, _("demux_ts: broken pes encountered\n"));
} else {
+ check_newpts( this, m->PTS );
+
m->broken_pes = 0;
buf = m->fifo->buffer_pool_alloc(m->fifo);
memcpy (buf->mem, ts+len-m->size, m->size); /* FIXME: reconstruct parser to do without memcpys */
@@ -790,7 +820,7 @@ static void demux_ts_parse_pmt (demux_ts *this,
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT video pid %.4x\n", pid);
#endif
- demux_ts_pes_new(this, mediaIndex, pid, this->fifoVideo);
+ demux_ts_pes_new(this, mediaIndex, pid, this->video_fifo);
}
this->videoPid = pid;
this->videoMedia = mediaIndex;
@@ -801,7 +831,7 @@ static void demux_ts_parse_pmt (demux_ts *this,
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT audio pid %.4x\n", pid);
#endif
- demux_ts_pes_new(this, mediaIndex, pid, this->fifoAudio);
+ demux_ts_pes_new(this, mediaIndex, pid, this->audio_fifo);
this->audioPid = pid;
this->audioMedia = mediaIndex;
}
@@ -821,7 +851,7 @@ static void demux_ts_parse_pmt (demux_ts *this,
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT AC3 audio pid %.4x\n", pid);
#endif
- demux_ts_pes_new(this, mediaIndex, pid, this->fifoAudio);
+ demux_ts_pes_new(this, mediaIndex, pid, this->audio_fifo);
this->audioPid = pid;
this->audioMedia = mediaIndex;
break;
@@ -840,7 +870,7 @@ static void demux_ts_parse_pmt (demux_ts *this,
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT AC3 audio pid %.4x\n", pid);
#endif
- demux_ts_pes_new(this, mediaIndex, pid, this->fifoAudio);
+ demux_ts_pes_new(this, mediaIndex, pid, this->audio_fifo);
this->audioPid = pid;
this->audioMedia = mediaIndex;
}
@@ -1060,6 +1090,29 @@ static void demux_ts_parse_packet (demux_ts *this) {
if (adaptation_field_length > 0) {
this->PCR = demux_ts_adaptation_field_parse (originalPkt+5,
adaptation_field_length);
+ if (this->PCR) {
+ int64_t scr_diff = this->PCR - this->last_PCR;
+
+ if ((abs(scr_diff) > 90000) && !this->send_newpts &&
+ !this->ignore_scr_discont ) {
+
+ buf_element_t *buf;
+
+ buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->disc_off = scr_diff;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->disc_off = scr_diff;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+ this->last_PCR = this->PCR;
+ this->ignore_scr_discont = 0;
+ }
}
/*
* Skip adaptation header.
@@ -1137,26 +1190,39 @@ static void *demux_ts_loop(void *gen_this) {
demux_ts *this = (demux_ts *)gen_this;
buf_element_t *buf;
- do {
+ while(1) {
+
+ pthread_mutex_lock( &this->mutex );
+
+ if( this->status != DEMUX_OK)
+ break;
+
demux_ts_parse_packet(this);
- } while (this->status == DEMUX_OK) ;
-
+
+ pthread_mutex_unlock( &this->mutex );
+
+ }
+
#ifdef TS_LOG
printf ("demux_ts: demux loop finished (status: %d)\n", this->status);
#endif
-
+
this->status = DEMUX_FINISHED;
- buf = this->fifoVideo->buffer_pool_alloc(this->fifoVideo);
- buf->type = BUF_CONTROL_END;
- buf->decoder_flags = BUF_FLAG_END_STREAM; /* stream finished */
- this->fifoVideo->put(this->fifoVideo, buf);
-
- if (this->fifoAudio) {
- buf = this->fifoAudio->buffer_pool_alloc(this->fifoAudio);
+ if (this->send_end_buffers) {
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = BUF_FLAG_END_STREAM; /* stream finished */
- this->fifoAudio->put(this->fifoAudio, buf);
+ this->video_fifo->put (this->video_fifo, buf);
+
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_END;
+ buf->decoder_flags = BUF_FLAG_END_STREAM; /* stream finished */
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
}
+
+ pthread_mutex_unlock( &this->mutex );
pthread_exit(NULL);
return NULL;
}
@@ -1283,32 +1349,35 @@ static int demux_ts_open(demux_plugin_t *this_gen, input_plugin_t *input,
}
static void demux_ts_start(demux_plugin_t *this_gen,
- fifo_buffer_t *fifoVideo,
- fifo_buffer_t *fifoAudio,
+ fifo_buffer_t *video_fifo,
+ fifo_buffer_t *audio_fifo,
off_t start_pos, int start_time) {
demux_ts *this = (demux_ts *)this_gen;
buf_element_t *buf;
int err;
- this->fifoVideo = fifoVideo;
- this->fifoAudio = fifoAudio;
+ pthread_mutex_lock( &this->mutex );
- /*
- * send start buffers
- */
- buf = this->fifoVideo->buffer_pool_alloc(this->fifoVideo);
- buf->type = BUF_CONTROL_START;
- this->fifoVideo->put(this->fifoVideo, buf);
- if (this->fifoAudio) {
- buf = this->fifoAudio->buffer_pool_alloc(this->fifoAudio);
- buf->type = BUF_CONTROL_START;
- this->fifoAudio->put(this->fifoAudio, buf);
- }
+ if( this->status != DEMUX_OK ) {
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
- this->status = DEMUX_OK ;
+ /*
+ * send start buffer
+ */
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->video_fifo->put (this->video_fifo, buf);
+ if(this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+ }
+
if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
if ( (!start_pos) && (start_time))
@@ -1317,15 +1386,36 @@ static void demux_ts_start(demux_plugin_t *this_gen,
this->input->seek (this->input, start_pos, SEEK_SET);
}
+ this->send_newpts = 1;
+ this->ignore_scr_discont = 0;
+
demux_ts_build_crc32_table(this);
-
- /*
- * Now start demuxing.
- */
- if ((err = pthread_create(&this->thread, NULL, demux_ts_loop, this)) != 0) {
- LOG_MSG_STDERR(this->xine, _("demux_ts: can't create new thread (%s)\n"), strerror(err));
- exit (1);
+
+ if( this->status != DEMUX_OK ) {
+ /*
+ * Now start demuxing.
+ */
+ this->status = DEMUX_OK ;
+ this->send_end_buffers = 1;
+ this->last_PCR = 0;
+
+ if ((err = pthread_create(&this->thread, NULL, demux_ts_loop, this)) != 0) {
+ LOG_MSG_STDERR(this->xine, _("demux_ts: can't create new thread (%s)\n"), strerror(err));
+ exit (1);
+ }
}
+ else {
+ xine_flush_engine(this->xine);
+ }
+ pthread_mutex_unlock( &this->mutex );
+}
+
+static void demux_ts_seek (demux_plugin_t *this_gen,
+ off_t start_pos, int start_time) {
+ demux_ts *this = (demux_ts *)this_gen;
+
+ demux_ts_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
static void demux_ts_stop(demux_plugin_t *this_gen)
@@ -1334,35 +1424,32 @@ static void demux_ts_stop(demux_plugin_t *this_gen)
buf_element_t *buf;
void *p;
- LOG_MSG(this->xine, _("demux_ts: stop...\n"));
-
+ pthread_mutex_lock( &this->mutex );
+
if (this->status != DEMUX_OK) {
-
- this->fifoVideo->clear(this->fifoVideo);
- if(this->fifoAudio)
- this->fifoAudio->clear(this->fifoAudio);
+ printf ("demux_ts: stop...ignored\n");
+ pthread_mutex_unlock( &this->mutex );
return;
}
+ this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
- pthread_cancel (this->thread);
+
+ pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
- this->fifoVideo->clear(this->fifoVideo);
- if(this->fifoAudio)
- this->fifoAudio->clear(this->fifoAudio);
+ xine_flush_engine(this->xine);
- buf = this->fifoVideo->buffer_pool_alloc (this->fifoVideo);
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = BUF_FLAG_END_USER; /* user finished */
- this->fifoVideo->put (this->fifoVideo, buf);
+ this->video_fifo->put (this->video_fifo, buf);
- if (this->fifoAudio) {
- buf = this->fifoAudio->buffer_pool_alloc (this->fifoAudio);
+ if (this->audio_fifo) {
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->type = BUF_CONTROL_END;
buf->decoder_flags = BUF_FLAG_END_USER; /* user finished */
- this->fifoAudio->put (this->fifoAudio, buf);
+ this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -1379,7 +1466,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
demux_ts *this;
int i;
- if (iface != 6) {
+ if (iface != 7) {
LOG_MSG (xine,
_("demux_ts: plugin doesn't support plugin API version %d.\n"
" this means there's a version mismatch between xine and this "
@@ -1406,6 +1493,7 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->plugin.open = demux_ts_open;
this->plugin.start = demux_ts_start;
+ this->plugin.seek = demux_ts_seek;
this->plugin.stop = demux_ts_stop;
this->plugin.close = demux_ts_close;
this->plugin.get_status = demux_ts_get_status;
@@ -1433,6 +1521,9 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->audioPid = INVALID_PID;
this->rate = 16000; /* FIXME */
+
+ this->status = DEMUX_FINISHED;
+ pthread_mutex_init( &this->mutex, NULL );
return (demux_plugin_t *)this;
}