diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-11-26 01:03:31 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-11-26 01:03:31 +0000 |
commit | f7c890258f736dc45ae81e2097df6c9658e93606 (patch) | |
tree | eed0d30d99ebbdc649d7fb20329ec2911357b877 | |
parent | 1daacd9d5b53cac2671d2bd9c93a3daa629254ea (diff) | |
download | xine-lib-f7c890258f736dc45ae81e2097df6c9658e93606.tar.gz xine-lib-f7c890258f736dc45ae81e2097df6c9658e93606.tar.bz2 |
* new unscaled overlay feature (using XShape extension)
text subtitles may now be rendered at full screen resolution
* load xine fonts on demand - faster startup
note: support added to xv, xshm and vidix
CVS patchset: 5780
CVS date: 2003/11/26 01:03:31
-rw-r--r-- | misc/xine-fontconv.c | 4 | ||||
-rw-r--r-- | src/libspudec/spu.c | 3 | ||||
-rw-r--r-- | src/libspudec/xine_decoder.c | 4 | ||||
-rw-r--r-- | src/libsputext/xine_decoder.c | 93 | ||||
-rw-r--r-- | src/video_out/Makefile.am | 10 | ||||
-rw-r--r-- | src/video_out/video_out_fb.c | 10 | ||||
-rw-r--r-- | src/video_out/video_out_opengl.c | 6 | ||||
-rw-r--r-- | src/video_out/video_out_sdl.c | 15 | ||||
-rw-r--r-- | src/video_out/video_out_syncfb.c | 11 | ||||
-rw-r--r-- | src/video_out/video_out_vidix.c | 97 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 124 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 91 | ||||
-rw-r--r-- | src/video_out/video_out_xvmc.c | 11 | ||||
-rw-r--r-- | src/video_out/x11osd.c | 375 | ||||
-rw-r--r-- | src/video_out/x11osd.h | 20 | ||||
-rw-r--r-- | src/xine-engine/osd.c | 308 | ||||
-rw-r--r-- | src/xine-engine/osd.h | 10 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 13 |
18 files changed, 978 insertions, 227 deletions
diff --git a/misc/xine-fontconv.c b/misc/xine-fontconv.c index 7a92417db..333e50e63 100644 --- a/misc/xine-fontconv.c +++ b/misc/xine-fontconv.c @@ -446,7 +446,7 @@ void render_font (FT_Face face, char *fontname, int size, int thickness, error = FT_Get_Glyph( face->glyph, &glyph ); if( i == 0 ) { - out_bitmap = create_bitmap( f266CeilToInt(MAX(face->glyph->metrics.horiAdvance, face->glyph->metrics.width + face->glyph->metrics.horiBearingX)), + out_bitmap = create_bitmap( f266CeilToInt(thickness + MAX(face->glyph->metrics.horiAdvance, face->glyph->metrics.width + face->glyph->metrics.horiBearingX)), f266CeilToInt((max_bearing_y<<6) - face->glyph->metrics.horiBearingY + face->glyph->metrics.height + thickness) ); } @@ -581,6 +581,8 @@ int main(int argc, char *argv[]) { render_font (face, argv[2], 20, thickness, unicodes); render_font (face, argv[2], 24, thickness, unicodes); render_font (face, argv[2], 32, thickness, unicodes); + render_font (face, argv[2], 48, thickness, unicodes); + render_font (face, argv[2], 64, thickness, unicodes); list_free(unicodes); diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c index 2270f6bb3..cd4219781 100644 --- a/src/libspudec/spu.c +++ b/src/libspudec/spu.c @@ -35,7 +35,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: spu.c,v 1.71 2003/11/12 17:53:01 mroi Exp $ + * $Id: spu.c,v 1.72 2003/11/26 01:03:31 miguelfreitas Exp $ * */ @@ -752,6 +752,7 @@ static void spudec_draw_picture (spudec_state_t *state, spudec_seq_t* seq, vo_ov ovl->num_rle = rle - ovl->rle; ovl->rgb_clut = 0; + ovl->unscaled = 0; #ifdef LOG_DEBUG printf ("spu: Num RLE=%d\n",ovl->num_rle); printf ("spu: Date size=%d\n",ovl->data_size); diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c index 1ef5bc841..3207f78dc 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.100 2003/10/23 20:12:33 mroi Exp $ + * $Id: xine_decoder.c,v 1.101 2003/11/26 01:03:32 miguelfreitas Exp $ * * stuff needed to turn libspu into a xine decoder plugin */ @@ -312,7 +312,7 @@ static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t this->menu_handle = -1; this->buttonN = 1; - this->event.object.overlay = malloc(sizeof(vo_overlay_t)); + this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t)); pthread_mutex_init(&this->nav_pci_lock, NULL); diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c index 2e0157b5c..c856dd827 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.65 2003/11/11 18:44:54 f1rmb Exp $ + * $Id: xine_decoder.c,v 1.66 2003/11/26 01:03:32 miguelfreitas Exp $ * */ @@ -49,6 +49,8 @@ typedef enum { SUBTITLE_SIZE_SMALL, SUBTITLE_SIZE_NORMAL, SUBTITLE_SIZE_LARGE, + SUBTITLE_SIZE_VERY_LARGE, + SUBTITLE_SIZE_HUGE, SUBTITLE_SIZE_NUM /* number of values in enum */ } subtitle_size; @@ -62,6 +64,7 @@ typedef struct sputext_class_s { int vertical_offset; char font[FONTNAME_SIZE]; /* subtitle font */ char *src_encoding; /* encoding of subtitle file */ + int use_unscaled; /* use unscaled OSD if possible */ xine_t *xine; @@ -97,11 +100,12 @@ typedef struct sputext_decoder_s { int64_t img_duration; int64_t last_subtitle_end; /* no new subtitle before this vpts */ + int unscaled; /* use unscaled OSD */ } sputext_decoder_t; static void update_font_size (sputext_decoder_t *this) { - static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32 }; + static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 }; int y; @@ -125,8 +129,60 @@ static void update_font_size (sputext_decoder_t *this) { this->renderer->set_font (this->osd, this->class->font, this->font_size); this->renderer->set_position (this->osd, 0, y); } + } +static void update_output_size (sputext_decoder_t *this) { + int unscaled; + + unscaled = this->class->use_unscaled && + (this->stream->video_out->get_capabilities(this->stream->video_out) & + VO_CAP_UNSCALED_OVERLAY); + if( unscaled != this->unscaled ) { + this->unscaled = unscaled; + this->width = 0; /* force update */ + } + + /* initialize decoder if needed */ + if( this->unscaled ) { + if( this->width != this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_WIDTH) || + this->height != this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_HEIGHT) || + !this->img_duration || !this->osd ) { + + int width, height; /* dummy */ + + if( this->stream->video_out->status(this->stream->video_out, NULL, + &width, &height, &this->img_duration )) { + + this->width = this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_WIDTH); + this->height = this->stream->video_out->get_property(this->stream->video_out, + VO_PROP_WINDOW_HEIGHT); + + if( this->width && this->height && this->img_duration ) { + this->renderer = this->stream->osd_renderer; + + update_font_size (this); + } + } + } + } else { + if( !this->width || !this->height || !this->img_duration || !this->osd ) { + + if( this->stream->video_out->status(this->stream->video_out, NULL, + &this->width, &this->height, &this->img_duration )) { + + if( this->width && this->height && this->img_duration ) { + this->renderer = this->stream->osd_renderer; + + update_font_size (this); + } + } + } + } +} static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) { @@ -182,7 +238,10 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->last_subtitle_end = sub_end; this->renderer->set_text_palette (this->osd, -1, OSD_TEXT1); - this->renderer->show (this->osd, sub_start); + if (this->unscaled) + this->renderer->show_unscaled (this->osd, sub_start); + else + this->renderer->show (this->osd, sub_start); this->renderer->hide (this->osd, sub_end); #ifdef LOG @@ -246,19 +305,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { while(this->seek_count == extra_info.seek_count) { - /* initialize decoder if needed */ - if( !this->width || !this->height || !this->img_duration || !this->osd ) { - - if( this->stream->video_out->status(this->stream->video_out, NULL, - &this->width, &this->height, &this->img_duration )) { - - if( this->width && this->height && this->img_duration ) { - this->renderer = this->stream->osd_renderer; - - update_font_size (this); - } - } - } + update_output_size( this ); if( this->osd ) { @@ -398,6 +445,13 @@ static void update_subtitle_size(void *class_gen, xine_cfg_entry_t *entry) class->subtitle_size = entry->num_value; } +static void update_use_unscaled(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->use_unscaled = entry->num_value; +} + static spu_decoder_t *sputext_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { sputext_class_t *class = (sputext_class_t *)class_gen; @@ -442,7 +496,7 @@ static void update_src_encoding(void *class_gen, xine_cfg_entry_t *entry) static void *init_spu_decoder_plugin (xine_t *xine, void *data) { static char *subtitle_size_strings[] = { - "tiny", "small", "normal", "large", NULL + "tiny", "small", "normal", "large", "very large", "huge", NULL }; sputext_class_t *this ; @@ -480,6 +534,11 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) { "iso-8859-1", _("Encoding of subtitles"), NULL, 10, update_src_encoding, this); + this->use_unscaled = xine->config->register_bool(xine->config, + "misc.spu_use_unscaled_osd", + 1, + _("Use unscale OSD if possible"), + NULL, 0, update_use_unscaled, this); return &this->class; } diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index 0f5936412..43489bf9c 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -17,6 +17,7 @@ libdir = $(XINE_PLUGINDIR) if HAVE_X11 xshm_module = xineplug_vo_out_xshm.la syncfb_module = xineplug_vo_out_syncfb.la +X11OSD = x11osd.c if HAVE_XV xv_module = xineplug_vo_out_xv.la endif @@ -66,7 +67,8 @@ lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) $(aa_module) $(pgx6 $(vidix_module) $(fb_module) $(sdl_module) $(syncfb_module) \ $(stk_module) $(directfb_module) xineplug_vo_out_none.la -xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c +xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c \ + $(X11OSD) xineplug_vo_out_xv_la_LIBADD = \ $(XV_LIB) \ $(X_LIBS) \ @@ -84,7 +86,7 @@ xineplug_vo_out_xvmc_la_LIBADD = \ xineplug_vo_out_xvmc_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ - alphablend.c video_out_xshm.c + alphablend.c video_out_xshm.c $(X11OSD) xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(X_LIBS) -lXext $(XINE_LIB) xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ @@ -115,7 +117,7 @@ xineplug_vo_out_sdl_la_SOURCES = alphablend.c video_out_sdl.c xineplug_vo_out_sdl_la_LIBADD = $(SDL_LIBS) $(XINE_LIB) xineplug_vo_out_sdl_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -xineplug_vo_out_vidix_la_SOURCES = alphablend.c video_out_vidix.c +xineplug_vo_out_vidix_la_SOURCES = alphablend.c video_out_vidix.c $(X11OSD) xineplug_vo_out_vidix_la_LIBADD = $(X_LIBS) \ $(top_builddir)/src/video_out/vidix/libvidix.la \ $(top_builddir)/src/video_out/libdha/libdha.la @@ -133,4 +135,4 @@ xineplug_vo_out_stk_la_LIBADD = $(LIBSTK_LIBS) xineplug_vo_out_stk_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ noinst_HEADERS = alphablend.h deinterlace.h video_out_syncfb.h \ - yuv2rgb.h video_out_win32.h + yuv2rgb.h video_out_win32.h x11osd.h diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index 0d7c8ff73..5fa3df6e6 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.31 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_fb.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_fb.c, frame buffer xine driver by Miguel Freitas * @@ -617,8 +617,14 @@ static int fb_get_property(vo_driver_t *this_gen, int property) return this->sc.user_ratio; case VO_PROP_BRIGHTNESS: - return this->yuv2rgb_gamma; + return this->yuv2rgb_gamma; + case VO_PROP_WINDOW_WIDTH: + return this->sc.gui_width; + + case VO_PROP_WINDOW_HEIGHT: + return this->sc.gui_height; + default: printf("video_out_fb: tried to get unsupported " "property %d\n", property); diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c index 42f4cc9e0..ffe00340d 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.31 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_opengl.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_glut.c, glut based OpenGL rendering interface for xine * Matthias Hopf <mat@mshopf.de> @@ -749,6 +749,10 @@ static int opengl_get_property (vo_driver_t *this_gen, int property) { return this->sc.user_ratio ; case VO_PROP_BRIGHTNESS: return this->yuv2rgb_gamma; + case VO_PROP_WINDOW_WIDTH: + return this->sc.gui_width; + case VO_PROP_WINDOW_HEIGHT: + return this->sc.gui_height; default: printf ("video_out_opengl: tried to get unsupported property %d\n", property); diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c index 3711855d4..18c9c962d 100644 --- a/src/video_out/video_out_sdl.c +++ b/src/video_out/video_out_sdl.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_sdl.c,v 1.31 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_sdl.c,v 1.32 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_sdl.c, Simple DirectMedia Layer * @@ -355,10 +355,15 @@ static void sdl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { static int sdl_get_property (vo_driver_t *this_gen, int property) { sdl_driver_t *this = (sdl_driver_t *) this_gen; - - if ( property == VO_PROP_ASPECT_RATIO) - return this->sc.user_ratio ; - + + switch (property) { + case VO_PROP_WINDOW_WIDTH: + return this->sc.gui_width; + case VO_PROP_WINDOW_HEIGHT: + return this->sc.gui_height; + case VO_PROP_ASPECT_RATIO: + return this->sc.user_ratio; + } return 0; } diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index ea301fd99..4aa89fa69 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.92 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_syncfb.c,v 1.93 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine * @@ -644,6 +644,15 @@ static int syncfb_get_property(vo_driver_t* this_gen, int property) { syncfb_driver_t* this = (syncfb_driver_t *) this_gen; + switch (property) { + case VO_PROP_WINDOW_WIDTH: + this->props[property].value = this->sc.gui_width; + break; + case VO_PROP_WINDOW_HEIGHT: + this->props[property].value = this->sc.gui_height; + break; + } + return this->props[property].value; } diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c index c6d32fa45..66bd8cf6d 100644 --- a/src/video_out/video_out_vidix.c +++ b/src/video_out/video_out_vidix.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_vidix.c,v 1.51 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_vidix.c,v 1.52 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_vidix.c * @@ -58,6 +58,10 @@ #include "alphablend.h" #include "xineutils.h" #include "vo_scale.h" + +#ifdef HAVE_X11 +#include "x11osd.h" +#endif /* #define LOG @@ -122,6 +126,8 @@ struct vidix_driver_s { int screen; Drawable drawable; GC gc; + x11osd *xoverlay; + int ovl_changed; #endif /* fb related stuff */ @@ -574,6 +580,34 @@ static void vidix_update_frame_format (vo_driver_t *this_gen, frame->ratio = ratio; } +static void vidix_overlay_begin (vo_driver_t *this_gen, + vo_frame_t *frame_gen, int changed) { +#ifdef HAVE_X11 + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + this->ovl_changed = changed; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_clear(this->xoverlay); + XUnlockDisplay (this->display); + } +#endif +} + +static void vidix_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { +#ifdef HAVE_X11 + vidix_driver_t *this = (vidix_driver_t *) this_gen; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_expose(this->xoverlay); + XUnlockDisplay (this->display); + } + + this->ovl_changed = 0; +#endif +} /* * @@ -581,12 +615,23 @@ static void vidix_update_frame_format (vo_driver_t *this_gen, static void vidix_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { vidix_frame_t *frame = (vidix_frame_t *) frame_gen; + vidix_driver_t *this = (vidix_driver_t *) this_gen; if (overlay->rle) { - if( frame->format == XINE_IMGFMT_YV12 ) - blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); - else - blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + if( overlay->unscaled ) { +#ifdef HAVE_X11 + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_blend(this->xoverlay, overlay); + XUnlockDisplay (this->display); + } +#endif + } else { + if( frame->format == XINE_IMGFMT_YV12 ) + blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches); + else + blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0]); + } } } @@ -658,6 +703,15 @@ static int vidix_get_property (vo_driver_t *this_gen, int property) { vidix_driver_t *this = (vidix_driver_t *) this_gen; + switch (property) { + case VO_PROP_WINDOW_WIDTH: + this->props[property].value = this->sc.gui_width; + break; + case VO_PROP_WINDOW_HEIGHT: + this->props[property].value = this->sc.gui_height; + break; + } + #ifdef LOG printf ("video_out_vidix: property #%d = %d\n", property, this->props[property].value); @@ -827,6 +881,8 @@ static int vidix_gui_data_exchange (vo_driver_t *this_gen, XLockDisplay(this->display); XFreeGC(this->display, this->gc); this->gc = XCreateGC(this->display, this->drawable, 0, NULL); + if(this->xoverlay) + x11osd_drawable_changed(this->xoverlay, this->drawable); XUnlockDisplay(this->display); #endif } @@ -837,6 +893,14 @@ static int vidix_gui_data_exchange (vo_driver_t *this_gen, printf ("video_out_vidix: GUI_DATA_EX_EXPOSE_EVENT\n"); #endif vidix_clean_output_area(this); +#ifdef HAVE_X11 + XLockDisplay (this->display); + if(this->xoverlay) + x11osd_expose(this->xoverlay); + + XSync(this->display, False); + XUnlockDisplay (this->display); +#endif break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: @@ -871,6 +935,16 @@ static void vidix_exit (vo_driver_t *this_gen) { vdlPlaybackOff(this->vidix_handler); } vdlClose(this->vidix_handler); + +#ifdef HAVE_X11 + if( this->xoverlay ) { + XLockDisplay (this->display); + x11osd_destroy (this->xoverlay); + XUnlockDisplay (this->display); + } +#endif + + free (this); } static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { @@ -975,9 +1049,9 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { this->vo_driver.get_capabilities = vidix_get_capabilities; this->vo_driver.alloc_frame = vidix_alloc_frame; this->vo_driver.update_frame_format = vidix_update_frame_format; - this->vo_driver.overlay_begin = NULL; /* not used */ + this->vo_driver.overlay_begin = vidix_overlay_begin; this->vo_driver.overlay_blend = vidix_overlay_blend; - this->vo_driver.overlay_end = NULL; /* not used */ + this->vo_driver.overlay_end = vidix_overlay_end; this->vo_driver.display_frame = vidix_display_frame; this->vo_driver.get_property = vidix_get_property; this->vo_driver.set_property = vidix_set_property; @@ -1079,6 +1153,8 @@ static vo_driver_t *vidix_open_plugin (video_driver_class_t *class_gen, const vo this->screen = visual->screen; this->drawable = visual->d; this->gc = XCreateGC(this->display, this->drawable, 0, NULL); + this->xoverlay = NULL; + this->ovl_changed = 0; XGetWindowAttributes(this->display, this->drawable, &window_attributes); this->sc.gui_width = window_attributes.width; @@ -1112,6 +1188,13 @@ static vo_driver_t *vidix_open_plugin (video_driver_class_t *class_gen, const vo query_fourccs(this); + XLockDisplay (this->display); + this->xoverlay = x11osd_create (this->display, this->screen, this->drawable); + XUnlockDisplay (this->display); + + if( this->xoverlay ) + this->capabilities |= VO_CAP_UNSCALED_OVERLAY; + return &this->vo_driver; } diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index 51193a0ef..5ec9b31aa 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.119 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_xshm.c,v 1.120 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -59,6 +59,7 @@ #include "yuv2rgb.h" #include "xineutils.h" #include "vo_scale.h" +#include "x11osd.h" /* #define LOG @@ -110,7 +111,8 @@ typedef struct { vo_scale_t sc; xshm_frame_t *cur_frame; - vo_overlay_t *overlay; + x11osd *xoverlay; + int ovl_changed; int (*x11_old_error_handler) (Display *, XErrorEvent *); @@ -303,7 +305,13 @@ static void dispose_ximage (xshm_driver_t *this, */ static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { - return VO_CAP_YV12 | VO_CAP_YUY2; + xshm_driver_t *this = (xshm_driver_t *) this_gen; + uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2; + + if( this->xoverlay ) + capabilities |= VO_CAP_UNSCALED_OVERLAY; + + return capabilities; } static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { @@ -597,38 +605,71 @@ static void xshm_overlay_clut_yuv2rgb(xshm_driver_t *this, vo_overlay_t *overla } } +static void xshm_overlay_begin (vo_driver_t *this_gen, + vo_frame_t *frame_gen, int changed) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + this->ovl_changed = changed; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_clear(this->xoverlay); + XUnlockDisplay (this->display); + } +} + +static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_expose(this->xoverlay); + XUnlockDisplay (this->display); + } + + this->ovl_changed = 0; +} + static void xshm_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; /* Alpha Blend here */ - if (overlay->rle) { - if (!overlay->rgb_clut || !overlay->clip_rgb_clut) - xshm_overlay_clut_yuv2rgb (this, overlay, frame); - - switch (this->bpp) { - case 16: - blend_rgb16 ((uint8_t *)frame->image->data, overlay, - frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); - break; - case 24: - blend_rgb24 ((uint8_t *)frame->image->data, overlay, - frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); - break; - case 32: - blend_rgb32 ((uint8_t *)frame->image->data, overlay, - frame->sc.output_width, frame->sc.output_height, - frame->sc.delivered_width, frame->sc.delivered_height); - break; - default: - printf("xine-lib:video_out_xshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp); + if (overlay->rle) { + if( overlay->unscaled ) { + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_blend(this->xoverlay, overlay); + XUnlockDisplay (this->display); + } + } else { + if (!overlay->rgb_clut || !overlay->clip_rgb_clut) + xshm_overlay_clut_yuv2rgb (this, overlay, frame); + + switch (this->bpp) { + case 16: + blend_rgb16 ((uint8_t *)frame->image->data, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height); + break; + case 24: + blend_rgb24 ((uint8_t *)frame->image->data, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height); + break; + case 32: + blend_rgb32 ((uint8_t *)frame->image->data, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height); + break; + default: + printf("xine-lib:video_out_xshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp); /* it should never get here, unless a user tries to play in bpp:8 */ break; - } - } + } + } + } } static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) { @@ -742,6 +783,10 @@ static int xshm_get_property (vo_driver_t *this_gen, int property) { return this->yuv2rgb_contrast; case VO_PROP_SATURATION: return this->yuv2rgb_saturation; + case VO_PROP_WINDOW_WIDTH: + return this->sc.gui_width; + case VO_PROP_WINDOW_HEIGHT: + return this->sc.gui_height; default: if (this->xine->verbosity >= XINE_VERBOSITY_LOG) { printf ("video_out_xshm: tried to get unsupported property %d\n", @@ -866,6 +911,9 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen, this->sc.border[i].w, this->sc.border[i].h); } + if(this->xoverlay) + x11osd_expose(this->xoverlay); + XSync(this->display, False); XUnlockDisplay (this->display); } @@ -878,6 +926,8 @@ static int xshm_gui_data_exchange (vo_driver_t *this_gen, XLockDisplay (this->display); XFreeGC(this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); + if(this->xoverlay) + x11osd_drawable_changed(this->xoverlay, this->drawable); XUnlockDisplay (this->display); break; @@ -915,6 +965,12 @@ static void xshm_dispose (vo_driver_t *this_gen) { this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); + if( this->xoverlay ) { + XLockDisplay (this->display); + x11osd_destroy (this->xoverlay); + XUnlockDisplay (this->display); + } + free (this); } @@ -1018,16 +1074,18 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi XLockDisplay(this->display); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); XUnlockDisplay(this->display); - + this->xoverlay = NULL; + this->ovl_changed = 0; + this->x11_old_error_handler = NULL; this->xine = class->xine; this->vo_driver.get_capabilities = xshm_get_capabilities; this->vo_driver.alloc_frame = xshm_alloc_frame; this->vo_driver.update_frame_format = xshm_update_frame_format; - this->vo_driver.overlay_begin = NULL; /* not used */ + this->vo_driver.overlay_begin = xshm_overlay_begin; this->vo_driver.overlay_blend = xshm_overlay_blend; - this->vo_driver.overlay_end = NULL; /* not used */ + this->vo_driver.overlay_end = xshm_overlay_end; this->vo_driver.display_frame = xshm_display_frame; this->vo_driver.get_property = xshm_get_property; this->vo_driver.set_property = xshm_set_property; @@ -1177,7 +1235,11 @@ static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const voi this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - + + XLockDisplay (this->display); + this->xoverlay = x11osd_create (this->display, this->screen, this->drawable); + XUnlockDisplay (this->display); + return &this->vo_driver; } diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 5c35d77be..cdb102b26 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.181 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_xv.c,v 1.182 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -29,6 +29,7 @@ * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de> * * overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001 + * X11 unscaled overlay support by Miguel Freitas - Nov 2003 */ #ifdef HAVE_CONFIG_H @@ -71,6 +72,7 @@ #include "deinterlace.h" #include "xineutils.h" #include "vo_scale.h" +#include "x11osd.h" /* #define LOG @@ -126,7 +128,8 @@ struct xv_driver_s { xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xv_frame_t *cur_frame; - vo_overlay_t *overlay; + x11osd *xoverlay; + int ovl_changed; /* all scaling information goes here */ vo_scale_t sc; @@ -607,21 +610,51 @@ static void xv_compute_output_size (xv_driver_t *this) { } } +static void xv_overlay_begin (vo_driver_t *this_gen, + vo_frame_t *frame_gen, int changed) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + this->ovl_changed = changed; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_clear(this->xoverlay); + XUnlockDisplay (this->display); + } +} + +static void xv_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_expose(this->xoverlay); + XUnlockDisplay (this->display); + } + + this->ovl_changed = 0; +} + static void xv_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + xv_driver_t *this = (xv_driver_t *) this_gen; 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->rle) { - if (frame->format == XINE_IMGFMT_YV12) - blend_yuv(frame->vo_frame.base, overlay, - frame->width, frame->height, frame->vo_frame.pitches); - else - blend_yuy2(frame->vo_frame.base[0], overlay, - frame->width, frame->height, frame->vo_frame.pitches[0]); + if( overlay->unscaled ) { + if( this->ovl_changed && this->xoverlay ) { + XLockDisplay (this->display); + x11osd_blend(this->xoverlay, overlay); + XUnlockDisplay (this->display); + } + } else { + if (frame->format == XINE_IMGFMT_YV12) + blend_yuv(frame->vo_frame.base, overlay, + frame->width, frame->height, frame->vo_frame.pitches); + else + blend_yuy2(frame->vo_frame.base[0], overlay, + frame->width, frame->height, frame->vo_frame.pitches[0]); + } } } @@ -756,6 +789,15 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { static int xv_get_property (vo_driver_t *this_gen, int property) { xv_driver_t *this = (xv_driver_t *) this_gen; + switch (property) { + case VO_PROP_WINDOW_WIDTH: + this->props[property].value = this->sc.gui_width; + break; + case VO_PROP_WINDOW_HEIGHT: + this->props[property].value = this->sc.gui_height; + break; + } + if (this->xine->verbosity >= XINE_VERBOSITY_LOG) printf ("video_out_xv: property #%d = %d\n", property, this->props[property].value); @@ -915,6 +957,9 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, this->sc.border[i].w, this->sc.border[i].h); } + if(this->xoverlay) + x11osd_expose(this->xoverlay); + XSync(this->display, False); XUnlockDisplay (this->display); } @@ -927,6 +972,8 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, XLockDisplay (this->display); XFreeGC(this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); + if(this->xoverlay) + x11osd_drawable_changed(this->xoverlay, this->drawable); XUnlockDisplay (this->display); this->sc.force_redraw = 1; break; @@ -988,6 +1035,12 @@ static void xv_dispose (vo_driver_t *this_gen) { this->recent_frames[i] = NULL; } + if( this->xoverlay ) { + XLockDisplay (this->display); + x11osd_destroy (this->xoverlay); + XUnlockDisplay (this->display); + } + free (this); } @@ -1143,7 +1196,6 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi memset (this, 0, sizeof(xv_driver_t)); this->display = visual->display; - this->overlay = NULL; this->screen = visual->screen; this->xv_port = class->xv_port; this->config = config; @@ -1162,6 +1214,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi this->deinterlace_frame.image = NULL; this->use_colorkey = 0; this->colorkey = 0; + this->xoverlay = NULL; + this->ovl_changed = 0; this->x11_old_error_handler = NULL; this->xine = class->xine; @@ -1174,9 +1228,9 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi 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_begin = NULL; /* not used */ + this->vo_driver.overlay_begin = xv_overlay_begin; this->vo_driver.overlay_blend = xv_overlay_blend; - this->vo_driver.overlay_end = NULL; /* not used */ + this->vo_driver.overlay_end = xv_overlay_end; this->vo_driver.display_frame = xv_display_frame; this->vo_driver.get_property = xv_get_property; this->vo_driver.set_property = xv_set_property; @@ -1322,6 +1376,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi NULL, 10, xv_update_deinterlace, this); this->deinterlace_enabled = 0; + XLockDisplay (this->display); + this->xoverlay = x11osd_create (this->display, this->screen, this->drawable); + XUnlockDisplay (this->display); + + if( this->xoverlay ) + this->capabilities |= VO_CAP_UNSCALED_OVERLAY; + return &this->vo_driver; } diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index 91f90530d..547cf5804 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.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_xvmc.c,v 1.7 2003/11/11 18:45:00 f1rmb Exp $ + * $Id: video_out_xvmc.c,v 1.8 2003/11/26 01:03:32 miguelfreitas Exp $ * * video_out_xvmc.c, X11 video motion compensation extension interface for xine * @@ -1023,6 +1023,15 @@ static int xvmc_get_property (vo_driver_t *this_gen, int property) { lprintf ("video_out_xvmc: xvmc_get_property\n"); + switch (property) { + case VO_PROP_WINDOW_WIDTH: + this->props[property].value = this->sc.gui_width; + break; + case VO_PROP_WINDOW_HEIGHT: + this->props[property].value = this->sc.gui_height; + break; + } + return this->props[property].value; } diff --git a/src/video_out/x11osd.c b/src/video_out/x11osd.c new file mode 100644 index 000000000..c94f2bd26 --- /dev/null +++ b/src/video_out/x11osd.c @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: x11osd.c,v 1.1 2003/11/26 01:03:32 miguelfreitas Exp $ + * + * x11osd.c, use X11 Nonrectangular Window Shape Extension to draw xine OSD + * + * Nov 2003 - Miguel Freitas + * + * based on ideas and code of + * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> + +#include <assert.h> + +#include <netinet/in.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/extensions/shape.h> +#include <X11/Xatom.h> + +#include "xine_internal.h" +#include "alphablend.h" +#include "x11osd.h" + +struct x11osd +{ + Display *display; + int screen; + Window window; + Window parent_window; + unsigned int depth; + Pixmap mask_bitmap; + Pixmap bitmap; + Visual *visual; + Colormap cmap; + + GC gc; + GC mask_gc; + GC mask_gc_back; + + int width; + int height; + int x; + int y; + int clean; + int mapped; +}; + + +void +x11osd_expose (x11osd * osd) +{ + assert (osd); + + if( !osd->clean ) { + + XShapeCombineMask (osd->display, osd->window, ShapeBounding, 0, 0, + osd->mask_bitmap, ShapeSet); + + if( !osd->mapped ) + XMapRaised (osd->display, osd->window); + osd->mapped = 1; + + XCopyArea (osd->display, osd->bitmap, osd->window, osd->gc, 0, 0, + osd->width, osd->height, 0, 0); + } else { + if( osd->mapped ) + XUnmapWindow (osd->display, osd->window); + osd->mapped = 0; + } +} + + +void +x11osd_resize (x11osd * osd, int width, int height) +{ + assert (osd); + osd->width = width; + osd->height = height; + + XResizeWindow (osd->display, osd->window, osd->width, osd->height); + XFreePixmap (osd->display, osd->mask_bitmap); + osd->mask_bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, osd->height, + 1); + XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back, + 0, 0, osd->width, osd->height); + + XFreePixmap (osd->display, osd->bitmap); + osd->bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, + osd->height, osd->depth); +} + +void +x11osd_drawable_changed (x11osd * osd, Window window) +{ + assert (osd); + +/* + Do I need to recreate the GC's?? + + XFreeGC (osd->display, osd->gc); + XFreeGC (osd->display, osd->mask_gc); + XFreeGC (osd->display, osd->mask_gc_back); +*/ + XFreePixmap (osd->display, osd->bitmap); + XFreePixmap (osd->display, osd->mask_bitmap); + XFreeColormap (osd->display, osd->cmap); + XDestroyWindow (osd->display, osd->window); + + + osd->parent_window = window; + osd->window = XCreateSimpleWindow (osd->display, + osd->parent_window, + 0, 0, + osd->width, osd->height, 1, + BlackPixel (osd->display, osd->screen), + BlackPixel (osd->display, osd->screen)); + + osd->mask_bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, osd->height, + 1); + XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back, + 0, 0, osd->width, osd->height); + + osd->bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, + osd->height, osd->depth); + + osd->cmap = XCreateColormap(osd->display, osd->window, + osd->visual, AllocNone); + + XSelectInput (osd->display, osd->window, ExposureMask); +} + + +x11osd * +x11osd_create (Display *display, int screen, Window window) +{ + x11osd *osd; + int event_basep, error_basep; + + osd = malloc (sizeof (x11osd)); + memset (osd, 0, sizeof (x11osd)); + if (osd == NULL) + return NULL; + + osd->display = display; + osd->screen = screen; + osd->parent_window = window; + + if (!XShapeQueryExtension (osd->display, &event_basep, &error_basep)) + goto error2; + + osd->visual = DefaultVisual (osd->display, osd->screen); + osd->depth = DefaultDepth (osd->display, osd->screen); + osd->width = XDisplayWidth (osd->display, osd->screen); + osd->height = XDisplayHeight (osd->display, osd->screen); + + osd->window = XCreateSimpleWindow (osd->display, + osd->parent_window, + 0, 0, + osd->width, osd->height, 1, + BlackPixel (osd->display, osd->screen), + BlackPixel (osd->display, osd->screen)); + + osd->mask_bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, osd->height, + 1); + osd->bitmap = + XCreatePixmap (osd->display, osd->window, osd->width, + osd->height, osd->depth); + + osd->gc = XCreateGC (osd->display, osd->window, 0, NULL); + osd->mask_gc = XCreateGC (osd->display, osd->mask_bitmap, 0, NULL); + osd->mask_gc_back = XCreateGC (osd->display, osd->mask_bitmap, 0, NULL); + + XSetForeground (osd->display, osd->mask_gc_back, + BlackPixel (osd->display, osd->screen)); + XSetBackground (osd->display, osd->mask_gc_back, + WhitePixel (osd->display, osd->screen)); + + XSetForeground (osd->display, osd->mask_gc, + WhitePixel (osd->display, osd->screen)); + XSetBackground (osd->display, osd->mask_gc, + BlackPixel (osd->display, osd->screen)); + + osd->cmap = XCreateColormap(osd->display, osd->window, + osd->visual, AllocNone); + + XSelectInput (osd->display, osd->window, ExposureMask); + + osd->clean = 0; + x11osd_clear(osd); + osd->mapped = 0; + x11osd_expose(osd); + + return osd; + +/* +error3: + XFreeGC (osd->display, osd->gc); + XFreeGC (osd->display, osd->mask_gc); + XFreeGC (osd->display, osd->mask_gc_back); + XFreePixmap (osd->display, osd->bitmap); + XFreePixmap (osd->display, osd->mask_bitmap); + XDestroyWindow (osd->display, osd->window); +*/ +error2: + free (osd); + return NULL; +} + +void +x11osd_destroy (x11osd * osd) +{ + + assert (osd); + + XFreeGC (osd->display, osd->gc); + XFreeGC (osd->display, osd->mask_gc); + XFreeGC (osd->display, osd->mask_gc_back); + XFreePixmap (osd->display, osd->bitmap); + XFreePixmap (osd->display, osd->mask_bitmap); + XFreeColormap (osd->display, osd->cmap); + XDestroyWindow (osd->display, osd->window); + + free (osd); +} + +void x11osd_clear(x11osd *osd) +{ + if( !osd->clean ) + XFillRectangle (osd->display, osd->mask_bitmap, osd->mask_gc_back, + 0, 0, osd->width, osd->height); + osd->clean = 1; +} + +#define TRANSPARENT 0xffffffff + +#define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n))) + +void x11osd_blend(x11osd *osd, vo_overlay_t *overlay) +{ + if (overlay->rle) { + int i, x, y, len, width; + int use_clip_palette, max_palette_colour[2]; + uint32_t palette[2][OVL_PALETTE_SIZE]; + + max_palette_colour[0] = -1; + max_palette_colour[1] = -1; + + for (i=0, x=0, y=0; i<overlay->num_rle; i++) { + len = overlay->rle[i].len; + + while (len > 0) { + use_clip_palette = 0; + if (len > overlay->width) { + width = overlay->width; + len -= overlay->width; + } + else { + width = len; + len = 0; + } + if ((y >= overlay->clip_top) && (y <= overlay->clip_bottom) && (x <= overlay->clip_right)) { + if ((x < overlay->clip_left) && (x + width - 1 >= overlay->clip_left)) { + width -= overlay->clip_left - x; + len += overlay->clip_left - x; + } + else if (x > overlay->clip_left) { + use_clip_palette = 1; + if (x + width - 1 > overlay->clip_right) { + width -= overlay->clip_right - x; + len += overlay->clip_right - x; + } + } + } + + if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) { + int j; + clut_t *src_clut; + uint8_t *src_trans; + + if (use_clip_palette) { + src_clut = (clut_t *)&overlay->clip_color; + src_trans = (uint8_t *)&overlay->clip_trans; + } + else { + src_clut = (clut_t *)&overlay->color; + src_trans = (uint8_t *)&overlay->trans; + } + for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) { + if (src_trans[j]) { + if (1) { + XColor xcolor; + int y, u, v, r, g, b; + + y = saturate(src_clut[j].y, 16, 235); + u = saturate(src_clut[j].cb, 16, 240); + v = saturate(src_clut[j].cr, 16, 240); + y = (9 * y) / 8; + r = y + (25 * v) / 16 - 218; + xcolor.red = (65536 * saturate(r, 0, 255)) / 256; + g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136; + xcolor.green = (65536 * saturate(g, 0, 255)) / 256; + b = y + 2 * u - 274; + xcolor.blue = (65536 * saturate(b, 0, 255)) / 256; + + xcolor.flags = DoRed | DoBlue | DoGreen; + + XAllocColor(osd->display, osd->cmap, &xcolor); + + palette[use_clip_palette][j] = xcolor.pixel; + } + else { + if (src_clut[j].y > 127) { + palette[use_clip_palette][j] = WhitePixel(osd->display, osd->screen); + } + else { + palette[use_clip_palette][j] = BlackPixel(osd->display, osd->screen); + } + } + } + else { + palette[use_clip_palette][j] = TRANSPARENT; + } + } + max_palette_colour[use_clip_palette] = overlay->rle[i].color; + } + + if(palette[use_clip_palette][overlay->rle[i].color] != TRANSPARENT) { + XSetForeground(osd->display, osd->gc, palette[use_clip_palette][overlay->rle[i].color]); + XFillRectangle(osd->display, osd->bitmap, osd->gc, overlay->x + x, overlay->y + y, width, 1); + XFillRectangle(osd->display, osd->mask_bitmap, osd->mask_gc, overlay->x + x, overlay->y + y, width, 1); + } + + x += width; + if (x == overlay->width) { + x = 0; + y++; + } + } + } + } + osd->clean = 0; +} + diff --git a/src/video_out/x11osd.h b/src/video_out/x11osd.h new file mode 100644 index 000000000..3d74df780 --- /dev/null +++ b/src/video_out/x11osd.h @@ -0,0 +1,20 @@ +#ifndef X11OSD_H +#define X11OSD_H + + typedef struct x11osd x11osd; + + x11osd *x11osd_create (Display *display, int screen, Window window); + + void x11osd_destroy (x11osd * osd); + + void x11osd_expose (x11osd * osd); + + void x11osd_resize (x11osd * osd, int width, int height); + + void x11osd_drawable_changed (x11osd * osd, Window window); + + void x11osd_clear(x11osd *osd); + + void x11osd_blend(x11osd *osd, vo_overlay_t *overlay); + +#endif diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 17c97d50b..2e8ff0637 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -21,7 +21,12 @@ */ #define __OSD_C__ - + +/* +#define LOG_VERBOSE 1 +#define LOG 1 +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -54,9 +59,7 @@ #include FT_FREETYPE_H #endif -/* -#define LOG_DEBUG 1 -*/ +#define FONT_VERSION 2 #define BINARY_SEARCH 1 @@ -89,11 +92,13 @@ typedef struct osd_fontchar_s { struct osd_font_s { char name[40]; + char *filename; uint16_t version; uint16_t size; uint16_t num_fontchars; osd_fontchar_t *fontchar; osd_font_t *next; + int loaded; }; #ifdef HAVE_FT2 @@ -146,9 +151,7 @@ static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height pthread_mutex_unlock (&this->osd_mutex); -#ifdef LOG_DEBUG - printf("osd_open %p [%dx%d]\n", osd, width, height); -#endif + lprintf("osd=%p size: %dx%d\n", osd, width, height); return osd; } @@ -159,16 +162,14 @@ static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height * send the osd to be displayed at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. */ -static int osd_show (osd_object_t *osd, int64_t vpts ) { +static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { osd_renderer_t *this = osd->renderer; rle_elem_t rle, *rle_p=0; int x, y, spare; uint8_t *c; -#ifdef LOG_DEBUG - printf("osd_show %p vpts=%lld\n", osd, vpts); -#endif + lprintf("osd=%p vpts=%lld\n", osd, vpts); if( osd->handle < 0 ) { if( (osd->handle = this->video_overlay->get_handle(this->video_overlay,0)) == -1 ) { @@ -193,6 +194,7 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) { osd->y2 = osd->height; memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) ); + this->event.object.overlay->unscaled = unscaled; this->event.object.overlay->x = osd->display_x + osd->x1; this->event.object.overlay->y = osd->display_y + osd->y1; this->event.object.overlay->width = osd->x2 - osd->x1 + 1; @@ -239,9 +241,7 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) { this->event.object.overlay->num_rle++; } -#ifdef LOG_DEBUG - printf("osd_show num_rle = %d\n", this->event.object.overlay->num_rle); -#endif + lprintf("num_rle = %d\n", this->event.object.overlay->num_rle); memcpy(this->event.object.overlay->clip_color, osd->color, sizeof(osd->color)); memcpy(this->event.object.overlay->clip_trans, osd->trans, sizeof(osd->trans)); @@ -257,6 +257,20 @@ static int osd_show (osd_object_t *osd, int64_t vpts ) { return 1; } +/* normal OSD show + * overlay is blended and scaled together with the stream. + */ +static int osd_show_scaled (osd_object_t *osd, int64_t vpts) { + return _osd_show(osd, vpts, 0); +} + +/* unscaled OSD show + * overlay is blended at output (screen) resolution. + */ +static int osd_show_unscaled (osd_object_t *osd, int64_t vpts) { + return _osd_show(osd, vpts, 1); +} + /* * send event to hide osd at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. @@ -265,9 +279,7 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) { osd_renderer_t *this = osd->renderer; -#ifdef LOG_DEBUG - printf("osd_hide %p vpts=%lld\n",osd, vpts); -#endif + lprintf("osd=%p vpts=%lld\n",osd, vpts); if( osd->handle < 0 ) return 0; @@ -294,9 +306,7 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) { */ static void osd_clear (osd_object_t *osd) { -#ifdef LOG_DEBUG - printf("osd_clear\n"); -#endif + lprintf("osd=%p\n",osd); memset(osd->area, 0, osd->width * osd->height); osd->x1 = osd->width; @@ -312,9 +322,7 @@ static void osd_clear (osd_object_t *osd) { static void osd_point (osd_object_t *osd, int x, int y, int color) { uint8_t *c; -#ifdef LOG_DEBUG - printf("osd_point %p (%d x %d)\n", osd, x, y); -#endif + lprintf("osd=%p (%d x %d)\n", osd, x, y); /* update clipping area */ osd->x1 = MIN(osd->x1, x); @@ -337,9 +345,7 @@ static void osd_line (osd_object_t *osd, uint8_t *c; int dx, dy, t, inc, d, inc1, inc2; -#ifdef LOG_DEBUG - printf("osd_line %p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 ); -#endif + lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 ); /* update clipping area */ t = MIN( x1, x2 ); @@ -428,9 +434,7 @@ static void osd_filled_rect (osd_object_t *osd, int x, y, dx, dy; -#ifdef LOG_DEBUG - printf("osd_filled_rect %p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 ); -#endif + lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 ); /* update clipping area */ x = MIN( x1, x2 ); @@ -525,65 +529,101 @@ static int osd_renderer_load_font(osd_renderer_t *this, char *filename) { osd_font_t *font = NULL; int i, ret = 0; -#ifdef LOG_DEBUG - printf("osd: renderer_load_font %p name=%s\n", this, filename ); -#endif - - pthread_mutex_lock (&this->osd_mutex); + lprintf("name=%s\n", filename ); /* load quick & dirt font format */ - /* fixme: check read errors... */ + /* fixme: check for all read errors... */ if( (fp = gzopen(filename,"rb")) != NULL ) { font = xine_xmalloc( sizeof(osd_font_t) ); gzread(fp, font->name, sizeof(font->name) ); font->version = gzread_i16(fp); - font->size = gzread_i16(fp); - font->num_fontchars = gzread_i16(fp); - - font->fontchar = malloc( sizeof(osd_fontchar_t) * font->num_fontchars ); - -#ifdef LOG_DEBUG - printf("osd: font %s %d\n", font->name, font->num_fontchars); -#endif - for( i = 0; i < font->num_fontchars; i++ ) { - font->fontchar[i].code = gzread_i16(fp); - font->fontchar[i].width = gzread_i16(fp); - font->fontchar[i].height = gzread_i16(fp); - font->fontchar[i].bmp = malloc(font->fontchar[i].width*font->fontchar[i].height); - if( gzread(fp, font->fontchar[i].bmp, - font->fontchar[i].width*font->fontchar[i].height) <= 0 ) - break; - } - if( i == font->num_fontchars ) { - ret = 1; - -#ifdef LOG_DEBUG - printf("osd: font %s loading ok\n",font->name); -#endif - - font->next = this->fonts; - this->fonts = font; - } else { - -#ifdef LOG_DEBUG - printf("osd: font %s loading failed (%d < %d)\n",font->name, - i, font->num_fontchars); -#endif - - while( --i >= 0 ) { - free(font->fontchar[i].bmp); + if( font->version == FONT_VERSION ) { + + font->size = gzread_i16(fp); + font->num_fontchars = gzread_i16(fp); + font->loaded = 1; + + font->fontchar = malloc( sizeof(osd_fontchar_t) * font->num_fontchars ); + + lprintf("font '%s' chars=%d\n", font->name, font->num_fontchars); + + /* load all characters */ + for( i = 0; i < font->num_fontchars; i++ ) { + font->fontchar[i].code = gzread_i16(fp); + font->fontchar[i].width = gzread_i16(fp); + font->fontchar[i].height = gzread_i16(fp); + font->fontchar[i].bmp = malloc(font->fontchar[i].width*font->fontchar[i].height); + if( gzread(fp, font->fontchar[i].bmp, + font->fontchar[i].width*font->fontchar[i].height) <= 0 ) + break; + } + + /* check if all expected characters were loaded */ + if( i == font->num_fontchars ) { + osd_font_t *known_font; + ret = 1; + + lprintf("font '%s' loaded\n",font->name); + + /* check if font is already known to us */ + known_font = this->fonts; + while( known_font ) { + if( !strcasecmp(known_font->name,font->name) && + known_font->size == font->size ) + break; + known_font = known_font->next; + } + + if( !known_font ) { + + /* new font, add it to list */ + font->filename = strdup(filename); + font->next = this->fonts; + this->fonts = font; + + } else { + + if( !known_font->loaded ) { + /* the font was preloaded before. + * add loaded characters to the existing entry. + */ + known_font->version = font->version; + known_font->num_fontchars = font->num_fontchars; + known_font->loaded = 1; + known_font->fontchar = font->fontchar; + } else { + printf("font '%s-%d' already loaded, weird.\n", + font->name, font->size); + while( --i >= 0 ) { + free(font->fontchar[i].bmp); + } + free(font->fontchar); + free(font); + } + + } + } else { + + printf("font '%s' loading failed (%d < %d)\n",font->name, + i, font->num_fontchars); + + while( --i >= 0 ) { + free(font->fontchar[i].bmp); + } + free(font->fontchar); + free(font); } - free(font->fontchar); + } else { + printf("wrong version for font '%s'. expected %d found %d.\n",font->name, + font->version, FONT_VERSION); free(font); } - gzclose(fp); } - pthread_mutex_unlock (&this->osd_mutex); return ret; } @@ -596,15 +636,13 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) { osd_object_t *osd; int i, ret = 0; -#ifdef LOG_DEBUG - printf("osd_renderer_unload_font %p name=%s\n", this, fontname); -#endif + lprintf("font '%s'\n", fontname); pthread_mutex_lock (&this->osd_mutex); osd = this->osds; while( osd ) { - if( !strcmp(osd->font->name, fontname) ) + if( !strcasecmp(osd->font->name, fontname) ) osd->font = NULL; osd = osd->next; } @@ -612,13 +650,17 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) { last = NULL; font = this->fonts; while( font ) { - if ( !strcmp(font->name,fontname) ) { + if ( !strcasecmp(font->name,fontname) ) { - for( i = 0; i < font->num_fontchars; i++ ) { - free( font->fontchar[i].bmp ); + free( font->filename ); + + if( font->loaded ) { + for( i = 0; i < font->num_fontchars; i++ ) { + free( font->fontchar[i].bmp ); + } + free( font->fontchar ); } - free( font->fontchar ); - + if( last ) last->next = font->next; else @@ -651,9 +693,7 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) { int error_flag = 0; #endif -#ifdef LOG_DEBUG - printf("osd_set_font %p name=%s\n", osd, fontname); -#endif + lprintf("osd=%p font '%s'\n", osd, fontname); pthread_mutex_lock (&this->osd_mutex); @@ -662,19 +702,25 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) { font = this->fonts; while( font ) { - if( !strcmp(font->name, fontname) && (size>=font->size) + if( !strcasecmp(font->name, fontname) && (size>=font->size) && (best<font->size)) { ret = 1; osd->font = font; best = font->size; -#ifdef LOG_DEBUG - printf ("osd_set_font: font->name=%s, size=%d\n", font->name, font->size); -#endif + lprintf ("best: font->name=%s, size=%d\n", font->name, font->size); } font = font->next; } - + + if( ret ) { + /* load font if needed */ + if( !osd->font->loaded ) + ret = osd_renderer_load_font(this, osd->font->filename); + if(!ret) + osd->font = NULL; + } + #ifdef HAVE_FT2 if (osd->ft2) { @@ -852,6 +898,8 @@ static int osd_set_encoding (osd_object_t *osd, const char *encoding) { } +#define FONT_OVERLAP 1/10 /* overlap between consecutive characters */ + /* * render text in current encoding on x,y position * no \n yet @@ -867,9 +915,7 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, uint16_t unicode; size_t inbytesleft; -#ifdef LOG_DEBUG - printf("osd_render_text %p (%d,%d) \"%s\"\n", osd, x1, y1, text); -#endif + lprintf("osd=%p (%d,%d) \"%s\"\n", osd, x1, y1, text); /* some sanity checks for the color indices */ if( color_base < 0 ) @@ -918,11 +964,9 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, i = osd_search(font->fontchar, font->num_fontchars, unicode); -#ifdef LOG_DEBUG - printf("font %s [%d, U+%04X == U+%04X] %dx%d -> %d,%d\n", font->name, i, + lprintf("font '%s' [%d, U+%04X == U+%04X] %dx%d -> %d,%d\n", font->name, i, unicode, font->fontchar[i].code, font->fontchar[i].width, font->fontchar[i].height, x1, y1); -#endif #ifdef HAVE_FT2 } /* !(osd->ft2 && osd->ft2->useme) */ @@ -980,7 +1024,8 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, uint8_t *s = src, *d = dst; while (s < src + width) { - if(d <= (osd->area + (osd->width * osd->height))) + if(d <= (osd->area + (osd->width * osd->height)) + && *s > 1) /* skip drawing transparency */ *d = *s + (uint8_t) color_base; d++; @@ -989,7 +1034,7 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, src += font->fontchar[i].width; dst += osd->width; } - x1 += font->fontchar[i].width; + x1 += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP); if( x1 > osd->x2 ) osd->x2 = x1; if( y1 + font->fontchar[i].height > osd->y2 ) @@ -1019,9 +1064,7 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in uint16_t unicode; size_t inbytesleft; -#ifdef LOG_DEBUG - printf("osd_get_text_size %p \"%s\"\n", osd, text); -#endif + lprintf("osd=%p \"%s\"\n", osd, text); pthread_mutex_lock (&this->osd_mutex); @@ -1086,7 +1129,7 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in if ( i != font->num_fontchars ) { if( font->fontchar[i].height > *height ) *height = font->fontchar[i].height; - *width += font->fontchar[i].width; + *width += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP); } #ifdef HAVE_FT2 } /* !(osd->ft2 && osd->ft2->useme) */ @@ -1098,13 +1141,13 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in return 1; } -static void osd_load_fonts (osd_renderer_t *this, char *path) { +static void osd_preload_fonts (osd_renderer_t *this, char *path) { DIR *dir; - char pathname [1024]; + osd_font_t *font; + char *pathname; + char *s, *p; -#ifdef LOG_DEBUG - printf ("osd: load_fonts, path=%s\n", path); -#endif + lprintf ("path='%s'\n", path); dir = opendir (path) ; @@ -1112,31 +1155,37 @@ static void osd_load_fonts (osd_renderer_t *this, char *path) { struct dirent *entry; -#ifdef LOG_DEBUG - printf ("osd: load_fonts, %s opened\n", path); -#endif - while ((entry = readdir (dir)) != NULL) { int len; len = strlen (entry->d_name); if ( (len>12) && !strncmp (&entry->d_name[len-12], ".xinefont.gz", 12)) { - -#ifdef LOG_DEBUG - printf ("osd: trying to load font >%s< (ending >%s<)\n", - entry->d_name,&entry->d_name[len-12]); -#endif - - sprintf (pathname, "%s/%s", path, entry->d_name); - - osd_renderer_load_font (this, pathname); + s = strdup(entry->d_name); + p = strchr(s, '-'); + if( p ) { + *p++ = '\0'; + font = xine_xmalloc( sizeof(osd_font_t) ); + + strncpy(font->name, s, sizeof(font->name)); + font->size = atoi(p); + + lprintf("font '%s' size %d is preloaded\n", + font->name, font->size); + + pathname = malloc(1024); + sprintf (pathname, "%s/%s", path, entry->d_name); + font->filename = pathname; + + font->next = this->fonts; + this->fonts = font; + } + free(s); } } closedir (dir); - } } @@ -1207,7 +1256,7 @@ static void update_text_palette(void *this_gen, xine_cfg_entry_t *entry) osd_renderer_t *this = (osd_renderer_t *)this_gen; this->textpalette = entry->num_value; - printf("osd: text palette will be %s\n", textpalettes_str[this->textpalette] ); + lprintf("palette will be '%s'\n", textpalettes_str[this->textpalette] ); } static void osd_draw_bitmap(osd_object_t *osd, uint8_t *bitmap, @@ -1216,9 +1265,7 @@ static void osd_draw_bitmap(osd_object_t *osd, uint8_t *bitmap, { int y, x; -#ifdef LOG_DEBUG - printf("osd_draw_bitmap %p at (%d,%d) %dx%d\n",osd, x1,y1, width,height ); -#endif + lprintf("osd=%p at (%d,%d) %dx%d\n",osd, x1,y1, width,height ); /* update clipping area */ osd->x1 = MIN( osd->x1, x1 ); @@ -1259,19 +1306,15 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co pthread_mutex_init (&this->osd_mutex, NULL); -#ifdef LOG_DEBUG - printf("osd: _x_osd_renderer_init %p\n", this); -#endif - /* * load available fonts */ - osd_load_fonts (this, XINE_FONTDIR); + osd_preload_fonts (this, XINE_FONTDIR); sprintf (str, "%s/.xine/fonts", xine_get_homedir ()); - osd_load_fonts (this, str); + osd_preload_fonts (this, str); this->textpalette = config->register_enum (config, "misc.osd_text_palette", 0, textpalettes_str, @@ -1284,7 +1327,7 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co this->new_object = osd_new_object; this->free_object = osd_free_object; - this->show = osd_show; + this->show = osd_show_scaled; this->hide = osd_hide; this->set_palette = osd_set_palette; this->set_text_palette = osd_set_text_palette; @@ -1300,6 +1343,7 @@ osd_renderer_t *_x_osd_renderer_init( video_overlay_manager_t *video_overlay, co this->get_text_size = osd_get_text_size; this->close = osd_renderer_close; this->draw_bitmap = osd_draw_bitmap; + this->show_unscaled = osd_show_unscaled; return this; } diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index a0aa75b7f..9a58f1a7c 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * OSD stuff (text and graphic primitives) - * $Id: osd.h,v 1.20 2003/11/19 19:43:23 miguelfreitas Exp $ + * $Id: osd.h,v 1.21 2003/11/26 01:03:32 miguelfreitas Exp $ */ #ifndef HAVE_OSD_H @@ -73,7 +73,6 @@ struct xine_osd_s { osd_object_t osd; }; -/* WARNING: this should be kept in sync with include/xine.h.in */ struct osd_renderer_s { /* @@ -201,6 +200,13 @@ struct osd_renderer_s { int x1, int y1, int width, int height, uint8_t *palette_map); + /* + * send the osd to be displayed (unscaled) at given pts (0=now) + * the object is not changed. there may be subsequent drawing on it. + * overlay is blended at output (screen) resolution. + */ + int (*show_unscaled) (osd_object_t *osd, int64_t vpts ); + /* private stuff */ pthread_mutex_t osd_mutex; diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 567f8ddfd..0f1e2db0e 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.102 2003/11/15 14:54:31 miguelfreitas Exp $ + * $Id: video_out.h,v 1.103 2003/11/26 01:03:32 miguelfreitas Exp $ * * * xine version of video_out.h @@ -254,7 +254,9 @@ struct xine_video_port_s { #define VO_PROP_MAX_NUM_FRAMES 11 #define VO_PROP_ZOOM_Y 13 #define VO_PROP_DISCARD_FRAMES 14 /* not used by drivers */ -#define VO_NUM_PROPERTIES 15 +#define VO_PROP_WINDOW_WIDTH 15 /* read-only */ +#define VO_PROP_WINDOW_HEIGHT 16 /* read-only */ +#define VO_NUM_PROPERTIES 17 /* number of colors in the overlay palette. Currently limited to 256 at most, because some alphablend functions use an 8-bit index into @@ -280,6 +282,7 @@ struct xine_video_port_s { #define VO_CAP_YUY2 0x00000002 /* driver can handle YUY2 pictures */ #define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */ #define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */ +#define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */ /* macroblock modes */ #define XINE_MACROBLOCK_INTRA 1 @@ -429,7 +432,7 @@ struct vo_overlay_s { uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ - int rgb_clut; /* true if clut was converted to rgb*/ + int rgb_clut; /* true if clut was converted to rgb */ int clip_top; int clip_bottom; @@ -437,8 +440,8 @@ struct vo_overlay_s { int clip_right; uint32_t clip_color[OVL_PALETTE_SIZE]; uint8_t clip_trans[OVL_PALETTE_SIZE]; - int clip_rgb_clut; /* true if clut was converted to rgb*/ - + int clip_rgb_clut; /* true if clut was converted to rgb */ + int unscaled; /* true if it should be blended unscaled */ }; |