diff options
-rw-r--r-- | xine/vo_hook.c | 201 | ||||
-rw-r--r-- | xine/vo_hook.h | 27 | ||||
-rw-r--r-- | xine/vo_osdscaler.h | 16 | ||||
-rw-r--r-- | xine/vo_post.h | 20 |
4 files changed, 264 insertions, 0 deletions
diff --git a/xine/vo_hook.c b/xine/vo_hook.c new file mode 100644 index 00000000..e8622d4a --- /dev/null +++ b/xine/vo_hook.c @@ -0,0 +1,201 @@ +/* + * vo_hook.c: Intercept video driver + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: vo_hook.c,v 1.1 2008-11-20 09:25:52 phintuka Exp $ + * + */ + +#include <stdlib.h> + +#include <xine/video_out.h> + +#define LOG_MODULENAME "[xine-vo ] " +#include "../logdefs.h" + +#include "vo_hook.h" +#include "vo_post.h" + +/* This module supports only video driver interface version 21 */ +#if VIDEO_OUT_DRIVER_IFACE_VERSION != 21 +# error xine-lib VIDEO_OUT_DRIVER_IFACE_VERSION != 21 +#endif + + +/* + * default handlers + * + * - Forward function call to original driver + */ + +#define DEF_HANDLER3(RET, NAME, ARG1, ARG2, ARG3) \ +static RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2, ARG3 a3) { \ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; \ + return this->orig_driver-> NAME (this->orig_driver, a1, a2, a3); \ +} + +#define DEF_HANDLER2(RET, NAME, ARG1, ARG2) \ +static RET vo_def_##NAME (vo_driver_t *self, ARG1 a1, ARG2 a2) { \ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; \ + return this->orig_driver-> NAME (this->orig_driver, a1, a2); \ +} + +#define DEF_HANDLER1(RET, NAME, ARG1) \ +static RET vo_def_##NAME (vo_driver_t *self, ARG1 a1) { \ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; \ + return this->orig_driver-> NAME (this->orig_driver, a1); \ +} + +#define DEF_HANDLER0(RET, NAME) \ +static RET vo_def_##NAME (vo_driver_t *self) { \ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; \ + return this->orig_driver-> NAME (this->orig_driver); \ +} + +/* + * + */ + +DEF_HANDLER0(uint32_t, get_capabilities); +DEF_HANDLER0(vo_frame_t*, alloc_frame); + +void vo_def_update_frame_format (vo_driver_t *self, vo_frame_t *img, + uint32_t width, uint32_t height, + double ratio, int format, int flags) +{ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; + return this->orig_driver-> update_frame_format (this->orig_driver, img, width, height, ratio, format, flags); +} + +DEF_HANDLER1(void, display_frame, vo_frame_t * ); +DEF_HANDLER2(void, overlay_begin, vo_frame_t *, int ); +DEF_HANDLER2(void, overlay_blend, vo_frame_t *, vo_overlay_t * ); +DEF_HANDLER1(void, overlay_end, vo_frame_t *); +DEF_HANDLER1(int, get_property, int); +DEF_HANDLER2(int, set_property, int, int); +DEF_HANDLER3(void, get_property_min_max, int, int*, int*); +DEF_HANDLER2(int, gui_data_exchange, int, void * ); +DEF_HANDLER0(int, redraw_needed ); + +static void vo_def_dispose(vo_driver_t *self) +{ + vo_driver_hook_t *this = (vo_driver_hook_t *) self; + if (this->orig_driver) + this->orig_driver->dispose(this->orig_driver); + free(self); +} + +/* + * vo_def_hooks_init() + * + * initialize driver_hook_t with default handlers + * + */ +static void vo_proxy_hooks_init(vo_driver_t *drv, vo_driver_t *next_driver) +{ + drv->get_capabilities = drv->get_capabilities ?: vo_def_get_capabilities; + drv->alloc_frame = drv->alloc_frame ?: vo_def_alloc_frame; + drv->update_frame_format = drv->update_frame_format ?: vo_def_update_frame_format; + drv->display_frame = drv->display_frame ?: vo_def_display_frame; + + drv->get_property = drv->get_property ?: vo_def_get_property; + drv->set_property = drv->set_property ?: vo_def_set_property; + drv->get_property_min_max = drv->get_property_min_max ?: vo_def_get_property_min_max; + drv->gui_data_exchange = drv->gui_data_exchange ?: vo_def_gui_data_exchange; + drv->redraw_needed = drv->redraw_needed ?: vo_def_redraw_needed; + drv->dispose = drv->dispose ?: vo_def_dispose; + + /* drop old default handlers for OSD (OSD handlers are optional) */ + if (drv->overlay_begin == vo_def_overlay_begin) + drv->overlay_begin = NULL; + if (drv->overlay_blend == vo_def_overlay_blend) + drv->overlay_blend = NULL; + if (drv->overlay_end == vo_def_overlay_end) + drv->overlay_end = NULL; + + /* Set proxy handlers for OSD only if next driver has OSD handlers */ + if (!drv->overlay_begin && next_driver->overlay_begin) + drv->overlay_begin = vo_def_overlay_begin; + if (!drv->overlay_blend && next_driver->overlay_blend) + drv->overlay_blend = vo_def_overlay_blend; + if (!drv->overlay_end && next_driver->overlay_end) + drv->overlay_end = vo_def_overlay_end; + + drv->node = next_driver->node; /* ??? used only by plugin_loader ? */ +} + +/* + * + */ + +/* from xine-lib video_out.c */ +typedef struct { + xine_video_port_t vo; /* public part */ + vo_driver_t *driver; + /* ... */ +} vos_t; + +/* + * wire_video_driver() + * + */ +int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook) +{ + vo_driver_t *vos_driver = ((vos_t*)video_port)->driver; + + if (video_port->driver != vos_driver) { + LOGMSG("wire_video_driver() FAILED (vo_driver != vos_driver)"); + return 0; + } + + LOGMSG("wire_video_driver: vo_driver == vos_driver"); + + /* wire */ + + /* set proxy handlers for undefined methods */ + vo_proxy_hooks_init(hook, video_port->driver); + + /* append original driver chain to new driver */ + ((vo_driver_hook_t *)hook)->orig_driver = video_port->driver; + + /* push new driver to start of driver chain */ + video_port->driver = hook; + ((vos_t*)video_port)->driver = hook; + + return 1; +} + +/* + * unwire_video_driver() + * + */ +int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook_gen, vo_driver_t *video_out) +{ + vo_driver_hook_t *hook = (vo_driver_hook_t*)hook_gen; + vo_driver_hook_t *next = (vo_driver_hook_t*)video_port->driver; + + if (next == hook) { + /* special handling for first entry */ + video_port->driver = next->orig_driver; + /* need to patch video_port private driver pointer too ... */ + ((vos_t*)video_port)->driver = next->orig_driver; + next->orig_driver = NULL; + return 1; + } + + vo_driver_hook_t *prev = next; + while (next && next != hook && (vo_driver_t*)next != video_out) { + prev = next; + next = (vo_driver_hook_t*)next->orig_driver; + } + + if (prev && next == hook) { + prev->orig_driver = next->orig_driver; + next->orig_driver = NULL; + return 1; + } + + return 0; +} diff --git a/xine/vo_hook.h b/xine/vo_hook.h new file mode 100644 index 00000000..59b17c07 --- /dev/null +++ b/xine/vo_hook.h @@ -0,0 +1,27 @@ +/* + * vo_hook.h: Intercept video driver + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: vo_hook.h,v 1.1 2008-11-20 09:24:27 phintuka Exp $ + * + */ + +#ifndef _XINELIBOUTPUT_VO_HOOK_H +#define _XINELIBOUTPUT_VO_HOOK_H + +#include <xine/video_out.h> + +/* + * vo_driver_hook_t + * + * Used as base for video driver hooks + */ + +typedef struct driver_hook_s { + vo_driver_t vo; /* public part */ + vo_driver_t *orig_driver; +} vo_driver_hook_t; + +#endif /* _XINELIBOUTPUT_VO_HOOK_H */ diff --git a/xine/vo_osdscaler.h b/xine/vo_osdscaler.h new file mode 100644 index 00000000..fe7d21d0 --- /dev/null +++ b/xine/vo_osdscaler.h @@ -0,0 +1,16 @@ +/* + * vo_osdscaler.h: OSD scaling video-out post plugin + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: vo_osdscaler.h,v 1.1 2008-11-20 09:24:27 phintuka Exp $ + * + */ + +#ifndef _XINELIBOUTPUT_VO_OSDSCALER_H +#define _XINELIBOUTPUT_VO_OSDSCALER_H + +vo_driver_t *osdscaler_init(void); + +#endif /* _XINELIBOUTPUT_VO_OSDSCALER_H */ diff --git a/xine/vo_post.h b/xine/vo_post.h new file mode 100644 index 00000000..c14cf9f3 --- /dev/null +++ b/xine/vo_post.h @@ -0,0 +1,20 @@ +/* + * vo_post.h: Intercept video driver + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: vo_post.h,v 1.1 2008-11-20 09:24:27 phintuka Exp $ + * + */ + +#ifndef _XINELIBOUTPUT_VO_POST_H +#define _XINELIBOUTPUT_VO_POST_H + +#include <xine/video_out.h> + +/* Wire / unwire hook chain to video port */ +int wire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook); +int unwire_video_driver(xine_video_port_t *video_port, vo_driver_t *hook, vo_driver_t *video_out); + +#endif /* _XINELIBOUTPUT_VO_POST_H */ |