From 458ba9e4fbc7069252d98c37e344feb77d37f823 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Mon, 4 Aug 2003 02:31:07 +0000 Subject: vo for libstk CVS patchset: 5240 CVS date: 2003/08/04 02:31:07 --- AUTHORS | 3 + ChangeLog | 1 + configure.ac | 26 +++ src/video_out/Makefile.am | 12 +- src/video_out/video_out_stk.c | 466 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 505 insertions(+), 3 deletions(-) create mode 100644 src/video_out/video_out_stk.c diff --git a/AUTHORS b/AUTHORS index 2e49c8788..08939169b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -397,4 +397,7 @@ Dirk Meyer + libstk video out plugin + (let us know if we've forgotten anyone) diff --git a/ChangeLog b/ChangeLog index d6de1d50d..b1a9d2068 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ xine-lib (1-rc1) * libdvdnav: fix some undetected stills (fixes "Red Dragon" RC2 scene selection) + * video output plugin for libstk xine-lib (1-rc0a) * includes ffmpeg's MPEG encode in dist tarball (fixes DXR3 support) diff --git a/configure.ac b/configure.ac index 2a9a3eee0..cbcba6cb9 100644 --- a/configure.ac +++ b/configure.ac @@ -522,6 +522,29 @@ AM_PATH_SDL(1.1.5, AM_CONDITIONAL(HAVE_SDL, [test x"$no_sdl" != x"yes"]) +dnl --------------------------------------------- +dnl check for Libstk +dnl --------------------------------------------- +AC_MSG_CHECKING(for Libstk) +dnl do some actual testing here +if test x$PKG_CONFIG = xno ; then + echo "*** pkg-config not found. See http://pkgconfig.sourceforge.net" + echo "*** All of LIBSTK dependent parts will be disabled" +else + LIBSTK_REQUIRED_VERSION=0.2.0 + if $PKG_CONFIG --atleast-version $LIBSTK_REQUIRED_VERSION libstk ; then + LIBSTK_CFLAGS=`$PKG_CONFIG --cflags libstk` + LIBSTK_LIBS=`$PKG_CONFIG --libs libstk` + have_stk="yes" + else + AC_MSG_RESULT([*** All of Libstk dependent parts will be disabled ***]) + fi +fi +AC_SUBST(LIBSTK_CFLAGS) +AC_SUBST(LIBSTK_LIBS) +AM_CONDITIONAL(HAVE_STK, [test x"$have_stk" = x"yes"]) + + dnl --------------------------------------------- dnl dxr3 / hollywood plus card dnl --------------------------------------------- @@ -1625,6 +1648,9 @@ fi if test x"$no_sdl" != x"yes"; then echo " - sdl (Simple DirectMedia Layer)" fi +if test x"$have_stk" = "xyes"; then + echo " - stk (Libstk Set-top Toolkit)" +fi if test x"$have_directfb" = "xyes"; then echo " - directfb (DirectFB driver)" fi diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index d6ee1cb66..c07dfd04b 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -9,7 +9,7 @@ VIDIX_CFLAGS = -I$(top_builddir)/src/video_out/vidix \ AM_CFLAGS = $(X_CFLAGS) \ -DXINE_COMPILE $(SDL_CFLAGS) $(VIDIX_CFLAGS) \ - $(AALIB_CFLAGS) $(MLIB_CFLAGS) + $(AALIB_CFLAGS) $(MLIB_CFLAGS) $(LIBSTK_CFLAGS) libdir = $(XINE_PLUGINDIR) @@ -48,7 +48,9 @@ if HAVE_SDL sdl_module = xineplug_vo_out_sdl.la endif - +if HAVE_STK +stk_module = xineplug_vo_out_stk.la +endif # important: # @@ -59,7 +61,7 @@ endif # $(syncfb_module) $(fb_module) $(opengl_module) $(sdl_module) $(vidix_module) lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(aa_module) $(pgx64_module) \ $(vidix_module) $(fb_module) $(sdl_module) $(syncfb_module) \ - xineplug_vo_out_none.la + $(stk_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_LIBADD = \ @@ -116,4 +118,8 @@ xineplug_vo_out_pgx64_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ xineplug_vo_out_none_la_SOURCES = video_out_none.c xineplug_vo_out_none_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ +xineplug_vo_out_stk_la_SOURCES = alphablend.c video_out_stk.c +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 diff --git a/src/video_out/video_out_stk.c b/src/video_out/video_out_stk.c new file mode 100644 index 000000000..5cc165cb0 --- /dev/null +++ b/src/video_out/video_out_stk.c @@ -0,0 +1,466 @@ +/* + * Copyright (C) 2000-2002 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: video_out_stk.c,v 1.1 2003/08/04 02:31:07 miguelfreitas Exp $ + * + * video_out_stk.c, Libstk Surface Video Driver + * more info on Libstk at http://www.libstk.org + * + * based on video_out_sdl from + * Miguel Freitas + * + * based on mpeg2dec code from + * Ryan C. Gordon and + * Dominik Schnitzer + * + * (SDL) xine version by Miguel Freitas (Jan/2002) + * Missing features: + * - event handling + * - fullscreen + * - surface locking (for Xlib error noted below) + * - stability, testing, etc?? ;) + * Known bugs: + * - using stk SDL backend, a window move is sometimes needed for the video + * to show up, alghough the audio is playing + * - using stk SDL backend an XLib unexpected async response error sometimes + * occurs + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "xine.h" +#include "xine_internal.h" +#include "video_out.h" +#include "alphablend.h" +#include "xineutils.h" +#include "vo_scale.h" + +/* +#define STK_LOG +*/ + +/* Extend the video frame class with stk private data */ +typedef struct stk_frame_s { + /* public interface */ + vo_frame_t vo_frame; + + /* stk private data */ + int width, height, ratio_code, format; /* which of these do we need ? */ + overlay_t* overlay; +} stk_frame_t; + + +/* Extend the video output class with stk private data */ +typedef struct stk_driver_s { + /* public interface */ + vo_driver_t vo_driver; + + /* stk private data */ + config_values_t* config; + surface_t* surface; + xine_panel_t* xine_panel; + uint8_t bpp; /* do we need this ? */ + pthread_mutex_t mutex; + uint32_t capabilities; + vo_scale_t sc; +} stk_driver_t; + + +typedef struct { + video_driver_class_t driver_class; + config_values_t* config; +} stk_class_t; + +static uint32_t stk_get_capabilities (vo_driver_t *this_gen) { + stk_driver_t* this = (stk_driver_t *)this_gen; + //printf("video_out_stk: get_capabilities()\n"); + return this->capabilities; +} + +/* copy YUV to RGB data (see fb driver)*/ +static void stk_frame_copy (vo_frame_t *vo_img, uint8_t **src) +{ + /* not needed by SDL, we may need it for other stk backends */ + //printf("video_out_stk: frame_copy()\n"); +} + +/* set up the rgb_dst and strides (see fb driver) */ +static void stk_frame_field (vo_frame_t *vo_img, int which_field) { + /* not needed for SDL, maybe not for libstk ? */ + //printf("video_out_stk: frame_field()\n"); +} + +static void stk_frame_dispose (vo_frame_t *vo_img) { + stk_frame_t* frame = (stk_frame_t *)vo_img; + //printf("video_out_stk: frame_dispose()\n"); + if (frame->overlay) stk_overlay_free(frame->overlay); + free (frame); +} + +static vo_frame_t *stk_alloc_frame(vo_driver_t *this_gen) { + /* allocate the frame */ + stk_frame_t* frame; + //printf("video_out_stk: alloc_frame()\n"); + frame = (stk_frame_t *)malloc(sizeof(stk_frame_t)); + memset(frame, 0, sizeof(stk_frame_t)); + if (frame == NULL) { + printf("stk_alloc_frame: out of memory\n"); + } + + /* populate the frame members*/ + pthread_mutex_init (&frame->vo_frame.mutex, NULL); + + /* map the frame function pointers */ + frame->vo_frame.copy = stk_frame_copy; + frame->vo_frame.field = stk_frame_field; + frame->vo_frame.dispose = stk_frame_dispose; + + return (vo_frame_t *) frame; +} + +static void stk_compute_ideal_size (stk_driver_t* this) { + //printf("video_out_stk: compute_ideal_size()\n"); + vo_scale_compute_ideal_size(&this->sc); +} + +static void stk_compute_output_size (stk_driver_t *this) { + //printf("video_out_stk: compute_output_size()\n"); + vo_scale_compute_output_size( &this->sc ); + +#ifdef LOG + printf ("video_out_stk: frame source %d x %d => screen output %d x %d\n", + this->sc.delivered_width, this->sc.delivered_height, + this->sc.output_width, this->sc.output_height); +#endif +} + + +static void stk_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, + uint32_t width, uint32_t height, int ratio_code, int format, int flags) { + stk_driver_t* this = (stk_driver_t*)this_gen; + stk_frame_t* frame = (stk_frame_t*)frame_gen; + //printf("video_out_stk: update_frame_format()\n"); + + if ((frame->width != width) || (frame->height != height) || (frame->format != format)) { +#ifdef STK_LOG + printf("video_out_stk: update_frame_format - %d=%d, %d=%d, %d=%d\n", + frame->width, width, frame->height, height, frame->format, format); + printf("video_out_stk: vo_frame data - width, height, format: %d, %d, %d\n", + frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.format); +#endif + + /* (re-) allocate image */ + if (frame->overlay) { + stk_overlay_free(frame->overlay); + frame->overlay = NULL; + } + + if (format == XINE_IMGFMT_YV12) { +#ifdef STK_LOG + printf ("video_out_stk: format YV12\n"); +#endif + frame->overlay = stk_surface_create_overlay(this->surface, width, height, + STK_YV12_OVERLAY); + + } else if (format == XINE_IMGFMT_YUY2) { +#ifdef STK_LOG + printf("video_out_stk: format YUY2\n"); +#endif + frame->overlay = stk_surface_create_overlay(this->surface, width, height, + STK_YUY2_OVERLAY); + } + + if (frame->overlay == NULL) + return; + + /* From the SDL driver: + * This needs to be done becuase I have found that + * pixels isn't setup until this is called. + */ + stk_overlay_lock(frame->overlay); + + frame->vo_frame.pitches[0] = stk_overlay_pitches(frame->overlay, 0); + frame->vo_frame.pitches[1] = stk_overlay_pitches(frame->overlay, 2); + frame->vo_frame.pitches[2] = stk_overlay_pitches(frame->overlay, 1); + frame->vo_frame.base[0] = stk_overlay_pixels(frame->overlay, 0); + frame->vo_frame.base[1] = stk_overlay_pixels(frame->overlay, 2); + frame->vo_frame.base[2] = stk_overlay_pixels(frame->overlay, 1); + + frame->width = width; + frame->height = height; + frame->format = format; + } else { + stk_overlay_lock(frame->overlay); + } + + frame->ratio_code = ratio_code; +} + + +static void stk_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { + stk_frame_t* frame = (stk_frame_t*)frame_gen; + //printf("video_out_stk: overlay_blend()\n"); + + 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]); + } + +} + +static void stk_check_events (stk_driver_t* this) { + /* SDL checks for a resize, our video panels aren't resizeable... */ + //printf("video_out_stk: check_events()\n"); +} + +/* when is this called ? */ +static int stk_redraw_needed (vo_driver_t* this_gen) { + stk_driver_t* this = (stk_driver_t*)this_gen; + int ret = 0; + static int last_gui_width, last_gui_height; + + //printf("video_out_stk: redraw_needed()\n"); + + if( last_gui_width != this->sc.gui_width || + last_gui_height != this->sc.gui_height || + this->sc.force_redraw ) { + + last_gui_width = this->sc.gui_width; + last_gui_height = this->sc.gui_height; + + stk_compute_output_size (this); + + ret = 1; + } + + this->sc.force_redraw = 0; + + return ret; +} + + +static void stk_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { + stk_driver_t* this = (stk_driver_t*)this_gen; + stk_frame_t* frame = (stk_frame_t*)frame_gen; + + //printf("video_out_stk: display_frame()\n"); + + pthread_mutex_lock(&this->mutex); + + if ( (frame->width != this->sc.delivered_width) + || (frame->height != this->sc.delivered_height) + || (frame->ratio_code != this->sc.delivered_ratio_code) ) { + printf("video_out_stk: change frame format\n"); + + this->sc.delivered_width = frame->width; + this->sc.delivered_height = frame->height; + this->sc.delivered_ratio_code = frame->ratio_code; + + stk_compute_ideal_size(this); + + this->sc.force_redraw = 1; + } + + /* + * tell gui that we are about to display a frame, + * ask for offset and output size + */ + stk_check_events (this); + stk_redraw_needed (this_gen); + + stk_overlay_unlock(frame->overlay); + stk_overlay_display(frame->overlay, this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height); + + frame->vo_frame.free (&frame->vo_frame); + + pthread_mutex_unlock(&this->mutex); +} + +static int stk_get_property (vo_driver_t* this_gen, int property) { + stk_driver_t* this = (stk_driver_t *)this_gen; + + //printf("video_out_stk: get_property()\n"); + + if (property == VO_PROP_ASPECT_RATIO) + return this->sc.user_ratio; + + return 0; +} + +static int stk_set_property (vo_driver_t* this_gen, int property, int value) { + stk_driver_t* this = (stk_driver_t*)this_gen; + + //printf("video_out_stk: set_property()\n"); + + if (property == VO_PROP_ASPECT_RATIO) { + if (value >= NUM_ASPECT_RATIOS) + value = ASPECT_AUTO; + this->sc.user_ratio = value; + printf("video_out_stk: aspect ratio changed to %s\n", vo_scale_aspect_ratio_name(value)); + + stk_compute_ideal_size (this); + this->sc.force_redraw = 1; + } + + return value; +} + +static void stk_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { + /* stk_driver_t* this = (stk_driver_t*)this_gen; */ + //printf("video_out_stk: get_property_min_max()\n"); +} + +static int stk_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { + int ret = 0; + + //printf("video_out_stk: gui_data_exchange()\n"); + + /* FIXME: handle various XINE events, if in X11 ? */ + + ret = -1; + + return ret; +} + +static void stk_dispose (vo_driver_t * this_gen) { + stk_driver_t* this = (stk_driver_t*)this_gen; + + //printf("video_out_stk: dispose()\n"); + + /* FIXME: any libstk deleting must be done in the app or library + * since we didn't create the surface */ + free(this); +} + +static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { + /* allocate the video output driver class */ + stk_driver_t* this; + + //printf("video_out_stk: open_plugin()\n"); + + this = malloc (sizeof (stk_driver_t)); + if (!this) { + printf ("video_out_stk: open_plugin - malloc failed\n"); + return NULL; + } + memset (this, 0, sizeof(stk_driver_t)); + + /* populate the video output driver members */ + this->config = ((stk_class_t*)class_gen)->config; + this->xine_panel = (xine_panel_t*)visual_gen; + this->surface = stk_xine_panel_surface(this->xine_panel); + /* FIXME: provide a way to get bpp from stk surfaces */ + /* this->bpp = stk_surface_bpp(this->surface); */ + this->bpp = 32; + pthread_mutex_init(&this->mutex, NULL); + /* FIXME: provide a way to get YUV formats from stk surfaces */ + /* this->capabilities = stk_surface_formats(this->surface); */ + this->capabilities = VO_CAP_YUY2 | VO_CAP_YV12; + /* FIXME: what does this do ? */ + vo_scale_init( &this->sc, 0, 0, this->config ); + this->sc.gui_x = stk_xine_panel_x(this->xine_panel); + this->sc.gui_y = stk_xine_panel_y(this->xine_panel); + this->sc.gui_width = stk_xine_panel_width(this->xine_panel); + this->sc.gui_height = stk_xine_panel_height(this->xine_panel); + + /* map the video output driver function pointers */ + this->vo_driver.get_capabilities = stk_get_capabilities; + this->vo_driver.alloc_frame = stk_alloc_frame; + this->vo_driver.update_frame_format = stk_update_frame_format; + this->vo_driver.overlay_begin = NULL; /* not used */ + this->vo_driver.overlay_blend = stk_overlay_blend; + this->vo_driver.overlay_end = NULL; /* not used */ + this->vo_driver.display_frame = stk_display_frame; + this->vo_driver.get_property = stk_get_property; + this->vo_driver.set_property = stk_set_property; + this->vo_driver.get_property_min_max = stk_get_property_min_max; + this->vo_driver.gui_data_exchange = stk_gui_data_exchange; + this->vo_driver.dispose = stk_dispose; + this->vo_driver.redraw_needed = stk_redraw_needed; + + /* FIXME: move this to the stk SDL driver code */ + xine_setenv("SDL_VIDEO_YUV_HWACCEL", "1", 1); + xine_setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1); + + printf ("video_out_stk: warning, xine's STK driver is EXPERIMENTAL\n"); + return &this->vo_driver; +} + + +/** + * Class Functions + */ +static char* get_identifier (video_driver_class_t *this_gen) { + //printf("video_out_stk: get_identifier()\n"); + return "stk"; +} + +static char* get_description (video_driver_class_t *this_gen) { + //printf("video_out_stk: get_description()\n"); + return _("xine video output plugin using the Libstk Surface Set-top Toolkit"); +} + +static void dispose_class (video_driver_class_t *this_gen) { + //printf("video_out_stk: dispose_class()\n"); + free(this_gen); +} + + +static void *init_class (xine_t *xine, void *visual_gen) { + stk_class_t* this; + + //printf("video_out_stk: init_class()\n"); + + this = (stk_class_t*)malloc(sizeof(stk_class_t)); + + this->driver_class.open_plugin = open_plugin; + this->driver_class.get_identifier = get_identifier; + this->driver_class.get_description = get_description; + this->driver_class.dispose = dispose_class; + + this->config = xine->config; + + return this; +} + +/* what priority should we be (what is low), what vistype should we declare ? */ +static vo_info_t vo_info_stk = { + 4, /* priority */ + XINE_VISUAL_TYPE_FB, /* visual type supported by this plugin */ +}; + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_OUT, 15, "stk", XINE_VERSION_CODE, &vo_info_stk, init_class }, + { PLUGIN_NONE, 0, "" , 0 , NULL, NULL} +}; + -- cgit v1.2.3