summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames Courtier-Dutton <jcdutton@users.sourceforge.net>2004-06-06 02:30:37 +0000
committerJames Courtier-Dutton <jcdutton@users.sourceforge.net>2004-06-06 02:30:37 +0000
commit3a3d6e18eec4ce49d352f68fbe52305f10e8a33e (patch)
tree69eb5e12d9050e5d5cbbf10d4d0dd1e8f231fb06 /src
parent6d0a15c5c157ccf8f46ae421e6bbb14fd49cb78d (diff)
downloadxine-lib-3a3d6e18eec4ce49d352f68fbe52305f10e8a33e.tar.gz
xine-lib-3a3d6e18eec4ce49d352f68fbe52305f10e8a33e.tar.bz2
From: Daniel Mack
Mac OSX video out support. CVS patchset: 6645 CVS date: 2004/06/06 02:30:37
Diffstat (limited to 'src')
-rw-r--r--src/video_out/Makefile.am10
-rw-r--r--src/video_out/macosx/video_window.m335
2 files changed, 339 insertions, 6 deletions
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 49f9cd406..dca4fb711 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -1,6 +1,6 @@
include $(top_srcdir)/misc/Makefile.common
-SUBDIRS = libdha vidix
+SUBDIRS = libdha vidix macosx
EXTRA_DIST = video_out_directfb.c video_out_opengl.c video_out_directx.c video_out_macosx.c
@@ -70,9 +70,9 @@ if HAVE_DIRECTX
directx_module = xineplug_vo_out_directx.la
endif
-#if HAVE_MACOSX_VIDEO
-#macosx_module = xineplug_vo_out_macosx.la
-#endif
+if HAVE_MACOSX_VIDEO
+macosx_module = xineplug_vo_out_macosx.la
+endif
# important:
@@ -165,13 +165,11 @@ xineplug_vo_out_none_la_SOURCES = video_out_none.c
xineplug_vo_out_none_la_LIBADD = $(XINE_LIB)
xineplug_vo_out_none_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
-#if 0
xineplug_vo_out_macosx_la_SOURCES = alphablend.c video_out_macosx.m
xineplug_vo_out_macosx_la_LIBADD = $(MLIB_LIBS) $(OPENGL_LIBS) $(GLUT_LIBS) \
$(GLU_LIBS) $(X_LIBS) $(XINE_LIB) macosx/libxine_macosx_video.la
xineplug_vo_out_macosx_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -framework Cocoa -framework OpenGL -lobjc -umbrella AppKit
xineplug_vo_out_macosx_la_OBJCFLAGS = $(OBJCFLAGS) $(AM_CFLAGS)
-#endif
noinst_HEADERS = alphablend.h deinterlace.h video_out_syncfb.h \
yuv2rgb.h x11osd.h
diff --git a/src/video_out/macosx/video_window.m b/src/video_out/macosx/video_window.m
new file mode 100644
index 000000000..f068329e0
--- /dev/null
+++ b/src/video_out/macosx/video_window.m
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2004 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:
+ *
+ * Most parts of this code were taken from VLC, http://www.videolan.org
+ * Thanks for the good research, folks!
+ */
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#import "video_window.h"
+
+@implementation XineVideoWindow
+
+- (void) displayTexture {
+ if ([openGLView lockFocusIfCanDraw]) {
+ [openGLView drawRect: [openGLView bounds]];
+ [openGLView reloadTexture];
+ [openGLView unlockFocus];
+ }
+}
+
+- (void) setContentSize: (NSSize) size {
+ width = size.width;
+ height = size.height;
+
+ [openGLView setVideoSize: width : height];
+
+ [super setContentSize: size];
+}
+
+- (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];
+
+ openGLView = [[XineOpenGLView alloc] initWithFrame:rect];
+ [self setContentView: openGLView];
+ [self setTitle: @"xine video output"];
+
+ return self;
+}
+
+- (XineOpenGLView *) getGLView {
+ return openGLView;
+}
+
+- (void) goFullScreen {
+ [openGLView goFullScreen];
+}
+
+- (void) exitFullScreen {
+ [openGLView exitFullScreen];
+}
+
+@end
+
+
+@implementation XineOpenGLView
+
+- (id) initWithFrame: (NSRect) frame {
+
+ NSOpenGLPixelFormatAttribute attribs[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAWindow,
+ 0
+ };
+
+ NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
+ initWithAttributes: attribs];
+
+ if (!fmt) {
+ printf ("Cannot create NSOpenGLPixelFormat\n");
+ return nil;
+ }
+
+ self = [super initWithFrame:frame pixelFormat: fmt];
+
+ currentContext = [self openGLContext];
+ [currentContext makeCurrentContext];
+ [currentContext update];
+
+ /* Black background */
+ glClearColor (0.0, 0.0, 0.0, 0.0);
+
+ i_texture = 0;
+ initDone = 0;
+ isFullScreen = 0;
+ width = frame.size.width;
+ height = frame.size.height;
+ texture_buffer = nil;
+
+ [self initTextures];
+
+ return self;
+}
+
+- (void) reshape {
+ if (!initDone)
+ return;
+
+ [currentContext makeCurrentContext];
+
+ NSRect bounds = [self bounds];
+ glViewport (0, 0, (GLint) bounds.size.width,
+ (GLint) bounds.size.height);
+
+ f_x = 1.0;
+ f_y = 1.0;
+}
+
+
+- (void) initTextures {
+ [currentContext makeCurrentContext];
+
+ /* Free previous texture if any */
+ if (i_texture)
+ glDeleteTextures (1, &i_texture);
+
+ if (texture_buffer)
+ texture_buffer = realloc (texture_buffer, sizeof (char) * width * height * 3);
+ else
+ texture_buffer = malloc (sizeof (char) * width * height * 3);
+
+ /* Create textures */
+ glGenTextures (1, &i_texture);
+
+ glEnable (GL_TEXTURE_RECTANGLE_EXT);
+ glEnable (GL_UNPACK_CLIENT_STORAGE_APPLE);
+
+ glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_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);
+
+ glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,
+ width, height, 0,
+ GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
+ texture_buffer);
+
+ initDone = 1;
+}
+
+- (void) reloadTexture {
+ if (!initDone)
+ return;
+
+ [currentContext makeCurrentContext];
+
+ glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
+
+ /* 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,
+ texture_buffer);
+}
+
+- (void) goFullScreen {
+ /* Create the new pixel format */
+ NSOpenGLPixelFormatAttribute attribs[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAFullScreen,
+ NSOpenGLPFAScreenMask,
+ CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay),
+ 0
+ };
+
+ NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
+ initWithAttributes: attribs];
+ if (!fmt) {
+ printf ("Cannot create NSOpenGLPixelFormat\n");
+ return;
+ }
+
+ /* Create the new OpenGL context */
+ fullScreenContext = [[NSOpenGLContext alloc]
+ initWithFormat: fmt shareContext: nil];
+ if (!fullScreenContext) {
+ printf ("Failed to create new NSOpenGLContext\n");
+ return;
+ }
+ currentContext = fullScreenContext;
+
+ /* Capture display, switch to fullscreen */
+ if (CGCaptureAllDisplays() != CGDisplayNoErr) {
+ printf ("CGCaptureAllDisplays() failed\n");
+ return;
+ }
+ [fullScreenContext setFullScreen];
+ [fullScreenContext makeCurrentContext];
+
+ /* Fix ratio */
+ width = CGDisplayPixelsWide (kCGDirectMainDisplay);
+ height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
+
+ f_x = 1.0;
+ f_y = 1.0;
+
+ /* Update viewport, re-init textures */
+ glViewport (0, 0, width, height);
+ [self initTextures];
+
+ /* Redraw the last picture */
+ [self setNeedsDisplay: YES];
+
+ isFullScreen = 1;
+}
+
+- (void) exitFullScreen {
+ /* Free current OpenGL context */
+ [NSOpenGLContext clearCurrentContext];
+ [fullScreenContext clearDrawable];
+ [fullScreenContext release];
+ CGReleaseAllDisplays();
+
+ currentContext = [self openGLContext];
+ [self initTextures];
+ [self reshape];
+
+ /* Redraw the last picture */
+ [self setNeedsDisplay: YES];
+
+ isFullScreen = 0;
+}
+
+- (void) drawQuad {
+ 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 {
+ [currentContext makeCurrentContext];
+
+ /* Swap buffers only during the vertical retrace of the monitor.
+ http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL/chap5/chapter_5_section_44.html */
+
+ long params[] = { 1 };
+ CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, params);
+
+ /* Black background */
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (!initDone) {
+ [currentContext flushBuffer];
+ return;
+ }
+
+ /* Draw */
+ glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
+ [self drawQuad];
+
+ /* Wait for the job to be done */
+ [currentContext flushBuffer];
+}
+
+- (char *) getTextureBuffer {
+ return texture_buffer;
+}
+
+- (void) setVideoSize: (int) w : (int) h {
+ width = w;
+ height = h;
+ [self initTextures];
+}
+
+@end
+