summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-07-08 18:15:54 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-07-08 18:15:54 +0000
commitc980a592bd835f2c0826e4f0638cef3fabd70ee7 (patch)
treeecf5e9adcd28cabe0d59e0842780a1dbb3cc0633
parentfbf6214d84dbed2b9e22da164748eca8c762cb82 (diff)
downloadxine-lib-c980a592bd835f2c0826e4f0638cef3fabd70ee7.tar.gz
xine-lib-c980a592bd835f2c0826e4f0638cef3fabd70ee7.tar.bz2
subtitle patches from james
CVS patchset: 259 CVS date: 2001/07/08 18:15:54
-rw-r--r--include/xine.h.tmpl.in3
-rw-r--r--src/libspudec/spu.c25
-rw-r--r--src/libspudec/xine_decoder.c22
-rw-r--r--src/video_out/alphablend.c40
-rw-r--r--src/video_out/video_out_xv.c17
-rw-r--r--src/xine-engine/metronom.c12
-rw-r--r--src/xine-engine/metronom.h5
-rw-r--r--src/xine-engine/spu_decoder.c5
-rw-r--r--src/xine-engine/video_out.c137
-rw-r--r--src/xine-engine/video_out.h16
10 files changed, 192 insertions, 90 deletions
diff --git a/include/xine.h.tmpl.in b/include/xine.h.tmpl.in
index 242994d28..41030a86f 100644
--- a/include/xine.h.tmpl.in
+++ b/include/xine.h.tmpl.in
@@ -29,7 +29,7 @@
\endverbatim
*/
/*
- * $Id: xine.h.tmpl.in,v 1.25 2001/07/04 17:10:24 uid32519 Exp $
+ * $Id: xine.h.tmpl.in,v 1.26 2001/07/08 18:15:54 guenter Exp $
*
*/
@@ -153,6 +153,7 @@ struct vo_driver_s {
void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img);
/* overlay functions */
+ void (*overlay_blend) (vo_frame_t *vo_img, vo_overlay_t *overlay);
void (*set_overlay) (vo_driver_t *this, vo_overlay_t *overlay);
/*
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index bb8717142..b17cddc00 100644
--- a/src/libspudec/spu.c
+++ b/src/libspudec/spu.c
@@ -173,12 +173,10 @@ static struct reassembly_s *_reassembly (uint8_t *pkt_data, u_int pkt_len)
// the whole spu fits into the supplied packet
if (pkt_len >= reassembly.buf_len) {
- LOG (LOG_DEBUG, "0)");
reassembly.buf = pkt_data;
reassembly_flag = REASSEMBLY_UNNEEDED;
return &reassembly;
} else {
- LOG (LOG_DEBUG, "1)");
if (!(reassembly.buf = malloc (reassembly.buf_len + 1))) {
LOG (LOG_DEBUG, "unable to alloc buffer");
return NULL;
@@ -190,7 +188,6 @@ static struct reassembly_s *_reassembly (uint8_t *pkt_data, u_int pkt_len)
reassembly_flag = REASSEMBLY_MID;
}
} else {
- LOG (LOG_DEBUG, "2)");
if ((reassembly.buf_ptr+pkt_len) > (reassembly.buf+reassembly.buf_len))
pkt_len = reassembly.buf_len - (reassembly.buf_ptr - reassembly.buf);
@@ -204,7 +201,6 @@ static struct reassembly_s *_reassembly (uint8_t *pkt_data, u_int pkt_len)
}
}
- LOG (LOG_DEBUG, "3)");
return NULL;
}
@@ -238,8 +234,8 @@ int spuParseHdr (vo_overlay_t *spu, uint8_t *pkt_data, u_int pkt_len)
while (DCSQ_offset != prev_DCSQ_offset) { /* Display Control Sequences */
u_int i = DCSQ_offset;
- spu->duration = /* PTS + */ ((buf[i] << 8) + buf[i+1]) * TIME_UNIT;
- LOG (LOG_DEBUG, "time = %d ms", spu->duration);
+ spu->duration = /* Frames + */ ((buf[i] << 8) + buf[i+1]) /* * TIME_UNIT */ ;
+ LOG (LOG_DEBUG, "duration = %d frames", spu->duration);
i += 2;
prev_DCSQ_offset = DCSQ_offset;
@@ -271,17 +267,12 @@ int spuParseHdr (vo_overlay_t *spu, uint8_t *pkt_data, u_int pkt_len)
break;
}
case CMD_SPU_SET_ALPHA: { /* transparency palette */
-#ifndef DENT_TEST
spu_clut_t *trans = (spu_clut_t *) &buf[i+1];
spu->trans[3] = trans->entry0;
spu->trans[2] = trans->entry1;
spu->trans[1] = trans->entry2;
spu->trans[0] = trans->entry3;
-#else
- spu->trans[0] = 0;
- spu->trans[1] = spu->trans[2] = spu->trans[3] = 15;
-#endif
LOG (LOG_DEBUG, "\ttrans [%d %d %d %d]\n",
spu->trans[0], spu->trans[1], spu->trans[2], spu->trans[3]);
i += 3;
@@ -299,7 +290,9 @@ int spuParseHdr (vo_overlay_t *spu, uint8_t *pkt_data, u_int pkt_len)
spu->height = (((buf[i+5] & 0x0f) << 8)
| buf[i+6]) - spu->y + 1; /* 1-576 */
- spu->data = (uint8_t *) malloc (spu->width * spu->height * sizeof (uint8_t));
+ if (spu->data) spu->data = (uint8_t *) realloc (spu->data,spu->width * spu->height * sizeof (uint8_t));
+ else spu->data = (uint8_t *) malloc (spu->width * spu->height * sizeof (uint8_t));
+
/* Private stuff */
spu->_x = spu->_y = 0;
LOG (LOG_DEBUG, "\tx = %d y = %d width = %d height = %d",
@@ -320,14 +313,6 @@ int spuParseHdr (vo_overlay_t *spu, uint8_t *pkt_data, u_int pkt_len)
* hardcoded menu clut, uncomment this and comment CMD_SPU_SET_PALETTE and
* CMD_SPU_SET_ALPHA to see the menu buttons
*/
-#ifdef DENT_TEST
- spu->clut[0] = 0;
- spu->clut[1] = 9;
- spu->clut[2] = 8;
- spu->clut[3] = 12;
- spu->trans[0] = 0;
- spu->trans[1] = spu->trans[2] = spu->trans[3] = 15;
-#endif
i++;
break;
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index 8f9acdeb6..714ebe179 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.2 2001/07/04 20:32:29 uid32519 Exp $
+ * $Id: xine_decoder.c,v 1.3 2001/07/08 18:15:54 guenter Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -73,15 +73,12 @@ int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {
void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
- printf("spudec_init %p\n",&vo_out);
this->vo_out = vo_out;
this->spu_caps = vo_out->get_capabilities(vo_out);
this->syncword = 0;
this->sync_todo = 6;
this->output_open = 0;
-// spu_init ();
-
}
/* overlay_txt is just for test purposes */
@@ -108,7 +105,7 @@ u_int *overlay_txt (vo_overlay_t *spu, float o1)
//clr_ptr2 = (u_char *) &spu_clut[*spu_data_ptr&0x0f];
*clr_ptr2 = *spu_data_ptr&0x0f;
tmp=*spu_data_ptr;
- printf("%X%X",tmp&0x0f,((tmp>>4)&0x0f));
+ //printf("%X%X",tmp&0x0f,((tmp>>4)&0x0f));
spu_data_ptr ++;
// printf("%d ",(*clr_ptr2++));
@@ -127,9 +124,6 @@ void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
uint8_t *current = buf->content;
- /* uint8_t *end = buf->content + buf->size; */
-
- printf ("spudec_decode_data\n");
if (!this->spu) {
this->spu = this->vo_out->get_overlay (this->vo_out);
@@ -139,23 +133,23 @@ void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if (!this->spu)
return;
+ this->spu->PTS = buf->PTS;
if (!spuParseHdr (this->spu, current, buf->size)) {
spuParseData (this->spu);
- printf("X=%d Y=%d w=%d h=%d\n",
- this->spu->x,this->spu->y,
- this->spu->width,this->spu->height);
/* overlay_txt(this->spu,1.0); Just for test purposes */
- this->spu->PTS = buf->PTS;
+ this->vo_out->queue_overlay (this->vo_out, this->spu);
+ this->spu = NULL;
+ } else {
+ this->spu->data=NULL;
this->vo_out->queue_overlay (this->vo_out, this->spu);
this->spu = NULL;
}
-
}
void spudec_close (spu_decoder_t *this_gen) {
/* spudec_decoder_t *this = (spudec_decoder_t *) this_gen; */
-
+/* FIXME not implemented */
// if (this->output_open)
// this->spu_out->close (this->spu_out);
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c
index 134c8aac3..65f96e5c0 100644
--- a/src/video_out/alphablend.c
+++ b/src/video_out/alphablend.c
@@ -1,7 +1,7 @@
//TOAST_SPU will define ALL spu entries - no matter the tranparency
//#define TOAST_SPU
/* #define PRIV_CLUT */
-
+/* Currently only blend_yuv(..) works */
/*
*
* Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001
@@ -34,6 +34,18 @@
#include "video_out.h"
+/* FIXME: CLUT_T should go elsewhere. */
+#ifndef CLUT_T
+#define CLUT_T
+typedef struct { // CLUT == Color LookUp Table
+ uint8_t:8;
+ uint8_t y:8;
+ uint8_t cr:8;
+ uint8_t cb:8;
+} __attribute__ ((packed)) clut_t;
+#endif
+
+
#define BLEND_COLOR(dst, src, mask, o) ((((src&mask)*o + ((dst&mask)*(0x0f-o)))/0xf) & mask)
static inline uint16_t blendpixel_rgb16 (uint16_t dst, uint16_t src,
@@ -227,7 +239,8 @@ void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl,
int dst_width, int dst_height)
{
-#ifdef PRIV_CLUT
+/* FIXME: my_clut should disappear once I find out how to get the clut from the MPEG2 stream. */
+/* This happens to work with "The Matrix" using 0(black), 8(white) and 9(edges) */
clut_t my_clut[] = {
{y: 0x51, cr: 0xef, cb:0x5a},
{y: 0xbf, cr: 0x80, cb:0x80},
@@ -237,8 +250,8 @@ void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl,
{y: 0xbf, cr: 0x80, cb:0x80},
{y: 0x36, cr: 0x80, cb:0x80},
{y: 0x28, cr: 0x6d, cb:0xef},
- {y: 0x5c, cr: 0x80, cb:0x80},
{y: 0xbf, cr: 0x80, cb:0x80},
+ {y: 0x5c, cr: 0x80, cb:0x80},
{y: 0x10, cr: 0x80, cb:0x80},
{y: 0x28, cr: 0x6d, cb:0xef},
{y: 0x5c, cr: 0x80, cb:0x80},
@@ -246,7 +259,6 @@ void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl,
{y: 0x1c, cr: 0x80, cb:0x80},
{y: 0x28, cr: 0x6d, cb:0xef}
};
-#endif
int src_width = img_overl->width;
int src_height = img_overl->height;
@@ -269,30 +281,18 @@ void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl,
uint8_t clr;
uint8_t o;
- clr = img_overl->clut[*src_data & 0x0f];
- o = img_overl->trans[*src_data & 0x0f];
+ clr = img_overl->clut[*src_data & 0x03];
+ o = img_overl->trans[*src_data & 0x03];
- if (clr)
-// *INDENT-OFF*
-#ifdef PRIV_CLUT
+ if (clr) {
*dst_y = BLEND_YUV (*dst_y, my_clut[clr].y, o);
-#else
- *dst_y = BLEND_YUV (*dst_y, img_overl->clut[clr]/*.y*/, o);
-#endif
-// *INDENT-ON*
+ }
dst_y++;
if (y & x & 1) {
if (clr) {
-// *INDENT-OFF*
-#ifdef PRIV_CLUT
*dst_cr = BLEND_YUV (*dst_cr, my_clut[clr].cr, o);
*dst_cb = BLEND_YUV (*dst_cb, my_clut[clr].cb, o);
-#else
- *dst_cr = BLEND_YUV (*dst_cr, img_overl->clut [clr]/*.cr*/, o);
- *dst_cb = BLEND_YUV (*dst_cb, img_overl->clut [clr]/*.cb*/, o);
-#endif
-// *INDENT-ON*
}
dst_cr++;
dst_cb++;
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 38bdca7e3..ce0b74e4c 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.49 2001/07/04 20:32:29 uid32519 Exp $
+ * $Id: video_out_xv.c,v 1.50 2001/07/08 18:15:54 guenter Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -539,6 +539,20 @@ static void xv_calc_format (xv_driver_t *this,
/*
*
*/
+static void xv_overlay_blend (vo_frame_t *frame_gen, vo_overlay_t *overlay) {
+
+ xv_frame_t *frame = (xv_frame_t *) frame_gen;
+
+// Alpha Blend here
+// As XV drivers improve to support Hardware overlay, we will change this function.
+ if (overlay->data) {
+ blend_yuv( frame->image->data, overlay, frame->width, frame->height);
+ }
+}
+
+/*
+ *
+ */
static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -880,6 +894,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->vo_driver.get_capabilities = xv_get_capabilities;
this->vo_driver.alloc_frame = xv_alloc_frame;
this->vo_driver.update_frame_format = xv_update_frame_format;
+ this->vo_driver.overlay_blend = xv_overlay_blend;
this->vo_driver.display_frame = xv_display_frame;
this->vo_driver.set_overlay = xv_set_overlay;
this->vo_driver.get_property = xv_get_property;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index ef6706ebf..bdea19b8e 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.14 2001/07/04 17:10:24 uid32519 Exp $
+ * $Id: metronom.c,v 1.15 2001/07/08 18:15:54 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -281,9 +281,13 @@ static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
}
-static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts) {
- /* FIXME: not tested */
-
+static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts,uint32_t duration) {
+ if (pts) {
+ this->spu_vpts=pts;
+ } else {
+ pts=this->spu_vpts;
+ this->spu_vpts=this->spu_vpts;
+ }
return pts + this->video_wrap_offset;
}
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index e7080b57d..49058124c 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.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: metronom.h,v 1.6 2001/07/04 17:10:24 uid32519 Exp $
+ * $Id: metronom.h,v 1.7 2001/07/08 18:15:54 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -107,7 +107,7 @@ struct metronom_s {
*
*/
- uint32_t (*got_spu_packet) (metronom_t *this, uint32_t pts);
+ uint32_t (*got_spu_packet) (metronom_t *this, uint32_t pts, uint32_t duration);
/*
* manually correct audio <-> video sync
@@ -161,6 +161,7 @@ struct metronom_s {
int32_t audio_pts_delta;
uint32_t video_vpts;
+ uint32_t spu_vpts;
uint32_t audio_vpts;
int32_t video_wrap_offset;
diff --git a/src/xine-engine/spu_decoder.c b/src/xine-engine/spu_decoder.c
index 047f9b90d..c4246e622 100644
--- a/src/xine-engine/spu_decoder.c
+++ b/src/xine-engine/spu_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: spu_decoder.c,v 1.4 2001/07/04 20:32:29 uid32519 Exp $
+ * $Id: spu_decoder.c,v 1.5 2001/07/08 18:15:54 guenter Exp $
*
* functions that implement spu decoding
@@ -57,6 +57,7 @@ void *spu_decoder_loop (void *this_gen) {
this->spu_finished = 0;
pthread_mutex_unlock (&this->xine_lock);
+/* FIXME: I don't think we need spu_track_map. */
for (i=0 ; i<50; i++)
this->spu_track_map[0] = 0;
@@ -100,7 +101,6 @@ void *spu_decoder_loop (void *this_gen) {
int streamtype = (buf->type>>16) & 0xFF;
decoder = this->spu_decoder_plugins [streamtype];
- printf("SPU DECODER: %p\n",decoder);
if (decoder) {
if (this->cur_spu_decoder_plugin != decoder) {
@@ -112,7 +112,6 @@ void *spu_decoder_loop (void *this_gen) {
this->cur_spu_decoder_plugin->init (this->cur_spu_decoder_plugin, this->video_out);
}
- printf ("spu_decoder: decoder data sent\n");
decoder->decode_data (decoder, buf);
}
}
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index d3b354ce6..aaa02bf4d 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.30 2001/07/04 20:32:29 uid32519 Exp $
+ * $Id: video_out.c,v 1.31 2001/07/08 18:15:54 guenter Exp $
*
*/
@@ -140,13 +140,14 @@ static void *video_out_loop (void *this_gen) {
uint32_t cur_pts;
int pts_absdiff, diff, absdiff, pts=0;
vo_frame_t *img;
+ vo_overlay_t *overlay;
+ int count;
uint32_t video_step, video_step_new;
vo_instance_t *this = (vo_instance_t *) this_gen;
sigset_t vo_mask;
/*
int dummysignum;
*/
- /* struct timespec ts; */
/* printf ("%d video_out start\n", getpid()); */
/*
@@ -173,34 +174,26 @@ static void *video_out_loop (void *this_gen) {
#endif
video_step = this->metronom->get_video_rate (this->metronom);
-
- /*
- ts.tv_sec = 0;
- ts.tv_nsec = video_step * 2000 / 9;
- */
-
vo_set_timer (video_step);
while (this->video_loop_running) {
/* sigwait(&vo_mask, &dummysignum); */ /* wait for next timer tick */
-
pause ();
- /* nanosleep (&ts, NULL); */
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);
- /* ts.tv_nsec = video_step * 2000 / 9; */
}
-
pts_absdiff = 1000000;
cur_pts = this->metronom->get_current_time (this->metronom);
xprintf (VERBOSE|VIDEO, "video_out : video loop iteration at audio pts %d\n", cur_pts);
+ /*printf ("video_out : video loop iteration at audio pts %d\n", cur_pts);
+ fflush (stdout); */
img = this->display_img_buf_queue->first;
@@ -253,6 +246,11 @@ static void *video_out_loop (void *this_gen) {
* time to display frame 0 ?
*/
+ /*
+ printf ("video_out: diff %d\n", diff);
+ fflush(stdout);
+ */
+
if (diff<0) {
continue;
}
@@ -277,7 +275,60 @@ static void *video_out_loop (void *this_gen) {
pthread_mutex_unlock (&img->mutex);
xprintf (VERBOSE|VIDEO, "video_out : passing to video driver, image with pts = %d\n", pts);
+
+ overlay=this->first_overlay;
+ while (overlay) {
+ if(overlay->state==OVERLAY_SHOWING) {
+ this->driver->overlay_blend (img,overlay);
+ }
+ overlay=overlay->next;
+ }
this->driver->display_frame (this->driver, img);
+
+ /* Control Overlay SHOW/HIDE based on PTS */
+ /* FIXME: Not implemented: These all need to be put to FREE state if the slider gets moved or STOP is pressed. */
+ overlay=this->first_overlay;
+ count=1;
+ while (overlay) {
+ count++;
+ switch(overlay->state) {
+ case OVERLAY_FREE:
+ break;
+ case OVERLAY_CREATING:
+ break;
+ case OVERLAY_READY_TO_SHOW:
+ if (cur_pts>overlay->PTS) overlay->state=OVERLAY_SHOWING;
+ if (abs(cur_pts-overlay->PTS) > pts_absdiff ) overlay->state=OVERLAY_READY_TO_FREE;
+ break;
+ case OVERLAY_SHOWING:
+ /* duration is in frames, Who knows why div 4 ? */
+ if ((cur_pts>overlay->PTS+(overlay->duration*video_step/4))) overlay->state=OVERLAY_READY_TO_FREE;
+ break;
+ case OVERLAY_READY_TO_FREE:
+ /* remove overlay from list */
+ if (overlay->next) {
+ if (overlay->priv)
+ overlay->priv->next=overlay->next;
+ else
+ this->first_overlay=overlay->next;
+ overlay->next->priv=overlay->priv;
+ } else {
+ overlay->state=OVERLAY_FREE;
+ break;
+ }
+ /* Set status to free */
+ overlay->state=OVERLAY_FREE;
+ /* Insert at end of list */
+ overlay->priv=this->last_overlay;
+ this->last_overlay->next=overlay;
+ overlay->next=NULL;
+ this->last_overlay=overlay;
+ break;
+ default:
+ printf("OVERLAY in UNKNOWN state\n");
+ }
+ overlay=overlay->next;
+ }
}
/*
@@ -326,6 +377,7 @@ static vo_frame_t *vo_get_frame (vo_instance_t *this,
/*
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) {
@@ -416,14 +468,16 @@ static int vo_frame_draw (vo_frame_t *img) {
int frames_to_skip;
pic_vpts = this->metronom->got_video_frame (this->metronom, img->PTS);
+
+ /*
+ printf ("video_out: got image %d. vpts for picture is %d (pts was %d)\n",
+ img, pic_vpts, img->PTS);
+ */
img->PTS = pic_vpts;
this->num_frames_delivered++;
xprintf (VERBOSE|VIDEO,"video_out: got image. vpts for picture is %d\n", pic_vpts);
- /*
- printf ("video_out: got image %d. vpts for picture is %d\n",
- img, pic_vpts);
- */
+
cur_vpts = this->metronom->get_current_time(this->metronom);
diff = pic_vpts - cur_vpts;
@@ -489,15 +543,54 @@ static int vo_frame_draw (vo_frame_t *img) {
return frames_to_skip;
}
+/****************************************************************
+ * Current assumption is that only one thread will call vo_get_overlay at a time
+ * Also mutex locks have not yet been considered or used
+ * Also, when one is FREEed, it is moved to the end of the queue, so it will be the first one used
+ * The design is based around a dynamic buffer size.
+ * The buffer starts at nothing, then increases as needed.
+ * If a buffer entry is free, it will be reused.
+ * If all buffers are full, xmalloc is called.
+ * FIXME: Can someone make this simpler ? It seems a bit long winded to me.
+ ***************************************************************/
static vo_overlay_t *vo_get_overlay (vo_instance_t *this) {
- /* FIXME: implement */
- return this->overlay;
+ vo_overlay_t *next_overlay;
+ vo_overlay_t *prev_overlay;
+ int count_overlay=0;
+ if (this->first_overlay==NULL) {
+ this->first_overlay = this->last_overlay = xmalloc (sizeof (vo_overlay_t)) ;
+ this->first_overlay->data=NULL;
+ this->first_overlay->next=NULL;
+ this->first_overlay->priv=NULL;
+ this->first_overlay->state=OVERLAY_CREATING;
+ count_overlay++;
+ return this->first_overlay;
+ }
+ prev_overlay=this->first_overlay;
+ next_overlay=this->first_overlay->next;
+ while (next_overlay && (prev_overlay->state!=OVERLAY_FREE)) {
+ count_overlay++;
+ prev_overlay=next_overlay;
+ next_overlay=prev_overlay->next;
+ }
+ if (prev_overlay->state==OVERLAY_FREE) {
+ prev_overlay->state=OVERLAY_CREATING;
+ return prev_overlay;
+ }
+ prev_overlay->next = next_overlay = this->last_overlay = xmalloc (sizeof (vo_overlay_t)) ;
+ count_overlay++;
+ next_overlay->data=NULL;
+ next_overlay->next=NULL;
+ next_overlay->priv=prev_overlay;
+ next_overlay->state=OVERLAY_CREATING;
+ return next_overlay;
}
static void vo_queue_overlay (vo_instance_t *this, vo_overlay_t *overlay) {
- /* FIXME: implement */
- this->driver->set_overlay (this->driver, overlay);
+ overlay->PTS = this->metronom->got_spu_packet (this->metronom, overlay->PTS,overlay->duration);
+ if (overlay->data==NULL) overlay->state=OVERLAY_FREE;
+ else overlay->state=OVERLAY_READY_TO_SHOW;
}
vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) {
@@ -506,8 +599,8 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) {
int i;
this = xmalloc (sizeof (vo_instance_t)) ;
- this->overlay = xmalloc (sizeof (vo_overlay_t)) ;
-
+ this->first_overlay=NULL;
+ this->last_overlay=NULL;
this->driver = driver;
this->metronom = metronom;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 30ffddd78..2d825462d 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_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: video_out.h,v 1.10 2001/07/04 20:32:29 uid32519 Exp $
+ * $Id: video_out.h,v 1.11 2001/07/08 18:15:54 guenter Exp $
*
*
* xine version of video_out.h
@@ -125,7 +125,8 @@ struct vo_instance_s {
/* private stuff */
vo_driver_t *driver;
- vo_overlay_t *overlay;
+ vo_overlay_t *first_overlay;
+ vo_overlay_t *last_overlay;
metronom_t *metronom;
img_buf_fifo_t *free_img_buf_queue;
@@ -217,6 +218,7 @@ struct vo_driver_s {
void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img);
/* overlay functions */
+ void (*overlay_blend) (vo_frame_t *vo_img, vo_overlay_t *overlay);
void (*set_overlay) (vo_driver_t *this, vo_overlay_t *overlay);
@@ -244,6 +246,12 @@ struct vo_driver_s {
};
+#define OVERLAY_FREE 0
+#define OVERLAY_CREATING 1
+#define OVERLAY_READY_TO_SHOW 2
+#define OVERLAY_SHOWING 3
+#define OVERLAY_READY_TO_FREE 4
+
struct vo_overlay_s {
uint8_t *data; /* 7-4: mixer key, 3-0: color index */
int x; /* x start of subpicture area */
@@ -256,7 +264,9 @@ struct vo_overlay_s {
uint32_t PTS, duration; /* 1/90000 s */
- struct overlay_s *next; /* optionally more overlays */
+ vo_overlay_t *next; /* optionally more overlays */
+ vo_overlay_t *priv; /* optionally more overlays */
+ int state; /* State:FREE,SHOWING etc. */
/* private stuff */
int _x; /* current destination x, y */