diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/Makefile.am | 10 | ||||
-rw-r--r-- | sys/osxvideo/Makefile.am | 17 | ||||
-rw-r--r-- | sys/osxvideo/cocoawindow.h | 70 | ||||
-rw-r--r-- | sys/osxvideo/cocoawindow.m | 400 | ||||
-rw-r--r-- | sys/osxvideo/osxvideosink.h | 107 | ||||
-rw-r--r-- | sys/osxvideo/osxvideosink.m | 665 |
6 files changed, 2 insertions, 1267 deletions
diff --git a/sys/Makefile.am b/sys/Makefile.am index 468b7b70..3866499c 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -34,12 +34,6 @@ else DVB_DIR= endif -if USE_OSX_VIDEO -OSX_VIDEO_DIR=osxvideo -else -OSX_VIDEO_DIR= -endif - -SUBDIRS = $(GL_DIR) $(DVB_DIR) $(OSX_VIDEO_DIR) +SUBDIRS = $(GL_DIR) $(DVB_DIR) -DIST_SUBDIRS = glsink dvb osxvideo +DIST_SUBDIRS = glsink dvb diff --git a/sys/osxvideo/Makefile.am b/sys/osxvideo/Makefile.am deleted file mode 100644 index 99bb0489..00000000 --- a/sys/osxvideo/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# FIXME: clean up this crap -OBJC=gcc - -plugin_LTLIBRARIES = libgstosxvideosink.la - -libgstosxvideosink_la_SOURCES = osxvideosink.m cocoawindow.m -libgstosxvideosink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) -libgstosxvideosink_la_LIBADD = \ - $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ - -lgstinterfaces-$(GST_MAJORMINOR) - -libgstosxvideosink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework -Wl,Cocoa -Wl,-framework -Wl,QuickTime -Wl,-framework -Wl,OpenGL - -AM_OBJCFLAGS=$(CFLAGS) $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) - -noinst_HEADERS = osxvideosink.h cocoawindow.h diff --git a/sys/osxvideo/cocoawindow.h b/sys/osxvideo/cocoawindow.h deleted file mode 100644 index 340bd160..00000000 --- a/sys/osxvideo/cocoawindow.h +++ /dev/null @@ -1,70 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Zaheer Abbas Merali <zaheerabbas at merali dot org> - * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com> - * - * 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. - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -/* inspiration gained from looking at source of osx video out of xine and vlc - * and is reflected in the code - */ - -#import <Cocoa/Cocoa.h> -#import <QuickTime/QuickTime.h> -#import <glib.h> - -struct _GstOSXImage; - -@interface GstGLView : NSOpenGLView -{ - int i_effect; - unsigned long pi_texture; - float f_x; - float f_y; - int initDone; - char* data; - int width, height; - BOOL fullscreen; - NSOpenGLContext* fullScreenContext; - NSOpenGLContext* actualContext; -} -- (void) drawQuad; -- (void) drawRect: (NSRect) rect; -- (id) initWithFrame: (NSRect) frame; -- (void) initTextures; -- (void) reloadTexture; -- (void) cleanUp; -- (void) displayTexture; -- (char*) getTextureBuffer; -- (void) setFullScreen: (BOOL) flag; -- (void) reshape; -- (void) setVideoSize: (int) w: (int) h; - -@end - -@interface GstOSXVideoSinkWindow: NSWindow { - int width, height; - GstGLView *gstview; -} - -- (void) setContentSize: (NSSize) size; -- (GstGLView *) gstView; -- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)aScreen; -@end diff --git a/sys/osxvideo/cocoawindow.m b/sys/osxvideo/cocoawindow.m deleted file mode 100644 index 9b5e7b31..00000000 --- a/sys/osxvideo/cocoawindow.m +++ /dev/null @@ -1,400 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Zaheer Abbas Merali <zaheerabbas at merali dot org> - * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com> - * - * 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. - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -/* inspiration gained from looking at source of osx video out of xine and vlc - * and is reflected in the code - */ - - -#include <Cocoa/Cocoa.h> -#include <gst/gst.h> -#import "cocoawindow.h" -#import "osxvideosink.h" - -#include <OpenGL/OpenGL.h> -#include <OpenGL/gl.h> -#include <OpenGL/glext.h> - -/* Debugging category */ -#include <gst/gstinfo.h> - -@ implementation GstOSXVideoSinkWindow - -/* The object has to be released */ -- (id) initWithContentRect: (NSRect) rect - styleMask: (unsigned int) styleMask - backing: (NSBackingStoreType) bufferingType - defer: (BOOL) flag - screen:(NSScreen *) aScreen -{ - self = [super initWithContentRect: rect - styleMask: styleMask - backing: bufferingType - defer: flag - screen:aScreen]; - - GST_DEBUG ("Initializing GstOSXvideoSinkWindow"); - - gstview = [[GstGLView alloc] initWithFrame:rect]; - - if (gstview) - [self setContentView:gstview]; - [self setTitle:@"GStreamer Video Output"]; - - return self; -} - -- (void) setContentSize:(NSSize) size { - width = size.width; - height = size.height; - - [gstview setVideoSize: (int) width:(int) height]; - - [super setContentSize:size]; -} - -- (GstGLView *) gstView { - return gstview; -} - -- (void) awakeFromNib { - [self setAcceptsMouseMovedEvents:YES]; -} - -- (void) sendEvent:(NSEvent *) event { - BOOL taken = NO; - - GST_DEBUG ("event %p type:%d", event,[event type]); - - if ([event type] == NSKeyDown) { - } - /*taken = [gstview keyDown:event]; */ - - if (!taken) { - [super sendEvent:event]; - } -} - - -@end - - -// -// OpenGL implementation -// - -@ implementation GstGLView - -- (id) initWithFrame:(NSRect) frame { - NSOpenGLPixelFormat *fmt; - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFANoRecovery, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAWindow, - 0 - }; - - fmt = [[NSOpenGLPixelFormat alloc] - initWithAttributes:attribs]; - - if (!fmt) { - GST_WARNING ("Cannot create NSOpenGLPixelFormat"); - return nil; - } - - self = [super initWithFrame: frame pixelFormat:fmt]; - - actualContext = [self openGLContext]; - [actualContext makeCurrentContext]; - [actualContext update]; - - /* Black background */ - glClearColor (0.0, 0.0, 0.0, 0.0); - - pi_texture = 0; - data = nil; - width = frame.size.width; - height = frame.size.height; - - GST_LOG ("Width: %d Height: %d", width, height); - - [self initTextures]; - return self; -} - -- (void) reshape { - NSRect bounds; - - GST_LOG ("reshaping"); - - if (!initDone) { - return; - } - - [actualContext makeCurrentContext]; - - bounds = [self bounds]; - - glViewport (0, 0, (GLint) bounds.size.width, (GLint) bounds.size.height); - -} - -- (void) initTextures { - - [actualContext makeCurrentContext]; - - /* Free previous texture if any */ - if (pi_texture) { - glDeleteTextures (1, &pi_texture); - } - - if (data) { - data = g_realloc (data, width * height * sizeof(short)); // short or 3byte? - } else { - data = g_malloc0(width * height * sizeof(short)); - } - /* Create textures */ - glGenTextures (1, &pi_texture); - - glEnable (GL_TEXTURE_RECTANGLE_EXT); - glEnable (GL_UNPACK_CLIENT_STORAGE_APPLE); - - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - glPixelStorei (GL_UNPACK_ROW_LENGTH, width); - - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); - - /* Use VRAM texturing */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE); - - /* Tell the driver not to make a copy of the texture but to use - our buffer */ - glPixelStorei (GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); - - /* Linear interpolation */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - /* I have no idea what this exactly does, but it seems to be - necessary for scaling */ - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_EXT, - GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); WHY ?? - - glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, - width, height, 0, - GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, data); - - - initDone = 1; -} - -- (void) reloadTexture { - if (!initDone) { - return; - } - - GST_LOG ("Reloading Texture"); - - [actualContext makeCurrentContext]; - - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); - glPixelStorei (GL_UNPACK_ROW_LENGTH, width); - - /* glTexSubImage2D is faster than glTexImage2D - http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/ - TextureRange/MainOpenGLView.m.htm */ - glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, - width, height, - GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, data); //FIXME -} - -- (void) cleanUp { - initDone = 0; -} - -- (void) drawQuad { - f_x = 1.0; - f_y = 1.0; - - glBegin (GL_QUADS); - /* Top left */ - glTexCoord2f (0.0, 0.0); - glVertex2f (-f_x, f_y); - /* Bottom left */ - glTexCoord2f (0.0, (float) height); - glVertex2f (-f_x, -f_y); - /* Bottom right */ - glTexCoord2f ((float) width, (float) height); - glVertex2f (f_x, -f_y); - /* Top right */ - glTexCoord2f ((float) width, 0.0); - glVertex2f (f_x, f_y); - glEnd (); -} - -- (void) drawRect:(NSRect) rect { - long params[] = { 1 }; - - [actualContext makeCurrentContext]; - - CGLSetParameter (CGLGetCurrentContext (), kCGLCPSwapInterval, params); - - /* Black background */ - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (!initDone) { - [actualContext flushBuffer]; - return; - } - - /* Draw */ - glBindTexture (GL_TEXTURE_RECTANGLE_EXT, pi_texture); // FIXME - [self drawQuad]; - /* Draw */ - [actualContext flushBuffer]; -} - -- (void) displayTexture { - if ([self lockFocusIfCanDraw]) { - - [self drawRect:[self bounds]]; - [self reloadTexture]; - - [self unlockFocus]; - - } - -} - -- (char *) getTextureBuffer { - return data; -} - -- (void) setFullScreen:(BOOL) flag { - if (!fullscreen && flag) { - // go to full screen - /* Create the new pixel format */ - NSOpenGLPixelFormat *fmt; - NSOpenGLPixelFormatAttribute attribs[] = { - NSOpenGLPFAAccelerated, - NSOpenGLPFANoRecovery, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAFullScreen, - NSOpenGLPFAScreenMask, - CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay), - 0 - }; - - fmt = [[NSOpenGLPixelFormat alloc] - initWithAttributes:attribs]; - - if (!fmt) { - GST_WARNING ("Cannot create NSOpenGLPixelFormat"); - return; - } - - /* Create the new OpenGL context */ - fullScreenContext = [[NSOpenGLContext alloc] - initWithFormat: fmt shareContext:nil]; - if (!fullScreenContext) { - GST_WARNING ("Failed to create new NSOpenGLContext"); - return; - } - - actualContext = fullScreenContext; - - /* Capture display, switch to fullscreen */ - if (CGCaptureAllDisplays () != CGDisplayNoErr) { - GST_WARNING ("CGCaptureAllDisplays() failed"); - return; - } - [fullScreenContext setFullScreen]; - [fullScreenContext makeCurrentContext]; - - fullscreen = YES; - - [self initTextures]; - [self setNeedsDisplay:YES]; - - } else if (fullscreen && !flag) { - // fullscreen now and needs to go back to normal - initDone = NO; - - actualContext = [self openGLContext]; - - [NSOpenGLContext clearCurrentContext]; - [fullScreenContext clearDrawable]; - [fullScreenContext release]; - fullScreenContext = nil; - - CGReleaseAllDisplays (); - - [self reshape]; - [self initTextures]; - - [self setNeedsDisplay:YES]; - - fullscreen = NO; - initDone = YES; - } -} - -- (void) setVideoSize: (int) w:(int) h { - GST_LOG ("width:%d, height:%d", w, h); - - width = w; - height = h; - -// if (data) g_free(data); - -// data = g_malloc0 (2 * w * h); - [self initTextures]; -} - -- (void) dealloc { - GST_LOG ("dealloc called"); - if (data) g_free(data); - - if (fullScreenContext) { - [NSOpenGLContext clearCurrentContext]; - [fullScreenContext clearDrawable]; - [fullScreenContext release]; - if (actualContext == fullScreenContext) actualContext = nil; - fullScreenContext = nil; - } - - [super dealloc]; -} -@end diff --git a/sys/osxvideo/osxvideosink.h b/sys/osxvideo/osxvideosink.h deleted file mode 100644 index d7fba966..00000000 --- a/sys/osxvideo/osxvideosink.h +++ /dev/null @@ -1,107 +0,0 @@ -/* GStreamer - * Copyright (C) 2004-6 Zaheer Abbas Merali <zaheerabbas at merali dot org> - * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com> - * - * - * 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. - * - * - * The development of this code was made possible due to the involvement of Pioneers - * of the Inevitable, the creators of the Songbird Music player - * - */ - -#ifndef __GST_OSX_VIDEO_SINK_H__ -#define __GST_OSX_VIDEO_SINK_H__ - -#include <gst/video/gstvideosink.h> - -#include <string.h> -#include <math.h> -#include <Cocoa/Cocoa.h> - -#include <QuickTime/QuickTime.h> -#import "cocoawindow.h" - -GST_DEBUG_CATEGORY_EXTERN (gst_debug_osx_video_sink); -#define GST_CAT_DEFAULT gst_debug_osx_video_sink - -G_BEGIN_DECLS - -#define GST_TYPE_OSX_VIDEO_SINK \ - (gst_osx_video_sink_get_type()) -#define GST_OSX_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_OSX_VIDEO_SINK, GstOSXVideoSink)) -#define GST_OSX_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_OSX_VIDEO_SINK, GstOSXVideoSinkClass)) -#define GST_IS_OSX_VIDEO_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OSX_VIDEO_SINK)) -#define GST_IS_OSX_VIDEO_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_OSX_VIDEO_SINK)) - -typedef struct _GstOSXWindow GstOSXWindow; - -typedef struct _GstOSXVideoSink GstOSXVideoSink; -typedef struct _GstOSXVideoSinkClass GstOSXVideoSinkClass; - -#define GST_TYPE_OSXVIDEOBUFFER (gst_osxvideobuffer_get_type()) - -/* OSXWindow stuff */ -struct _GstOSXWindow { - gint width, height; - gboolean internal; - GstOSXVideoSinkWindow* win; - GstGLView* gstview; - NSAutoreleasePool *pool; -}; - -struct _GstOSXVideoSink { - /* Our element stuff */ - GstVideoSink videosink; - GstOSXWindow *osxwindow; - - gint fps_n; - gint fps_d; - - /* Unused */ - gint pixel_width, pixel_height; - - GstClockTime time; - - gboolean embed; - gboolean fullscreen; - gboolean sw_scaling_failed; -}; - -struct _GstOSXVideoSinkClass { - GstVideoSinkClass parent_class; -}; - -GType gst_osx_video_sink_get_type(void); - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 -@interface NSApplication(AppleMenu) -- (void)setAppleMenu:(NSMenu *)menu; -@end -#endif - -@interface GstAppDelegate : NSObject -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end - -G_END_DECLS - -#endif /* __GST_OSX_VIDEO_SINK_H__ */ diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m deleted file mode 100644 index 2bb0447b..00000000 --- a/sys/osxvideo/osxvideosink.m +++ /dev/null @@ -1,665 +0,0 @@ -/* GStreamer - * OSX video sink - * Copyright (C) 2004-6 Zaheer Abbas Merali <zaheerabbas at merali dot org> - * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com> - * - * 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. - * - * The development of this code was made possible due to the involvement of - * Pioneers of the Inevitable, the creators of the Songbird Music player. - * - */ - -/** - * SECTION:element-osxvideosink - * - * <refsect2> - * <para> - * The OSXVideoSink renders video frames to a MacOSX window. The video output - * can be directed to a window embedded in an existing NSApp. This can be done - * by setting the "embed" property to #TRUE. When the NSView to be embedded is - * created an element #GstMessage with a name of 'have-ns-view' will be created - * and posted on the bus. The pointer to the NSView to embed will be in the - * 'nsview' field of that message. If no embedding is requested, the plugin will - * create a standalone window. - * </para> - * <title>Examples</title> - * <para> - * Simple timeline to test the sink : - * <programlisting> - * gst-launch-0.10 -v videotestsrc ! osxvideosink - * </programlisting> - * </para> - * </refsect2> - */ - -#include "config.h" - -/* Object header */ -#include "osxvideosink.h" -#include <unistd.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 ], " -#if G_BYTE_ORDER == G_BIG_ENDIAN - "format = (fourcc) YUY2") -#else - "format = (fourcc) UYVY") -#endif - ); - -// much of the following cocoa NSApp code comes from libsdl and libcaca -@implementation NSApplication(Gst) -- (void)setRunning -{ - _running = 1; -} -@end - -@implementation GstAppDelegate : NSObject -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - // destroy stuff here! - GST_DEBUG("Kill me please!"); - return NSTerminateNow; -} -@end - - -enum -{ - ARG_0, - ARG_EMBED, - ARG_FULLSCREEN - /* FILL ME */ -}; - -static GstVideoSinkClass *parent_class = NULL; - - -/* cocoa event loop - needed if not run in own app */ -gint -cocoa_event_loop (GstOSXVideoSink * vsink) -{ - NSAutoreleasePool *pool; - gboolean ret = TRUE; - - GST_DEBUG_OBJECT (vsink, "Entering event loop"); - - pool = [[NSAutoreleasePool alloc] init]; - - if ([NSApp isRunning]) { - NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode dequeue:YES ]; - if ( event != nil ) { - switch ([event type]) { - default: //XXX Feed me please - [NSApp sendEvent:event]; - break; - } - } - } - - [pool release]; - - GST_DEBUG_OBJECT (vsink, "Leaving event loop with ret : %d", ret); - - return ret; -} - -static NSString * -GetApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -static void -CreateApplicationMenus(void) -{ - NSString *appName; - NSString *title; - NSMenu *appleMenu; - NSMenu *windowMenu; - NSMenuItem *menuItem; - - /* Create the main menu bar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - - /* Create the application menu */ - appName = GetApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@/*"h"*/""]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@/*"h"*/""]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@/*"q"*/""]; - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - [appleMenu release]; - - - /* Create the window menu */ - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@/*"m"*/""]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - [windowMenu release]; -} - -/* 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; - osxwindow->pool = [[NSAutoreleasePool alloc] init]; - - if (osxvideosink->embed == FALSE) { - ProcessSerialNumber psn; - unsigned int mask = NSTitledWindowMask | - NSClosableWindowMask | - NSResizableWindowMask | - NSTexturedBackgroundWindowMask | - NSMiniaturizableWindowMask; - - rect.origin.x = 100.0; - rect.origin.y = 100.0; - rect.size.width = (float) osxwindow->width; - rect.size.height = (float) osxwindow->height; - - if (!GetCurrentProcess(&psn)) { - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); - } - - [NSApplication sharedApplication]; - - osxwindow->win =[[GstOSXVideoSinkWindow alloc] - initWithContentRect: rect - styleMask: mask - backing: NSBackingStoreBuffered - defer: NO - screen: nil]; - [osxwindow->win autorelease]; - [NSApplication sharedApplication]; - [osxwindow->win makeKeyAndOrderFront:NSApp]; - osxwindow->gstview =[osxwindow->win gstView]; - [osxwindow->gstview autorelease]; - if (osxvideosink->fullscreen) - [osxwindow->gstview setFullScreen:YES]; - - CreateApplicationMenus(); - - [NSApp finishLaunching]; - [NSApp setDelegate:[[GstAppDelegate alloc] init]]; - - [NSApp setRunning]; - // insert event dispatch in the glib main loop - g_idle_add ((GSourceFunc) cocoa_event_loop, osxvideosink); - } else { - GstStructure *s; - GstMessage *msg; - gchar * tmp; - /* 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]; - [osxwindow->gstview autorelease]; - - s = gst_structure_new ("have-ns-view", - "nsview", G_TYPE_POINTER, osxwindow->gstview, - nil); - - tmp = gst_structure_to_string (s); - GST_DEBUG_OBJECT (osxvideosink, "Sending message %s", - tmp); - g_free (tmp); - - msg = gst_message_new_element (GST_OBJECT (osxvideosink), s); - gst_element_post_message (GST_ELEMENT (osxvideosink), msg); - - GST_LOG_OBJECT (osxvideosink, "'have-ns-view' message sent"); - } - 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)); - - [osxwindow->pool release]; - - 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; - NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; - g_return_if_fail (osxwindow != NULL); - g_return_if_fail (GST_IS_OSX_VIDEO_SINK (osxvideosink)); - - osxwindow->width = width; - osxwindow->height = height; - - size.width = width; - size.height = height; - /* Call relevant cocoa function to resize window */ - [osxwindow->win setContentSize:size]; - [subPool release]; -} - -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); - - GST_DEBUG_OBJECT (osxvideosink, "%s => %s", - gst_element_state_get_name(GST_STATE_TRANSITION_CURRENT (transition)), - gst_element_state_get_name(GST_STATE_TRANSITION_NEXT (transition))); - - 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_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->set_property = gst_osx_video_sink_set_property; - gobject_class->get_property = gst_osx_video_sink_get_property; - - 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; - - /** - * GstOSXVideoSink:embed - * - * Set to #TRUE if you are embedding the video window in an application. - * - **/ - - 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)); - - /** - * GstOSXVideoSink:fullscreen - * - * Set to #TRUE to have the video displayed in fullscreen. - **/ - - 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) |