summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--src/liba52/xine_decoder.c12
-rw-r--r--src/libdivx4/xine_decoder.c10
-rw-r--r--src/libdts/xine_decoder.c4
-rw-r--r--src/libffmpeg/xine_decoder.c9
-rw-r--r--src/liblpcm/xine_decoder.c4
-rw-r--r--src/libmad/xine_decoder.c4
-rw-r--r--src/libmpeg2/decode.c39
-rw-r--r--src/libmpeg2/mpeg2.h1
-rw-r--r--src/libmpeg2/slice.c2
-rw-r--r--src/libmpeg2/xine_decoder.c16
-rw-r--r--src/libvorbis/xine_decoder.c4
-rw-r--r--src/libw32dll/w32codec.c29
-rw-r--r--src/xine-engine/audio_decoder.c18
-rw-r--r--src/xine-engine/buffer.h4
-rw-r--r--src/xine-engine/metronom.c10
-rw-r--r--src/xine-engine/osd.c16
-rw-r--r--src/xine-engine/video_decoder.c15
-rw-r--r--src/xine-engine/video_out.c13
-rw-r--r--src/xine-engine/xine.c134
-rw-r--r--src/xine-engine/xine_internal.h7
32 files changed, 1456 insertions, 758 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;
}
diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c
index dfcf5b850..484001a15 100644
--- a/src/liba52/xine_decoder.c
+++ b/src/liba52/xine_decoder.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: xine_decoder.c,v 1.21 2002/04/06 02:49:47 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.22 2002/04/09 03:38:00 miguelfreitas Exp $
*
* stuff needed to turn liba52 into a xine decoder plugin
*/
@@ -441,16 +441,8 @@ void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_flags & BUF_FLAG_PREVIEW)
return;
- /*
- printf ("liba52: got buffer, pts =%d, pts - last_pts=%d\n",
- buf->PTS, buf->PTS - this->last_pts);
-
- this->last_pts = buf->PTS;
- */
-
if (buf->pts)
this->pts = buf->pts;
-
while (current != end) {
@@ -549,7 +541,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
a52dec_decoder_t *this ;
config_values_t *cfg;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "liba52: plugin doesn't support plugin API version %d.\n"
"liba52: this means there's a version mismatch between xine and this "
"liba52: decoder plugin.\nInstalling current plugins should help.\n",
diff --git a/src/libdivx4/xine_decoder.c b/src/libdivx4/xine_decoder.c
index 1aff0ee38..225865a3d 100644
--- a/src/libdivx4/xine_decoder.c
+++ b/src/libdivx4/xine_decoder.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: xine_decoder.c,v 1.25 2002/04/07 09:37:11 guenter Exp $
+ * $Id: xine_decoder.c,v 1.26 2002/04/09 03:38:00 miguelfreitas Exp $
*
* xine decoder plugin using divx4
*
@@ -522,6 +522,11 @@ static char *divx4_get_id(void) {
static void divx4_flush(video_decoder_t *this_gen) {
}
+static void divx4_reset(video_decoder_t *this_gen) {
+ /* seems to handle seeking quite nicelly without any code here */
+}
+
+
/* This is pretty generic. I took the liberty to increase the
priority over that of libffmpeg :-) */
video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
@@ -532,7 +537,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
decoreFunc libdecore_func = 0;
config_values_t *cfg;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "divx4: plugin doesn't support plugin API version %d.\n"
"divx4: this means there's a version mismatch between xine and this "
"divx4: decoder plugin.\nInstalling current plugins should help.\n",
@@ -566,6 +571,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
this->video_decoder.close = divx4_close;
this->video_decoder.get_identifier = divx4_get_id;
this->video_decoder.flush = divx4_flush;
+ this->video_decoder.reset = divx4_reset;
this->video_decoder.priority = cfg->register_num (cfg, "codec.divx4_priority", 4,
"priority of the divx4 plugin (>5 => enable)",
NULL, NULL, NULL);
diff --git a/src/libdts/xine_decoder.c b/src/libdts/xine_decoder.c
index 215c32092..3b67d889a 100644
--- a/src/libdts/xine_decoder.c
+++ b/src/libdts/xine_decoder.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: xine_decoder.c,v 1.16 2002/04/01 17:59:41 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.17 2002/04/09 03:38:00 miguelfreitas Exp $
*
* 04-09-2001 DTS passtrough (C) Joachim Koenig
* 09-12-2001 DTS passthrough inprovements (C) James Courtier-Dutton
@@ -220,7 +220,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
dts_decoder_t *this ;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "libdts: plugin doesn't support plugin API version %d.\n"
"libdts: this means there's a version mismatch between xine and this "
"libdts: decoder plugin.\nInstalling current plugins should help.\n",
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
index f65dfe443..f4831f4ac 100644
--- a/src/libffmpeg/xine_decoder.c
+++ b/src/libffmpeg/xine_decoder.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: xine_decoder.c,v 1.29 2002/04/01 17:59:47 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.30 2002/04/09 03:38:00 miguelfreitas Exp $
*
* xine decoder plugin using ffmpeg
*
@@ -360,6 +360,10 @@ static void ff_flush (video_decoder_t *this_gen) {
}
+static void ff_reset (video_decoder_t *this_gen) {
+ /* seems to handle seeking quite nicelly without any code here */
+}
+
static void ff_close (video_decoder_t *this_gen) {
ff_decoder_t *this = (ff_decoder_t *) this_gen;
@@ -391,7 +395,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
ff_decoder_t *this ;
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "ffmpeg: plugin doesn't support plugin API version %d.\n"
"ffmpeg: this means there's a version mismatch between xine and this "
"ffmpeg: decoder plugin.\nInstalling current plugins should help.\n",
@@ -407,6 +411,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
this->video_decoder.init = ff_init;
this->video_decoder.decode_data = ff_decode_data;
this->video_decoder.flush = ff_flush;
+ this->video_decoder.reset = ff_reset;
this->video_decoder.close = ff_close;
this->video_decoder.get_identifier = ff_get_id;
this->video_decoder.priority = 5;
diff --git a/src/liblpcm/xine_decoder.c b/src/liblpcm/xine_decoder.c
index 07c3f8edd..408c12490 100644
--- a/src/liblpcm/xine_decoder.c
+++ b/src/liblpcm/xine_decoder.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: xine_decoder.c,v 1.20 2002/03/11 12:31:25 guenter Exp $
+ * $Id: xine_decoder.c,v 1.21 2002/04/09 03:38:00 miguelfreitas Exp $
*
* 31-8-2001 Added LPCM rate sensing.
* (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk
@@ -153,7 +153,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
lpcm_decoder_t *this ;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "liblpcm: plugin doesn't support plugin API version %d.\n"
"liblpcm: this means there's a version mismatch between xine and this "
"liblpcm: decoder plugin.\nInstalling current plugins should help.\n",
diff --git a/src/libmad/xine_decoder.c b/src/libmad/xine_decoder.c
index f159481a2..4ec9aa907 100644
--- a/src/libmad/xine_decoder.c
+++ b/src/libmad/xine_decoder.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: xine_decoder.c,v 1.16 2002/04/07 12:11:48 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.17 2002/04/09 03:38:00 miguelfreitas Exp $
*
* stuff needed to turn libmad into a xine decoder plugin
*/
@@ -275,7 +275,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
mad_decoder_t *this ;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "libmad: plugin doesn't support plugin API version %d.\n"
"libmad: this means there's a version mismatch between xine and this "
"libmad: decoder plugin.\nInstalling current plugins should help.\n",
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 86d9cc0f4..f5bff3815 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -181,8 +181,8 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if (((picture->picture_structure == FRAME_PICTURE) ||
(picture->second_field)) ) {
- if (!mpeg2dec->drop_frame)
- picture->current_frame->bad_frame = 0;
+ if (mpeg2dec->drop_frame)
+ picture->current_frame->bad_frame = 1;
if (picture->picture_coding_type == B_TYPE) {
if( picture->current_frame && !picture->current_frame->drawn ) {
@@ -481,6 +481,41 @@ int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end,
return ret;
}
+void mpeg2_reset (mpeg2dec_t * mpeg2dec) {
+
+ picture_t *picture = mpeg2dec->picture;
+
+ if( !picture )
+ return;
+
+ mpeg2dec->pts = 0;
+
+ if( !picture->mpeg1 )
+ mpeg2dec->is_sequence_needed = 1;
+
+ mpeg2dec->in_slice = 0;
+
+ /* to free reference frames one also needs to fix slice.c to
+ * abort when they are NULL. unfortunately it seems to break
+ * DVD menus.
+ */
+ /*
+ if ( picture->current_frame &&
+ picture->current_frame != picture->backward_reference_frame &&
+ picture->current_frame != picture->forward_reference_frame )
+ picture->current_frame->free (picture->current_frame);
+ picture->current_frame = NULL;
+
+ if (picture->forward_reference_frame)
+ picture->forward_reference_frame->free (picture->forward_reference_frame);
+ picture->forward_reference_frame = NULL;
+
+ if (picture->backward_reference_frame)
+ picture->backward_reference_frame->free (picture->backward_reference_frame);
+ picture->backward_reference_frame = NULL;
+ */
+}
+
void mpeg2_flush (mpeg2dec_t * mpeg2dec) {
picture_t *picture = mpeg2dec->picture;
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index 77a96965f..a3994930e 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -64,6 +64,7 @@ void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec,
uint8_t * data_start, uint8_t * data_end);
void mpeg2_flush (mpeg2dec_t * mpeg2dec);
+void mpeg2_reset (mpeg2dec_t * mpeg2dec);
/* Not needed, it is defined as static in decode.c, and no-one else called it
* currently
diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c
index 555b10782..07f92ea10 100644
--- a/src/libmpeg2/slice.c
+++ b/src/libmpeg2/slice.c
@@ -1452,6 +1452,7 @@ static inline int slice_init (picture_t * picture, int code)
forward_reference_frame = picture->forward_reference_frame;
}
else {
+ /* return 1; */
forward_reference_frame = picture->current_frame;
}
@@ -1459,6 +1460,7 @@ static inline int slice_init (picture_t * picture, int code)
backward_reference_frame = picture->backward_reference_frame;
}
else {
+ /* return 1; */
backward_reference_frame = picture->current_frame;
}
diff --git a/src/libmpeg2/xine_decoder.c b/src/libmpeg2/xine_decoder.c
index 56af6324b..3543ce6e2 100644
--- a/src/libmpeg2/xine_decoder.c
+++ b/src/libmpeg2/xine_decoder.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: xine_decoder.c,v 1.26 2002/04/04 00:08:36 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.27 2002/04/09 03:38:00 miguelfreitas Exp $
*
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
@@ -109,6 +109,17 @@ static void mpeg2dec_flush (video_decoder_t *this_gen) {
pthread_mutex_unlock (&this->lock);
}
+static void mpeg2dec_reset (video_decoder_t *this_gen) {
+ mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen;
+
+ pthread_mutex_lock (&this->lock);
+
+ mpeg2_reset (&this->mpeg2);
+
+ pthread_mutex_unlock (&this->lock);
+}
+
+
static void mpeg2dec_close (video_decoder_t *this_gen) {
mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen;
@@ -134,7 +145,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
mpeg2dec_decoder_t *this ;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "libmpeg2: plugin doesn't support plugin API version %d.\n"
"libmpeg2: this means there's a version mismatch between xine and this "
"libmpeg2: decoder plugin.\nInstalling current plugins should help.\n",
@@ -150,6 +161,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
this->video_decoder.init = mpeg2dec_init;
this->video_decoder.decode_data = mpeg2dec_decode_data;
this->video_decoder.flush = mpeg2dec_flush;
+ this->video_decoder.reset = mpeg2dec_reset;
this->video_decoder.close = mpeg2dec_close;
this->video_decoder.get_identifier = mpeg2dec_get_id;
this->video_decoder.priority = 5;
diff --git a/src/libvorbis/xine_decoder.c b/src/libvorbis/xine_decoder.c
index 26df1f494..37e618bd7 100644
--- a/src/libvorbis/xine_decoder.c
+++ b/src/libvorbis/xine_decoder.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: xine_decoder.c,v 1.7 2002/04/01 18:00:13 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.8 2002/04/09 03:38:01 miguelfreitas Exp $
*
* (ogg/)vorbis audio decoder plugin (libvorbis wrapper) for xine
*/
@@ -239,7 +239,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
vorbis_decoder_t *this ;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "libvorbis: plugin doesn't support plugin API version %d.\n"
"libvorbis: this means there's a version mismatch between xine and this "
"libvorbis: decoder plugin.\nInstalling current plugins should help.\n",
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index d675aeb0d..d92398a40 100644
--- a/src/libw32dll/w32codec.c
+++ b/src/libw32dll/w32codec.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: w32codec.c,v 1.69 2002/04/01 18:01:17 miguelfreitas Exp $
+ * $Id: w32codec.c,v 1.70 2002/04/09 03:38:01 miguelfreitas Exp $
*
* routines for using w32 codecs
* DirectShow support by Miguel Freitas (Nov/2001)
@@ -818,6 +818,26 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
static void w32v_flush (video_decoder_t *this_gen) {
}
+static void w32v_reset (video_decoder_t *this_gen) {
+
+ w32v_decoder_t *this = (w32v_decoder_t *) this_gen;
+
+ /* FIXME: need to improve this function. currently it
+ doesn't avoid artifacts when seeking. */
+
+ pthread_mutex_lock(&win32_codec_mutex);
+ if ( !this->ds_driver ) {
+ if (!this->ex_functions)
+ ICDecompressBegin(this->hic, &this->bih, &this->o_bih);
+ else
+ ICDecompressBeginEx(this->hic, &this->bih, &this->o_bih);
+ } else {
+ }
+ this->size = 0;
+ pthread_mutex_unlock(&win32_codec_mutex);
+}
+
+
static void w32v_close (video_decoder_t *this_gen) {
w32v_decoder_t *this = (w32v_decoder_t *) this_gen;
@@ -828,6 +848,8 @@ static void w32v_close (video_decoder_t *this_gen) {
#endif
{
if ( !this->ds_driver ) {
+ ICDecompressEnd(this->hic);
+ ICClose(this->hic);
} else {
if( this->ds_dec )
DS_VideoDecoder_Destroy(this->ds_dec);
@@ -1282,7 +1304,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
w32v_decoder_t *this ;
config_values_t *cfg;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "w32codec: plugin doesn't support plugin API version %d.\n"
"w32codec: this means there's a version mismatch between xine and this "
"w32codec: decoder plugin.\nInstalling current input plugins should help.\n",
@@ -1302,6 +1324,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
this->video_decoder.init = w32v_init;
this->video_decoder.decode_data = w32v_decode_data;
this->video_decoder.flush = w32v_flush;
+ this->video_decoder.reset = w32v_reset;
this->video_decoder.close = w32v_close;
this->video_decoder.get_identifier = w32v_get_id;
this->video_decoder.priority = 1;
@@ -1322,7 +1345,7 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, xine_t *xine) {
w32a_decoder_t *this ;
config_values_t *cfg;
- if (iface_version != 5) {
+ if (iface_version != 6) {
printf( "w32codec: plugin doesn't support plugin API version %d.\n"
"w32codec: this means there's a version mismatch between xine and this "
"w32codec: decoder plugin.\nInstalling current input plugins should help.\n",
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 172557345..04139231d 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.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: audio_decoder.c,v 1.69 2002/04/06 02:56:04 miguelfreitas Exp $
+ * $Id: audio_decoder.c,v 1.70 2002/04/09 03:38:01 miguelfreitas Exp $
*
*
* functions that implement audio decoding
@@ -70,7 +70,7 @@ void *audio_decoder_loop (void *this_gen) {
if (buf->input_time)
this->cur_input_time = buf->input_time;
-
+
switch (buf->type) {
case BUF_CONTROL_START:
@@ -128,20 +128,16 @@ void *audio_decoder_loop (void *this_gen) {
case BUF_CONTROL_NOP:
break;
- case BUF_CONTROL_DISCONTINUITY:
- /* reseting decoder on discontinuities is needed to make sure there will
- * be no held back pts values. it's unlikely that it would do any harm
- * given metronom's in_discontinuity counter but, at least in theory,
- * we might have problems with still frame + audio dvd menus.
- */
+ case BUF_CONTROL_RESET_DECODER:
if (this->cur_audio_decoder_plugin)
- this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
+ this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
+ break;
+
+ case BUF_CONTROL_DISCONTINUITY:
this->metronom->handle_audio_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
break;
case BUF_CONTROL_NEWPTS:
- if (this->cur_audio_decoder_plugin)
- this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
this->metronom->handle_audio_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
break;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index e4be9b9bb..3d70f54c6 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.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: buffer.h,v 1.38 2002/03/24 14:15:37 guenter Exp $
+ * $Id: buffer.h,v 1.39 2002/04/09 03:38:01 miguelfreitas Exp $
*
*
* contents:
@@ -70,7 +70,7 @@ extern "C" {
#define BUF_CONTROL_AUDIO_CHANNEL 0x01050000
#define BUF_CONTROL_SPU_CHANNEL 0x01060000
#define BUF_CONTROL_NEWPTS 0x01070000
-#define BUF_CONTROL_SEEK 0x01080000
+#define BUF_CONTROL_RESET_DECODER 0x01080000
/* video buffer types: (please keep in sync with buffer_types.c) */
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 5e00d273d..62abe76b3 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.79 2002/04/07 12:09:38 miguelfreitas Exp $
+ * $Id: metronom.c,v 1.80 2002/04/09 03:38:01 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -368,14 +368,12 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
#endif
if (abs (diff) > VIDEO_DRIFT_TOLERANCE) {
-
+
this->video_vpts = vpts;
this->video_drift = 0;
-
-#ifdef LOG
+
printf ("metronom: video jump\n");
-#endif
-
+
} else {
this->video_drift = diff;
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 69c06bbff..d0c5ef4a6 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -252,12 +252,6 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) {
this->event.vpts = vpts;
this->video_overlay->add_event(this->video_overlay,(void *)&this->event);
- this->event.event_type = EVENT_FREE_HANDLE;
- this->event.vpts = vpts+1;
- this->video_overlay->add_event(this->video_overlay,(void *)&this->event);
-
- osd->handle = -1; /* handle will be freed */
-
pthread_mutex_unlock (&this->osd_mutex);
return 1;
@@ -777,6 +771,16 @@ static void osd_free_object (osd_object_t *osd_to_close) {
if( osd_to_close->handle >= 0 ) {
osd_hide(osd_to_close,0);
+
+ this->event.object.handle = osd_to_close->handle;
+
+ /* not really needed this, but good pratice to clean it up */
+ memset( this->event.object.overlay, 0, sizeof(this->event.object.overlay) );
+ this->event.event_type = EVENT_FREE_HANDLE;
+ this->event.vpts = 0;
+ this->video_overlay->add_event(this->video_overlay,(void *)&this->event);
+
+ osd_to_close->handle = -1; /* handle will be freed */
}
pthread_mutex_lock (&this->osd_mutex);
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 035326005..359c28274 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.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: video_decoder.c,v 1.80 2002/03/27 15:30:16 miguelfreitas Exp $
+ * $Id: video_decoder.c,v 1.81 2002/04/09 03:38:01 miguelfreitas Exp $
*
*/
@@ -181,13 +181,19 @@ void *video_decoder_loop (void *this_gen) {
running = 0;
break;
+ case BUF_CONTROL_RESET_DECODER:
+ if (this->cur_video_decoder_plugin) {
+ this->cur_video_decoder_plugin->reset (this->cur_video_decoder_plugin);
+ }
+ break;
+
case BUF_CONTROL_DISCONTINUITY:
printf ("video_decoder: discontinuity ahead\n");
this->video_in_discontinuity = 1;
this->metronom->handle_video_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
-
+
this->video_in_discontinuity = 0;
break;
@@ -197,7 +203,7 @@ void *video_decoder_loop (void *this_gen) {
this->video_in_discontinuity = 1;
this->metronom->handle_video_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
-
+
this->video_in_discontinuity = 0;
break;
@@ -301,8 +307,5 @@ void video_decoder_shutdown (xine_t *this) {
this->video_fifo->put (this->video_fifo, buf);
pthread_join (this->video_thread, &p);
-
- this->video_out->exit (this->video_out);
- this->video_fifo->dispose (this->video_fifo);
}
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index b090cddeb..43ccff317 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.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: video_out.c,v 1.92 2002/04/02 19:29:09 esnel Exp $
+ * $Id: video_out.c,v 1.93 2002/04/09 03:38:01 miguelfreitas Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -666,11 +666,14 @@ static void *video_out_loop (void *this_gen) {
diff = vpts - this->last_delivery_pts;
if (diff > 30000 && !this->display_img_buf_queue->first) {
if (this->xine->cur_video_decoder_plugin) {
- this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin);
#ifdef LOG
- printf ("video_out: flushing current video decoder plugin\n");
+ printf ("video_out: flushing current video decoder plugin (%d %d)\n",
+ this->display_img_buf_queue->num_buffers,
+ this->free_img_buf_queue->num_buffers);
#endif
+
+ this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin);
}
this->last_delivery_pts = vpts;
}
@@ -700,6 +703,10 @@ static void *video_out_loop (void *this_gen) {
usec_to_sleep, vpts);
#endif
+ if ( (next_frame_vpts - vpts) > 2*90000 )
+ printf("video_out: vpts/clock error, next_vpts=%lld cur_vpts=%lld\n",
+ next_frame_vpts,vpts);
+
if (usec_to_sleep>0)
xine_usec_sleep (usec_to_sleep);
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index abe7d9db9..f6694dcd9 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.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: xine.c,v 1.113 2002/03/24 14:15:37 guenter Exp $
+ * $Id: xine.c,v 1.114 2002/04/09 03:38:01 miguelfreitas Exp $
*
* top-level xine functions
*
@@ -92,6 +92,33 @@ void xine_notify_stream_finished (xine_t *this) {
}
}
+/* internal use only - called from demuxers on seek/stop
+ * warning: after clearing decoders fifos an absolute discontinuity
+ * indication must be sent. relative discontinuities are likely
+ * to cause "jumps" on metronom.
+ */
+void xine_flush_engine (xine_t *this) {
+
+ buf_element_t *buf;
+
+ 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_RESET_DECODER;
+ 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_RESET_DECODER;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+
+ this->metronom->adjust_clock(this->metronom,
+ this->metronom->get_current_time(this->metronom) + 30 * 90000 );
+}
+
static void xine_internal_osd (xine_t *this, char *str,
uint32_t start_time, uint32_t duration) {
@@ -282,10 +309,10 @@ int xine_play (xine_t *this, char *mrl,
pthread_mutex_lock (&this->xine_lock);
/*
- * stop engine?
+ * stop engine only for different mrl
*/
- if (this->status == XINE_PLAY) {
+ if (this->status == XINE_PLAY && strcmp (mrl, this->cur_mrl) ) {
if(this->cur_demuxer_plugin) {
this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin);
@@ -305,76 +332,82 @@ int xine_play (xine_t *this, char *mrl,
this->status = XINE_STOP;
}
- /*
- * find input plugin
- */
-
- this->cur_input_plugin = NULL;
+ if (this->status == XINE_STOP ) {
+ /*
+ * find input plugin
+ */
+ this->cur_input_plugin = NULL;
- for (i = 0; i < this->num_input_plugins; i++) {
- if (this->input_plugins[i]->open(this->input_plugins[i], mrl)) {
- this->cur_input_plugin = this->input_plugins[i];
- break;
+ for (i = 0; i < this->num_input_plugins; i++) {
+ if (this->input_plugins[i]->open(this->input_plugins[i], mrl)) {
+ this->cur_input_plugin = this->input_plugins[i];
+ break;
+ }
}
- }
- if (!this->cur_input_plugin) {
- xine_log (this, XINE_LOG_FORMAT,
- _("xine: cannot find input plugin for this MRL\n"));
- this->cur_demuxer_plugin = NULL;
- this->err = XINE_ERROR_NO_INPUT_PLUGIN;
- pthread_mutex_unlock (&this->xine_lock);
+ if (!this->cur_input_plugin) {
+ xine_log (this, XINE_LOG_FORMAT,
+ _("xine: cannot find input plugin for this MRL\n"));
+ this->cur_demuxer_plugin = NULL;
+ this->err = XINE_ERROR_NO_INPUT_PLUGIN;
+ pthread_mutex_unlock (&this->xine_lock);
- return 0;
- }
+ return 0;
+ }
- printf ("xine: using input plugin >%s< for this MRL (%s).\n",
- this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl);
+ printf ("xine: using input plugin >%s< for this MRL (%s).\n",
+ this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl);
- xine_log (this, XINE_LOG_FORMAT,
- _("using input plugin '%s' for MRL '%s'\n"),
- this->cur_input_plugin->get_identifier(this->cur_input_plugin),
- mrl);
+ xine_log (this, XINE_LOG_FORMAT,
+ _("using input plugin '%s' for MRL '%s'\n"),
+ this->cur_input_plugin->get_identifier(this->cur_input_plugin),
+ mrl);
- /*
- * find demuxer plugin
- */
+ /*
+ * find demuxer plugin
+ */
- if (!find_demuxer(this, mrl)) {
- xine_log (this, XINE_LOG_FORMAT,
- _("xine: couldn't find demuxer for >%s<\n"), mrl);
- this->err = XINE_ERROR_NO_DEMUXER_PLUGIN;
- pthread_mutex_unlock (&this->xine_lock);
- return 0;
- }
+ if (!find_demuxer(this, mrl)) {
+ xine_log (this, XINE_LOG_FORMAT,
+ _("xine: couldn't find demuxer for >%s<\n"), mrl);
+ this->err = XINE_ERROR_NO_DEMUXER_PLUGIN;
+ pthread_mutex_unlock (&this->xine_lock);
+ return 0;
+ }
- xine_log (this, XINE_LOG_FORMAT,
- _("system layer format '%s' detected.\n"),
- this->cur_demuxer_plugin->get_identifier());
-
+ xine_log (this, XINE_LOG_FORMAT,
+ _("system layer format '%s' detected.\n"),
+ this->cur_demuxer_plugin->get_identifier());
+ }
+
/*
* start demuxer
*/
if (start_pos) {
+ /* FIXME: do we need to protect concurrent access to input plugin here? */
len = this->cur_input_plugin->get_length (this->cur_input_plugin);
share = (double) start_pos / 65535;
pos = (off_t) (share * len) ;
} else
pos = 0;
-
- this->cur_demuxer_plugin->start (this->cur_demuxer_plugin,
- this->video_fifo,
- this->audio_fifo,
- pos, start_time);
+
+ if( this->status == XINE_STOP )
+ this->cur_demuxer_plugin->start (this->cur_demuxer_plugin,
+ this->video_fifo,
+ this->audio_fifo,
+ pos, start_time);
+ else
+ this->cur_demuxer_plugin->seek (this->cur_demuxer_plugin,
+ pos, start_time);
if (this->cur_demuxer_plugin->get_status(this->cur_demuxer_plugin) != DEMUX_OK) {
xine_log (this, XINE_LOG_MSG,
_("xine_play: demuxer failed to start\n"));
- this->cur_input_plugin->close(this->cur_input_plugin);
-
- this->status = XINE_STOP;
+ if( this->status == XINE_STOP )
+ this->cur_input_plugin->close(this->cur_input_plugin);
+
} else {
this->status = XINE_PLAY;
@@ -383,6 +416,7 @@ int xine_play (xine_t *this, char *mrl,
xine_set_speed_internal (this, SPEED_NORMAL);
/* osd */
+ xine_usec_sleep(100000); /* FIXME: how do we assure an updated cur_input_time? */
xine_internal_osd (this, ">", this->metronom->get_current_time (this->metronom), 300000);
}
@@ -426,6 +460,8 @@ void xine_exit (xine_t *this) {
video_decoder_shutdown (this);
this->osd_renderer->close( this->osd_renderer );
+ this->video_out->exit (this->video_out);
+ this->video_fifo->dispose (this->video_fifo);
this->status = XINE_QUIT;
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 7e7f375b1..8afb1d402 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.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: xine_internal.h,v 1.74 2002/03/18 19:34:17 guenter Exp $
+ * $Id: xine_internal.h,v 1.75 2002/04/09 03:38:01 miguelfreitas Exp $
*
*/
@@ -55,7 +55,7 @@ extern "C" {
#define INPUT_PLUGIN_MAX 50
#define DEMUXER_PLUGIN_MAX 50
#define DECODER_PLUGIN_MAX 256
-#define DECODER_PLUGIN_IFACE_VERSION 5
+#define DECODER_PLUGIN_IFACE_VERSION 6
#define AUDIO_OUT_PLUGIN_MAX 50
#define VIDEO_OUT_PLUGIN_MAX 50
#define XINE_MAX_EVENT_LISTENERS 50
@@ -80,6 +80,8 @@ struct video_decoder_s {
void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
+ void (*reset) (video_decoder_t *this);
+
void (*flush) (video_decoder_t *this);
void (*close) (video_decoder_t *this);
@@ -407,6 +409,7 @@ char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id, int *num_mrls);
*/
void xine_notify_stream_finished (xine_t *this);
+void xine_flush_engine (xine_t *this);
/*
* video decoder stuff