diff options
author | Edward Hervey <bilboed@bilboed.com> | 2007-01-30 17:19:33 +0000 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2007-01-30 17:19:33 +0000 |
commit | 385bba644fffe6d585467a34ac8e01563263f4b5 (patch) | |
tree | 4bedc4db2b677228da2b34bacc43558e60e43563 /sys/osxvideo/osxvideosink.m | |
parent | 3838fe023eaf04917356e6db8ce548b16538d0db (diff) | |
download | gst-plugins-bad-385bba644fffe6d585467a34ac8e01563263f4b5.tar.gz gst-plugins-bad-385bba644fffe6d585467a34ac8e01563263f4b5.tar.bz2 gst-plugins-bad-385bba644fffe6d585467a34ac8e01563263f4b5.zip |
configure.ac: Check for an Objective C compiler
Original commit message from CVS:
* configure.ac:
Check for an Objective C compiler
* sys/Makefile.am:
* sys/osxvideo/Makefile.am:
* sys/osxvideo/cocoawindow.h:
* sys/osxvideo/cocoawindow.m:
* sys/osxvideo/osxvideosink.h:
* sys/osxvideo/osxvideosink.m:
Port of osxvideo plugin to 0.10. Do NOT consider 100% stable !
Fixes #402470
Diffstat (limited to 'sys/osxvideo/osxvideosink.m')
-rw-r--r-- | sys/osxvideo/osxvideosink.m | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m new file mode 100644 index 00000000..f3f09975 --- /dev/null +++ b/sys/osxvideo/osxvideosink.m @@ -0,0 +1,474 @@ +/* GStreamer + * OSX video sink + * Copyright (C) 2004-6 Zaheer Abbas Merali <zaheerabbas at merali dot org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +/* Object header */ +#include "osxvideosink.h" + +#import "cocoawindow.h" + +/* Debugging category */ +GST_DEBUG_CATEGORY (gst_debug_osx_video_sink); +#define GST_CAT_DEFAULT gst_debug_osx_video_sink + +/* ElementFactory information */ +static const GstElementDetails gst_osx_video_sink_details = +GST_ELEMENT_DETAILS ("OSX Video sink", + "Sink/Video", + "OSX native videosink", + "Zaheer Abbas Merali <zaheerabbas at merali dot org>"); + +/* Default template - initiated with class struct to allow gst-register to work + without X running */ +static GstStaticPadTemplate gst_osx_video_sink_sink_template_factory = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ], " + "format = (fourcc) UYVY") + ); + +enum +{ + ARG_0, + ARG_EMBED, + ARG_FULLSCREEN + /* FILL ME */ +}; + +static GstVideoSinkClass *parent_class = NULL; + +/* cocoa event loop - needed if not run in own app */ +gpointer +cocoa_event_loop (GstOSXVideoSink * vsink) +{ + GST_DEBUG_OBJECT (vsink, "About to start cocoa event loop"); + + [NSApp run]; + + GST_DEBUG_OBJECT (vsink, "Cocoa event loop ended"); + + return NULL; +} + +/* This function handles osx window creation */ +static GstOSXWindow * +gst_osx_video_sink_osxwindow_new (GstOSXVideoSink * osxvideosink, gint width, + gint height) +{ + NSRect rect; + GstOSXWindow *osxwindow = NULL; + + g_return_val_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink), NULL); + + osxwindow = g_new0 (GstOSXWindow, 1); + + osxwindow->width = width; + osxwindow->height = height; + osxwindow->internal = TRUE; + + if (osxvideosink->embed == FALSE) { + NSAutoreleasePool *pool; + + rect.origin.x = 100.0; + rect.origin.y = 100.0; + rect.size.width = (float) osxwindow->width; + rect.size.height = (float) osxwindow->height; + + pool =[[NSAutoreleasePool alloc] init]; + + [NSApplication sharedApplication]; + osxwindow->win =[[GstOSXVideoSinkWindow alloc] initWithContentRect: rect styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask backing: NSBackingStoreBuffered defer: NO screen:nil]; + [osxwindow->win makeKeyAndOrderFront:NSApp]; + osxwindow->gstview =[osxwindow->win gstView]; + if (osxvideosink->fullscreen) + [osxwindow->gstview setFullScreen:YES]; + + [pool release]; + + /* Start Cocoa event loop */ + g_thread_create ((GThreadFunc) cocoa_event_loop, osxvideosink, FALSE, NULL); + } else { + /* Needs to be embedded */ + + rect.origin.x = 0.0; + rect.origin.y = 0.0; + rect.size.width = (float) osxwindow->width; + rect.size.height = (float) osxwindow->height; + osxwindow->gstview =[[GstGLView alloc] initWithFrame:rect]; + /* send signal + FIXME: need to send a bus message */ + /*g_signal_emit (G_OBJECT(osxvideosink), + gst_osx_video_sink_signals[SIGNAL_VIEW_CREATED], 0, + osxwindow->gstview); */ + } + return osxwindow; +} + +/* This function destroys a GstXWindow */ +static void +gst_osx_video_sink_osxwindow_destroy (GstOSXVideoSink * osxvideosink, + GstOSXWindow * osxwindow) +{ + g_return_if_fail (osxwindow != NULL); + g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); + + g_free (osxwindow); +} + +/* This function resizes a GstXWindow */ +static void +gst_osx_video_sink_osxwindow_resize (GstOSXVideoSink * osxvideosink, + GstOSXWindow * osxwindow, guint width, guint height) +{ + NSSize size; + + g_return_if_fail (osxwindow != NULL); + g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); + + //SizeWindow (osxwindow->win, width, height, 1); + osxwindow->width = width; + osxwindow->height = height; + + size.width = width; + size.height = height; + /* Call relevant cocoa function to resize window */ +[osxwindow->win setContentSize:size]; +} + +static void +gst_osx_video_sink_osxwindow_clear (GstOSXVideoSink * osxvideosink, + GstOSXWindow * osxwindow) +{ + + g_return_if_fail (osxwindow != NULL); + g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); + +} + + +/* Element stuff */ +static gboolean +gst_osx_video_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) +{ + GstOSXVideoSink *osxvideosink; + GstStructure *structure; + gboolean res, result = FALSE; + gint video_width, video_height; + const GValue *framerate; + + osxvideosink = GST_OSX_VIDEO_SINK (bsink); + + GST_DEBUG_OBJECT (osxvideosink, "caps: %" GST_PTR_FORMAT, caps); + + structure = gst_caps_get_structure (caps, 0); + res = gst_structure_get_int (structure, "width", &video_width); + res &= gst_structure_get_int (structure, "height", &video_height); + framerate = gst_structure_get_value (structure, "framerate"); + res &= (framerate != NULL); + + if (!res) { + goto beach; + } + + osxvideosink->fps_n = gst_value_get_fraction_numerator (framerate); + osxvideosink->fps_d = gst_value_get_fraction_denominator (framerate); + + GST_DEBUG_OBJECT (osxvideosink, "our format is: %dx%d video at %d/%d fps", + video_width, video_height, osxvideosink->fps_n, osxvideosink->fps_d); + + GST_VIDEO_SINK_WIDTH (osxvideosink) = video_width; + GST_VIDEO_SINK_HEIGHT (osxvideosink) = video_height; + + gst_osx_video_sink_osxwindow_resize (osxvideosink, osxvideosink->osxwindow, + video_width, video_height); + result = TRUE; + +beach: + return result; + +} + +static GstStateChangeReturn +gst_osx_video_sink_change_state (GstElement * element, + GstStateChange transition) +{ + GstOSXVideoSink *osxvideosink; + + osxvideosink = GST_OSX_VIDEO_SINK (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + /* Creating our window and our image */ + if (!osxvideosink->osxwindow) { + GST_VIDEO_SINK_WIDTH (osxvideosink) = 320; + GST_VIDEO_SINK_HEIGHT (osxvideosink) = 240; + osxvideosink->osxwindow = + gst_osx_video_sink_osxwindow_new (osxvideosink, + GST_VIDEO_SINK_WIDTH (osxvideosink), + GST_VIDEO_SINK_HEIGHT (osxvideosink)); + gst_osx_video_sink_osxwindow_clear (osxvideosink, + osxvideosink->osxwindow); + } else { + if (osxvideosink->osxwindow->internal) + gst_osx_video_sink_osxwindow_resize (osxvideosink, + osxvideosink->osxwindow, GST_VIDEO_SINK_WIDTH (osxvideosink), + GST_VIDEO_SINK_HEIGHT (osxvideosink)); + } + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + GST_DEBUG ("ready to paused"); + if (osxvideosink->osxwindow) + gst_osx_video_sink_osxwindow_clear (osxvideosink, + osxvideosink->osxwindow); + osxvideosink->time = 0; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + osxvideosink->fps_n = 0; + osxvideosink->fps_d = 0; + osxvideosink->sw_scaling_failed = FALSE; + GST_VIDEO_SINK_WIDTH (osxvideosink) = 0; + GST_VIDEO_SINK_HEIGHT (osxvideosink) = 0; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + + if (osxvideosink->osxwindow) { + gst_osx_video_sink_osxwindow_destroy (osxvideosink, + osxvideosink->osxwindow); + osxvideosink->osxwindow = NULL; + } + break; + } + + return (GST_ELEMENT_CLASS (parent_class))->change_state (element, transition); + +} + +static GstFlowReturn +gst_osx_video_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) +{ + GstOSXVideoSink *osxvideosink; + + osxvideosink = GST_OSX_VIDEO_SINK (bsink); + + char *viewdata =[osxvideosink->osxwindow->gstview getTextureBuffer]; + + GST_DEBUG ("show_frame"); + memcpy (viewdata, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + [osxvideosink->osxwindow->gstview displayTexture]; + + return GST_FLOW_OK; +} + +/* Buffer management */ + + + +/* =========================================== */ +/* */ +/* Init & Class init */ +/* */ +/* =========================================== */ + +static void +gst_osx_video_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOSXVideoSink *osxvideosink; + + g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object)); + + osxvideosink = GST_OSX_VIDEO_SINK (object); + + switch (prop_id) { + case ARG_EMBED: + osxvideosink->embed = g_value_get_boolean (value); + break; + case ARG_FULLSCREEN: + osxvideosink->fullscreen = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_osx_video_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOSXVideoSink *osxvideosink; + + g_return_if_fail (GST_IS_OSX_VIDEO_SINK (object)); + + osxvideosink = GST_OSX_VIDEO_SINK (object); + + switch (prop_id) { + case ARG_EMBED: + g_value_set_boolean (value, osxvideosink->embed); + break; + case ARG_FULLSCREEN: + g_value_set_boolean (value, osxvideosink->fullscreen); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_osx_video_sink_dispose (GObject * object) +{ + GstOSXVideoSink *osxvideosink; + + osxvideosink = GST_OSX_VIDEO_SINK (object); + + g_mutex_free (osxvideosink->pool_lock); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_osx_video_sink_init (GstOSXVideoSink * osxvideosink) +{ + + + osxvideosink->osxwindow = NULL; + + + osxvideosink->fps_n = 0; + osxvideosink->fps_d = 0; + + osxvideosink->pixel_width = osxvideosink->pixel_height = 1; + osxvideosink->sw_scaling_failed = FALSE; + osxvideosink->embed = FALSE; + osxvideosink->fullscreen = FALSE; + +} + +static void +gst_osx_video_sink_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_set_details (element_class, &gst_osx_video_sink_details); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_osx_video_sink_sink_template_factory)); +} + +static void +gst_osx_video_sink_class_init (GstOSXVideoSinkClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasesink_class = (GstBaseSinkClass *) klass; + + + parent_class = g_type_class_ref (GST_TYPE_VIDEO_SINK); + + gobject_class->dispose = gst_osx_video_sink_dispose; + gobject_class->set_property = gst_osx_video_sink_set_property; + gobject_class->get_property = gst_osx_video_sink_get_property; + + //gstbasesink_class->get_times = gst_osx_video_sink_get_times; + gstbasesink_class->set_caps = gst_osx_video_sink_setcaps; + gstbasesink_class->preroll = gst_osx_video_sink_show_frame; + gstbasesink_class->render = gst_osx_video_sink_show_frame; + gstelement_class->change_state = gst_osx_video_sink_change_state; + + g_object_class_install_property (gobject_class, ARG_EMBED, + g_param_spec_boolean ("embed", "embed", "When enabled, it " + "can be embedded", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_FULLSCREEN, + g_param_spec_boolean ("fullscreen", "fullscreen", + "When enabled, the view " "is fullscreen", FALSE, + G_PARAM_READWRITE)); +} + +/* ============================================================= */ +/* */ +/* Public Methods */ +/* */ +/* ============================================================= */ + +/* =========================================== */ +/* */ +/* Object typing & Creation */ +/* */ +/* =========================================== */ + +GType +gst_osx_video_sink_get_type (void) +{ + static GType osxvideosink_type = 0; + + if (!osxvideosink_type) { + static const GTypeInfo osxvideosink_info = { + sizeof (GstOSXVideoSinkClass), + gst_osx_video_sink_base_init, + NULL, + (GClassInitFunc) gst_osx_video_sink_class_init, + NULL, + NULL, + sizeof (GstOSXVideoSink), + 0, + (GInstanceInitFunc) gst_osx_video_sink_init, + }; + + osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK, + "GstOSXVideoSink", &osxvideosink_info, 0); + + } + + return osxvideosink_type; +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + + if (!gst_element_register (plugin, "osxvideosink", + GST_RANK_PRIMARY, GST_TYPE_OSX_VIDEO_SINK)) + return FALSE; + + GST_DEBUG_CATEGORY_INIT (gst_debug_osx_video_sink, "osxvideosink", 0, + "osxvideosink element"); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "osxvideo", + "OSX native video output plugin", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) |