diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-07-08 18:15:54 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-07-08 18:15:54 +0000 |
commit | c980a592bd835f2c0826e4f0638cef3fabd70ee7 (patch) | |
tree | ecf5e9adcd28cabe0d59e0842780a1dbb3cc0633 | |
parent | fbf6214d84dbed2b9e22da164748eca8c762cb82 (diff) | |
download | xine-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.in | 3 | ||||
-rw-r--r-- | src/libspudec/spu.c | 25 | ||||
-rw-r--r-- | src/libspudec/xine_decoder.c | 22 | ||||
-rw-r--r-- | src/video_out/alphablend.c | 40 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 17 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 12 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 5 | ||||
-rw-r--r-- | src/xine-engine/spu_decoder.c | 5 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 137 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 16 |
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 */ |