diff options
Diffstat (limited to 'src/video_out/video_out_macosx.m')
-rw-r--r-- | src/video_out/video_out_macosx.m | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/video_out/video_out_macosx.m b/src/video_out/video_out_macosx.m new file mode 100644 index 000000000..68a9de836 --- /dev/null +++ b/src/video_out/video_out_macosx.m @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2000-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: video_out_macosx.m,v 1.1 2004/06/05 16:06:13 jcdutton Exp $ + * + * This output driver makes use of xine's objective-c video_output + * classes located in the macosx folder. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "xine.h" +#include "video_out.h" +#include "xine_internal.h" +#include "xineutils.h" +#include "vo_scale.h" + +#include "macosx/video_window.h" + +typedef struct { + vo_frame_t vo_frame; + int width; + int height; + double ratio; + int format; + xine_t *xine; +} macosx_frame_t; + +typedef struct { + vo_driver_t vo_driver; + config_values_t *config; + int ratio; + xine_t *xine; + XineVideoWindow *window; +} macosx_driver_t; + +typedef struct { + video_driver_class_t driver_class; + config_values_t *config; + xine_t *xine; +} macosx_class_t; + + +static void free_framedata(macosx_frame_t* frame) { + if(frame->vo_frame.base[0]) { + free(frame->vo_frame.base[0]); + frame->vo_frame.base[0] = NULL; + frame->vo_frame.base[1] = NULL; + frame->vo_frame.base[2] = NULL; + } +} + +static void macosx_frame_dispose(vo_frame_t *vo_frame) { + macosx_frame_t *frame = (macosx_frame_t *)vo_frame; + free_framedata(frame); + free (frame); +} + +static void macosx_frame_field(vo_frame_t *vo_frame, int which_field) { + /* do nothing */ +} + +static uint32_t macosx_get_capabilities(vo_driver_t *vo_driver) { + /* both styles, country and western */ + return VO_CAP_YV12 | VO_CAP_YUY2; +} + +static vo_frame_t *macosx_alloc_frame(vo_driver_t *vo_driver) { + /* macosx_driver_t *this = (macosx_driver_t *) vo_driver; */ + macosx_frame_t *frame; + + frame = (macosx_frame_t *) xine_xmalloc(sizeof(macosx_frame_t)); + if(!frame) + return NULL; + + frame->vo_frame.base[0] = NULL; + frame->vo_frame.base[1] = NULL; + frame->vo_frame.base[2] = NULL; + + frame->vo_frame.proc_slice = NULL; + frame->vo_frame.proc_frame = NULL; + frame->vo_frame.field = macosx_frame_field; + frame->vo_frame.dispose = macosx_frame_dispose; + frame->vo_frame.driver = vo_driver; + + return (vo_frame_t *)frame; +} + +static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_frame, + uint32_t width, uint32_t height, + double ratio, int format, int flags) { + macosx_driver_t *this = (macosx_driver_t *) vo_driver; + macosx_frame_t *frame = (macosx_frame_t *) vo_frame; + + if((frame->width != width) || (frame->height != height) || (frame->format != format)) { + + free_framedata(frame); + + frame->width = width; + frame->height = height; + frame->format = format; + + switch(format) { + + case XINE_IMGFMT_YV12: + { + int y_size, uv_size; + + frame->vo_frame.pitches[0] = 8*((width + 7) / 8); + frame->vo_frame.pitches[1] = 8*((width + 15) / 16); + frame->vo_frame.pitches[2] = 8*((width + 15) / 16); + + y_size = frame->vo_frame.pitches[0] * height; + uv_size = frame->vo_frame.pitches[1] * ((height+1)/2); + + frame->vo_frame.base[0] = malloc (y_size + 2*uv_size); + frame->vo_frame.base[1] = frame->vo_frame.base[0]+y_size+uv_size; + frame->vo_frame.base[2] = frame->vo_frame.base[0]+y_size; + } + break; + + case XINE_IMGFMT_YUY2: + frame->vo_frame.pitches[0] = 8*((width + 3) / 4); + frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); + frame->vo_frame.base[1] = NULL; + frame->vo_frame.base[2] = NULL; + break; + + default: + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_macosx: unknown frame format %04x)\n", format); + break; + + } + + NSSize nssize; + nssize.width = width; + nssize.height = height; + + [this->window setContentSize: nssize]; + + if((format == XINE_IMGFMT_YV12 + && (frame->vo_frame.base[0] == NULL + || frame->vo_frame.base[1] == NULL + || frame->vo_frame.base[2] == NULL)) + || (format == XINE_IMGFMT_YUY2 && frame->vo_frame.base[0] == NULL)) { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, + "video_out_macosx: error. (framedata allocation failed: out of memory)\n"); + free_framedata(frame); + } + } + + frame->ratio = ratio; +} + +static void macosx_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) { + macosx_driver_t *driver = (macosx_driver_t *)vo_driver; + macosx_frame_t *frame = (macosx_frame_t *)vo_frame; + char *texture_buffer = [[driver->window getGLView] getTextureBuffer]; + + switch (vo_frame->format) { + case XINE_IMGFMT_YV12: + yv12_to_yuy2 (vo_frame->base[0], vo_frame->pitches[0], + vo_frame->base[1], vo_frame->pitches[1], + vo_frame->base[2], vo_frame->pitches[2], + texture_buffer, vo_frame->width * 2, + vo_frame->width, vo_frame->height, 0); + + [driver->window displayTexture]; + break; + case XINE_IMGFMT_YUY2: + memcpy (texture_buffer, vo_frame->base[0], vo_frame->pitches[0] * vo_frame->height * 3); + [driver->window displayTexture]; + break; + default: + /* unsupported frame format, do nothing. */ + break; + } + + frame->vo_frame.free(&frame->vo_frame); +} + +static int macosx_get_property(vo_driver_t *vo_driver, int property) { + macosx_driver_t *driver = (macosx_driver_t *)vo_driver; + + switch(property) { + + case VO_PROP_ASPECT_RATIO: + return driver->ratio; + break; + + default: + break; + } + + return 0; +} + +static int macosx_set_property(vo_driver_t *vo_driver, int property, int value) { + macosx_driver_t *driver = (macosx_driver_t *)vo_driver; + + switch(property) { + + case VO_PROP_ASPECT_RATIO: + if(value >= XINE_VO_ASPECT_NUM_RATIOS) + value = XINE_VO_ASPECT_AUTO; + + driver->ratio = value; + break; + + default: + break; + } + return value; +} + +static void macosx_get_property_min_max(vo_driver_t *vo_driver, + int property, int *min, int *max) { + *min = 0; + *max = 0; +} + +static int macosx_gui_data_exchange(vo_driver_t *vo_driver, int data_type, void *data) { +/* macosx_driver_t *this = (macosx_driver_t *) vo_driver; */ + + switch (data_type) { + case XINE_GUI_SEND_COMPLETION_EVENT: + case XINE_GUI_SEND_DRAWABLE_CHANGED: + case XINE_GUI_SEND_EXPOSE_EVENT: + case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: + case XINE_GUI_SEND_VIDEOWIN_VISIBLE: + case XINE_GUI_SEND_SELECT_VISUAL: + break; + } + + return 0; +} +static void macosx_dispose(vo_driver_t *vo_driver) { + macosx_driver_t *this = (macosx_driver_t *) vo_driver; + + free(this); +} + +static int macosx_redraw_needed(vo_driver_t *vo_driver) { + return 0; +} + + +static vo_driver_t *open_plugin(video_driver_class_t *driver_class, const void *visual) { + macosx_class_t *class = (macosx_class_t *) driver_class; + macosx_driver_t *driver; + XineVideoWindow *window = (XineVideoWindow *) visual; + + driver = (macosx_driver_t *) xine_xmalloc(sizeof(macosx_driver_t)); + + driver->config = class->config; + driver->xine = class->xine; + driver->ratio = XINE_VO_ASPECT_AUTO; + driver->window = window; + + driver->vo_driver.get_capabilities = macosx_get_capabilities; + driver->vo_driver.alloc_frame = macosx_alloc_frame ; + driver->vo_driver.update_frame_format = macosx_update_frame_format; + driver->vo_driver.overlay_begin = NULL; + driver->vo_driver.overlay_blend = NULL; + driver->vo_driver.overlay_end = NULL; + driver->vo_driver.display_frame = macosx_display_frame; + driver->vo_driver.get_property = macosx_get_property; + driver->vo_driver.set_property = macosx_set_property; + driver->vo_driver.get_property_min_max = macosx_get_property_min_max; + driver->vo_driver.gui_data_exchange = macosx_gui_data_exchange; + driver->vo_driver.dispose = macosx_dispose; + driver->vo_driver.redraw_needed = macosx_redraw_needed; + + NSSize s; + s.width = 720; + s.height = 576; + + + return &driver->vo_driver; +} + +/* + * Class related functions. + */ +static char* get_identifier (video_driver_class_t *driver_class) { + return "MacOSX"; +} + +static char* get_description (video_driver_class_t *driver_class) { + return _("xine video output plugin for MacOSX"); +} + +static void dispose_class (video_driver_class_t *driver_class) { + macosx_class_t *this = (macosx_class_t *) driver_class; + + free (this); +} + +static void *init_class (xine_t *xine, void *visual) { + macosx_class_t *this; + + this = (macosx_class_t *) xine_xmalloc(sizeof(macosx_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; + this->xine = xine; + + return this; +} + +static vo_info_t vo_info_macosx = { + 1, /* Priority */ + XINE_VISUAL_TYPE_MACOSX /* Visual type */ +}; + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_OUT, 19, "macosx", XINE_VERSION_CODE, &vo_info_macosx, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + +/* Dirty hack to get around the problem that dlclose() is not allowed to + * get rid of an image module which contains objective C code and simply + * crashes with a Trace/BPT trap when we try to do so. + * If this symbol if found in the library, dlclose() will be omitted. + */ +int plugin_contains_objc_code = 1; + |