Commit d4ac5770 authored by Eric Petit's avatar Eric Petit
Browse files

ALL: OS X OpenGL provider

  + vout.m contains the common code for the QT video output and the
    GL provider (window creation, events handling)
  + opengl.c: higher priority on OS X
 Things are a bit broken atm, any help to debug is welcome ;p
parent bb7f54bb
......@@ -25,6 +25,8 @@ SOURCES_macosx = \
output.h \
output.m \
vout.m \
voutqt.m \
voutgl.m \
vout.h \
$(NULL)
......@@ -291,7 +291,9 @@
}
else
{
[o_window toggleFullscreen];
vlc_value_t val;
var_Get( p_vout, "fullscreen", &val );
var_Set( p_vout, "fullscreen", (vlc_value_t)!val.b_bool );
}
break;
}
......
......@@ -38,8 +38,11 @@
int E_(OpenIntf) ( vlc_object_t * );
void E_(CloseIntf) ( vlc_object_t * );
int E_(OpenVideo) ( vlc_object_t * );
void E_(CloseVideo) ( vlc_object_t * );
int E_(OpenVideoQT) ( vlc_object_t * );
void E_(CloseVideoQT) ( vlc_object_t * );
int E_(OpenVideoGL) ( vlc_object_t * );
void E_(CloseVideoGL) ( vlc_object_t * );
/*****************************************************************************
* Module descriptor
......@@ -59,49 +62,28 @@ void E_(CloseVideo) ( vlc_object_t * );
"of the movie when resizing the video, stretch the video " \
"to fill the entire window." )
#define MACOSX_VOUT_TEXT N_("video rendering mode")
#define MACOSX_VOUT_LONGTEXT N_("The default method is OpenGL " \
"for Quartz Extreme machines and Quartz for the others.")
#define OPENGL_EFFECT_TEXT N_("OpenGL effect")
#define OPENGL_EFFECT_LONGTEXT N_("Use 'None' to display the video " \
"without any fantasy, 'Cube' to let the video play on " \
"the faces of a rotating cube, 'Transparent cube' do make this " \
"cube transparent." )
#define FILL_TEXT N_("Fill fullscreen")
#define FILL_LONGTEXT N_("In fullscreen mode, crop the picture if " \
"necessary in order to fill the screen without black " \
"borders (OpenGL only)." )
static char * effect_list[] = { "none", "cube", "transparent-cube" };
static char * effect_list_text[] = { N_("None"), N_("Cube"),
N_("Transparent cube") };
static char *ppsz_vout_list[] = { "auto", "quartz", "opengl" };
static char *ppsz_vout_list_text[] = { N_("Auto"), "Quartz", "OpenGL" };
vlc_module_begin();
set_description( _("Mac OS X interface, sound and video") );
set_capability( "interface", 100 );
set_callbacks( E_(OpenIntf), E_(CloseIntf) );
add_submodule();
set_capability( "video output", 200 );
set_callbacks( E_(OpenVideo), E_(CloseVideo) );
set_capability( "video output", 100 );
set_callbacks( E_(OpenVideoQT), E_(CloseVideoQT) );
add_integer( "macosx-vdev", 0, NULL, VDEV_TEXT, VDEV_LONGTEXT,
VLC_FALSE );
add_bool( "macosx-stretch", 0, NULL, STRETCH_TEXT, STRETCH_LONGTEXT,
VLC_FALSE );
add_float_with_range( "macosx-opaqueness", 1, 0, 1, NULL,
OPAQUENESS_TEXT, OPAQUENESS_LONGTEXT, VLC_TRUE );
add_string( "macosx-vout", "auto", NULL, MACOSX_VOUT_TEXT,
MACOSX_VOUT_LONGTEXT, VLC_TRUE );
change_string_list( ppsz_vout_list, ppsz_vout_list_text, 0 );
add_string( "macosx-opengl-effect", "none", NULL,
OPENGL_EFFECT_TEXT, OPENGL_EFFECT_LONGTEXT,
VLC_TRUE );
change_string_list( effect_list, effect_list_text, 0 );
add_bool( "macosx-fill", 0, NULL, FILL_TEXT, FILL_LONGTEXT,
VLC_TRUE );
add_submodule();
set_capability( "opengl provider", 100 );
set_callbacks( E_(OpenVideoGL), E_(CloseVideoGL) );
vlc_module_end();
......@@ -30,10 +30,18 @@
@interface VLCWindow : NSWindow
{
vout_thread_t * p_vout;
Ptr p_fullscreen_state;
mtime_t i_time_mouse_last_moved;
}
- (void)setVout:(vout_thread_t *)_p_vout;
- (vout_thread_t *)getVout;
- (id)initWithVout:(vout_thread_t *)_p_vout
frame:(NSRect *)s_frame;
- (void)close;
- (void)setOnTop:(bool)b_on_top;
- (void)hideMouse:(bool)b_hide;
- (void)manage;
- (void)scaleWindowWithFactor: (float)factor;
- (void)toggleFloatOnTop;
......@@ -44,65 +52,3 @@
- (BOOL)windowShouldClose:(id)sender;
@end
/*****************************************************************************
* VLCView interface
*****************************************************************************/
@interface VLCQTView : NSQuickDrawView
{
}
@end
/*****************************************************************************
* VLCView interface
*****************************************************************************/
@interface VLCGLView : NSOpenGLView
{
vout_thread_t * p_vout;
int i_effect;
unsigned long pi_textures[2];
float f_x;
float f_y;
int initDone;
}
- (id) initWithFrame: (NSRect) frame vout: (vout_thread_t*) p_vout;
- (void) initTextures;
- (void) reloadTexture: (int) index;
- (void) cleanUp;
@end
/*****************************************************************************
* vout_sys_t: MacOS X video output method descriptor
*****************************************************************************/
struct vout_sys_t
{
NSAutoreleasePool *o_pool;
NSRect s_rect;
VLCWindow * o_window;
VLCQTView * o_qtview;
int i_opengl;
int b_pos_saved;
vlc_bool_t b_mouse_moved;
mtime_t i_time_mouse_last_moved;
#ifdef __QUICKTIME__
CodecType i_codec;
CGrafPtr p_qdport;
ImageSequence i_seq;
MatrixRecordPtr p_matrix;
DecompressorComponent img_dc;
ImageDescriptionHandle h_img_descr;
Ptr p_fullscreen_state;
#endif
/* OpenGL */
VLCGLView * o_glview;
uint8_t * p_data[2];
uint8_t * p_data_orig[2];
int i_cur_pic;
};
This diff is collapsed.
/*****************************************************************************
* vout.m: MacOS X video output module
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
* $Id: vout.m 8351 2004-08-02 13:06:38Z hartman $
*
* Authors: Colin Delacroix <colin@zoy.org>
* Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <hartman at videolan dot org>
* Eric Petit <titer@m0k.org>
*
* This program 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.
*
* This program 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, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <vlc_keys.h>
#include "intf.h"
#include "vout.h"
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
/*****************************************************************************
* VLCView interface
*****************************************************************************/
@interface VLCGLView : NSOpenGLView
{
vout_thread_t * p_vout;
}
- (id)initWithFrame: (NSRect) frame vout: (vout_thread_t*) p_vout;
@end
struct vout_sys_t
{
NSAutoreleasePool *o_pool;
VLCWindow * o_window;
VLCGLView * o_glview;
vlc_bool_t b_saved_frame;
NSRect s_frame;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Init ( vout_thread_t * p_vout );
static void End ( vout_thread_t * p_vout );
static int Manage ( vout_thread_t * p_vout );
static void Swap ( vout_thread_t * p_vout );
int E_(OpenVideoGL) ( vlc_object_t * p_this )
{
vout_thread_t * p_vout = (vout_thread_t *) p_this;
int i_timeout;
vlc_value_t val;
if( !CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay ) )
{
msg_Warn( p_vout, "no hardware acceleration" );
return VLC_EGENERIC;
}
msg_Dbg( p_vout, "display is Quartz Extreme accelerated" );
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
msg_Err( p_vout, "out of memory" );
return( 1 );
}
memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
/* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
for( i_timeout = 20 ; i_timeout-- ; )
{
if( NSApp == NULL )
{
msleep( INTF_IDLE_SLEEP );
}
}
if( NSApp == NULL )
{
/* No MacOS X intf, unable to communicate with MT */
msg_Err( p_vout, "no MacOS X interface present" );
return VLC_EGENERIC;
}
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
p_vout->pf_swap = Swap;
p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
var_Create( p_vout, "macosx-vout", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-opengl-effect", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Setup the menuitem for the multiple displays. Read the vlc preference (macosx-vdev) for the primary display */
NSArray * o_screens = [NSScreen screens];
if( [o_screens count] > 0 && var_Type( p_vout, "video-device" ) == 0 )
{
int i = 1;
vlc_value_t val2, text;
NSScreen * o_screen;
var_Get( p_vout, "macosx-vdev", &val );
var_Create( p_vout, "video-device", VLC_VAR_INTEGER |
VLC_VAR_HASCHOICE );
text.psz_string = _("Video device");
var_Change( p_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL );
NSEnumerator * o_enumerator = [o_screens objectEnumerator];
while( (o_screen = [o_enumerator nextObject]) != NULL )
{
char psz_temp[255];
NSRect s_rect = [o_screen frame];
snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1,
"%s %d (%dx%d)", _("Screen"), i,
(int)s_rect.size.width, (int)s_rect.size.height );
text.psz_string = psz_temp;
val2.i_int = i;
var_Change( p_vout, "video-device",
VLC_VAR_ADDCHOICE, &val2, &text );
if( ( i - 1 ) == val.i_int )
{
var_Set( p_vout, "video-device", val2 );
}
i++;
}
var_AddCallback( p_vout, "video-device", vout_VarCallback,
NULL );
val2.b_bool = VLC_TRUE;
var_Set( p_vout, "intf-change", val2 );
}
/* Spawn window */
p_vout->p_sys->o_window = [[VLCWindow alloc] initWithVout: p_vout
frame: nil];
/* Add OpenGL view */
#define o_glview p_vout->p_sys->o_glview
o_glview = [[VLCGLView alloc] initWithFrame:
[p_vout->p_sys->o_window frame] vout: p_vout];
[p_vout->p_sys->o_window setContentView: o_glview];
[o_glview autorelease];
#undef o_glview
return VLC_SUCCESS;
}
int E_(CloseVideoGL) ( vlc_object_t * p_this )
{
vout_thread_t * p_vout = (vout_thread_t *) p_this;
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
[p_vout->p_sys->o_window close];
[o_pool release];
return VLC_SUCCESS;
}
static int Init( vout_thread_t * p_vout )
{
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
return VLC_SUCCESS;
}
static void End( vout_thread_t * p_vout )
{
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
}
static int Manage( vout_thread_t * p_vout )
{
if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
{
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
if( !p_vout->b_fullscreen )
{
/* Save window size and position */
p_vout->p_sys->s_frame.size =
[[p_vout->p_sys->o_window contentView] frame].size;
p_vout->p_sys->s_frame.origin =
[p_vout->p_sys->o_window frame].origin;
p_vout->p_sys->b_saved_frame = VLC_TRUE;
}
[p_vout->p_sys->o_window close];
p_vout->b_fullscreen = !p_vout->b_fullscreen;
if( p_vout->p_sys->b_saved_frame )
{
p_vout->p_sys->o_window = [[VLCWindow alloc]
initWithVout: p_vout frame: &p_vout->p_sys->s_frame];
}
else
{
p_vout->p_sys->o_window = [[VLCWindow alloc]
initWithVout: p_vout frame: nil];
}
#define o_glview p_vout->p_sys->o_glview
o_glview = [[VLCGLView alloc] initWithFrame: [p_vout->p_sys->o_window frame] vout: p_vout];
[p_vout->p_sys->o_window setContentView: o_glview];
[o_glview autorelease];
[[o_glview openGLContext] makeCurrentContext];
#undef o_glview
[o_pool release];
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
}
[p_vout->p_sys->o_window manage];
return VLC_SUCCESS;
}
static void Swap( vout_thread_t * p_vout )
{
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
if( [p_vout->p_sys->o_glview lockFocusIfCanDraw] )
{
glFlush();
[p_vout->p_sys->o_glview unlockFocus];
}
}
/*****************************************************************************
* VLCGLView implementation
*****************************************************************************/
@implementation VLCGLView
- (id) initWithFrame: (NSRect) frame vout: (vout_thread_t*) _p_vout
{
p_vout = _p_vout;
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAWindow,
0
};
NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes: attribs];
if( !fmt )
{
msg_Warn( p_vout, "Cannot create NSOpenGLPixelFormat" );
return nil;
}
self = [super initWithFrame:frame pixelFormat: fmt];
[fmt release];
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
/* 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 );
return self;
}
- (void)reshape
{
int x, y;
NSRect bounds = [self bounds];
[[self openGLContext] makeCurrentContext];
if( bounds.size.height * p_vout->render.i_aspect <
bounds.size.width * VOUT_ASPECT_FACTOR )
{
x = bounds.size.height * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
y = bounds.size.height;
}
else
{
x = bounds.size.width;
y = bounds.size.width * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
}
glViewport( ( bounds.size.width - x ) / 2,
( bounds.size.height - y ) / 2, x, y );
glClear( GL_COLOR_BUFFER_BIT );
}
- (void) drawRect: (NSRect) rect
{
[[self openGLContext] makeCurrentContext];
glFlush();
}
@end
/*****************************************************************************
* vout.m: MacOS X video output module
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
* $Id: vout.m 8351 2004-08-02 13:06:38Z hartman $
*
* Authors: Colin Delacroix <colin@zoy.org>
* Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <hartman at videolan dot org>
* Eric Petit <titer@m0k.org>
*
* This program 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.
*
* This program 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, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <QuickTime/QuickTime.h>
#include <vlc_keys.h>
#include "intf.h"
#include "vout.h"
#define QT_MAX_DIRECTBUFFERS 10
#define VL_MAX_DISPLAYS 16
/*****************************************************************************
* VLCView interface
*****************************************************************************/
@interface VLCQTView : NSQuickDrawView
{
vout_thread_t * p_vout;
}
- (id) initWithVout:(vout_thread_t *)p_vout;
@end
struct vout_sys_t
{
NSAutoreleasePool *o_pool;
VLCWindow * o_window;
VLCQTView * o_qtview;
vlc_bool_t b_saved_frame;
NSRect s_frame;
CodecType i_codec;
CGrafPtr p_qdport;
ImageSequence i_seq;
MatrixRecordPtr p_matrix;
DecompressorComponent img_dc;
ImageDescriptionHandle h_img_descr;
};
struct picture_sys_t
{
void *p_data;
unsigned int i_size;
};
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int InitVideo ( vout_thread_t * );
static void EndVideo ( vout_thread_t * );
static int ManageVideo ( vout_thread_t * );
static void DisplayVideo ( vout_thread_t *, picture_t * );
static int ControlVideo ( vout_thread_t *, int, va_list );
static int CoToggleFullscreen( vout_thread_t *p_vout );
static void QTScaleMatrix ( vout_thread_t * );
static int QTCreateSequence ( vout_thread_t * );
static void QTDestroySequence ( vout_thread_t * );
static int QTNewPicture ( vout_thread_t *, picture_t * );
static void QTFreePicture ( vout_thread_t *, picture_t * );
/*****************************************************************************
* OpenVideo: allocates MacOS X video thread output method
*****************************************************************************