summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2002-02-09 07:13:22 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2002-02-09 07:13:22 +0000
commit8700c75544d88f1479d5455b5b2788921d4dd5ee (patch)
tree7a80e2b00e4e7294c7d7ca1440c4d136ccf12998
parent2f8fed75fc94e7afe89f7b60586f7cb55737efe1 (diff)
downloadxine-lib-8700c75544d88f1479d5455b5b2788921d4dd5ee.tar.gz
xine-lib-8700c75544d88f1479d5455b5b2788921d4dd5ee.tar.bz2
the long-awaited video_out changes, not completely debuged (races)
- pts are 64 bit now - scr and video_out-loop run all the time - video_out cleanups - metronom cleanups - buffer type BUF_CONTROL_DISCONTINUITY is used internally now, input plugins should no longer send this one - support for individual frame durations - using nano-/usleep instead of itimer (simpler code, maybe this will help freebsd) CVS patchset: 1487 CVS date: 2002/02/09 07:13:22
-rw-r--r--src/Makefile.am2
-rw-r--r--src/demuxers/demux_asf.c10
-rw-r--r--src/demuxers/demux_avi.c14
-rw-r--r--src/demuxers/demux_cda.c8
-rw-r--r--src/demuxers/demux_elem.c6
-rw-r--r--src/demuxers/demux_mpeg.c30
-rw-r--r--src/demuxers/demux_mpeg_block.c26
-rw-r--r--src/demuxers/demux_mpgaudio.c6
-rw-r--r--src/demuxers/demux_ogg.c6
-rw-r--r--src/demuxers/demux_pes.c14
-rw-r--r--src/demuxers/demux_qt.c10
-rw-r--r--src/demuxers/demux_ts.c10
-rw-r--r--src/input/input_net.c1
-rw-r--r--src/input/strict_scr.c12
-rw-r--r--src/input/strict_scr.h2
-rw-r--r--src/liba52/xine_decoder.c12
-rw-r--r--src/libdivx4/xine_decoder.c10
-rw-r--r--src/libdts/xine_decoder.c6
-rw-r--r--src/libffmpeg/xine_decoder.c6
-rw-r--r--src/liblpcm/xine_decoder.c6
-rw-r--r--src/libmad/xine_decoder.c10
-rw-r--r--src/libmpeg2/decode.c169
-rw-r--r--src/libmpeg2/header.c43
-rw-r--r--src/libmpeg2/mpeg2_internal.h10
-rw-r--r--src/libmpeg2/slice.c17
-rw-r--r--src/libmpeg2/xine_decoder.c41
-rw-r--r--src/libspucc/xine_decoder.c4
-rw-r--r--src/libspudec/xine_decoder.c61
-rw-r--r--src/libsputext/xine_decoder.c11
-rw-r--r--src/libvorbis/xine_decoder.c8
-rw-r--r--src/libw32dll/w32codec.c21
-rw-r--r--src/video_out/alphablend.c1
-rw-r--r--src/video_out/video_out_fb.c7
-rw-r--r--src/video_out/video_out_opengl.c7
-rw-r--r--src/video_out/video_out_syncfb.c10
-rw-r--r--src/video_out/video_out_xshm.c13
-rw-r--r--src/video_out/video_out_xv.c25
-rw-r--r--src/xine-engine/audio_decoder.c17
-rw-r--r--src/xine-engine/audio_out.c5
-rw-r--r--src/xine-engine/audio_out.h11
-rw-r--r--src/xine-engine/buffer.h15
-rw-r--r--src/xine-engine/buffer_types.c9
-rw-r--r--src/xine-engine/metronom.c523
-rw-r--r--src/xine-engine/metronom.h108
-rw-r--r--src/xine-engine/video_decoder.c23
-rw-r--r--src/xine-engine/video_out.c985
-rw-r--r--src/xine-engine/video_out.h98
-rw-r--r--src/xine-engine/video_overlay.h38
-rw-r--r--src/xine-engine/xine.c14
49 files changed, 1102 insertions, 1399 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index db4b15167..df72f0989 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = xine-utils xine-engine audio_out video_out dxr3 input libmpeg2 libspudec demuxers \
- liba52 libffmpeg liblpcm libw32dll libmad libdts libvfill \
+ liba52 libffmpeg liblpcm libw32dll libmad libdts \
libvorbis libdivx4 libsputext libspucc
debug:
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 034f03126..4fef54fb8 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.21 2002/02/03 23:26:08 guenter Exp $
+ * $Id: demux_asf.c,v 1.22 2002/02/09 07:13:22 guenter Exp $
*
* demultiplexer for asf streams
*
@@ -701,8 +701,8 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream,
buf->input_pos = 0 ;
buf->input_time = 0 ;
}
- buf->PTS = timestamp * 90;
- buf->SCR = timestamp * 90;
+ buf->pts = timestamp * 90;
+ buf->scr = timestamp * 90;
buf->type = stream->buf_type;
buf->size = bufsize;
timestamp = 0;
@@ -774,9 +774,9 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream,
buf->input_time = 0 ;
}
- buf->PTS = stream->timestamp * 90 + stream->ts_per_kbyte *
+ buf->pts = stream->timestamp * 90 + stream->ts_per_kbyte *
(p-stream->buffer) / 1024;
- buf->SCR = buf->PTS;
+ buf->scr = buf->pts;
buf->type = stream->buf_type;
buf->size = bufsize;
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index 257dcc88a..6bb2b1ae3 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.62 2002/01/24 22:55:51 guenter Exp $
+ * $Id: demux_avi.c,v 1.63 2002/02/09 07:13:22 guenter Exp $
*
* demultiplexer for avi streams
*
@@ -751,8 +751,8 @@ static int demux_avi_next (demux_avi_t *this) {
/* read audio */
- buf->PTS = audio_pts;
- buf->SCR = audio_pts;
+ buf->pts = audio_pts;
+ buf->scr = audio_pts;
buf->size = AVI_read_audio (this, this->avi, buf->mem, 2048, &buf->decoder_info[0]);
if (buf->size<0) {
@@ -778,8 +778,8 @@ static int demux_avi_next (demux_avi_t *this) {
/* read video */
- buf->PTS = video_pts;
- buf->SCR = video_pts;
+ buf->pts = video_pts;
+ buf->scr = video_pts;
buf->size = AVI_read_video (this, this->avi, buf->mem, 2048, &buf->decoder_info[0]);
buf->type = this->avi->video_type;
@@ -807,7 +807,7 @@ static int demux_avi_next (demux_avi_t *this) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_SPU_TEXT;
- buf->PTS = video_pts;
+ buf->pts = video_pts;
buf->decoder_info[0] = 1;
buf->decoder_info[1] = this->avi->video_posf;
@@ -923,7 +923,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
LOG_MSG(this->xine, _("demux_avi: video format = %s, audio format = 0x%lx\n"),
this->avi->compressor, this->avi->a_fmt);
- LOG_MSG(this->xine, _("demux_avi: video frame size %d x %d\n"),
+ LOG_MSG(this->xine, _("demux_avi: video frame size %ld x %ld\n"),
this->avi->width, this->avi->height);
this->no_audio = 0;
diff --git a/src/demuxers/demux_cda.c b/src/demuxers/demux_cda.c
index a585a988b..d5fd46b0f 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.6 2002/01/14 21:42:59 f1rmb Exp $
+ * $Id: demux_cda.c,v 1.7 2002/02/09 07:13:22 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -93,11 +93,11 @@ static int demux_cda_next (demux_cda_t *this) {
pos = this->input->get_current_pos(this->input);
len = this->input->get_length(this->input);
- buf->PTS = 0;
- buf->SCR = 0;
+ buf->pts = 0;
+ buf->scr = 0;
buf->input_pos = pos;
buf->input_time = buf->input_pos / this->blocksize;
- buf->type = BUF_VIDEO_FILL; /* Fake */
+ buf->type = BUF_CONTROL_NOP; /* Fake */
this->video_fifo->put(this->video_fifo, buf);
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
index 44f000590..608c74fa0 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.32 2002/01/02 18:16:07 jkeil Exp $
+ * $Id: demux_elem.c,v 1.33 2002/02/09 07:13:22 guenter Exp $
*
* demultiplexer for elementary mpeg streams
*
@@ -108,8 +108,8 @@ static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) {
else
buf->decoder_info[0] = 1;
- buf->PTS = 0;
- buf->SCR = 0;
+ buf->pts = 0;
+ buf->scr = 0;
buf->input_pos = this->input->get_current_pos(this->input);
buf->type = BUF_VIDEO_MPEG;
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index 8df1d4fe1..ddfc39cfc 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.48 2002/01/02 18:16:07 jkeil Exp $
+ * $Id: demux_mpeg.c,v 1.49 2002/02/09 07:13:22 guenter Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -185,8 +185,8 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
return ;
}
buf->type = BUF_AUDIO_A52 + track;
- buf->PTS = pts;
- buf->SCR = scr;
+ buf->pts = pts;
+ buf->scr = scr;
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -235,8 +235,8 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
return ;
}
buf->type = BUF_AUDIO_MPEG + track;
- buf->PTS = pts;
- buf->SCR = scr;
+ buf->pts = pts;
+ buf->scr = scr;
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -280,8 +280,8 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
return ;
}
buf->type = BUF_VIDEO_MPEG;
- buf->PTS = pts;
- buf->SCR = scr;
+ buf->pts = pts;
+ buf->scr = scr;
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -392,8 +392,8 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
return ;
}
buf->type = BUF_AUDIO_MPEG + track ;
- buf->PTS = pts;
- buf->SCR = scr;
+ buf->pts = pts;
+ buf->scr = scr;
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -415,8 +415,8 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
return ;
}
buf->type = BUF_VIDEO_MPEG;
- buf->PTS = pts;
- buf->SCR = scr;
+ buf->pts = pts;
+ buf->scr = scr;
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -516,14 +516,14 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
buf_element_t *buf;
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_AVSYNC_RESET;
- buf->SCR = scr;
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->scr = scr;
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_AVSYNC_RESET;
- buf->SCR = scr;
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->scr = scr;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index 0eb35d522..53f1a0b86 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.75 2002/02/01 13:01:57 f1rmb Exp $
+ * $Id: demux_mpeg_block.c,v 1.76 2002/02/09 07:13:23 guenter Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -202,7 +202,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr |= (p[6] & 0xFF) << 7;
scr |= (p[7] & 0xFE) >> 1;
- buf->SCR = scr;
+ buf->scr = scr;
/* mux_rate */
@@ -234,7 +234,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
*/
- buf->SCR = scr;
+ buf->scr = scr;
/* mux_rate */
@@ -294,14 +294,14 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
#endif
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_AVSYNC_RESET;
- buf->SCR = scr;
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->scr = scr;
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_AVSYNC_RESET;
- buf->SCR = scr;
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->scr = scr;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -315,7 +315,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->content = p;
buf->size = packet_len;
buf->type = BUF_SPU_NAV;
- buf->PTS = 0; /* NAV packets do not have PES values */
+ buf->pts = 0; /* NAV packets do not have PES values */
buf->input_pos = this->input->get_current_pos(this->input);
this->video_fifo->put (this->video_fifo, buf);
return ;
@@ -424,7 +424,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->content = p+1;
buf->size = packet_len-1;
buf->type = BUF_SPU_PACKAGE + spu_id;
- buf->PTS = PTS;
+ buf->pts = PTS;
buf->input_pos = this->input->get_current_pos(this->input);
this->video_fifo->put (this->video_fifo, buf);
@@ -445,7 +445,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
} else {
buf->type = BUF_AUDIO_A52 + track;
}
- buf->PTS = PTS;
+ buf->pts = PTS;
buf->input_pos = this->input->get_current_pos(this->input);
@@ -505,7 +505,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->content = p+pcm_offset;
buf->size = packet_len-pcm_offset;
buf->type = BUF_AUDIO_LPCM_BE + track;
- buf->PTS = PTS;
+ buf->pts = PTS;
buf->input_pos = this->input->get_current_pos(this->input);
@@ -522,7 +522,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->content = p;
buf->size = packet_len;
buf->type = BUF_VIDEO_MPEG;
- buf->PTS = PTS;
+ buf->pts = PTS;
buf->input_pos = this->input->get_current_pos(this->input);
@@ -538,7 +538,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->content = p;
buf->size = packet_len;
buf->type = BUF_AUDIO_MPEG + track;
- buf->PTS = PTS;
+ buf->pts = PTS;
buf->input_pos = this->input->get_current_pos(this->input);
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
index 17e10c138..df01ac14d 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.33 2002/01/13 21:15:48 jcdutton Exp $
+ * $Id: demux_mpgaudio.c,v 1.34 2002/02/09 07:13:23 guenter Exp $
*
* demultiplexer for mpeg audio (i.e. mp3) streams
*
@@ -207,8 +207,8 @@ static int demux_mpgaudio_next (demux_mpgaudio_t *this) {
}
}
- buf->PTS = 0;
- buf->SCR = 0;
+ buf->pts = 0;
+ buf->scr = 0;
buf->input_pos = this->input->get_current_pos(this->input);
buf->input_time = buf->input_pos * this->stream_length /
this->input->get_length(this->input);
diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c
index b78f9cd63..c1382cbdb 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.13 2002/01/02 18:16:07 jkeil Exp $
+ * $Id: demux_ogg.c,v 1.14 2002/02/09 07:13:23 guenter Exp $
*
* demultiplexer for ogg streams
*
@@ -184,8 +184,8 @@ static void demux_ogg_send_package (demux_ogg_t *this, int is_content) {
}
- buf->PTS = 0; /* FIXME */
- buf->SCR = 0; /* FIXME */
+ buf->pts = 0; /* FIXME */
+ buf->scr = 0; /* FIXME */
buf->size = op.bytes;
buf->decoder_info[0] = is_content;
diff --git a/src/demuxers/demux_pes.c b/src/demuxers/demux_pes.c
index 26d36ecad..2a5305aee 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.17 2002/01/02 18:16:07 jkeil Exp $
+ * $Id: demux_pes.c,v 1.18 2002/02/09 07:13:23 guenter Exp $
*
* demultiplexer for mpeg 2 PES (Packetized Elementary Streams)
* reads streams of variable blocksizes
@@ -183,8 +183,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
return ;
}
buf->type = BUF_AUDIO_A52 + track;
- buf->PTS = pts;
- buf->SCR = pts; /* FIMXE! */
+ buf->pts = pts;
+ buf->scr = pts; /* FIMXE! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -229,8 +229,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
return ;
}
buf->type = BUF_AUDIO_MPEG + track;
- buf->PTS = pts;
- buf->SCR = pts; /* FIXME ! */
+ buf->pts = pts;
+ buf->scr = pts; /* FIXME ! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -275,8 +275,8 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
return ;
}
buf->type = BUF_VIDEO_MPEG;
- buf->PTS = pts;
- buf->SCR = pts; /* FIXME! */
+ buf->pts = pts;
+ buf->scr = pts; /* FIXME! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index bfbda7a61..a739bfa59 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.19 2002/01/15 21:10:31 miguelfreitas Exp $
+ * $Id: demux_qt.c,v 1.20 2002/02/09 07:13:23 guenter Exp $
*
* demultiplexer for quicktime streams, based on:
*
@@ -4026,8 +4026,8 @@ static void *demux_qt_loop (void *this_gen) {
/* int count; */
- buf->PTS = audio_pts;
- buf->SCR = audio_pts;
+ buf->pts = audio_pts;
+ buf->scr = audio_pts;
buf->type = this->audio_type;
buf->decoder_info[0] = 1;
buf->input_time = 0;
@@ -4073,8 +4073,8 @@ static void *demux_qt_loop (void *this_gen) {
buf->content = buf->mem;
buf->size = copy_bytes;
- buf->PTS = video_pts;
- buf->SCR = video_pts;
+ buf->pts = video_pts;
+ buf->scr = video_pts;
buf->type = this->video_type;
buf->input_time = video_pts / 90000;
buf->input_pos = this->input->get_current_pos(this->input);
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 54bcd6c8e..44e05147c 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.35 2002/01/13 21:15:48 jcdutton Exp $
+ * $Id: demux_ts.c,v 1.36 2002/02/09 07:13:23 guenter Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -544,8 +544,8 @@ static void demux_ts_buffer_pes(demux_ts *this, unsigned char *ts,
buf->content = buf->mem;
buf->size = m->size;
buf->type = m->type;
- buf->PTS = m->PTS;
- buf->SCR = this->PCR;
+ buf->pts = m->PTS;
+ buf->scr = this->PCR;
buf->decoder_info[0] = 1;
m->fifo->put (m->fifo, buf);
}
@@ -556,8 +556,8 @@ static void demux_ts_buffer_pes(demux_ts *this, unsigned char *ts,
buf->content = buf->mem;
buf->size = len;
buf->type = m->type;
- buf->PTS = 0;
- buf->SCR = 0;
+ buf->pts = 0;
+ buf->scr = 0;
buf->input_pos = this->input->get_current_pos(this->input);
buf->decoder_info[0] = 1;
m->fifo->put (m->fifo, buf);
diff --git a/src/input/input_net.c b/src/input/input_net.c
index 6b859ea6e..c89c25524 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -99,7 +99,6 @@ static int host_connect_attempt(struct in_addr ia, int port, xine_t *xine) {
int s;
struct sockaddr_in sin;
- fd_set wfd;
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s==-1) {
diff --git a/src/input/strict_scr.c b/src/input/strict_scr.c
index ba045418e..a0c78f1f3 100644
--- a/src/input/strict_scr.c
+++ b/src/input/strict_scr.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: strict_scr.c,v 1.1 2002/01/10 21:42:50 guenter Exp $
+ * $Id: strict_scr.c,v 1.2 2002/02/09 07:13:23 guenter Exp $
*
* scr plugin that may not allow others to adjust it (used for streaming)
*/
@@ -70,7 +70,7 @@ static int strictscr_set_speed (scr_plugin_t *scr, int speed) {
return speed;
}
-static void strictscr_adjust (scr_plugin_t *scr, uint32_t vpts) {
+static void strictscr_adjust (scr_plugin_t *scr, int64_t vpts) {
strictscr_t *this = (strictscr_t*) scr;
struct timeval tv;
@@ -88,7 +88,7 @@ static void strictscr_adjust (scr_plugin_t *scr, uint32_t vpts) {
}
}
-static void strictscr_start (scr_plugin_t *scr, uint32_t start_vpts) {
+static void strictscr_start (scr_plugin_t *scr, int64_t start_vpts) {
strictscr_t *this = (strictscr_t*) scr;
pthread_mutex_lock (&this->lock);
@@ -99,11 +99,11 @@ static void strictscr_start (scr_plugin_t *scr, uint32_t start_vpts) {
pthread_mutex_unlock (&this->lock);
}
-static uint32_t strictscr_get_current (scr_plugin_t *scr) {
+static int64_t strictscr_get_current (scr_plugin_t *scr) {
strictscr_t *this = (strictscr_t*) scr;
struct timeval tv;
- uint32_t pts;
+ int64_t pts;
double pts_calc;
pthread_mutex_lock (&this->lock);
@@ -139,4 +139,4 @@ strictscr_t* strictscr_init () {
return this;
}
-
+
diff --git a/src/input/strict_scr.h b/src/input/strict_scr.h
index 934060c4c..39d8bb8bf 100644
--- a/src/input/strict_scr.h
+++ b/src/input/strict_scr.h
@@ -29,7 +29,7 @@ typedef struct strictscr_s {
scr_plugin_t scr;
struct timeval cur_time;
- uint32_t cur_pts;
+ int64_t cur_pts;
double speed_factor;
int adjustable;
diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c
index 52910aada..0dbf203e3 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.16 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.17 2002/02/09 07:13:23 guenter Exp $
*
* stuff needed to turn liba52 into a xine decoder plugin
*/
@@ -50,8 +50,8 @@ int a52file;
typedef struct a52dec_decoder_s {
audio_decoder_t audio_decoder;
- uint32_t pts;
- uint32_t last_pts;
+ int64_t pts;
+ int64_t last_pts;
uint8_t frame_buffer[3840];
uint8_t *frame_ptr;
@@ -457,14 +457,14 @@ void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->last_pts = buf->PTS;
*/
- if (buf->PTS)
- this->pts = buf->PTS;
+ if (buf->pts)
+ this->pts = buf->pts;
while (current != end) {
if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) {
- a52dec_decode_frame (this, this->pts, buf->SCR);
+ a52dec_decode_frame (this, this->pts, buf->scr);
#ifdef DEBUG_A52
write (a52file, this->frame_buffer, this->frame_length);
#endif
diff --git a/src/libdivx4/xine_decoder.c b/src/libdivx4/xine_decoder.c
index ce63350b6..0e41addfa 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.16 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.17 2002/02/09 07:13:23 guenter Exp $
*
* xine decoder plugin using divx4
*
@@ -394,9 +394,11 @@ static void divx4_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_info[0] == 2) { /* need to decode a frame */
/* allocate image (taken from ffmpeg plugin) */
img = this->video_out->get_frame (this->video_out, this->biWidth,
- this->biHeight, XINE_ASPECT_RATIO_DONT_TOUCH, IMGFMT_YV12,
- this->video_step, VO_BOTH_FIELDS);
+ this->biHeight, XINE_ASPECT_RATIO_DONT_TOUCH,
+ IMGFMT_YV12,
+ VO_BOTH_FIELDS);
+ img->duration = this->video_step;
/* setup the decode frame parameters, as demonstrated by avifile.
Old versions used DEC_YV12, but that was basically wrong and just
happened to work with the Xv driver. Now DEC_USER is the only option.
@@ -422,7 +424,7 @@ static void divx4_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
}
/* this again from ffmpeg plugin */
- img->PTS = buf->PTS;
+ img->pts = buf->pts;
img->draw(img);
img->free(img);
diff --git a/src/libdts/xine_decoder.c b/src/libdts/xine_decoder.c
index c8849ffbc..89b8cf1d2 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.13 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.14 2002/02/09 07:13:23 guenter Exp $
*
* 04-09-2001 DTS passtrough (C) Joachim Koenig
* 09-12-2001 DTS passthrough inprovements (C) James Courtier-Dutton
@@ -123,8 +123,8 @@ void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
/* printf("DTS first access unit=%u\n",audio_buffer->first_access_unit); */
if (n == first_access_unit) {
- audio_buffer->vpts = buf->PTS;
- audio_buffer->scr = buf->SCR;
+ audio_buffer->vpts = buf->pts;
+ audio_buffer->scr = buf->scr;
} else {
audio_buffer->vpts = 0;
audio_buffer->scr = 0;
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
index c239648d6..609a60ee7 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.25 2002/01/28 17:28:39 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.26 2002/02/09 07:13:23 guenter Exp $
*
* xine decoder plugin using ffmpeg
*
@@ -249,10 +249,10 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
this->biHeight,
42,
IMGFMT_YV12,
- this->video_step,
VO_BOTH_FIELDS);
- img->PTS = buf->PTS;
+ img->pts = buf->pts;
+ img->duration = this->video_step;
if (len<0 || this->skipframes) {
if( !this->skipframes )
printf ("ffmpeg: error decompressing frame\n");
diff --git a/src/liblpcm/xine_decoder.c b/src/liblpcm/xine_decoder.c
index a333695d2..dbff95cda 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.18 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.19 2002/02/09 07:13:23 guenter Exp $
*
* 31-8-2001 Added LPCM rate sensing.
* (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk
@@ -129,8 +129,8 @@ void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
else
memcpy (audio_buffer->mem, sample_buffer, buf->size);
- audio_buffer->vpts = buf->PTS;
- audio_buffer->scr = buf->SCR;
+ audio_buffer->vpts = buf->pts;
+ audio_buffer->scr = buf->scr;
audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample);
this->audio_out->put_buffer (this->audio_out, audio_buffer);
diff --git a/src/libmad/xine_decoder.c b/src/libmad/xine_decoder.c
index fb6cc03b8..854057761 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.12 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.13 2002/02/09 07:13:23 guenter Exp $
*
* stuff needed to turn libmad into a xine decoder plugin
*/
@@ -37,7 +37,7 @@
typedef struct mad_decoder_s {
audio_decoder_t audio_decoder;
- uint32_t pts;
+ int64_t pts;
struct mad_synth synth;
struct mad_stream stream;
@@ -225,12 +225,12 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
}
audio_buffer->num_frames = pcm->length;
- audio_buffer->vpts = buf->PTS;
- audio_buffer->scr = buf->SCR;
+ audio_buffer->vpts = buf->pts;
+ audio_buffer->scr = buf->scr;
this->audio_out->put_buffer (this->audio_out, audio_buffer);
- buf->PTS = 0;
+ buf->pts = 0;
}
/* printf ("libmad: decode worked\n"); */
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 2c2a25de2..999ef3079 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -22,10 +22,6 @@
*
*/
-/*
-#define LOG_PAN_SCAN
-*/
-
#include "config.h"
#include <stdio.h>
@@ -40,6 +36,12 @@
#include "xine_internal.h"
#include "events.h"
+/*
+#define LOG_PAN_SCAN
+*/
+
+#define LOG
+
#define BUFFER_SIZE (224 * 1024)
mpeg2_config_t config;
@@ -49,7 +51,7 @@ static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer);
void mpeg2_init (mpeg2dec_t * mpeg2dec,
vo_instance_t * output)
{
- static int do_init = 1;
+ static int do_init = 1;
if (do_init) {
do_init = 0;
@@ -79,50 +81,54 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec,
header_state_init (mpeg2dec->picture);
}
-static int get_frame_duration(mpeg2dec_t * mpeg2dec, vo_frame_t * frame)
+static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame)
{
- int duration;
- switch (frame->frame_rate_code) {
+ switch (mpeg2dec->picture->frame_rate_code) {
case 1: /* 23.976 fps */
- frame->duration = 3913;
+ frame->duration = 3913;
+ frame->pts_corrector = 0;
break;
case 2: /* 24 fps */
- frame->duration = 3750;
+ frame->duration = 3750;
+ frame->pts_corrector = 0;
break;
case 3: /* 25 fps */
- frame->duration = frame->repeat_first_field ? 5400 : 3600;
+ frame->duration = mpeg2dec->picture->repeat_first_field ? 5400 : 3600;
+ frame->pts_corrector = 0;
break;
case 4: /* 29.97 fps */
- if ((frame->repeat_first_field) || (mpeg2dec->last_repeat_first_field)) {
- frame->duration = 3754;
+ if ((mpeg2dec->picture->repeat_first_field) || (mpeg2dec->last_repeat_first_field)) {
+ frame->duration = 3754;
frame->pts_corrector = frame->repeat_first_field ? 375 : -375;
} else {
- frame->duration = 3003;
+ frame->duration = 3003;
frame->pts_corrector = 0;
}
-// duration = 3754;
-// duration = frame->repeat_first_field ? 4504 : 3003;
break;
case 5: /* 30 fps */
- frame->duration = 3000;
+ frame->duration = 3000;
+ frame->pts_corrector = 0;
break;
case 6: /* 50 fps */
- frame->duration = 1800;
+ frame->duration = 1800;
+ frame->pts_corrector = 0;
break;
case 7: /* 59.94 fps */
- frame->duration = 1525;
+ frame->duration = 1525;
+ frame->pts_corrector = 0;
break;
case 8: /* 60 fps */
- frame->duration = 1509;
+ frame->duration = 1509;
+ frame->pts_corrector = 0;
break;
default:
/* printf ("invalid/unknown frame rate code : %d \n",
frame->frame_rate_code); */
- duration = 3000;
+ frame->duration = 3000;
+ frame->pts_corrector = 0;
}
/* printf("mpeg2dec: rff=%u\n",frame->repeat_first_field); */
mpeg2dec->last_repeat_first_field = frame->repeat_first_field;
- return 1;
}
static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
@@ -159,8 +165,6 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if ( picture->current_frame && ((picture->picture_structure == FRAME_PICTURE) ||
(picture->second_field)) ) {
- picture->current_frame->bad_frame |= mpeg2dec->drop_frame;
-
#if 0
printf ("type %s: %s\n",
picture->picture_coding_type == I_TYPE ? "I" :
@@ -168,10 +172,11 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame->bad_frame ? "BAD" : "good");
#endif
if (picture->picture_coding_type == B_TYPE) {
- if (picture->mpeg1) {
- picture->current_frame->PTS = 0;
- }
- get_frame_duration(mpeg2dec, picture->current_frame);
+
+ /* hack against wrong mpeg1 pts */
+ if (picture->mpeg1)
+ picture->current_frame->pts = 0;
+
mpeg2dec->frames_to_drop = picture->current_frame->draw (picture->current_frame);
picture->current_frame->free (picture->current_frame);
picture->current_frame = NULL;
@@ -225,7 +230,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
break;
case I_TYPE:
- /*
+ /* for the sake of dvd menus, never drop i-frames
if (mpeg2dec->frames_to_drop>4) {
mpeg2dec->drop_frame = 1;
}
@@ -249,7 +254,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
|| (picture->frame_height != picture->coded_picture_height)) {
xine_frame_change_event_t notify_event;
- printf ("mpeg2dec: frame size has changed to from %d x %d to %d x %d\n",
+ printf ("libmpeg2: frame size has changed to from %d x %d to %d x %d\n",
picture->frame_width, picture->frame_height,
picture->coded_picture_width, picture->coded_picture_height);
@@ -264,7 +269,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if (picture->backward_reference_frame)
picture->backward_reference_frame->free (picture->backward_reference_frame);
- printf ("mpeg2dec: old frames freed.\n");
+ printf ("libmpeg2: old frames freed.\n");
mpeg2dec->is_sequence_needed = 0;
picture->forward_reference_frame = NULL;
@@ -277,23 +282,23 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
case 0xb5: /* extension_start_code */
if (header_process_extension (picture, buffer)) {
- fprintf (stderr, "bad extension\n");
- exit (1);
+ printf ("libmpeg2: bad extension\n");
+ exit (1);
}
break;
case 0xb7: /* sequence end code */
#ifdef LOG_PAN_SCAN
- printf ("libmpeg2:SEQUENCE END CODE NOT HANDLED!\n");
+ printf ("libmpeg2: sequence end code not handled\n");
#endif
case 0xb8: /* group of pictures start code */
if (header_process_group_of_pictures (picture, buffer)) {
- fprintf (stderr, "bad group of pictures\n");
- exit (1);
+ printf ("libmpeg2: bad group of pictures\n");
+ exit (1);
}
default:
if (code >= 0xb9)
- fprintf (stderr, "stream not demultiplexed ?\n");
+ printf ("libmpeg2: stream not demultiplexed ?\n");
if (code >= 0xb0)
break;
@@ -315,7 +320,6 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->coded_picture_height,
picture->aspect_ratio_information,
IMGFMT_YV12,
- picture->frame_duration,
picture->picture_structure);
else {
picture->current_frame =
@@ -324,7 +328,6 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->coded_picture_height,
picture->aspect_ratio_information,
IMGFMT_YV12,
- picture->frame_duration,
(VO_PREDICTION_FLAG | picture->picture_structure));
if (picture->forward_reference_frame)
picture->forward_reference_frame->free (picture->forward_reference_frame);
@@ -333,19 +336,15 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->backward_reference_frame;
picture->backward_reference_frame = picture->current_frame;
}
- picture->current_frame->bad_frame = 0;
- picture->current_frame->drawn = 0;
- picture->current_frame->PTS = mpeg2dec->pts;
- picture->current_frame->SCR = mpeg2dec->scr;
- picture->current_frame->aspect_ratio = picture->aspect_ratio_information;
- picture->current_frame->frame_rate_code = picture->frame_rate_code;
- picture->current_frame->top_field_first = picture->top_field_first;
- picture->current_frame->progressive_sequence = picture->progressive_sequence;
+ picture->current_frame->bad_frame = 1;
+ picture->current_frame->drawn = 0;
+ picture->current_frame->pts = mpeg2dec->pts;
+ picture->current_frame->scr = mpeg2dec->scr;
+ picture->current_frame->top_field_first = picture->top_field_first;
picture->current_frame->repeat_first_field = picture->repeat_first_field;
- picture->current_frame->progressive_frame = picture->progressive_frame;
- picture->current_frame->picture_coding_type = picture->picture_coding_type;
- picture->current_frame->bitrate = picture->bitrate;
- picture->current_frame->repeat_first_field = picture->repeat_first_field;
+
+ get_frame_duration(mpeg2dec, picture->current_frame);
+
mpeg2dec->pts = 0;
}
}
@@ -353,7 +352,8 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
if (!(mpeg2dec->drop_frame)) {
/* printf ("slice_process\n"); */
- slice_process (picture, code, buffer);
+ if (slice_process (picture, code, buffer) == 1)
+ picture->current_frame->bad_frame = 0;
#ifdef ARCH_X86
if (config.flags & MM_ACCEL_X86_MMX)
@@ -362,7 +362,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
}
}
- /* printf ("parse_chunk %d completed\n", code); */
+ /* printf ("libmpeg2: parse_chunk %d completed\n", code); */
return is_frame_done;
}
@@ -381,8 +381,8 @@ static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec,
limit = end;
/*
- printf ("copy chunk current %08x\n", current );
- printf ("copy chunk end %08x\n", end); fflush(stdout);
+ printf ("libmpeg2: copy chunk current %08x\n", current );
+ printf ("libmpeg2: copy chunk end %08x\n", end); fflush(stdout);
*/
while (1) {
@@ -444,31 +444,32 @@ int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end,
void mpeg2_flush (mpeg2dec_t * mpeg2dec) {
- picture_t *picture = mpeg2dec->picture;
+ picture_t *picture = mpeg2dec->picture;
- if (picture->backward_reference_frame && !picture->backward_reference_frame->drawn) {
- vo_frame_t *img;
-
- printf ("libmpeg2: blasting out backward reference frame on flush\n");
- picture->backward_reference_frame->PTS = 0;
- picture->backward_reference_frame->SCR = mpeg2dec->scr;
- get_frame_duration(mpeg2dec, picture->backward_reference_frame);
- picture->backward_reference_frame->bad_frame = 0;
- picture->backward_reference_frame->drawn = 1;
- picture->backward_reference_frame->displayed (picture->backward_reference_frame);
-
- /* output a copy instead of the frame used by decoder */
- img = picture->backward_reference_frame->instance->duplicate_frame(
- picture->backward_reference_frame->instance,
- picture->backward_reference_frame);
- img->PTS = 0;
- img->SCR = mpeg2dec->scr;
- img->bad_frame = 0;
- img->drawn = 2;
- img->draw(img);
-
- img->free(img);
- }
+ if (picture->backward_reference_frame && !picture->backward_reference_frame->drawn
+ && !picture->backward_reference_frame->bad_frame) {
+
+ vo_frame_t *img;
+
+ printf ("libmpeg2: blasting out backward reference frame on flush\n");
+
+ picture->backward_reference_frame->drawn = 1;
+
+ /* output a copy instead of the frame used by decoder */
+ img = picture->backward_reference_frame->instance->duplicate_frame(picture->backward_reference_frame->instance,
+ picture->backward_reference_frame);
+ img->pts = 0;
+ img->scr = 0;
+ img->bad_frame = 0;
+ img->drawn = 1;
+
+ img->draw(img);
+ img->free(img);
+
+ } else {
+ printf ("libmpeg2: flush called, but I have no frame to flush\n");
+
+ }
}
@@ -501,9 +502,8 @@ void mpeg2_close (mpeg2dec_t * mpeg2dec)
if (picture->throwaway_frame) {
printf ("libmpeg2: blasting out throwaway frame on close\n");
- picture->throwaway_frame->PTS = 0;
- picture->throwaway_frame->SCR = mpeg2dec->scr;
- picture->throwaway_frame->bad_frame = 0;
+ picture->throwaway_frame->pts = 0;
+ picture->throwaway_frame->scr = 0;
get_frame_duration(mpeg2dec, picture->throwaway_frame);
picture->throwaway_frame->draw (picture->throwaway_frame);
picture->throwaway_frame->free (picture->throwaway_frame);
@@ -511,10 +511,9 @@ void mpeg2_close (mpeg2dec_t * mpeg2dec)
if (picture->backward_reference_frame) {
printf ("libmpeg2: blasting out backward reference frame on close\n");
- picture->backward_reference_frame->PTS = 0;
- picture->backward_reference_frame->SCR = mpeg2dec->scr;
+ picture->backward_reference_frame->pts = 0;
+ picture->backward_reference_frame->scr = mpeg2dec->scr;
get_frame_duration(mpeg2dec, picture->backward_reference_frame);
- picture->backward_reference_frame->bad_frame = 0;
if( !picture->backward_reference_frame->drawn)
picture->backward_reference_frame->draw (picture->backward_reference_frame);
picture->backward_reference_frame->free (picture->backward_reference_frame);
diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c
index e075f51e1..0a486f0f9 100644
--- a/src/libmpeg2/header.c
+++ b/src/libmpeg2/header.c
@@ -131,39 +131,7 @@ int header_process_sequence_header (picture_t * picture, uint8_t * buffer)
/* this is not used by the decoder */
picture->aspect_ratio_information = buffer[3] >> 4;
picture->frame_rate_code = buffer[3] & 15;
-
- switch (picture->frame_rate_code) {
- case 1: /* 23.976 fps */
- picture->frame_duration = 3913;
- break;
- case 2: /* 24 fps */
- picture->frame_duration = 3750;
- break;
- case 3: /* 25 fps */
- picture->frame_duration = 3600;
- break;
- case 4: /* 29.97 fps */
- picture->frame_duration = 3003;
- break;
- case 5: /* 30 fps */
- picture->frame_duration = 3000;
- break;
- case 6: /* 50 fps */
- picture->frame_duration = 1800;
- break;
- case 7: /* 59.94 fps */
- picture->frame_duration = 1525;
- break;
- case 8: /* 60 fps */
- picture->frame_duration = 1509;
- break;
- default:
- /* printf ("invalid/unknown frame rate code : %d \n",
- picture->frame_rate_code); */
- picture->frame_duration = 3000;
- }
-
- picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6);
+ /* picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6); */
if (buffer[7] & 2) {
for (i = 0; i < 64; i++)
@@ -194,6 +162,7 @@ int header_process_sequence_header (picture_t * picture, uint8_t * buffer)
/* picture->alternate_scan = 0; */
picture->picture_structure = FRAME_PICTURE;
/* picture->second_field = 0; */
+ picture->last_mba = ((width * height) >> 8) - 1;
return 0;
}
@@ -209,10 +178,14 @@ static int header_process_sequence_extension (picture_t * picture,
/* this is not used by the decoder */
picture->progressive_sequence = (buffer[1] >> 3) & 1;
+ picture->low_delay = buffer[5] & 0x80;
+
if (picture->progressive_sequence)
picture->coded_picture_height =
(picture->coded_picture_height + 31) & ~31;
+ printf ("libmpeg2: low_delay : %d\n", picture->low_delay);
+
/*
printf ("libmpeg2: sequence extension+5 : %08x (%d)\n",
buffer[5], buffer[5] % 0x80);
@@ -422,6 +395,8 @@ int header_process_group_of_pictures (picture_t * picture, uint8_t * buffer) {
int header_process_picture_header (picture_t *picture, uint8_t * buffer)
{
picture->picture_coding_type = (buffer [1] >> 3) & 7;
+ picture->vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) |
+ (buffer[3] >> 3)) & 0xffff;
/* forward_f_code and backward_f_code - used in mpeg1 only */
picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1;
@@ -437,3 +412,5 @@ int header_process_picture_header (picture_t *picture, uint8_t * buffer)
return 0;
}
+
+
diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h
index fcb70368b..767be0093 100644
--- a/src/libmpeg2/mpeg2_internal.h
+++ b/src/libmpeg2/mpeg2_internal.h
@@ -91,6 +91,9 @@ typedef struct picture_s {
/* what type of picture this is (I, P, B, D) */
int picture_coding_type;
+
+ int vbv_delay;
+ int low_delay;
/* picture coding extension stuff */
@@ -107,6 +110,8 @@ typedef struct picture_s {
int q_scale_type;
/* bool to use different vlc tables */
int intra_vlc_format;
+ /* last macroblock in the picture */
+ int last_mba;
/* used for DMV MC */
int top_field_first;
@@ -132,11 +137,10 @@ typedef struct picture_s {
/* this is a temporary interface, we will build a better one later. */
int aspect_ratio_information;
int frame_rate_code;
- int frame_duration;
int progressive_sequence;
int repeat_first_field;
int progressive_frame;
- int bitrate;
+ /*int bitrate; */
uint32_t frame_centre_horizontal_offset;
uint32_t frame_centre_vertical_offset;
uint32_t video_format;
@@ -222,7 +226,7 @@ extern mc_functions_t mc_functions_altivec;
extern mc_functions_t mc_functions_mlib;
/* slice.c */
-void slice_process (picture_t *picture, uint8_t code, uint8_t * buffer);
+int slice_process (picture_t *picture, uint8_t code, uint8_t * buffer);
/* stats.c */
void stats_header (uint8_t code, uint8_t * buffer);
diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c
index 4abdf8a4a..3cd547f24 100644
--- a/src/libmpeg2/slice.c
+++ b/src/libmpeg2/slice.c
@@ -968,7 +968,7 @@ do { \
NEEDBITS (bit_buf, bits, bit_ptr); \
continue; \
default: /* end of slice, or error */ \
- return; \
+ return (mba >= picture->last_mba); \
} \
} \
DUMPBITS (bit_buf, bits, tab->len); \
@@ -1497,15 +1497,15 @@ do { \
dest[2] += 4 * stride; \
} while (0); \
if (! (picture->mpeg1)) \
- return; \
+ return (mba >= picture->last_mba); \
picture->v_offset += 16; \
if (picture->v_offset >= picture->coded_picture_height) \
- return; \
+ return 1; \
offset = 0; \
} \
} while (0)
-void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
+int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
{
#define bit_buf (picture->bitstream_buf)
#define bits (picture->bitstream_bits)
@@ -1515,8 +1515,10 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
uint8_t * dest[3];
int offset;
uint8_t ** forward_ref[2];
+ int mba;
stride = picture->coded_picture_width;
+ mba = (code-1) * (stride >> 4);
offset = (code - 1) * stride * 4;
picture->v_offset = (code - 1) * 16;
@@ -1592,6 +1594,7 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
NEEDBITS (bit_buf, bits, bit_ptr);
GET_MACROBLOCK_ADDRESS_INCREMENT (offset);
+ mba += offset;
offset <<= 4;
while (1) {
@@ -1744,6 +1747,7 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision+7);
}
+ mba++;
offset += 16;
CHECK_DISPLAY;
@@ -1764,6 +1768,7 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
else
MOTION (motion_fi_zero, MACROBLOCK_MOTION_FORWARD);
+ mba++;
offset += 16;
CHECK_DISPLAY;
} while (--mba_inc);
@@ -1776,6 +1781,7 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
else
MOTION (motion_fi_reuse, macroblock_modes);
+ mba++;
offset += 16;
CHECK_DISPLAY;
} while (--mba_inc);
@@ -1785,4 +1791,7 @@ void slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
#undef bit_buf
#undef bits
#undef bit_ptr
+
+ return (mba >= picture->last_mba);
+
}
diff --git a/src/libmpeg2/xine_decoder.c b/src/libmpeg2/xine_decoder.c
index 2f6a338bb..da5415253 100644
--- a/src/libmpeg2/xine_decoder.c
+++ b/src/libmpeg2/xine_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
* This file is part of xine, a unix video player.
*
@@ -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/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.21 2002/02/09 07:13:23 guenter Exp $
*
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
@@ -36,69 +36,74 @@
#include "buffer.h"
#include "xine_internal.h"
+#define LOG
+
typedef struct mpeg2dec_decoder_s {
video_decoder_t video_decoder;
mpeg2dec_t mpeg2;
vo_instance_t *video_out;
- /*int mpeg_file;*/ /* debugging purposes only */
+ pthread_mutex_t lock; /* mutex for async flush */
} mpeg2dec_decoder_t;
static int mpeg2dec_can_handle (video_decoder_t *this_gen, int buf_type) {
return ((buf_type & 0xFFFF0000) == BUF_VIDEO_MPEG) ;
}
-
static void mpeg2dec_init (video_decoder_t *this_gen, vo_instance_t *video_out) {
mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen;
+ printf ("libmpeg2: init \n");
mpeg2_init (&this->mpeg2, video_out);
video_out->open(video_out);
this->video_out = video_out;
-
- /* debugging purposes */
- /*this->mpeg_file = open ("/tmp/video.mpv",O_CREAT | O_WRONLY | O_TRUNC, 0644);*/
+ pthread_mutex_init (&this->lock, NULL);
}
static void mpeg2dec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen;
+ printf ("libmpeg2: decode_data...\n");
+
+ pthread_mutex_lock (&this->lock);
+
if (buf->decoder_info[0] == 0) {
mpeg2_find_sequence_header (&this->mpeg2, buf->content, buf->content + buf->size);
} else {
- /* debugging purposes */
- /* write (this->mpeg_file, buf->content, buf->size); */
-
mpeg2_decode_data (&this->mpeg2, buf->content, buf->content + buf->size,
- buf->PTS, buf->SCR);
-
- this->video_out->decoder_started(this->video_out);
+ buf->pts, buf->scr);
}
+ pthread_mutex_unlock (&this->lock);
+
+ printf ("libmpeg2: decode_data...done\n");
}
static void mpeg2dec_flush (video_decoder_t *this_gen) {
mpeg2dec_decoder_t *this = (mpeg2dec_decoder_t *) this_gen;
+ pthread_mutex_lock (&this->lock);
+ printf ("libmpeg2: flush\n");
+
mpeg2_flush (&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;
+ printf ("libmpeg2: close\n");
+
mpeg2_close (&this->mpeg2);
this->video_out->close(this->video_out);
- /* debugging purposes */
- /*
- close (this->mpeg_file);
- this->mpeg_file = -1;
- */
+ pthread_mutex_destroy (&this->lock);
+
}
static char *mpeg2dec_get_id(void) {
diff --git a/src/libspucc/xine_decoder.c b/src/libspucc/xine_decoder.c
index 07fa47dc3..cfde5387b 100644
--- a/src/libspucc/xine_decoder.c
+++ b/src/libspucc/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.3 2002/01/07 23:04:26 cvogler Exp $
+ * $Id: xine_decoder.c,v 1.4 2002/02/09 07:13:23 guenter Exp $
*
* closed caption spu decoder. receive data by events.
*
@@ -276,7 +276,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if(this->cc_cfg.can_cc) {
decode_cc(this->ccdec, buf->content, buf->size,
- buf->PTS, buf->SCR);
+ buf->pts, buf->scr);
}
}
pthread_mutex_unlock(&this->cc_mutex);
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index e92586a52..ee824d9d1 100644
--- a/src/libspudec/xine_decoder.c
+++ b/src/libspudec/xine_decoder.c
@@ -19,7 +19,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.55 2002/01/15 20:22:43 jcdutton Exp $
+ * $Id: xine_decoder.c,v 1.56 2002/02/09 07:13:23 guenter Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -179,6 +179,7 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
// spu_overlay_event_t *event;
// spu_object_t *object;
// vo_overlay_t *overlay;
+ video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
int pending = 1;
this->cur_seq = &this->spu_stream_state[stream_id].ra_seq;
@@ -255,9 +256,10 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
//if (this->state.menu == 0) {
if (1) {
/* Subtitle */
- if( this->menu_handle < 0 )
- this->menu_handle = this->vo_out->overlay_source->get_handle(this->vo_out->overlay_source,1);
-
+ if( this->menu_handle < 0 ) {
+ this->menu_handle = ovl_instance->get_handle(ovl_instance,1);
+ }
+
if( this->menu_handle < 0 ) {
printf("libspudec: No video_overlay handles left for menu\n");
return;
@@ -301,9 +303,10 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
*/
} else {
/* Menu */
- if( this->menu_handle < 0 )
- this->menu_handle = this->vo_out->overlay_source->get_handle(this->vo_out->overlay_source,1);
-
+ if( this->menu_handle < 0 ) {
+ this->menu_handle = ovl_instance->get_handle (ovl_instance, 1);
+ }
+
if( this->menu_handle < 0 ) {
printf("libspudec: No video_overlay handles left for menu\n");
return;
@@ -330,7 +333,7 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
+ (this->state.delay*1000);
printf("libspudec: vpts current time estimation around discontinuity\n");
}
- this->vo_out->overlay_source->add_event(this->vo_out->overlay_source, (void *)&this->event);
+ ovl_instance->add_event(ovl_instance, (void *)&this->event);
} else {
pending = 0;
}
@@ -339,12 +342,13 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
}
static void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
- uint8_t *p;
- uint32_t packet_len;
- uint32_t stream_id;
- uint32_t header_len;
- pci_t *pci;
- dsi_t *dsi;
+ uint8_t *p;
+ uint32_t packet_len;
+ uint32_t stream_id;
+ uint32_t header_len;
+ pci_t *pci;
+ dsi_t *dsi;
+ video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
p = buf->content;
if (p[0] || p[1] || (p[2] != 1)) {
@@ -416,7 +420,7 @@ static void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
/* Hide menu spu between menus */
printf("libspudec:nav:SHOULD HIDE SPU here\n");
if( this->menu_handle < 0 ) {
- this->menu_handle = this->vo_out->overlay_source->get_handle(this->vo_out->overlay_source,1);
+ this->menu_handle = ovl_instance->get_handle(ovl_instance,1);
}
if( this->menu_handle >= 0 ) {
metronom_t *metronom = this->xine->metronom;
@@ -427,7 +431,7 @@ static void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
instead as an aproximation.
*/
this->event.vpts = metronom->got_spu_packet(metronom, pci->pci_gi.vobu_s_ptm, 0, 0);
- this->vo_out->overlay_source->add_event(this->vo_out->overlay_source, (void *)&this->event);
+ ovl_instance->add_event(ovl_instance, (void *)&this->event);
} else {
printf("libspudec: No video_overlay handles left for menu\n");
}
@@ -483,9 +487,9 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if ( this->spu_stream_state[stream_id].stream_filter == 0)
return;
- if (buf->PTS) {
+ if (buf->pts) {
metronom_t *metronom = this->xine->metronom;
- uint32_t vpts = metronom->got_spu_packet(metronom, buf->PTS, 0, buf->SCR);
+ uint32_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0, buf->scr);
if (vpts < this->buf_pts) {
/* FIXME: Don't do this yet,
@@ -496,7 +500,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
}
this->spu_stream_state[stream_id].vpts = vpts; /* Show timer */
- this->spu_stream_state[stream_id].pts = buf->PTS; /* Required to match up with NAV packets */
+ this->spu_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */
}
/* if (this->ra_complete) {
@@ -528,19 +532,20 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
}
static void spudec_close (spu_decoder_t *this_gen) {
- spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
- int i;
+ spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+ int i;
+ video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
if( this->menu_handle >= 0 )
- this->vo_out->overlay_source->free_handle(this->vo_out->overlay_source,
- this->menu_handle);
+ ovl_instance->free_handle(ovl_instance,
+ this->menu_handle);
this->menu_handle = -1;
for (i=0; i < MAX_STREAMS; i++) {
if( this->spu_stream_state[i].overlay_handle >= 0 )
- this->vo_out->overlay_source->free_handle(this->vo_out->overlay_source,
- this->spu_stream_state[i].overlay_handle);
+ ovl_instance->free_handle(ovl_instance,
+ this->spu_stream_state[i].overlay_handle);
this->spu_stream_state[i].overlay_handle = -1;
}
}
@@ -566,11 +571,15 @@ static void spudec_nextseq(spudec_decoder_t* this) {
static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
xine_spu_event_t *event = (xine_spu_event_t *) event_gen;
+ video_overlay_instance_t *ovl_instance;
if((!this) || (!event)) {
return;
}
+ if (this->vo_out)
+ ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
+
switch (event->event.type) {
case XINE_EVENT_SPU_BUTTON:
{
@@ -650,7 +659,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
overlay_event->event_type = EVENT_HIDE_MENU;
}
overlay_event->vpts = 0; /* Activate it NOW */
- this->vo_out->overlay_source->add_event(this->vo_out->overlay_source, (void *)overlay_event);
+ ovl_instance->add_event (ovl_instance, (void *)overlay_event);
}
break;
case XINE_EVENT_SPU_CLUT:
diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c
index 2fb5725a9..90eb173cf 100644
--- a/src/libsputext/xine_decoder.c
+++ b/src/libsputext/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.11 2002/01/08 16:47:56 cvogler Exp $
+ * $Id: xine_decoder.c,v 1.12 2002/02/09 07:13:23 guenter Exp $
*
* code based on mplayer module:
*
@@ -791,14 +791,14 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
} else {
- uint32_t pts, pts_end;
- int32_t pts_factor;
+ int64_t pts, pts_end;
+ int64_t pts_factor;
int frame_num;
subtitle_t *subtitle;
subtitle = NULL;
- pts = buf->PTS;
+ pts = buf->pts;
pts_end = pts;
frame_num = buf->decoder_info[1];
@@ -820,7 +820,10 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if (subtitle->start > frame_num)
return;
+ /* FIXME FIXME FIXME
pts_factor = this->xine->metronom->get_video_rate (this->xine->metronom);
+ */
+ pts_factor = 3000;
pts += this->xine->metronom->video_wrap_offset;
diff --git a/src/libvorbis/xine_decoder.c b/src/libvorbis/xine_decoder.c
index cd0517e29..4e85b0678 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.5 2002/01/05 21:54:17 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.6 2002/02/09 07:13:24 guenter Exp $
*
* (ogg/)vorbis audio decoder plugin (libvorbis wrapper) for xine
*/
@@ -41,7 +41,7 @@
typedef struct vorbis_decoder_s {
audio_decoder_t audio_decoder;
- uint32_t pts;
+ int64_t pts;
ao_instance_t *audio_out;
int output_sampling_rate;
@@ -204,12 +204,12 @@ static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
}
}
- audio_buffer->vpts = buf->PTS;
+ audio_buffer->vpts = buf->pts;
audio_buffer->num_frames = bout;
this->audio_out->put_buffer (this->audio_out, audio_buffer);
- buf->PTS=0;
+ buf->pts=0;
vorbis_synthesis_read(&this->vd,bout);
}
}
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index 0d8f123d2..3c9dacd51 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.62 2002/01/22 01:55:12 miguelfreitas Exp $
+ * $Id: w32codec.c,v 1.63 2002/02/09 07:13:24 guenter Exp $
*
* routines for using w32 codecs
* DirectShow support by Miguel Freitas (Nov/2001)
@@ -127,11 +127,11 @@ typedef struct w32a_decoder_s {
unsigned char *buf;
int size;
- uint32_t pts;
- uint32_t scr;
+ int64_t pts;
+ int64_t scr;
/* these are used for pts estimation */
- uint32_t lastpts, sumpts, sumsize;
+ int64_t lastpts, sumpts, sumsize;
unsigned char *outbuf;
int outsize;
@@ -633,9 +633,10 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
this->bih.biHeight,
42,
IMGFMT_YUY2,
- this->video_step,
VO_BOTH_FIELDS);
+ img->duration = this->video_step;
+
if (this->outfmt==IMGFMT_YUY2)
img_buffer = img->base[0];
@@ -717,8 +718,8 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
}
}
- img->PTS = buf->PTS;
- img->SCR = buf->SCR;
+ img->pts = buf->pts;
+ img->scr = buf->scr;
if(ret || this->skipframes) {
if( !this->skipframes )
printf("w32codec: Error decompressing frame, err=%ld\n", (long)ret);
@@ -976,8 +977,8 @@ static void w32a_decode_audio (w32a_decoder_t *this,
unsigned char *data,
uint32_t size,
int frame_end,
- uint32_t pts,
- uint32_t scr) {
+ int64_t pts,
+ int64_t scr) {
static ACMSTREAMHEADER ash;
HRESULT hr;
@@ -1128,7 +1129,7 @@ static void w32a_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
w32a_decode_audio (this, buf->content, buf->size,
buf->decoder_info[0]==2,
- buf->PTS, buf->SCR);
+ buf->pts, buf->scr);
}
}
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c
index 8646d2864..2c819b86e 100644
--- a/src/video_out/alphablend.c
+++ b/src/video_out/alphablend.c
@@ -34,6 +34,7 @@
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
#include <inttypes.h>
#include "video_out.h"
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index 0c073845c..8dbbd0f46 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.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_fb.c,v 1.4 2002/01/22 01:43:13 miguelfreitas Exp $
+ * $Id: video_out_fb.c,v 1.5 2002/02/09 07:13:24 guenter Exp $
*
* video_out_fb.c, frame buffer xine driver by Miguel Freitas
*
@@ -154,7 +154,7 @@ static uint32_t fb_get_capabilities (vo_driver_t *this_gen) {
static void fb_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
fb_frame_t *frame = (fb_frame_t *) vo_img ;
- fb_driver_t *this = (fb_driver_t *) vo_img->instance->driver;
+ fb_driver_t *this = (fb_driver_t *) vo_img->driver;
xine_profiler_start_count (this->prof_yuv2rgb);
@@ -176,7 +176,7 @@ static void fb_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
static void fb_frame_field (vo_frame_t *vo_img, int which_field) {
fb_frame_t *frame = (fb_frame_t *) vo_img ;
- fb_driver_t *this = (fb_driver_t *) vo_img->instance->driver;
+ fb_driver_t *this = (fb_driver_t *) vo_img->driver;
switch (which_field) {
case VO_TOP_FIELD:
@@ -226,6 +226,7 @@ static vo_frame_t *fb_alloc_frame (vo_driver_t *this_gen) {
frame->vo_frame.copy = fb_frame_copy;
frame->vo_frame.field = fb_frame_field;
frame->vo_frame.dispose = fb_frame_dispose;
+ frame->vo_frame.driver = this_gen;
return (vo_frame_t *) frame;
}
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 8a2993de9..23e690719 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.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_opengl.c,v 1.4 2002/01/23 23:27:10 f1rmb Exp $
+ * $Id: video_out_opengl.c,v 1.5 2002/02/09 07:13:24 guenter Exp $
*
* video_out_glut.c, glut based OpenGL rendering interface for xine
* Matthias Hopf <mat@mshopf.de>
@@ -231,7 +231,7 @@ static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) {
static void opengl_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
- opengl_driver_t *this = (opengl_driver_t *) vo_img->instance->driver;
+ opengl_driver_t *this = (opengl_driver_t *) vo_img->driver;
/*fprintf (stderr, "*** frame_copy\n"); */
xine_profiler_start_count (this->prof_yuv2rgb);
@@ -301,12 +301,13 @@ static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) {
pthread_mutex_init (&frame->vo_frame.mutex, NULL);
/*
- * supply required functions
+ * supply required functions/fields
*/
frame->vo_frame.copy = opengl_frame_copy;
frame->vo_frame.field = opengl_frame_field;
frame->vo_frame.dispose = opengl_frame_dispose;
+ frame->vo_frame.driver = this_gen;
return (vo_frame_t *) frame;
}
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index 87a042c61..ce34a6b1c 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.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_syncfb.c,v 1.52 2002/01/24 23:09:53 guenter Exp $
+ * $Id: video_out_syncfb.c,v 1.53 2002/02/09 07:13:24 guenter Exp $
*
* video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine
*
@@ -327,10 +327,6 @@ static void write_frame_sfb(syncfb_driver_t* this, syncfb_frame_t* frame)
}
break;
- case IMGFMT_RGB:
- printf("video_out_syncfb: error. (RGB565 not yet supported)\n");
- break;
-
default:
printf("video_out_syncfb: error. (unknown frame format)\n");
break;
@@ -545,10 +541,6 @@ static void syncfb_adapt_to_output_area(syncfb_driver_t* this,
this->syncfb_config.src_palette = VIDEO_PALETTE_YUV422;
break;
- case IMGFMT_RGB:
- this->syncfb_config.src_palette = VIDEO_PALETTE_RGB565;
- break;
-
default:
this->syncfb_config.src_palette = 0;
break;
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 6d5ccb918..61e9b3fb2 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.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_xshm.c,v 1.55 2002/01/15 20:35:24 jcdutton Exp $
+ * $Id: video_out_xshm.c,v 1.56 2002/02/09 07:13:24 guenter Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -349,7 +349,7 @@ static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) {
static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
xshm_frame_t *frame = (xshm_frame_t *) vo_img ;
- xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver;
+ xshm_driver_t *this = (xshm_driver_t *) vo_img->driver;
xine_profiler_start_count (this->prof_yuv2rgb);
@@ -371,7 +371,7 @@ static void xshm_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
xshm_frame_t *frame = (xshm_frame_t *) vo_img ;
- xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver;
+ xshm_driver_t *this = (xshm_driver_t *) vo_img->driver;
switch (which_field) {
case VO_TOP_FIELD:
@@ -391,7 +391,7 @@ static void xshm_frame_field (vo_frame_t *vo_img, int which_field) {
static void xshm_frame_dispose (vo_frame_t *vo_img) {
xshm_frame_t *frame = (xshm_frame_t *) vo_img ;
- xshm_driver_t *this = (xshm_driver_t *) vo_img->instance->driver;
+ xshm_driver_t *this = (xshm_driver_t *) vo_img->driver;
if (frame->image) {
XLockDisplay (this->display);
@@ -417,13 +417,14 @@ static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) {
pthread_mutex_init (&frame->vo_frame.mutex, NULL);
/*
- * supply required functions
+ * supply required functions/fields
*/
frame->vo_frame.copy = xshm_frame_copy;
frame->vo_frame.field = xshm_frame_field;
frame->vo_frame.dispose = xshm_frame_dispose;
-
+ frame->vo_frame.driver = this_gen;
+
return (vo_frame_t *) frame;
}
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 68fd7b15d..30aadd009 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.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_xv.c,v 1.90 2002/01/24 23:09:54 guenter Exp $
+ * $Id: video_out_xv.c,v 1.91 2002/02/09 07:13:24 guenter Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -97,7 +97,6 @@ struct xv_driver_s {
Display *display;
int screen;
Drawable drawable;
- unsigned int xv_format_rgb;
unsigned int xv_format_yv12;
unsigned int xv_format_yuy2;
XVisualInfo vinfo;
@@ -184,7 +183,7 @@ static void xv_frame_field (vo_frame_t *vo_img, int which_field) {
static void xv_frame_dispose (vo_frame_t *vo_img) {
xv_frame_t *frame = (xv_frame_t *) vo_img ;
- xv_driver_t *this = (xv_driver_t *) vo_img->instance->driver;
+ xv_driver_t *this = (xv_driver_t *) vo_img->driver;
if (frame->image) {
XLockDisplay (this->display);
@@ -220,6 +219,8 @@ static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) {
frame->vo_frame.field = xv_frame_field;
frame->vo_frame.dispose = xv_frame_dispose;
+ frame->vo_frame.driver = this_gen;
+
return (vo_frame_t *) frame;
}
@@ -258,9 +259,6 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo,
case IMGFMT_YV12:
xv_format = this->xv_format_yv12;
break;
- case IMGFMT_RGB:
- xv_format = this->xv_format_rgb;
- break;
case IMGFMT_YUY2:
xv_format = this->xv_format_yuy2;
break;
@@ -842,11 +840,15 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
+ printf ("video_out_xv: xv_display_frame...\n");
+
if (this->expecting_event) {
frame->vo_frame.displayed (&frame->vo_frame);
this->expecting_event--;
+ printf ("video_out_xv: xv_display_frame... not displayed, waiting for completion event\n");
+
} else {
xv_add_recent_frame (this, frame);
this->cur_frame = frame;
@@ -862,8 +864,12 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
if (this->deinterlace_enabled && this->deinterlace_method)
xv_deinterlace_frame (this);
+ printf ("video_out_xv: xv_display_frame... lock display...\n");
+
XLockDisplay (this->display);
+ printf ("video_out_xv: xv_display_frame... lock display...locked\n");
+
if (this->use_shm) {
XvShmPutImage(this->display, this->xv_port,
this->drawable, this->gc, this->cur_frame->image,
@@ -887,6 +893,8 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
XUnlockDisplay (this->display);
}
+
+ printf ("video_out_xv: xv_display_frame... done\n");
}
static int xv_get_property (vo_driver_t *this_gen, int property) {
@@ -1450,7 +1458,6 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->xv_format_yv12 = 0;
this->xv_format_yuy2 = 0;
- this->xv_format_rgb = 0;
for(i = 0; i < formats; i++) {
#ifdef XV_LOG
@@ -1466,10 +1473,6 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->xv_format_yuy2 = fo[i].id;
this->capabilities |= VO_CAP_YUY2;
printf("video_out_xv: this adaptor supports the yuy2 format.\n");
- } else if (fo[i].id == IMGFMT_RGB) {
- this->xv_format_rgb = fo[i].id;
- this->capabilities |= VO_CAP_RGB;
- printf("video_out_xv: this adaptor supports the rgb format.\n");
}
}
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index fa6a3582b..169919f2b 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.57 2001/12/11 15:30:06 miguelfreitas Exp $
+ * $Id: audio_decoder.c,v 1.58 2002/02/09 07:13:24 guenter Exp $
*
*
* functions that implement audio decoding
@@ -81,14 +81,12 @@ void *audio_decoder_loop (void *this_gen) {
this->audio_finished = 0;
pthread_mutex_unlock (&this->finished_lock);
- this->metronom->audio_stream_start (this->metronom);
+ this->metronom->expect_audio_discontinuity (this->metronom);
break;
case BUF_CONTROL_END:
- this->metronom->audio_stream_end (this->metronom);
-
if (this->cur_audio_decoder_plugin) {
this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
this->cur_audio_decoder_plugin = NULL;
@@ -124,23 +122,12 @@ void *audio_decoder_loop (void *this_gen) {
running = 0;
break;
- case BUF_VIDEO_FILL:
- break;
-
case BUF_CONTROL_NOP:
break;
case BUF_CONTROL_DISCONTINUITY:
- printf ("audio_decoder: BUF_CONTROL_DISCONTINUITY is deprecated\n");
- break;
-
- case BUF_CONTROL_AVSYNC_RESET:
printf ("audio_decoder: discontinuity ahead\n");
- if (this->cur_audio_decoder_plugin) {
- this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin);
- }
-
this->metronom->expect_audio_discontinuity (this->metronom);
break;
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index c1c099fe7..2eca26b8f 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.39 2001/12/24 12:36:19 miguelfreitas Exp $
+ * $Id: audio_out.c,v 1.40 2002/02/09 07:13:24 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -237,7 +237,6 @@ static void *ao_loop (void *this_gen) {
audio_buffer_t *buf;
int32_t gap;
int delay;
- uint8_t *data;
uint32_t cur_time;
int num_output_frames ;
int paused_wait;
@@ -474,7 +473,7 @@ static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) {
if ( buf->vpts<this->last_audio_vpts) {
/* reject buffer */
- printf ("audio_out: rejected buffer vpts=%d, last_audio_vpts=%d\n",
+ printf ("audio_out: rejected buffer vpts=%lld, last_audio_vpts=%lld\n",
buf->vpts, this->last_audio_vpts);
fifo_append (this->free_fifo, buf);
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index ab219a648..23e987560 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.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: audio_out.h,v 1.22 2001/11/27 00:00:35 jcdutton Exp $
+ * $Id: audio_out.h,v 1.23 2002/02/09 07:13:24 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -31,6 +31,9 @@ extern "C" {
#if defined(XINE_COMPILE)
#include "metronom.h"
#include "configfile.h"
+#else
+#include <xine/metronom.h>
+#include <xine/configfile.h>
#endif
@@ -133,8 +136,8 @@ struct audio_buffer_s {
int mem_size;
int num_frames;
- uint32_t vpts;
- uint32_t scr;
+ int64_t vpts;
+ int64_t scr;
uint32_t frame_header_count;
uint32_t first_access_unit;
};
@@ -191,7 +194,7 @@ struct ao_instance_s {
int32_t output_frame_rate, input_frame_rate;
double frame_rate_factor;
uint32_t num_channels;
- uint32_t last_audio_vpts;
+ int64_t last_audio_vpts;
int resample_conf;
int force_rate; /* force audio output rate to this value if non-zero */
int do_resample;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index f63327e23..685faf347 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.32 2002/01/15 17:30:51 miguelfreitas Exp $
+ * $Id: buffer.h,v 1.33 2002/02/09 07:13:24 guenter Exp $
*
*
* contents:
@@ -65,12 +65,10 @@ extern "C" {
#define BUF_CONTROL_START 0x01000000
#define BUF_CONTROL_END 0x01010000
#define BUF_CONTROL_QUIT 0x01020000
-#define BUF_CONTROL_DISCONTINUITY 0x01030000 /* deprecated */
+#define BUF_CONTROL_DISCONTINUITY 0x01030000 /* former AVSYNC_RESET */
#define BUF_CONTROL_NOP 0x01040000
#define BUF_CONTROL_AUDIO_CHANNEL 0x01050000
#define BUF_CONTROL_SPU_CHANNEL 0x01060000
-#define BUF_CONTROL_AVSYNC_RESET 0x01070000
-#define BUF_CONTROL_FLUSH 0x01080000
/* video buffer types: (please keep in sync with buffer_types.c) */
@@ -90,7 +88,6 @@ extern "C" {
#define BUF_VIDEO_ATIVCR2 0x020c0000
#define BUF_VIDEO_I263 0x020d0000
#define BUF_VIDEO_RV10 0x020e0000
-#define BUF_VIDEO_FILL 0x020f0000
#define BUF_VIDEO_RGB 0x02100000
#define BUF_VIDEO_YUY2 0x02110000
#define BUF_VIDEO_JPEG 0x02120000
@@ -142,13 +139,13 @@ struct buf_element_s {
buf_element_t *next;
unsigned char *mem;
- unsigned char *content; /* start of raw content in pMem (without header etc) */
+ unsigned char *content; /* start of raw content in pMem (without header etc) */
- int32_t size ; /* size of _content_ */
+ int32_t size ; /* size of _content_ */
int32_t max_size;
uint32_t type;
- uint32_t PTS; /* presentation time stamp, used for a/v sync */
- uint32_t SCR; /* system clock reference, used for discont. detection */
+ int64_t pts; /* presentation time stamp, used for a/v sync */
+ int64_t scr; /* system clock reference, used for discont. detection */
off_t input_pos; /* remember where this buf came from in the input source */
int input_time;/* time offset in seconds from beginning of stream */
uint32_t decoder_info[4]; /* additional decoder flags and other dec-spec. stuff */
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 994cacd97..f9b66892f 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.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: buffer_types.c,v 1.9 2002/01/15 17:30:51 miguelfreitas Exp $
+ * $Id: buffer_types.c,v 1.10 2002/02/09 07:13:24 guenter Exp $
*
*
* contents:
@@ -215,13 +215,6 @@ static video_db_t video_db[] = {
},
{
{
- 0
- },
- BUF_VIDEO_FILL,
- ""
-},
-{
- {
mmioFOURCC('r','a','w',' '),
0
},
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index f2d4e2875..8dd7d81f3 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.52 2002/01/28 17:28:39 miguelfreitas Exp $
+ * $Id: metronom.c,v 1.53 2002/02/09 07:13:24 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -37,41 +37,20 @@
#include "xine_internal.h"
#include "metronom.h"
#include "xineutils.h"
+#include "video_out.h"
-#define MAX_PTS_TOLERANCE 5000
-#define MAX_VIDEO_DELTA 1600
#define MAX_AUDIO_DELTA 1600
#define AUDIO_SAMPLE_NUM 32768
-#define WRAP_START_TIME 100000
#define WRAP_THRESHOLD 120000
-#define SCR_DISCONTINUITY 60000
-#define MAX_NUM_WRAP_DIFF 100
+#define MAX_NUM_WRAP_DIFF 10
#define MAX_SCR_PROVIDERS 10
#define PREBUFFER_PTS_OFFSET 30000
+#define VIDEO_DRIFT_TOLERANCE 45000
-#ifdef __GNUC__
-#define LOG_MSG_STDERR(xine, message, args...) { \
- xine_log((xine_t*)xine, XINE_LOG_METRONOM, message, ##args); \
- fprintf(stderr, message, ##args); \
- }
-#define LOG_MSG(xine, message, args...) { \
- xine_log((xine_t*)xine, XINE_LOG_METRONOM, message, ##args); \
- printf(message, ##args); \
- }
-#else
-#define LOG_MSG_STDERR(xine, ...) { \
- xine_log((xine_t*)xine, XINE_LOG_METRONOM, __VA_ARGS__); \
- fprintf(stderr, __VA_ARGS__); \
- }
-#define LOG_MSG(xine, ...) { \
- xine_log((xine_t*)xine, XINE_LOG_METRONOM, __VA_ARGS__); \
- printf(__VA_ARGS__); \
- }
-#endif
+#define METRONOM_REPORT
-/*
#define METRONOM_LOG
-*/
+
/*
* ****************************************
@@ -84,7 +63,7 @@ typedef struct unixscr_s {
scr_plugin_t scr;
struct timeval cur_time;
- uint32_t cur_pts;
+ int64_t cur_pts;
double speed_factor;
pthread_mutex_t lock;
@@ -99,7 +78,7 @@ static int unixscr_get_priority (scr_plugin_t *scr) {
static void unixscr_set_pivot (unixscr_t *this) {
struct timeval tv;
- uint32_t pts;
+ int64_t pts;
double pts_calc;
gettimeofday(&tv, NULL);
@@ -130,7 +109,7 @@ static int unixscr_set_speed (scr_plugin_t *scr, int speed) {
return speed;
}
-static void unixscr_adjust (scr_plugin_t *scr, uint32_t vpts) {
+static void unixscr_adjust (scr_plugin_t *scr, int64_t vpts) {
unixscr_t *this = (unixscr_t*) scr;
struct timeval tv;
@@ -144,7 +123,7 @@ static void unixscr_adjust (scr_plugin_t *scr, uint32_t vpts) {
pthread_mutex_unlock (&this->lock);
}
-static void unixscr_start (scr_plugin_t *scr, uint32_t start_vpts) {
+static void unixscr_start (scr_plugin_t *scr, int64_t start_vpts) {
unixscr_t *this = (unixscr_t*) scr;
pthread_mutex_lock (&this->lock);
@@ -155,11 +134,11 @@ static void unixscr_start (scr_plugin_t *scr, uint32_t start_vpts) {
pthread_mutex_unlock (&this->lock);
}
-static uint32_t unixscr_get_current (scr_plugin_t *scr) {
+static int64_t unixscr_get_current (scr_plugin_t *scr) {
unixscr_t *this = (unixscr_t*) scr;
struct timeval tv;
- uint32_t pts;
+ int64_t pts;
double pts_calc;
pthread_mutex_lock (&this->lock);
@@ -202,14 +181,17 @@ static scr_plugin_t* unixscr_init () {
*/
-static void metronom_start_clock (metronom_t *this, uint32_t pts) {
+static void metronom_start_clock (metronom_t *this, int64_t pts) {
scr_plugin_t** scr;
+
+ printf ("metronom: start_clock (at %lld)\n", pts);
+
for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++)
if (*scr) (*scr)->start(*scr, pts);
}
-static uint32_t metronom_get_current_time (metronom_t *this) {
+static int64_t metronom_get_current_time (metronom_t *this) {
return this->scr_master->get_current(this->scr_master);
}
@@ -228,7 +210,7 @@ static void metronom_resume_clock(metronom_t *this) {
-static void metronom_adjust_clock(metronom_t *this, uint32_t desired_pts) {
+static void metronom_adjust_clock(metronom_t *this, int64_t desired_pts) {
this->scr_master->adjust(this->scr_master, desired_pts);
}
@@ -245,179 +227,8 @@ static int metronom_set_speed (metronom_t *this, int speed) {
return true_speed;
}
-/*
- * virtual pts calculation
- */
-
-static void metronom_video_stream_start (metronom_t *this) {
-
- pthread_mutex_lock (&this->lock);
-
- LOG_MSG(this->xine, _("metronom: video stream start...\n"));
-
- if (this->video_stream_running) {
- LOG_MSG(this->xine, _("metronom: video stream start ignored\n"));
- pthread_mutex_unlock (&this->lock);
- return;
- }
-
- /*this->pts_per_frame = 3000; */
- this->avg_frame_duration = this->pts_per_frame;
-
- this->video_vpts = PREBUFFER_PTS_OFFSET;
-
- this->last_video_pts = 0;
- this->last_video_scr = 0;
- this->num_video_vpts_guessed = 0;
-
- /* video_wrap_offset will be updated with the first pts */
- /* this->video_wrap_offset = PREBUFFER_PTS_OFFSET; */
- this->wrap_diff_counter = 0;
-
- this->video_stream_running = 1;
- this->video_stream_starting = 1;
-
- this->video_discontinuity = 0;
- this->video_discontinuity_count = 0;
-
- if (this->have_audio) {
- /*while (!this->audio_stream_running) {*/
- if (!this->audio_stream_running) {
- LOG_MSG(this->xine, _("metronom: waiting for audio to start...\n"));
- pthread_cond_wait (&this->audio_started, &this->lock);
- }
- }
- pthread_cond_signal (&this->video_started);
-
- pthread_mutex_unlock (&this->lock);
-
- metronom_start_clock (this, 0);
-}
-
-
-static void metronom_video_stream_end (metronom_t *this) {
-
- pthread_mutex_lock (&this->lock);
-
- LOG_MSG(this->xine, _("metronom: video stream end\n"));
-
- if (!this->video_stream_running) {
- LOG_MSG(this->xine, _("metronom: video stream end ignored\n"));
- pthread_mutex_unlock (&this->lock);
- return;
- }
-
- this->video_stream_running = 0;
-
- if (this->have_audio) {
- /* while (this->audio_stream_running) { */
- if (this->audio_stream_running) {
- LOG_MSG(this->xine, _("metronom: waiting for audio to end...\n"));
- pthread_cond_wait (&this->audio_ended, &this->lock);
- }
- }
- pthread_cond_signal (&this->video_ended);
-
-
- pthread_mutex_unlock (&this->lock);
-}
-
-static void metronom_audio_stream_start (metronom_t *this) {
-
- pthread_mutex_lock (&this->lock);
-
- LOG_MSG(this->xine, _("metronom: audio stream start...\n"));
-
- if (this->audio_stream_running) {
- LOG_MSG(this->xine, _("metronom: audio stream start ignored\n"));
- pthread_mutex_unlock (&this->lock);
- return;
- }
-
- this->audio_vpts = PREBUFFER_PTS_OFFSET;
-
- this->audio_pts_delta = 0;
-
- this->num_audio_samples_guessed = 1;
- this->last_audio_pts = 0;
- this->last_audio_scr = 0;
-
- /* audio_wrap_offset will be updated with the first pts */
- /* this->audio_wrap_offset = PREBUFFER_PTS_OFFSET; */
- this->wrap_diff_counter = 0;
-
- this->audio_stream_running = 1;
- this->audio_stream_starting = 1;
-
- this->audio_discontinuity = 0;
- this->audio_discontinuity_count = 0;
-
- /*while (!this->video_stream_running) { */
- if (!this->video_stream_running) {
- LOG_MSG(this->xine, _("metronom: waiting for video to start...\n"));
- pthread_cond_wait (&this->video_started, &this->lock);
- }
-
- pthread_cond_signal (&this->audio_started);
-
- pthread_mutex_unlock (&this->lock);
-
- LOG_MSG(this->xine, _("metronom: audio stream start...done\n"));
-
- metronom_start_clock (this, 0);
-}
-
-static void metronom_audio_stream_end (metronom_t *this) {
-
- pthread_mutex_lock (&this->lock);
-
- LOG_MSG(this->xine, _("metronom: audio stream end\n"));
- if (!this->audio_stream_running) {
- LOG_MSG(this->xine, _("metronom: audio stream end ignored\n"));
- pthread_mutex_unlock (&this->lock);
- return;
- }
-
- this->audio_stream_running = 0;
-
- /* while (this->video_stream_running) { */
- if (this->video_stream_running) {
- LOG_MSG(this->xine, _("metronom: waiting for video to end...\n"));
- pthread_cond_wait (&this->video_ended, &this->lock);
- }
-
- pthread_cond_signal (&this->audio_ended);
- pthread_mutex_unlock (&this->lock);
-}
-
-static void metronom_set_video_rate (metronom_t *this, uint32_t pts_per_frame) {
- pthread_mutex_lock (&this->lock);
-
- printf ("metronom: set_video_rate %d\n", pts_per_frame);
-
- this->pts_per_frame = pts_per_frame;
-
- this->avg_frame_duration = this->pts_per_frame;
-
- pthread_mutex_unlock (&this->lock);
-}
-
-static uint32_t metronom_get_video_rate (metronom_t *this) {
- int ret;
-
- pthread_mutex_lock (&this->lock);
- ret = this->avg_frame_duration;
- pthread_mutex_unlock (&this->lock);
-
- /* this is due bad streams, but returning 0 will
- cause problems to video out timer setting. */
- if( ret < 100 )
- ret = 100;
- return ret;
-}
-
-static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
+static void metronom_set_audio_rate (metronom_t *this, int64_t pts_per_smpls) {
pthread_mutex_lock (&this->lock);
this->pts_per_smpls = pts_per_smpls;
@@ -425,14 +236,14 @@ static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
pthread_mutex_unlock (&this->lock);
#ifdef METRONOM_LOG
- printf ("metronom: %d pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM);
+ printf ("metronom: %lld pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM);
#endif
}
-static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts,
- uint32_t duration, uint32_t scr ) {
- uint32_t vpts;
+static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts,
+ int64_t duration, int64_t scr ) {
+ int64_t vpts;
pthread_mutex_lock (&this->lock);
@@ -452,9 +263,7 @@ static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts,
detected but this->video_wrap_offset not updated (would give
wrong values too).
*/
- if ( this->video_stream_starting ) {
- vpts = 0;
- } else if ( this->video_discontinuity ) {
+ if ( this->video_discontinuity ) {
/* we can safely use audio_wrap_offset if already updated */
if( !this->audio_discontinuity ) {
vpts = pts + this->audio_wrap_offset;
@@ -478,14 +287,14 @@ static void metronom_expect_video_discontinuity (metronom_t *this) {
this->video_discontinuity_count++;
pthread_cond_signal (&this->video_discontinuity_reached);
- LOG_MSG(this->xine, _("metronom: video discontinuity #%d\n"),
+ printf ("metronom: video discontinuity #%d\n",
this->video_discontinuity_count);
if( this->have_audio ) {
while ( this->audio_discontinuity_count <
this->video_discontinuity_count ) {
- LOG_MSG(this->xine, _("metronom: waiting for audio discontinuity #%d\n"),
+ printf ("metronom: waiting for audio discontinuity #%d\n",
this->video_discontinuity_count);
pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock);
@@ -493,56 +302,53 @@ static void metronom_expect_video_discontinuity (metronom_t *this) {
if ( this->video_vpts < this->audio_vpts ) {
this->video_vpts = this->audio_vpts;
- LOG_MSG(this->xine, _("metronom: video vpts adjusted to %d\n"), this->video_vpts);
+ printf ("metronom: video vpts adjusted to %lld\n", this->video_vpts);
}
}
- /* this->num_video_vpts_guessed = 0; */
- /* this->last_video_pts = this->video_vpts - this->video_wrap_offset; */
- /*
- this->avg_frame_duration = this->pts_per_frame;
- */
- this->frames_since_start = 0;
-
pthread_mutex_unlock (&this->lock);
}
-static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32_t scr) {
+static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
- uint32_t vpts;
- int pts_discontinuity = 0;
+ int64_t vpts;
+ int64_t pts = img->pts;
+ int64_t duration = img->duration;
+ int pts_discontinuity = 0;
pthread_mutex_lock (&this->lock);
- if( (this->audio_discontinuity || this->audio_stream_starting) &&
- (this->video_discontinuity || this->video_stream_starting) ) {
-
- /* this is needed to take care of still frame with no audio
- were vpts are not updated.
- we can only do it here because audio and video decoder threads
- have just been synced */
- if ( this->video_vpts < metronom_get_current_time(this) ) {
- this->video_vpts = metronom_get_current_time(this) + PREBUFFER_PTS_OFFSET;
- this->audio_vpts = this->video_vpts;
- LOG_MSG(this->xine, _("metronom: audio/video vpts too old, adjusted to %d\n"),
- this->video_vpts);
- }
- }
-
/* check for pts discontinuities against the predicted pts value */
- if (pts && this->last_video_pts) {
- vpts = this->last_video_pts +
- (this->num_video_vpts_guessed+1) * this->avg_frame_duration;
- if( ( pts > vpts && (pts - vpts) > WRAP_THRESHOLD ) ||
- ( pts < vpts && (vpts - pts) > WRAP_THRESHOLD ) ) {
+ if (pts) {
+
+ int64_t diff, predicted_pts;
+
+ predicted_pts = this->last_video_pts + duration;
+
+ diff = pts - predicted_pts;
+
+#ifdef METRONOM_LOG
+ printf ("metronom: got video pts %lld, predicted %lld (= %lld + %lld) => diff %lld\n",
+ pts, predicted_pts, this->last_video_pts, duration, diff);
+#endif
+
+ if ( abs (diff) > WRAP_THRESHOLD ) {
+
pts_discontinuity = 1;
+#ifdef METRONOM_LOG
+ printf ("metronom: this is a video discontinuity\n");
+#endif
+
/*
- ignore discontinuities created by frame reordering around
- the REAL discontinuity. :)
- */
- if( !this->video_discontinuity && !this->video_stream_starting ) {
+ * ignore discontinuities created by frame reordering around
+ * the REAL discontinuity. :)
+ */
+ if( !this->video_discontinuity ) {
pts = 0;
+#ifdef METRONOM_LOG
+ printf ("metronom: not expecting a video discontinuity => ignored\n");
+#endif
}
}
}
@@ -552,33 +358,33 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32
* check if there was any pending SCR discontinuity (video_discontinuity
* is set from the decoder loop) together with pts discont.
*/
- if ( (this->video_discontinuity && pts_discontinuity) ||
- this->video_stream_starting ) {
+ if (this->video_discontinuity && pts_discontinuity) {
this->video_discontinuity = 0;
- this->video_stream_starting = 0;
this->wrap_diff_counter = 0;
- this->video_wrap_offset = this->video_vpts + this->avg_frame_duration - pts;
- /* + this->num_video_vpts_guessed * this->avg_frame_duration; */
+ this->video_wrap_offset = this->video_vpts - pts;
vpts = pts + this->video_wrap_offset;
- LOG_MSG(this->xine, _("metronom: video pts discontinuity/start, pts is %d, wrap_offset is %d, vpts is %d\n"),
+ printf ("metronom: video pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n",
pts, this->video_wrap_offset, vpts);
} else {
+ int64_t diff;
+
/*
* audio and video wrap are not allowed to differ for too long
*/
- if ( !this->audio_stream_starting && this->have_audio
+
+ if ( this->have_audio
&& (this->video_wrap_offset != this->audio_wrap_offset)
&& !this->video_discontinuity && !this->audio_discontinuity ) {
this->wrap_diff_counter++;
if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) {
- LOG_MSG(this->xine, _("metronom: forcing video_wrap (%d) and audio wrap (%d)"),
+ printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)",
this->video_wrap_offset, this->audio_wrap_offset);
if (this->video_wrap_offset > this->audio_wrap_offset)
@@ -586,103 +392,64 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32
else
this->video_wrap_offset = this->audio_wrap_offset;
- LOG_MSG(this->xine, _(" to %d\n"), this->video_wrap_offset);
+ printf (this->xine, " to %d\n", this->video_wrap_offset);
this->wrap_diff_counter = 0;
}
}
/*
- * calc overall average frame duration (according to pts values)
+ * compare predicted (this->video_vpts) and given (pts+wrap_offset)
+ * pts values - hopefully they will be the same
+ * if not, for small diffs try to interpolate
+ * for big diffs: jump
*/
- if (this->frames_since_start && this->last_video_pts) {
- int current_avg_delta;
-
- int weight_old = 9;
- int weight_new = 1;
-
- /*
- printf("foo: pts %d, last pts %d\n", pts, this->last_video_pts);
- */
-
- if (pts > this->last_video_pts) {
- current_avg_delta = (pts - this->last_video_pts) / (this->num_video_vpts_guessed + 1);
-
- /*
- printf("foo: current_avg_delta %d\n", current_avg_delta);
- */
-
- this->avg_frame_duration =
- (((this->avg_frame_duration * weight_old) + (current_avg_delta * weight_new)) /
- (weight_old + weight_new));
- } else {
- current_avg_delta = (this->last_video_pts - pts) / (this->num_video_vpts_guessed + 1);
-
- /*
- printf("foo: current_avg_delta - %d\n", current_avg_delta);
- */
- this->avg_frame_duration =
- (((this->avg_frame_duration * weight_old) - (current_avg_delta * weight_new)) /
- (weight_old + weight_new));
- }
- }
- }
+ vpts = pts + this->video_wrap_offset;
- this->last_video_pts = pts;
- }
+ diff = this->video_vpts - vpts;
- this->video_vpts += this->avg_frame_duration;
+#ifdef METRONOM_LOG
+ printf ("metronom: video diff is %lld (predicted %lld, given %lld)\n",
+ diff, this->video_vpts, vpts);
+#endif
- /*
- * smoothen possibly wrong pts as long as delta is small
- */
+ if (abs (diff) > VIDEO_DRIFT_TOLERANCE) {
- if (pts) {
- int drift;
- int delta = this->video_vpts - this->video_wrap_offset - pts;
+ this->video_vpts = vpts;
+ this->video_wrap_offset = vpts - pts;
#ifdef METRONOM_LOG
- printf("metronom: delta (vpts <-> pts+wrap_offset): %d\n", delta);
+ printf ("metronom: video jump, wrap offset is now %lld\n",
+ this->video_wrap_offset);
#endif
+
+ } else if (diff) {
- if (abs (delta) > 45000) {
-
- this->video_vpts = pts + this->video_wrap_offset;
-
- LOG_MSG(this->xine, _("metronom: delta too big, setting vpts to %d\n"),
- this->video_vpts);
+ this->video_vpts -= diff / 8; /* FIXME: better heuristics ? */
+ this->video_wrap_offset = vpts - pts;
-
- } else {
-
- if (this->num_video_vpts_guessed > 10)
- this->num_video_vpts_guessed = 10;
-
- drift = delta / 20 * (this->num_video_vpts_guessed + 1);
#ifdef METRONOM_LOG
- printf("metronom: compensation drift: %d\n", drift);
+ printf ("metronom: video drift, wrap offset is now %lld\n",
+ this->video_wrap_offset);
#endif
-
- this->video_vpts -= drift;
+ }
}
- this->num_video_vpts_guessed = 0;
+ this->last_video_pts = pts;
} else
- this->num_video_vpts_guessed++;
+ this->last_video_pts = this->video_vpts - this->video_wrap_offset;
- this->frames_since_start++;
+ img->vpts = this->video_vpts + this->av_offset;
#ifdef METRONOM_LOG
- printf ("metronom: video vpts for %10d : %10d (avg_frame_duration %d)\n",
- pts, this->video_vpts, this->avg_frame_duration);
+ printf ("metronom: video vpts for %10lld : %10lld\n",
+ pts, this->video_vpts);
#endif
- vpts = this->video_vpts + this->av_offset;
-
- pthread_mutex_unlock (&this->lock);
+ this->video_vpts += duration;
- return vpts;
+ pthread_mutex_unlock (&this->lock);
}
static void metronom_expect_audio_discontinuity (metronom_t *this) {
@@ -693,13 +460,13 @@ static void metronom_expect_audio_discontinuity (metronom_t *this) {
this->audio_discontinuity_count++;
pthread_cond_signal (&this->audio_discontinuity_reached);
- LOG_MSG(this->xine, _("metronom: audio discontinuity #%d\n"),
+ printf ("metronom: audio discontinuity #%d\n",
this->audio_discontinuity_count);
while ( this->audio_discontinuity_count >
this->video_discontinuity_count ) {
- LOG_MSG(this->xine, _("metronom: waiting for video_discontinuity #%d\n"),
+ printf ("metronom: waiting for video_discontinuity #%d\n",
this->audio_discontinuity_count);
pthread_cond_wait (&this->video_discontinuity_reached, &this->lock);
@@ -707,7 +474,7 @@ static void metronom_expect_audio_discontinuity (metronom_t *this) {
if ( this->audio_vpts < this->video_vpts ) {
this->audio_vpts = this->video_vpts;
- LOG_MSG(this->xine, _("metronom: audio vpts adjusted to %d\n"), this->audio_vpts);
+ printf ("metronom: audio vpts adjusted to %lld\n", this->audio_vpts);
}
/* this->num_audio_samples_guessed = 1; */
@@ -717,20 +484,20 @@ static void metronom_expect_audio_discontinuity (metronom_t *this) {
}
-static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
- uint32_t nsamples, uint32_t scr) {
+static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts,
+ int nsamples, int64_t scr) {
- uint32_t vpts;
+ int64_t vpts;
#ifdef METRONOM_LOG
- printf ("metronom: got %d samples, pts is %u, last_pts is %u, diff = %d\n",
+ printf ("metronom: got %d samples, pts is %lld, last_pts is %lld, diff = %lld\n",
nsamples, pts, this->last_audio_pts, pts - this->last_audio_pts);
#endif
pthread_mutex_lock (&this->lock);
- if( (this->audio_discontinuity || this->audio_stream_starting) &&
- (this->video_discontinuity || this->video_stream_starting) ) {
+#if 0
+ if (this->audio_discontinuity && this->video_discontinuity) {
/* this is needed to take care of still frame with no audio
were vpts are not updated.
@@ -739,32 +506,31 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
if ( this->audio_vpts < metronom_get_current_time(this) ) {
this->audio_vpts = metronom_get_current_time(this) + PREBUFFER_PTS_OFFSET;
this->video_vpts = this->audio_vpts;
- LOG_MSG(this->xine, _("metronom: audio/video vpts too old, adjusted to %d\n"),
+ printf ("metronom: audio/video vpts too old, adjusted to %lld\n",
this->audio_vpts);
}
}
-
- this->last_audio_scr = scr;
+#endif
if (pts) {
/*
* discontinuity ?
*/
- if ( this->audio_discontinuity || this->audio_stream_starting ) {
+ if ( this->audio_discontinuity ) {
this->audio_discontinuity = 0;
- this->audio_stream_starting = 0;
this->wrap_diff_counter = 0;
this->audio_wrap_offset = this->audio_vpts - pts ;
+
/*
- + this->num_audio_samples_guessed
- * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ;
- */
+ * this->num_audio_samples_guessed
+ * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ;
+ */
vpts = pts + this->audio_wrap_offset;
- LOG_MSG(this->xine, _("metronom: audio pts discontinuity/start, pts is %d, wrap_offset is %d, vpts is %d\n"),
+ printf ("metronom: audio pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n",
pts, this->audio_wrap_offset, vpts);
@@ -781,7 +547,7 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) {
- LOG_MSG(this->xine, _("metronom: forcing video_wrap (%d) and audio wrap (%d)"),
+ printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)",
this->video_wrap_offset, this->audio_wrap_offset);
if (this->video_wrap_offset > this->audio_wrap_offset)
@@ -789,7 +555,7 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
else
this->video_wrap_offset = this->audio_wrap_offset;
- LOG_MSG(this->xine, _("to %d\n"), this->video_wrap_offset);
+ printf ("to %lld\n", this->video_wrap_offset);
this->wrap_diff_counter = 0;
}
@@ -823,7 +589,7 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
this->num_audio_samples_guessed += nsamples;
#ifdef METRONOM_LOG
- printf ("metronom: audio vpts for %10d : %10d\n", pts, vpts);
+ printf ("metronom: audio vpts for %10lld : %10lld\n", pts, vpts);
#endif
pthread_mutex_unlock (&this->lock);
@@ -839,7 +605,7 @@ static void metronom_set_av_offset (metronom_t *this, int32_t pts) {
pthread_mutex_unlock (&this->lock);
- LOG_MSG(this->xine, _("metronom: av_offset=%d pts\n"), pts);
+ printf ("metronom: av_offset=%d pts\n", pts);
}
static int32_t metronom_get_av_offset (metronom_t *this) {
@@ -859,7 +625,7 @@ static scr_plugin_t* get_master_scr(metronom_t *this) {
}
}
if (select < 0) {
- LOG_MSG(this->xine, _("metronom: panic - no scr provider found!\n"));
+ printf ("metronom: panic - no scr provider found!\n");
return NULL;
}
return this->scr_list[select];
@@ -896,8 +662,9 @@ static void metronom_unregister_scr (metronom_t *this, scr_plugin_t *scr) {
}
static int metronom_sync_loop (metronom_t *this) {
+
scr_plugin_t** scr;
- uint32_t pts;
+ int64_t pts;
while (((xine_t*)this->xine)->status != XINE_QUIT) {
pts = this->scr_master->get_current(this->scr_master);
@@ -917,12 +684,6 @@ metronom_t * metronom_init (int have_audio, void *xine) {
int err;
this->xine = xine;
- this->audio_stream_start = metronom_audio_stream_start;
- this->audio_stream_end = metronom_audio_stream_end ;
- this->video_stream_start = metronom_video_stream_start;
- this->video_stream_end = metronom_video_stream_end ;
- this->set_video_rate = metronom_set_video_rate;
- this->get_video_rate = metronom_get_video_rate;
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
@@ -945,20 +706,50 @@ metronom_t * metronom_init (int have_audio, void *xine) {
if ((err = pthread_create(&this->sync_thread, NULL,
(void*(*)(void*)) metronom_sync_loop, this)) != 0)
- LOG_MSG(this->xine, _("metronom: cannot create sync thread (%s)\n"),
+ printf ("metronom: cannot create sync thread (%s)\n",
strerror(err));
pthread_mutex_init (&this->lock, NULL);
- pthread_cond_init (&this->video_started, NULL);
- pthread_cond_init (&this->audio_started, NULL);
- pthread_cond_init (&this->video_ended, NULL);
- pthread_cond_init (&this->audio_ended, NULL);
pthread_cond_init (&this->video_discontinuity_reached, NULL);
pthread_cond_init (&this->audio_discontinuity_reached, NULL);
this->av_offset = 0;
- this->have_audio = have_audio;
- this->pts_per_frame = 3600;
+
+
+ /* initialize video stuff */
+
+ this->have_audio = have_audio;
+ this->video_vpts = PREBUFFER_PTS_OFFSET;
+
+ this->last_video_pts = 0;
+
+ this->video_wrap_offset = PREBUFFER_PTS_OFFSET;
+ this->wrap_diff_counter = 0;
+
+ this->video_discontinuity = 0;
+ this->video_discontinuity_count = 0;
+
+ /* initialize audio stuff */
+
+ this->audio_vpts = PREBUFFER_PTS_OFFSET;
+
+ this->audio_pts_delta = 0;
+
+ this->num_audio_samples_guessed = 1;
+ this->last_audio_pts = 0;
+
+ this->audio_wrap_offset = PREBUFFER_PTS_OFFSET;
+ this->wrap_diff_counter = 0;
+
+ this->audio_discontinuity = 0;
+ this->audio_discontinuity_count = 0;
return this;
}
+
+
+
+
+
+
+
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 18dd2ca8e..1b6a841cc 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
* This file is part of xine, a unix video player.
*
@@ -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.h,v 1.16 2001/12/27 14:30:30 f1rmb Exp $
+ * $Id: metronom.h,v 1.17 2002/02/09 07:13:24 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -50,6 +50,7 @@ extern "C" {
#include <inttypes.h>
#include <sys/time.h>
#include <pthread.h>
+#include "video_out.h"
typedef struct metronom_s metronom_t ;
typedef struct scr_plugin_s scr_plugin_t;
@@ -63,58 +64,26 @@ struct metronom_s {
void *xine;
/*
- * this is called to tell metronom to prepare for a new video stream
- * (video and audio decoder threads may be blocked at these functions
- * to synchronize starting and stopping)
- */
-
- void (*video_stream_start) (metronom_t *this);
- void (*video_stream_end) (metronom_t *this);
-
- /*
- * this is called to tell metronom to prepare for a new audio stream
- * (video and audio decoder threads may be blocked at these functions
- * to synchronize starting and stopping)
- */
-
- void (*audio_stream_start) (metronom_t *this);
- void (*audio_stream_end) (metronom_t *this);
-
- /*
- * called by video output driver to inform metronom about current framerate
- *
- * parameter pts_per_frame : frame display duration in 1/90000 sec
- */
- void (*set_video_rate) (metronom_t *this, uint32_t pts_per_frame);
-
- /*
- * return current video rate (including delta corrections)
- */
-
- uint32_t (*get_video_rate) (metronom_t *this);
-
- /*
* called by audio output driver to inform metronom about current audio
- * bitrate
+ * samplerate
*
* parameter pts_per_smpls : 1/90000 sec per 65536 samples
*/
- void (*set_audio_rate) (metronom_t *this, uint32_t pts_per_smpls);
+ void (*set_audio_rate) (metronom_t *this, int64_t pts_per_smpls);
/*
* called by video output driver for *every* frame
*
- * parameter pts: pts for frame if known, 0 otherwise
- * scr: system clock reference, may be 0 or == pts if unknown
+ * parameter frame containing pts, scr, ... information
*
- * return value: virtual pts for frame (interpolated if pts == 0)
+ * will set vpts field in frame
*
* this function will also update video_wrap_offset if a discontinuity
* is detected (read the comentaries below about discontinuities).
*
*/
- uint32_t (*got_video_frame) (metronom_t *this, uint32_t pts, uint32_t scr);
+ void (*got_video_frame) (metronom_t *this, vo_frame_t *frame);
/*
* called by audio output driver whenever audio samples are delivered to it
@@ -130,7 +99,8 @@ struct metronom_s {
*
*/
- uint32_t (*got_audio_samples) (metronom_t *this, uint32_t pts, uint32_t nsamples, uint32_t scr);
+ int64_t (*got_audio_samples) (metronom_t *this, int64_t pts,
+ int nsamples, int64_t scr);
/*
* called by SPU decoder whenever a packet is delivered to it
@@ -143,17 +113,17 @@ struct metronom_s {
* due to the lack of regularity on spu packets)
*/
- uint32_t (*got_spu_packet) (metronom_t *this, uint32_t pts, uint32_t duration,
- uint32_t scr);
+ int64_t (*got_spu_packet) (metronom_t *this, int64_t pts, int64_t duration,
+ int64_t scr);
/*
- * Tell metronom about discontinuities.
+ * tell metronom about discontinuities.
*
- * These functions are called due to a discontinuity detected at
+ * these functions are called due to a discontinuity detected at
* demux stage from SCR values. As SCR are not guarateed to happen with
* any regularity, we can not correct the xxx_wrap_offset right now.
*
- * We will instead prepare both audio and video to correct the
+ * we will instead prepare both audio and video to correct the
* discontinuity at the first new PTS value (got_video_frame or
* got_audio_samples). As we can predict with reasonably accuracy what
* the old PTS would have being the calculated wrap_offset should be
@@ -185,7 +155,7 @@ struct metronom_s {
* start metronom clock (no clock reset)
* at given pts
*/
- void (*start_clock) (metronom_t *this, uint32_t pts);
+ void (*start_clock) (metronom_t *this, int64_t pts);
/*
@@ -203,13 +173,13 @@ struct metronom_s {
/*
* get current clock value in vpts
*/
- uint32_t (*get_current_time) (metronom_t *this);
+ int64_t (*get_current_time) (metronom_t *this);
/*
* adjust master clock to external timer (e.g. audio hardware)
*/
- void (*adjust_clock) (metronom_t *this, uint32_t desired_pts);
+ void (*adjust_clock) (metronom_t *this, int64_t desired_pts);
/*
@@ -229,28 +199,24 @@ struct metronom_s {
* metronom internal stuff
*/
- uint32_t pts_per_frame;
- uint32_t pts_per_smpls;
+ int64_t pts_per_smpls;
- int32_t audio_pts_delta;
+ int64_t audio_pts_delta;
- uint32_t video_vpts;
- uint32_t spu_vpts;
- uint32_t audio_vpts;
+ int64_t video_vpts;
+ int64_t spu_vpts;
+ int64_t audio_vpts;
- int32_t video_wrap_offset;
- int32_t audio_wrap_offset;
+ int64_t video_wrap_offset;
+ int64_t audio_wrap_offset;
int wrap_diff_counter;
- uint32_t last_video_pts;
- uint32_t last_video_scr;
- int num_video_vpts_guessed;
+ int64_t last_video_pts;
- uint32_t last_audio_pts;
- uint32_t last_audio_scr;
+ int64_t last_audio_pts;
int num_audio_samples_guessed;
- int32_t av_offset;
+ int64_t av_offset;
scr_plugin_t* scr_master;
scr_plugin_t** scr_list;
@@ -259,29 +225,19 @@ struct metronom_s {
pthread_mutex_t lock;
int have_audio;
- int video_stream_starting;
- int video_stream_running;
- int audio_stream_starting;
- int audio_stream_running;
int video_discontinuity;
int video_discontinuity_count;
int audio_discontinuity;
int audio_discontinuity_count;
pthread_cond_t video_discontinuity_reached;
pthread_cond_t audio_discontinuity_reached;
- pthread_cond_t video_started;
- pthread_cond_t audio_started;
- pthread_cond_t video_ended;
- pthread_cond_t audio_ended;
- int frames_since_start;
- int avg_frame_duration;
};
metronom_t *metronom_init (int have_audio, void *xine);
/*
- * SCR plugins
+ * SCR (system clock reference) plugins
*/
struct scr_plugin_s
@@ -299,11 +255,11 @@ struct scr_plugin_s
int (*set_speed) (scr_plugin_t *this, int speed);
- void (*adjust) (scr_plugin_t *this, uint32_t vpts);
+ void (*adjust) (scr_plugin_t *this, int64_t vpts);
- void (*start) (scr_plugin_t *this, uint32_t start_vpts);
+ void (*start) (scr_plugin_t *this, int64_t start_vpts);
- uint32_t (*get_current) (scr_plugin_t *this);
+ int64_t (*get_current) (scr_plugin_t *this);
metronom_t *metronom;
};
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 6c0f1db43..d14467557 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.71 2002/01/25 00:35:46 f1rmb Exp $
+ * $Id: video_decoder.c,v 1.72 2002/02/09 07:13:24 guenter Exp $
*
*/
@@ -105,8 +105,8 @@ void *video_decoder_loop (void *this_gen) {
this->spu_finished = 0;
pthread_mutex_unlock (&this->finished_lock);
-
- this->metronom->video_stream_start (this->metronom);
+
+ this->metronom->expect_video_discontinuity (this->metronom);
break;
@@ -144,8 +144,6 @@ void *video_decoder_loop (void *this_gen) {
case BUF_CONTROL_END:
- this->metronom->video_stream_end (this->metronom);
-
if (this->cur_video_decoder_plugin) {
this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
this->cur_video_decoder_plugin = NULL;
@@ -184,15 +182,8 @@ void *video_decoder_loop (void *this_gen) {
break;
case BUF_CONTROL_DISCONTINUITY:
- printf ("video_decoder: BUF_CONTROL_DISCONTINUITY is deprecated\n");
- break;
-
- case BUF_CONTROL_AVSYNC_RESET:
printf ("video_decoder: discontinuity ahead\n");
- if (this->cur_video_decoder_plugin)
- this->cur_video_decoder_plugin->flush (this->cur_video_decoder_plugin);
-
this->video_in_discontinuity = 1;
this->metronom->expect_video_discontinuity (this->metronom);
@@ -200,14 +191,6 @@ void *video_decoder_loop (void *this_gen) {
this->video_in_discontinuity = 0;
break;
- case BUF_VIDEO_FILL:
- break;
-
- case BUF_CONTROL_FLUSH:
- if (this->cur_video_decoder_plugin)
- this->cur_video_decoder_plugin->flush (this->cur_video_decoder_plugin);
- break;
-
case BUF_CONTROL_AUDIO_CHANNEL:
{
xine_ui_event_t ui_event;
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 8f43d71ce..10a327045 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,8 +17,9 @@
* 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.70 2002/02/02 13:39:30 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.71 2002/02/09 07:13:24 guenter Exp $
*
+ * frame allocation / queuing / scheduling / output functions
*/
#ifdef HAVE_CONFIG_H
@@ -34,6 +35,7 @@
#include <zlib.h>
#include "video_out.h"
+#include "metronom.h"
#include "xine_internal.h"
#include "xineutils.h"
@@ -57,12 +59,48 @@
}
#endif
-/*
+
#define VIDEO_OUT_LOG
-*/
#define NUM_FRAME_BUFFERS 15
+typedef struct {
+
+ vo_instance_t vo; /* public part */
+
+ vo_driver_t *driver;
+ metronom_t *metronom;
+ xine_t *xine;
+
+ img_buf_fifo_t *free_img_buf_queue;
+ img_buf_fifo_t *display_img_buf_queue;
+
+ vo_frame_t *last_frame;
+ vo_frame_t *img_backup;
+ int backup_is_logo;
+
+ int video_loop_running;
+ int video_opened;
+ pthread_t video_thread;
+
+ int num_frames_delivered;
+ int num_frames_skipped;
+ int num_frames_discarded;
+
+ /* pts value when decoder delivered last video frame */
+ int64_t last_delivery_pts;
+
+ int logo_w, logo_h;
+ uint8_t *logo_yuy2;
+
+ video_overlay_instance_t *overlay_source;
+ int overlay_enabled;
+} vos_t;
+
+/*
+ * frame queue (fifo) util functions
+ */
+
struct img_buf_fifo_s {
vo_frame_t *first;
vo_frame_t *last;
@@ -144,439 +182,521 @@ static vo_frame_t *vo_remove_from_img_buf_queue (img_buf_fifo_t *queue) {
return img;
}
-static void vo_set_timer (uint32_t video_step) {
- struct itimerval tval;
-
- tval.it_interval.tv_sec = 0;
- tval.it_interval.tv_usec = video_step*100000/90000;
- tval.it_value.tv_sec = 0;
- tval.it_value.tv_usec = video_step*100000/90000;
-
- if (setitimer(ITIMER_REAL, &tval, NULL)) {
- printf ("vo_set_timer: setitimer failed :");
- }
-}
+/*
+ * function called by video output driver
+ */
-void video_timer_handler (int hubba) {
-#if !HAVE_SIGACTION
- signal (SIGALRM, video_timer_handler);
-#endif
-}
+static void vo_frame_displayed (vo_frame_t *img) {
-/* send a buf to force video_decoder->flush */
-static void video_out_send_decoder_flush( fifo_buffer_t *video_fifo ) {
- buf_element_t *buf;
+ pthread_mutex_lock (&img->mutex);
- if( !video_fifo )
- return;
-
- buf = video_fifo->buffer_pool_alloc (video_fifo);
-
- buf->type = BUF_CONTROL_FLUSH ;
- buf->PTS = 0;
- buf->SCR = 0;
- buf->input_pos = 0;
- buf->input_time = 0;
+ img->driver_locked = 0;
- video_fifo->put (video_fifo, buf);
+ if (!img->decoder_locked) {
+ vos_t *this = (vos_t *) img->instance;
+ vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
+ }
+ pthread_mutex_unlock (&img->mutex);
}
-static vo_frame_t *vo_get_frame (vo_instance_t *this,
+/*
+ *
+ * functions called by video decoder:
+ *
+ * get_frame => alloc frame for rendering
+ *
+ * frame_draw=> queue finished frame for display
+ *
+ * frame_free=> frame no longer used as reference frame by decoder
+ *
+ */
+
+static vo_frame_t *vo_get_frame (vo_instance_t *this_gen,
uint32_t width, uint32_t height,
- int ratio, int format, uint32_t duration,
+ int ratio, int format,
int flags) {
vo_frame_t *img;
+ vos_t *this = (vos_t *) this_gen;
- /*
- printf ("video_out : get_frame %d x %d from queue %d\n",
- width, height, this->free_img_buf_queue);
- fflush(stdout);
- */
-
- if (this->pts_per_frame != duration) {
- this->pts_per_frame = duration;
- this->pts_per_half_frame = duration / 2;
- this->metronom->set_video_rate (this->metronom, duration);
- }
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: get_frame (%d x %d)\n", width, height);
+#endif
img = vo_remove_from_img_buf_queue (this->free_img_buf_queue);
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: got a frame -> pthread_mutex_lock (&img->mutex)\n");
+#endif
+
pthread_mutex_lock (&img->mutex);
img->display_locked = 0;
img->decoder_locked = 1;
img->driver_locked = 0;
- img->width = width;
- img->height = height;
- img->ratio = ratio;
- img->format = format;
- img->duration = duration;
- img->drawn = 0;
+ img->width = width;
+ img->height = height;
+ img->ratio = ratio;
+ img->format = format;
/* let driver ensure this image has the right format */
- this->driver->update_frame_format (this->driver, img, width, height, ratio, format, flags);
+ this->driver->update_frame_format (this->driver, img, width, height,
+ ratio, format, flags);
pthread_mutex_unlock (&img->mutex);
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: get_frame (%d x %d) done\n", width, height);
+#endif
+
return img;
}
-static void *video_out_loop (void *this_gen) {
+static int vo_frame_draw (vo_frame_t *img) {
- uint32_t cur_pts;
- int diff, absdiff, pts=0;
- vo_frame_t *img, *img_backup;
- int backup_is_logo = 0;
- uint32_t video_step, video_step_new;
- vo_instance_t *this = (vo_instance_t *) this_gen;
- static int prof_video_out = -1;
- static int prof_spu_blend = -1;
- sigset_t vo_mask;
-
- int flush_sent = 0;
+ vos_t *this = (vos_t *) img->instance;
+ int64_t diff;
+ int64_t cur_vpts;
+ int64_t pic_vpts ;
+ int frames_to_skip;
- /* printf ("%d video_out start\n", getpid()); */
+ this->metronom->got_video_frame (this->metronom, img);
- if (prof_video_out == -1)
- prof_video_out = xine_profiler_allocate_slot ("video output");
- if (prof_spu_blend == -1)
- prof_spu_blend = xine_profiler_allocate_slot ("spu blend");
+ pic_vpts = img->vpts;
- img_backup = NULL;
- this->last_draw_vpts = 0;
-
- /*
- * set up timer signal
- */
-
- sigemptyset(&vo_mask);
- sigaddset(&vo_mask, SIGALRM);
- if (sigprocmask (SIG_UNBLOCK, &vo_mask, NULL)) {
- LOG_MSG(this->xine, _("video_out: sigprocmask failed.\n"));
- }
-#if HAVE_SIGACTION
- {
- struct sigaction sig_act;
- memset (&sig_act, 0, sizeof(sig_act));
- sig_act.sa_handler = video_timer_handler;
- sigaction (SIGALRM, &sig_act, NULL);
- }
-#else
- signal (SIGALRM, video_timer_handler);
-#endif
+ cur_vpts = this->metronom->get_current_time(this->metronom);
+ this->last_delivery_pts = cur_vpts;
- video_step = this->metronom->get_video_rate (this->metronom);
- vo_set_timer (video_step);
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: got image at master vpts %lld. vpts for picture is %lld (pts was %lld)\n",
+ cur_vpts, pic_vpts, pic_vpts);
+#endif
- /*
- * here it is - the big video output loop
- */
+ this->num_frames_delivered++;
- while ( this->video_loop_running ) {
+ diff = pic_vpts - cur_vpts;
+ frames_to_skip = ((-1 * diff) / img->duration + 3) * 2;
- /*
- * wait until it's time to display a frame
- */
-
- pause ();
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: delivery diff : %lld, current vpts is %lld\n",
+ diff, cur_vpts);
+#endif
- video_step_new = this->metronom->get_video_rate (this->metronom);
- if (video_step_new != video_step) {
- video_step = video_step_new;
-
- vo_set_timer (video_step);
- }
-
- /*
- * now, look at the frame queue and decide which frame to display
- * or generate still frames if no frames are available
- */
+ if (img->display_locked) {
+ printf ("video_out: ALERT! frame is already locked for displaying\n");
+ return frames_to_skip;
+ }
- xine_profiler_start_count (prof_video_out);
+ if (cur_vpts>0) {
- cur_pts = this->metronom->get_current_time (this->metronom);
+ if (diff<(-1 * img->duration) && img->drawn != 2 ) {
+ this->num_frames_discarded++;
#ifdef VIDEO_OUT_LOG
- printf ("video_out : video loop iteration at audio pts %d\n", cur_pts);
+ printf ("video_out: frame rejected, %d frames to skip\n", frames_to_skip);
#endif
-
- img = this->display_img_buf_queue->first;
- /* update timer for inactivity flush */
- if( img ) {
- this->last_draw_vpts = cur_pts;
- } else {
- /* start timer when decoder receives the first packet */
- if( !this->last_draw_vpts && this->decoder_started_flag )
- this->last_draw_vpts = cur_pts;
-
- if( this->last_draw_vpts && (cur_pts - this->last_draw_vpts) > (8 * this->pts_per_frame) ) {
-#ifdef VIDEO_OUT_LOG
- printf("video_out : sending decoder flush due to inactivity\n");
-#endif
- video_out_send_decoder_flush( this->xine->video_fifo );
- this->last_draw_vpts = cur_pts;
- flush_sent = 1;
- }
+ pthread_mutex_lock (&img->mutex);
+ img->display_locked = 0;
+ pthread_mutex_unlock (&img->mutex);
+
+ vo_frame_displayed (img);
+
+ this->last_frame = img;
+
+ return frames_to_skip;
+
}
-
-
+ } /* else: we are probably in precaching mode */
+
+ if (!img->bad_frame) {
/*
- * throw away expired frames
+ * put frame into FIFO-Buffer
*/
- diff = 1000000;
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: frame is ok => appending to display buffer\n");
+#endif
+
+ this->last_frame = img;
+
+ pthread_mutex_lock (&img->mutex);
+ img->display_locked = 1;
+ pthread_mutex_unlock (&img->mutex);
+
+ vo_append_to_img_buf_queue (this->display_img_buf_queue, img);
+
+ } else {
+ this->num_frames_skipped++;
+
+ pthread_mutex_lock (&img->mutex);
+ img->display_locked = 0;
+ pthread_mutex_unlock (&img->mutex);
+
+ vo_frame_displayed (img);
+ }
+
+ /*
+ * performance measurement
+ */
+
+ if (this->num_frames_delivered>199) {
+ LOG_MSG_STDERR(this->xine,
+ _("%d frames delivered, %d frames skipped, %d frames discarded\n"),
+ this->num_frames_delivered,
+ this->num_frames_skipped, this->num_frames_discarded);
+
+ this->num_frames_delivered = 0;
+ this->num_frames_discarded = 0;
+ this->num_frames_skipped = 0;
+ }
+
+ return frames_to_skip;
+}
+
+static void vo_frame_free (vo_frame_t *img) {
+
+ pthread_mutex_lock (&img->mutex);
+ img->decoder_locked = 0;
+
+ if (!img->display_locked && !img->driver_locked ) {
+ vos_t *this = (vos_t *) img->instance;
+ vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
+ }
+
+ pthread_mutex_unlock (&img->mutex);
+}
+
+
+
+/*
+ *
+ * video out loop related functions
+ *
+ */
+
+static void expire_frames (vos_t *this, int64_t cur_vpts) {
+
+ int64_t pts;
+ int64_t diff;
+ vo_frame_t *img;
+
+ img = this->display_img_buf_queue->first;
+
+ /*
+ * throw away expired frames
+ */
+
+ diff = 1000000; /* always enter the while-loop */
- while (img && (diff >this->pts_per_half_frame)) {
- pts = img->PTS;
- diff = cur_pts - pts;
- absdiff = abs(diff);
+ while (img && (diff > img->duration)) {
+ pts = img->vpts;
+ diff = cur_vpts - pts;
- if (diff >this->pts_per_half_frame) {
- LOG_MSG(this->xine, _("video_out : throwing away image with pts %d because "
- "it's too old (diff : %d > %d).\n"),
- pts, diff, this->pts_per_half_frame);
+ if (diff > img->duration) {
+ LOG_MSG(this->xine,
+ _("video_out: throwing away image with pts %lld because "
+ "it's too old (diff : %lld).\n"), pts, diff);
- this->num_frames_discarded++;
+ this->num_frames_discarded++;
- img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
- /*
- * last frame? back it up for
- * still frame creation
- */
+ /*
+ * last frame? back it up for
+ * still frame creation
+ */
- if (!this->display_img_buf_queue->first) {
+ if (!this->display_img_buf_queue->first) {
- if (img_backup) {
- pthread_mutex_lock (&img_backup->mutex);
+ if (this->img_backup) {
+ pthread_mutex_lock (&this->img_backup->mutex);
#ifdef VIDEO_OUT_LOG
- printf("video_out : overwriting frame backup\n");
+ printf("video_out: overwriting frame backup\n");
#endif
- img_backup->display_locked = 0;
- if (!img->decoder_locked)
- vo_append_to_img_buf_queue (this->free_img_buf_queue, img_backup);
-
- pthread_mutex_unlock (&img_backup->mutex);
- }
- printf("video_out : possible still frame (old)\n");
- flush_sent = 0;
-
- /* we must not clear display_locked from img_backup.
- without it decoder may try to free our backup. */
- img_backup = img;
- backup_is_logo = 0;
- } else {
- pthread_mutex_lock (&img->mutex);
-
- img->display_locked = 0;
+ this->img_backup->display_locked = 0;
if (!img->decoder_locked)
- vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
-
- pthread_mutex_unlock (&img->mutex);
+ vo_append_to_img_buf_queue (this->free_img_buf_queue,
+ this->img_backup);
+
+ pthread_mutex_unlock (&this->img_backup->mutex);
}
-
- img = this->display_img_buf_queue->first;
+ printf("video_out: possible still frame (old)\n");
+
+ /* we must not clear display_locked from img_backup.
+ without it decoder may try to free our backup. */
+ this->img_backup = img;
+ this->backup_is_logo = 0;
+ } else {
+ pthread_mutex_lock (&img->mutex);
+
+ img->display_locked = 0;
+ if (!img->decoder_locked)
+ vo_append_to_img_buf_queue (this->free_img_buf_queue, img);
+
+ pthread_mutex_unlock (&img->mutex);
}
- }
+
+ img = this->display_img_buf_queue->first;
+ }
+ }
- /*
- * still frame detection:
- */
+}
+
+static vo_frame_t *get_next_frame (vos_t *this, int64_t cur_vpts) {
+
+ vo_frame_t *img;
+
+ img = this->display_img_buf_queue->first;
+
+ /*
+ * still frame detection:
+ */
- /* no frame? => still frame detection */
+ /* no frame? => still frame detection */
- if (!img) {
+ if (!img) {
#ifdef VIDEO_OUT_LOG
- printf ("video_out : no frame\n");
+ printf ("video_out: no frame\n");
#endif
- /*
- * display logo ?
- */
- if (!this->video_opened && (!img_backup || !backup_is_logo)) {
+ /*
+ * display logo ?
+ */
+ if (!this->video_opened && (!this->img_backup || !this->backup_is_logo)) {
- if (img_backup) {
- pthread_mutex_lock (&img_backup->mutex);
+ if (this->img_backup) {
+ pthread_mutex_lock (&this->img_backup->mutex);
#ifdef VIDEO_OUT_LOG
- printf("video_out : overwriting frame backup\n");
+ printf("video_out: overwriting frame backup\n");
#endif
- img_backup->display_locked = 0;
- if (!img_backup->decoder_locked)
- vo_append_to_img_buf_queue (this->free_img_buf_queue, img_backup);
+ this->img_backup->display_locked = 0;
+ if (!this->img_backup->decoder_locked)
+ vo_append_to_img_buf_queue (this->free_img_buf_queue,
+ this->img_backup);
- pthread_mutex_unlock (&img_backup->mutex);
- }
+ pthread_mutex_unlock (&this->img_backup->mutex);
+ }
- printf("video_out : copying logo image\n");
+ printf("video_out: copying logo image\n");
- img_backup = vo_get_frame (this, this->logo_w, this->logo_h,
- 42, IMGFMT_YUY2, 6000, VO_BOTH_FIELDS);
-
- img_backup->decoder_locked = 0;
- img_backup->display_locked = 1;
- img_backup->driver_locked = 0;
-
- xine_fast_memcpy(img_backup->base[0], this->logo_yuy2,
- this->logo_w*this->logo_h*2);
-
- /* this shouldn't be needed, duplicate_frame will call
- img->copy for us. [mf]
- if (img_backup->copy) {
- int height = this->logo_h;
- int stride = this->logo_w;
- uint8_t* src[3];
-
- src[0] = img_backup->base[0];
-
- while ((height -= 16) >= 0) {
- img_backup->copy(img_backup, src);
- src[0] += 32 * stride;
- }
- }
- */
-
- backup_is_logo = 1;
- }
+ this->img_backup = vo_get_frame (&this->vo, this->logo_w, this->logo_h,
+ 42, IMGFMT_YUY2, VO_BOTH_FIELDS);
+ this->img_backup->decoder_locked = 0;
+ this->img_backup->display_locked = 1;
+ this->img_backup->driver_locked = 0;
+ this->img_backup->duration = 10000;
- if (img_backup) {
+ xine_fast_memcpy(this->img_backup->base[0], this->logo_yuy2,
+ this->logo_w*this->logo_h*2);
- /*
- * wait until it's time to display this still frame
- */
- pts = this->metronom->get_current_time (this->metronom);
- do {
- xine_usec_sleep ( 10000 );
- cur_pts = this->metronom->get_current_time (this->metronom);
- /* using abs will avoid problems if metronom gets updated */
- diff = abs(cur_pts - pts);
-
- } while (diff < 2 * this->pts_per_frame) ;
+ this->backup_is_logo = 1;
+ }
- /* if some frame arrived dont generate still */
- if( this->display_img_buf_queue->first ) {
- xine_profiler_stop_count (prof_video_out);
- continue;
- }
+ if (this->img_backup) {
#ifdef VIDEO_OUT_LOG
- printf("video_out : generating still frame (cur_pts = %d) \n", cur_pts);
+ printf("video_out: generating still frame (cur_vpts = %lld) \n",
+ cur_vpts);
#endif
- /* keep playing still frames */
- img = this->duplicate_frame( this, img_backup );
- img->display_locked = 1;
+ /* keep playing still frames */
+ img = this->vo.duplicate_frame (&this->vo, this->img_backup );
+ img->display_locked = 1;
- img->PTS = cur_pts;
- diff = 0;
+ do {
+ this->metronom->got_video_frame(this->metronom, img);
+ } while (img->vpts < cur_vpts);
- } else {
+ return img;
+
+ } else {
#ifdef VIDEO_OUT_LOG
- printf ("video_out : no frame, but no backup frame\n");
+ printf ("video_out: no frame, but no backup frame\n");
#endif
- xine_profiler_stop_count (prof_video_out);
- continue;
- }
- } else {
+ return NULL;
+ }
+ } else {
- /*
- * time to display frame >img< ?
- */
+ int64_t diff;
+
+ diff = cur_vpts - img->vpts;
+
+ /*
+ * time to display frame "img" ?
+ */
#ifdef VIDEO_OUT_LOG
- printf ("video_out : diff %d\n", diff);
+ printf ("video_out: diff %lld\n", diff);
#endif
- if (diff<0) {
- xine_profiler_stop_count (prof_video_out);
- continue;
- }
+ if (diff < 0) {
+ return 0;
+ }
- if (img_backup) {
- pthread_mutex_lock (&img_backup->mutex);
- printf("video_out : freeing frame backup\n");
+ if (this->img_backup) {
+ pthread_mutex_lock (&this->img_backup->mutex);
+ printf("video_out: freeing frame backup\n");
- img_backup->display_locked = 0;
- if( !img_backup->decoder_locked )
- vo_append_to_img_buf_queue (this->free_img_buf_queue, img_backup);
- pthread_mutex_unlock (&img_backup->mutex);
- img_backup = NULL;
- }
+ this->img_backup->display_locked = 0;
+ if( !this->img_backup->decoder_locked )
+ vo_append_to_img_buf_queue (this->free_img_buf_queue,
+ this->img_backup);
+ pthread_mutex_unlock (&this->img_backup->mutex);
+ this->img_backup = NULL;
+ }
- /*
- * last frame? make backup for possible still image
- */
- if (img && !img->next &&
- (this->xine->video_fifo->size(this->xine->video_fifo) < 10 ||
- flush_sent || this->xine->video_in_discontinuity) ) {
+ /*
+ * last frame? make backup for possible still image
+ */
+ if (img && !img->next &&
+ (this->xine->video_fifo->size(this->xine->video_fifo) < 10
+ || this->xine->video_in_discontinuity) ) {
- printf("video_out : possible still frame (fifosize = %d, flushsent=%d)\n",
- this->xine->video_fifo->size(this->xine->video_fifo), flush_sent);
+ printf ("video_out: possible still frame (fifosize = %d)\n",
+ this->xine->video_fifo->size(this->xine->video_fifo));
- img_backup = this->duplicate_frame(this, img);
- backup_is_logo = 0;
- }
+ this->img_backup = this->vo.duplicate_frame (&this->vo, img);
+ this->backup_is_logo = 0;
+ }
- flush_sent = 0;
-
- /*
- * remove frame from display queue and show it
- */
+ /*
+ * remove frame from display queue and show it
+ */
- img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
+ img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
- if (!img) {
- xine_profiler_stop_count (prof_video_out);
- continue;
- }
- }
+ return img;
+ }
+}
+
+static void overlay_and_display_frame (vos_t *this,
+ vo_frame_t *img) {
+
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: displaying image with vpts = %lld\n",
+ img->vpts);
+#endif
+
+ pthread_mutex_lock (&img->mutex);
+ img->driver_locked = 1;
+
+#ifdef VIDEO_OUT_LOG
+ if (!img->display_locked)
+ printf ("video_out: ALERT! frame was not locked for display queue\n");
+#endif
+
+ img->display_locked = 0;
+ pthread_mutex_unlock (&img->mutex);
+
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: passing to video driver image with pts = %lld\n",
+ img->vpts);
+#endif
+
+ if (this->overlay_source) {
+ /* This is the only way for the overlay manager to get pts values
+ * for flushing its buffers. So don't remove it! */
+
+ this->overlay_source->multiple_overlay_blend (this->overlay_source,
+ img->vpts,
+ this->driver, img,
+ this->video_loop_running && this->overlay_enabled);
+ }
+
+ this->driver->display_frame (this->driver, img);
+}
+
+static void *video_out_loop (void *this_gen) {
+
+ int64_t vpts, diff;
+ vo_frame_t *img;
+ vos_t *this = (vos_t *) this_gen;
+ int64_t frame_duration, next_frame_pts;
+ int64_t usec_to_sleep;
+
+ /*
+ * here it is - the heart of xine (or rather: one of the hearts
+ * of xine) : the video output loop
+ */
+
+ frame_duration = 1500; /* default */
+ next_frame_pts = 0;
+
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out: loop starting...\n");
+#endif
+
+ while ( this->video_loop_running ) {
/*
- * from this point on, img must be a valid frame for
- * overlay and output
+ * get current time and find frame to display
*/
+ vpts = this->metronom->get_current_time (this->metronom);
#ifdef VIDEO_OUT_LOG
- printf ("video_out : displaying image with pts = %d (diff=%d)\n", pts, diff);
+ printf ("video_out: loop iteration at %lld\n", vpts);
#endif
+ expire_frames (this, vpts);
+ img = get_next_frame (this, vpts);
- pthread_mutex_lock (&img->mutex);
- img->driver_locked = 1;
+ /*
+ * if we have found a frame, display it
+ */
+
+ if (img)
+ overlay_and_display_frame (this, img);
+
+ /*
+ * if we haven't heared from the decoder for some time
+ * flush it
+ */
+
+ diff = vpts - this->last_delivery_pts;
+ if (diff > 30000) {
+ if (this->xine->cur_video_decoder_plugin) {
+ this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin);
#ifdef VIDEO_OUT_LOG
- if (!img->display_locked)
- printf ("video_out : ALERT! frame was not locked for display queue\n");
+ printf ("video_out: flushing current video decoder plugin\n");
#endif
- img->display_locked = 0;
- pthread_mutex_unlock (&img->mutex);
+ }
+ }
+
+ /*
+ * wait until it's time to display next frame
+ */
+
+ if (img)
+ frame_duration = img->duration;
+
+ next_frame_pts += frame_duration;
#ifdef VIDEO_OUT_LOG
- printf ("video_out : passing to video driver, image with pts = %d\n", pts);
+ printf ("video_out: next_frame_pts is %lld\n", next_frame_pts);
#endif
+
+ do {
+ vpts = this->metronom->get_current_time (this->metronom);
- if (this->overlay_source) {
- /* This is the only way for the overlay manager to get pts values
- * for flushing it's buffers. So don't remove it! */
- xine_profiler_start_count (prof_spu_blend);
+ usec_to_sleep = (next_frame_pts - vpts) * 100 / 9;
- this->overlay_source->multiple_overlay_blend (this->overlay_source, img->PTS,
- this->driver, img,
- this->video_loop_running && this->overlay_enabled);
- xine_profiler_stop_count (prof_spu_blend);
- }
-
- this->driver->display_frame (this->driver, img);
+ printf ("video_out: %lld usec to sleep at master vpts %lld\n",
+ usec_to_sleep, vpts);
+
+ if (usec_to_sleep>0)
+ xine_usec_sleep (usec_to_sleep);
- xine_profiler_stop_count (prof_video_out);
+ } while (usec_to_sleep > 0);
}
+
/*
* throw away undisplayed frames
*/
@@ -596,29 +716,32 @@ static void *video_out_loop (void *this_gen) {
img = this->display_img_buf_queue->first;
}
- if( img_backup ) {
- pthread_mutex_lock (&img_backup->mutex);
+ if (this->img_backup) {
+ pthread_mutex_lock (&this->img_backup->mutex);
- img_backup->display_locked = 0;
- if( !img_backup->decoder_locked )
- vo_append_to_img_buf_queue (this->free_img_buf_queue, img_backup);
+ this->img_backup->display_locked = 0;
+ if (!this->img_backup->decoder_locked)
+ vo_append_to_img_buf_queue (this->free_img_buf_queue, this->img_backup);
- pthread_mutex_unlock (&img_backup->mutex);
+ pthread_mutex_unlock (&this->img_backup->mutex);
}
pthread_exit(NULL);
}
-static uint32_t vo_get_capabilities (vo_instance_t *this) {
+static uint32_t vo_get_capabilities (vo_instance_t *this_gen) {
+ vos_t *this = (vos_t *) this_gen;
return this->driver->get_capabilities (this->driver);
}
-static vo_frame_t * vo_duplicate_frame( vo_instance_t *this, vo_frame_t *img ) {
+static vo_frame_t * vo_duplicate_frame( vo_instance_t *this_gen, vo_frame_t *img ) {
+
vo_frame_t *dupl;
- int image_size;
+ /* vos_t *this = (vos_t *) this_gen; */
+ int image_size;
- dupl = vo_get_frame( this, img->width, img->height, img->ratio,
- img->format, img->duration, VO_BOTH_FIELDS );
+ dupl = vo_get_frame (this_gen, img->width, img->height, img->ratio,
+ img->format, VO_BOTH_FIELDS );
pthread_mutex_lock (&dupl->mutex);
@@ -643,7 +766,10 @@ static vo_frame_t * vo_duplicate_frame( vo_instance_t *this, vo_frame_t *img ) {
}
dupl->bad_frame = 0;
- dupl->PTS = dupl->SCR = 0;
+ dupl->pts = 0;
+ dupl->vpts = 0;
+ dupl->scr = 0;
+ dupl->duration = img->duration;
/* Support copy; Dangerous, since some decoders may use a source that's
* not dupl->base. It's up to the copy implementation to check for NULL */
@@ -683,14 +809,18 @@ static vo_frame_t * vo_duplicate_frame( vo_instance_t *this, vo_frame_t *img ) {
return dupl;
}
-static void vo_open (vo_instance_t *this) {
+static void vo_open (vo_instance_t *this_gen) {
+
+ vos_t *this = (vos_t *) this_gen;
- this->decoder_started_flag = 0;
this->video_opened = 1;
+ this->last_delivery_pts = 0;
}
-static void vo_close (vo_instance_t *this) {
-
+static void vo_close (vo_instance_t *this_gen) {
+
+ vos_t *this = (vos_t *) this_gen;
+
/* this will make sure all hide events were processed */
if (this->overlay_source)
this->overlay_source->flush_events (this->overlay_source);
@@ -698,7 +828,8 @@ static void vo_close (vo_instance_t *this) {
this->video_opened = 0;
}
-static void vo_free_img_buffers (vo_instance_t *this) {
+static void vo_free_img_buffers (vo_instance_t *this_gen) {
+ vos_t *this = (vos_t *) this_gen;
vo_frame_t *img;
while (this->free_img_buf_queue->first) {
@@ -712,163 +843,45 @@ static void vo_free_img_buffers (vo_instance_t *this) {
}
}
-static void vo_exit (vo_instance_t *this) {
+static void vo_exit (vo_instance_t *this_gen) {
+
+ vos_t *this = (vos_t *) this_gen;
printf ("video_out: vo_exit...\n");
if (this->video_loop_running) {
void *p;
this->video_loop_running = 0;
- this->video_paused = 0;
pthread_join (this->video_thread, &p);
}
- vo_free_img_buffers (this);
+ vo_free_img_buffers (this_gen);
this->driver->exit (this->driver);
printf ("video_out: vo_exit... done\n");
}
-static void vo_frame_displayed (vo_frame_t *img) {
-
- pthread_mutex_lock (&img->mutex);
-
- img->driver_locked = 0;
-
- if (!img->decoder_locked) {
- vo_append_to_img_buf_queue (img->instance->free_img_buf_queue, img);
- }
-
- pthread_mutex_unlock (&img->mutex);
-}
-
-static void vo_frame_free (vo_frame_t *img) {
-
- pthread_mutex_lock (&img->mutex);
- img->decoder_locked = 0;
-
- if (!img->display_locked && !img->driver_locked ) {
- vo_append_to_img_buf_queue (img->instance->free_img_buf_queue, img);
- }
-
- pthread_mutex_unlock (&img->mutex);
-}
-
-static vo_frame_t *vo_get_last_frame (vo_instance_t *this) {
+static vo_frame_t *vo_get_last_frame (vo_instance_t *this_gen) {
+ vos_t *this = (vos_t *) this_gen;
return this->last_frame;
}
-static int vo_frame_draw (vo_frame_t *img) {
-
- vo_instance_t *this = img->instance;
- int32_t diff;
- uint32_t cur_vpts;
- uint32_t pic_vpts ;
- int frames_to_skip;
-
- pic_vpts = this->metronom->got_video_frame (this->metronom, img->PTS, img->SCR);
-
-#ifdef VIDEO_OUT_LOG
- printf ("video_out : got image %d. vpts for picture is %d (pts was %d)\n",
- img, pic_vpts, img->PTS);
-#endif
-
- img->PTS = pic_vpts;
- this->num_frames_delivered++;
-
- cur_vpts = this->metronom->get_current_time(this->metronom);
- this->last_draw_vpts = cur_vpts;
-
- diff = pic_vpts - cur_vpts;
- frames_to_skip = ((-1 * diff) / this->pts_per_frame + 3) * 2;
-
-#ifdef VIDEO_OUT_LOG
- printf ("video_out : delivery diff : %d\n",diff);
-#endif
-
- if (img->display_locked) {
- LOG_MSG(this->xine, _("video_out : ALERT! frame is already locked for displaying\n"));
- return frames_to_skip;
- }
-
- if (cur_vpts>0) {
-
- if (diff<(-1 * this->pts_per_half_frame) && img->drawn != 2 ) {
-
- this->num_frames_discarded++;
-#ifdef VIDEO_OUT_LOG
- printf ("video_out : frame rejected, %d frames to skip\n", frames_to_skip);
-#endif
-
- LOG_MSG(this->xine, _("video_out: rejected, %d frames to skip\n"), frames_to_skip);
-
- pthread_mutex_lock (&img->mutex);
- img->display_locked = 0;
- pthread_mutex_unlock (&img->mutex);
-
- vo_frame_displayed (img);
-
- this->last_frame = img;
-
- return frames_to_skip;
-
- }
- } /* else: we are probably in precaching mode */
-
- if (!img->bad_frame) {
- /*
- * put frame into FIFO-Buffer
- */
-
-#ifdef VIDEO_OUT_LOG
- printf ("video_out : frame is ok => appending to display buffer\n");
-#endif
-
- this->last_frame = img;
-
- pthread_mutex_lock (&img->mutex);
- img->display_locked = 1;
- pthread_mutex_unlock (&img->mutex);
-
- vo_append_to_img_buf_queue (this->display_img_buf_queue, img);
-
- } else {
- this->num_frames_skipped++;
-
- pthread_mutex_lock (&img->mutex);
- img->display_locked = 0;
- pthread_mutex_unlock (&img->mutex);
-
- vo_frame_displayed (img);
- }
-
- /*
- * performance measurement
- */
-
- if (this->num_frames_delivered>199) {
- LOG_MSG_STDERR(this->xine,
- _("%d frames delivered, %d frames skipped, %d frames discarded\n"),
- this->num_frames_delivered, this->num_frames_skipped, this->num_frames_discarded);
+/*
+ * overlay stuff
+ */
- this->num_frames_delivered = 0;
- this->num_frames_discarded = 0;
- this->num_frames_skipped = 0;
- }
-
- return frames_to_skip;
+static video_overlay_instance_t *vo_get_overlay_instance (vo_instance_t *this_gen) {
+ vos_t *this = (vos_t *) this_gen;
+ return this->overlay_source;
}
-static void vo_enable_overlay (vo_instance_t *this, int overlay_enabled) {
+static void vo_enable_overlay (vo_instance_t *this_gen, int overlay_enabled) {
+ vos_t *this = (vos_t *) this_gen;
this->overlay_enabled = overlay_enabled;
}
-static void vo_decoder_started (vo_instance_t *this) {
- this->decoder_started_flag = 1;
-}
-
static uint16_t gzread_i16(gzFile *fp) {
uint16_t ret;
ret = gzgetc(fp) << 8 ;
@@ -880,28 +893,28 @@ static uint16_t gzread_i16(gzFile *fp) {
vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) {
- vo_instance_t *this;
+ vos_t *this;
int i;
char pathname[LOGO_PATH_MAX];
pthread_attr_t pth_attrs;
int err;
gzFile *fp;
+ this = xine_xmalloc (sizeof (vos_t)) ;
- this = xine_xmalloc (sizeof (vo_instance_t)) ;
this->driver = driver;
this->xine = xine;
this->metronom = xine->metronom;
- this->open = vo_open;
- this->get_frame = vo_get_frame;
- this->duplicate_frame = vo_duplicate_frame;
- this->get_last_frame = vo_get_last_frame;
- this->close = vo_close;
- this->exit = vo_exit;
- this->get_capabilities = vo_get_capabilities;
- this->enable_ovl = vo_enable_overlay;
- this->decoder_started = vo_decoder_started;
+ this->vo.open = vo_open;
+ this->vo.get_frame = vo_get_frame;
+ this->vo.duplicate_frame = vo_duplicate_frame;
+ this->vo.get_last_frame = vo_get_last_frame;
+ this->vo.close = vo_close;
+ this->vo.exit = vo_exit;
+ this->vo.get_capabilities = vo_get_capabilities;
+ this->vo.enable_ovl = vo_enable_overlay;
+ this->vo.get_overlay_instance = vo_get_overlay_instance;
this->num_frames_delivered = 0;
this->num_frames_skipped = 0;
@@ -909,9 +922,9 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) {
this->free_img_buf_queue = vo_new_img_buf_queue ();
this->display_img_buf_queue = vo_new_img_buf_queue ();
this->video_loop_running = 0;
- this->video_paused = 0;
- this->pts_per_frame = 6000;
- this->pts_per_half_frame = 3000;
+
+ this->img_backup = NULL;
+ this->backup_is_logo = 0;
this->overlay_source = video_overlay_new_instance();
this->overlay_source->init (this->overlay_source);
@@ -922,7 +935,7 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) {
img = driver->alloc_frame (driver) ;
- img->instance = this;
+ img->instance = &this->vo;
img->free = vo_frame_free ;
img->displayed = vo_frame_displayed;
img->draw = vo_frame_draw;
@@ -961,7 +974,6 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) {
*/
this->video_loop_running = 1;
- this->decoder_started_flag = 0;
this->video_opened = 0;
pthread_attr_init(&pth_attrs);
@@ -976,10 +988,7 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, xine_t *xine) {
printf (_("video_out: sorry, this should not happen. please restart xine.\n"));
exit(1);
} else
- LOG_MSG(this->xine, _("video_out : thread created\n"));
+ LOG_MSG(this->xine, _("video_out: thread created\n"));
- return this;
+ return &this->vo;
}
-
-
-
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 7738e8ad8..a75547236 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
* This file is part of xine, a free video player.
*
@@ -17,11 +17,19 @@
* 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.h,v 1.39 2002/01/24 23:09:54 guenter Exp $
+ * $Id: video_out.h,v 1.40 2002/02/09 07:13:24 guenter Exp $
*
*
* xine version of video_out.h
*
+ * vo_frame : frame containing yuv data and timing info,
+ * transferred between video_decoder and video_output
+ *
+ * vo_driver : lowlevel, platform-specific video output code
+ *
+ * vo_instance : generic frame_handling code, uses
+ * a vo_driver for output
+ *
*/
#ifndef HAVE_VIDEO_OUT_H
@@ -38,6 +46,7 @@ extern "C" {
#include <inttypes.h>
#include <pthread.h>
+#if 0
#if defined(XINE_COMPILE)
#include "configfile.h"
#include "metronom.h"
@@ -47,6 +56,7 @@ extern "C" {
#include "xine/metronom.h"
#include "xine/buffer.h"
#endif
+#endif
#define VIDEO_OUT_PLUGIN_IFACE_VERSION 1
@@ -58,46 +68,50 @@ typedef struct img_buf_fifo_s img_buf_fifo_t;
typedef struct vo_overlay_s vo_overlay_t;
typedef struct video_overlay_instance_s video_overlay_instance_t;
typedef struct xine_s xine_t;
+typedef struct vo_private_s vo_private_t;
/* public part, video drivers may add private fields */
struct vo_frame_s {
struct vo_frame_s *next;
- uint32_t PTS;
- uint32_t pts_corrector; /* Repeat first field tricks */
- uint32_t SCR;
- int bad_frame; /* e.g. frame skipped or based on skipped frame */
- int drawn;
- uint8_t *base[3];
+ int64_t pts; /* presentation time stamp (1/90000 sec) */
+ int64_t vpts; /* virtual pts, generated by metronom */
+ int64_t pts_corrector; /* used for pepeat first field tricks */
+ int64_t scr; /* system clock reference (discont. detection) */
+ int bad_frame; /* e.g. frame skipped or based on skipped frame */
+ int duration; /* frame length in time, in 1/90000 sec */
+ /* yv12 (planar) base[0]: y, base[1]: u, base[2]: v */
+ /* yuy2 (interleaved) base[0]: yuyv..., base[1]: --, base[2]: -- */
+ uint8_t *base[3];
- /* additional information to be able to duplicate frames: */
+ /* info that can be used for interlaced output (e.g. tv-out) */
+ int top_field_first;
+ int repeat_first_field;
+
+ /* additional information to be able to duplicate frames: */
int width, height;
- int ratio, format;
- int duration;
- int aspect_ratio;
- int frame_rate_code;
- int progressive_sequence;
- int top_field_first;
- int repeat_first_field;
- int progressive_frame;
- int picture_coding_type;
- int bitrate;
+ int ratio; /* aspect ratio, codes see below */
+ int format; /* IMGFMT_YV12 or IMGFMT_RGB */
+
+ int drawn; /* used by decoder, frame has already been drawn */
int display_locked, decoder_locked, driver_locked;
pthread_mutex_t mutex; /* so the various locks will be serialized */
- vo_instance_t *instance;
+ /* "backward" references to where this frame originates from */
+ vo_instance_t *instance;
+ vo_driver_t *driver;
/*
* member functions
*/
- /* this frame is no longer used by decoder */
+ /* this frame is no longer used by the decoder */
void (*free) (vo_frame_t *vo_img);
- /* tell video driver to copy/convert a slice of this frame */
+ /* tell video driver to copy/convert a slice of this frame, may be NULL */
void (*copy) (vo_frame_t *vo_img, uint8_t **src);
/* tell video driver that the decoder starts a new field */
@@ -128,13 +142,11 @@ struct vo_instance_s {
* height == height of video to display.
* ratio == aspect ration information
* format == FOURCC descriptor of image format
- * duration == frame duration in 1/90000 sec
* flags == field/prediction flags
*/
vo_frame_t* (*get_frame) (vo_instance_t *this, uint32_t width,
uint32_t height, int ratio_code,
- int format, uint32_t duration,
- int flags);
+ int format, int flags);
vo_frame_t* (*get_last_frame) (vo_instance_t *this);
@@ -146,46 +158,18 @@ struct vo_instance_s {
/* overlay stuff */
void (*enable_ovl) (vo_instance_t *this, int ovl_enable);
- video_overlay_instance_t *overlay_source;
- int overlay_enabled;
- /* this is just a hint to video_out to detect single frame streams */
- void (*decoder_started) (vo_instance_t *this);
-
/* video driver is no longer used by decoder => close */
void (*close) (vo_instance_t *this);
/* called on xine exit */
void (*exit) (vo_instance_t *this);
- /* private stuff */
-
- vo_driver_t *driver;
- metronom_t *metronom;
- xine_t *xine;
-
- img_buf_fifo_t *free_img_buf_queue;
- img_buf_fifo_t *display_img_buf_queue;
-
- vo_frame_t *last_frame;
-
- int video_loop_running;
- int video_opened;
- int video_paused;
- pthread_t video_thread;
-
- int pts_per_half_frame;
- int pts_per_frame;
-
- int num_frames_delivered;
- int num_frames_skipped;
- int num_frames_discarded;
+ /* get overlay instance (overlay source) */
+ video_overlay_instance_t* (*get_overlay_instance) (vo_instance_t *this);
- int decoder_started_flag;
- uint32_t last_draw_vpts;
+ /* private stuff can be added here */
- int logo_w, logo_h;
- uint8_t *logo_yuy2;
} ;
/* constants for the get/set property functions */
@@ -225,7 +209,7 @@ struct vo_instance_s {
#define IMGFMT_YV12 0x32315659
#define IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y')
-#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8))
+/*#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) unused */
/* possible ratios for the VO_PROP_ASPECT_RATIO call */
diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h
index 5752642c9..08bf6e0a6 100644
--- a/src/xine-engine/video_overlay.h
+++ b/src/xine-engine/video_overlay.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: video_overlay.h,v 1.4 2002/01/05 19:09:55 jcdutton Exp $
+ * $Id: video_overlay.h,v 1.5 2002/02/09 07:13:24 guenter Exp $
*
*/
@@ -32,33 +32,33 @@
#define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) { (_cb), (_cr), (_y) }
#endif
-#define MAX_OBJECTS 50
-#define MAX_EVENTS 50
-#define MAX_SHOWING 5
+#define MAX_OBJECTS 50
+#define MAX_EVENTS 50
+#define MAX_SHOWING 5
-#define EVENT_NULL 0
-#define EVENT_SHOW_SPU 1
-#define EVENT_HIDE_SPU 2
-#define EVENT_HIDE_MENU 3
-#define EVENT_MENU_SPU 4
-#define EVENT_MENU_BUTTON 5
-#define EVENT_DELETE_RESOURCE 6 /* Maybe release handle will do this */
-#define EVENT_SHOW_OSD 7 /* Not yet implemented */
-#define EVENT_FREE_HANDLE 8 /* Frees a handle, previous allocated via get_handle */
+#define EVENT_NULL 0
+#define EVENT_SHOW_SPU 1
+#define EVENT_HIDE_SPU 2
+#define EVENT_HIDE_MENU 3
+#define EVENT_MENU_SPU 4
+#define EVENT_MENU_BUTTON 5
+#define EVENT_DELETE_RESOURCE 6 /* Maybe release handle will do this */
+#define EVENT_SHOW_OSD 7 /* Not yet implemented */
+#define EVENT_FREE_HANDLE 8 /* Frees a handle, previous allocated via get_handle */
typedef struct video_overlay_object_s {
- int32_t handle; /* Used to match Show and Hide events. */
- uint32_t object_type; /* 0=Subtitle, 1=Menu */
- uint32_t pts; /* Needed for Menu button compares */
- vo_overlay_t *overlay; /* The image data. */
+ int32_t handle; /* Used to match Show and Hide events. */
+ uint32_t object_type; /* 0=Subtitle, 1=Menu */
+ uint32_t pts; /* Needed for Menu button compares */
+ vo_overlay_t *overlay; /* The image data. */
uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */
- uint32_t *palette; /* If NULL, no palette contained in this event. */
+ uint32_t *palette; /* If NULL, no palette contained in this event. */
} video_overlay_object_t;
/* This will hold all details of an event item, needed for event queue to function */
typedef struct video_overlay_event_s {
uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */
- uint32_t vpts; /* Time when event will action. 0 means action now */
+ uint32_t vpts; /* Time when event will action. 0 means action now */
/* Once video_out blend_yuv etc. can take rle_elem_t with Colour, blend and length information.
* we can remove clut and blend from this structure.
* This will allow for many more colours for OSD.
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 5f8e9be8d..1329dde12 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.102 2002/02/01 09:59:08 f1rmb Exp $
+ * $Id: xine.c,v 1.103 2002/02/09 07:13:24 guenter Exp $
*
* top-level xine functions
*
@@ -159,7 +159,7 @@ void xine_stop_internal (xine_t *this) {
this->metronom->set_speed (this->metronom, SPEED_NORMAL);
this->speed = SPEED_NORMAL;
- this->video_out->video_paused = 0;
+
if( this->audio_out )
this->audio_out->audio_paused = 0;
@@ -298,11 +298,6 @@ int xine_play (xine_t *this, char *mrl,
this->cur_input_plugin->stop(this->cur_input_plugin);
}
- /* this will make output threads discard about everything
- (seeking should be faster!) */
- this->metronom->adjust_clock(this->metronom,
- this->metronom->get_current_time(this->metronom) + 30 * 90000 );
-
this->status = XINE_STOP;
}
@@ -373,7 +368,7 @@ int xine_play (xine_t *this, char *mrl,
strncpy (this->cur_mrl, mrl, 1024);
this->metronom->set_speed (this->metronom, SPEED_NORMAL);
- this->video_out->video_paused = 0;
+
if( this->audio_out )
this->audio_out->audio_paused = 0;
this->speed = SPEED_NORMAL;
@@ -504,7 +499,7 @@ xine_t *xine_init (vo_driver_t *vo,
this->video_out = vo_new_instance (vo, this);
video_decoder_init (this);
- this->osd_renderer = osd_renderer_init( this->video_out->overlay_source, config );
+ this->osd_renderer = osd_renderer_init (this->video_out->get_overlay_instance (this->video_out), config );
this->osd = this->osd_renderer->new_object (this->osd_renderer, 300, 100);
this->osd_renderer->set_font (this->osd, "cetus", 24);
@@ -704,7 +699,6 @@ void xine_set_speed (xine_t *this, int speed) {
this->metronom->set_speed (this->metronom, speed);
- this->video_out->video_paused = (speed == SPEED_PAUSE);
/* see coment on audio_out loop about audio_paused */
if( this->audio_out )
this->audio_out->audio_paused = (speed != SPEED_NORMAL) +