summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2011-12-11 12:26:00 +0100
committerUoti Urpala <uau@mplayer2.org>2012-04-26 21:03:10 +0300
commitd12b9b611aa7030047e6556714e859dd2bfd38fc (patch)
tree6df7a9b89ae07f5235310c5b952189c81c753236
parent237f44db44b5479c78c90c1a045e0123a2f9c2b8 (diff)
downloadmpv-d12b9b611aa7030047e6556714e859dd2bfd38fc.tar.bz2
mpv-d12b9b611aa7030047e6556714e859dd2bfd38fc.tar.xz
vo_corevideo: use cocoa_common to display the window
Change vo_corevideo to use cocoa_common to create and manage the window. This doesn't affect external OSX GUIs, since they don't use vo_corevideo window management, but only read the image data from the shared buffer.
-rwxr-xr-xconfigure44
-rw-r--r--libvo/cocoa_common.h3
-rw-r--r--libvo/cocoa_common.m15
-rw-r--r--libvo/vo_corevideo.h73
-rw-r--r--libvo/vo_corevideo.m913
5 files changed, 185 insertions, 863 deletions
diff --git a/configure b/configure
index 27dde1a754..f9a4bbaafe 100755
--- a/configure
+++ b/configure
@@ -4187,21 +4187,35 @@ else
fi
echores $quicktime
-echocheck "CoreVideo"
-if test "$_corevideo" = auto ; then
+echocheck "Cocoa"
+if test "$_cocoa" = auto ; then
cat > $TMPC <<EOF
-#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
#include <OpenGL/OpenGL.h>
+int main(void) {
+ NSApplicationLoad();
+}
+EOF
+ _cocoa=no
+ cc_check -framework Cocoa -framework OpenGL && _cocoa=yes
+fi
+if test "$_cocoa" = yes ; then
+ libs_mplayer="$libs_mplayer -framework Cocoa -framework OpenGL"
+fi
+echores "$_cocoa"
+
+echocheck "CoreVideo"
+if test "$_cocoa" = yes && test "$_corevideo" = auto ; then
+ cat > $TMPC <<EOF
#include <QuartzCore/CoreVideo.h>
int main(void) { return 0; }
EOF
_corevideo=no
- cc_check -framework Carbon -framework Cocoa -framework QuartzCore -framework OpenGL && _corevideo=yes
+ cc_check -framework Cocoa -framework QuartzCore -framework OpenGL && _corevideo=yes
fi
if test "$_corevideo" = yes ; then
vomodules="corevideo $vomodules"
- libs_mplayer="$libs_mplayer -framework Carbon -framework Cocoa -framework QuartzCore -framework OpenGL"
+ libs_mplayer="$libs_mplayer -framework QuartzCore"
def_corevideo='#define CONFIG_COREVIDEO 1'
else
novomodules="corevideo $novomodules"
@@ -4209,26 +4223,6 @@ else
fi
echores "$_corevideo"
-echocheck "Cocoa"
-if test "$_gl" = no ; then
- # if _gl is not enabled there is no point to add potentially unused linker flags
- _cocoa=no
-fi
-if test "$_cocoa" = auto ; then
- cat > $TMPC <<EOF
-#include <CoreServices/CoreServices.h>
-#include <OpenGL/OpenGL.h>
-#include <QuartzCore/CoreVideo.h>
-int main(void) { return 0; }
-EOF
- _cocoa=no
- cc_check -framework Cocoa -framework QuartzCore -framework OpenGL && _cocoa=yes
-fi
-if test "$_cocoa" = yes ; then
- libs_mplayer="$libs_mplayer -framework Cocoa -framework QuartzCore -framework OpenGL"
-fi
-echores "$_cocoa"
-
fi #if darwin
diff --git a/libvo/cocoa_common.h b/libvo/cocoa_common.h
index 16f9a2f1f9..a118f37149 100644
--- a/libvo/cocoa_common.h
+++ b/libvo/cocoa_common.h
@@ -39,4 +39,7 @@ void vo_cocoa_ontop(struct vo *vo);
// returns an int to conform to the gl extensions from other platforms
int vo_cocoa_swap_interval(int enabled);
+void *vo_cocoa_cgl_context(void);
+void *vo_cocoa_cgl_pixel_format(void);
+
#endif /* MPLAYER_COCOA_COMMON_H */
diff --git a/libvo/cocoa_common.m b/libvo/cocoa_common.m
index f5ad7a0943..af2f4adaaf 100644
--- a/libvo/cocoa_common.m
+++ b/libvo/cocoa_common.m
@@ -54,6 +54,7 @@ struct vo_cocoa_state {
NSAutoreleasePool *pool;
GLMPlayerWindow *window;
NSOpenGLContext *glContext;
+ NSOpenGLPixelFormat *pixelFormat;
NSSize current_video_size;
NSSize previous_video_size;
@@ -212,8 +213,8 @@ int vo_cocoa_create_window(struct vo *vo, uint32_t d_width,
(NSOpenGLPixelFormatAttribute)0
};
- NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
- s->glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
+ s->pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
+ s->glContext = [[NSOpenGLContext alloc] initWithFormat:s->pixelFormat shareContext:nil];
create_menu();
@@ -345,6 +346,16 @@ int vo_cocoa_swap_interval(int enabled)
return 0;
}
+void *vo_cocoa_cgl_context(void)
+{
+ return [s->glContext CGLContextObj];
+}
+
+void *vo_cocoa_cgl_pixel_format(void)
+{
+ return [s->pixelFormat CGLPixelFormatObj];
+}
+
void create_menu()
{
NSMenu *menu;
diff --git a/libvo/vo_corevideo.h b/libvo/vo_corevideo.h
index 926399053f..28b3807376 100644
--- a/libvo/vo_corevideo.h
+++ b/libvo/vo_corevideo.h
@@ -39,77 +39,4 @@
- (void) ontop;
@end
-@interface MPlayerOpenGLView : NSOpenGLView
-{
- //Cocoa
- NSWindow *window;
-
- //CoreVideo
- CVPixelBufferRef frameBuffers[2];
- CVOpenGLTextureCacheRef textureCache;
- CVOpenGLTextureRef texture;
- NSRect textureFrame;
-
- GLfloat lowerLeft[2];
- GLfloat lowerRight[2];
- GLfloat upperRight[2];
- GLfloat upperLeft[2];
-
- BOOL mouseHide;
-
- //menu command id
- NSMenuItem *kHalfScreenCmd;
- NSMenuItem *kNormalScreenCmd;
- NSMenuItem *kDoubleScreenCmd;
- NSMenuItem *kFullScreenCmd;
- NSMenuItem *kKeepAspectCmd;
- NSMenuItem *kAspectOrgCmd;
- NSMenuItem *kAspectFullCmd;
- NSMenuItem *kAspectWideCmd;
- NSMenuItem *kPanScanCmd;
-
- //timestamps for disabling screensaver and mouse hiding
- int lastMouseHide;
- int lastScreensaverUpdate;
-@public
- float winSizeMult;
-}
-
-- (BOOL) acceptsFirstResponder;
-- (BOOL) becomeFirstResponder;
-- (BOOL) resignFirstResponder;
-
-//window & rendering
-- (void) preinit;
-- (void) config;
-- (void) prepareOpenGL;
-- (void) render;
-- (void) reshape;
-- (void) setCurrentTexture;
-- (void) drawRect: (NSRect *) bounds;
-
-//vo control
-- (void) fullscreen: (BOOL) animate;
-- (void) ontop;
-- (void) panscan;
-- (void) rootwin;
-
-//menu
-- (void) initMenu;
-- (void) menuAction:(id)sender;
-
-//event
-- (void) keyDown: (NSEvent *) theEvent;
-- (void) mouseMoved: (NSEvent *) theEvent;
-- (void) mouseDown: (NSEvent *) theEvent;
-- (void) mouseUp: (NSEvent *) theEvent;
-- (void) rightMouseDown: (NSEvent *) theEvent;
-- (void) rightMouseUp: (NSEvent *) theEvent;
-- (void) otherMouseDown: (NSEvent *) theEvent;
-- (void) otherMouseUp: (NSEvent *) theEvent;
-- (void) scrollWheel: (NSEvent *) theEvent;
-- (void) mouseEvent: (NSEvent *) theEvent;
-- (void) check_events;
-@end
-
#endif /* MPLAYER_VO_COREVIDEO_H */
diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m
index 5e1dd71259..7506a8d108 100644
--- a/libvo/vo_corevideo.m
+++ b/libvo/vo_corevideo.m
@@ -25,11 +25,6 @@
#include <sys/mman.h>
#include <unistd.h>
#include <CoreServices/CoreServices.h>
-//special workaround for Apple bug #6267445
-//(OSServices Power API disabled in OSServices.h for 64bit systems)
-#ifndef __POWER__
-#include <CoreServices/../Frameworks/OSServices.framework/Headers/Power.h>
-#endif
//MPLAYER
#include "config.h"
@@ -45,12 +40,12 @@
#include "input/input.h"
#include "input/keycodes.h"
-#include "osx_common.h"
+
+#import "cocoa_common.h"
//Cocoa
NSDistantObject *mplayerosxProxy;
id <MPlayerOSXVOProto> mplayerosxProto;
-MPlayerOpenGLView *mpGLView;
NSAutoreleasePool *autoreleasepool;
OSType pixelFormat;
@@ -59,11 +54,18 @@ BOOL shared_buffer = false;
#define DEFAULT_BUFFER_NAME "mplayerosx"
static char *buffer_name;
-//Screen
-int screen_id = -1;
-NSRect screen_frame;
-NSScreen *screen_handle;
-NSArray *screen_array;
+int screen_id;
+
+//CoreVideo
+CVPixelBufferRef frameBuffers[2];
+CVOpenGLTextureCacheRef textureCache;
+CVOpenGLTextureRef texture;
+NSRect textureFrame;
+
+GLfloat lowerLeft[2];
+GLfloat lowerRight[2];
+GLfloat upperRight[2];
+GLfloat upperLeft[2];
//image
unsigned char *image_data;
@@ -77,24 +79,11 @@ static uint32_t image_depth;
static uint32_t image_bytes;
static uint32_t image_format;
-//vo
-static int isFullscreen;
-static int isOntop;
-static int isRootwin;
-
-static float winAlpha = 1;
-static int int_pause = 0;
-
-static BOOL isLeopardOrLater;
-
-#define NSLeftAlternateKeyMask (0x000020 | NSAlternateKeyMask)
-#define NSRightAlternateKeyMask (0x000040 | NSAlternateKeyMask)
-
static vo_info_t info =
{
"Mac OS X Core Video",
"corevideo",
- "Nicolas Plourde <nicolas.plourde@gmail.com>",
+ "Nicolas Plourde <nicolas.plourde@gmail.com> and others",
""
};
@@ -117,29 +106,6 @@ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigne
}
}
-static void update_screen_info(void)
-{
- if (screen_id == -1 && xinerama_screen > -1)
- screen_id = xinerama_screen;
-
- screen_array = [NSScreen screens];
- if(screen_id >= (int)[screen_array count])
- {
- mp_msg(MSGT_VO, MSGL_INFO, "[vo_corevideo] Device ID %d does not exist, falling back to main device\n", screen_id);
- screen_id = -1;
- }
- if (screen_id < 0 && [mpGLView window])
- screen_handle = [[mpGLView window] screen];
- else
- screen_handle = [screen_array objectAtIndex:(screen_id < 0 ? 0 : screen_id)];
-
- screen_frame = [screen_handle frame];
- vo_screenwidth = screen_frame.size.width;
- vo_screenheight = screen_frame.size.height;
- xinerama_x = xinerama_y = 0;
- aspect_save_screenres(vo_screenwidth, vo_screenheight);
-}
-
static void free_file_specific(void)
{
if(shared_buffer)
@@ -164,6 +130,32 @@ static void free_file_specific(void)
}
}
+static void resize(int width, int height)
+{
+ int d_width, d_height;
+
+ mp_msg(MSGT_VO, MSGL_V, "[vo_corevideo] New OpenGL Viewport (0, 0, %d, %d)\n", width, height);
+
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, height, 0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ aspect(&d_width, &d_height, A_WINZOOM);
+ textureFrame = NSMakeRect((vo_dwidth - d_width) / 2, (vo_dheight - d_height) / 2, d_width, d_height);
+}
+
+static void prepare_opengl(void)
+{
+ glEnable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_CULL_FACE);
+ resize(global_vo->dwidth, global_vo->dheight);
+}
+
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
free_file_specific();
@@ -171,8 +163,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
//misc mplayer setup
image_width = width;
image_height = height;
- switch (image_format)
- {
+ switch (image_format) {
case IMGFMT_RGB24:
image_depth = 24;
break;
@@ -184,14 +175,11 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
image_depth = 16;
break;
}
- image_bytes = (image_depth + 7) / 8;
- if(!shared_buffer)
- {
- config_movie_aspect((float)d_width/d_height);
+ image_bytes = (image_depth ? image_depth : 16 + 7) / 8;
- vo_dwidth = d_width *= mpGLView->winSizeMult;
- vo_dheight = d_height *= mpGLView->winSizeMult;
+ if (!shared_buffer) {
+ CVReturn error;
image_data = malloc(image_width*image_height*image_bytes);
image_datas[0] = image_data;
@@ -199,30 +187,50 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
image_datas[1] = malloc(image_width*image_height*image_bytes);
image_page = 0;
- vo_fs = flags & VOFLAG_FULLSCREEN;
+ CVPixelBufferRelease(frameBuffers[0]);
+ frameBuffers[0] = NULL;
+ CVPixelBufferRelease(frameBuffers[1]);
+ frameBuffers[1] = NULL;
+ CVOpenGLTextureRelease(texture);
+ texture = NULL;
- //config OpenGL View
- [mpGLView config];
- [mpGLView reshape];
- }
- else
- {
+ vo_cocoa_create_window(global_vo, d_width, d_height, flags);
+ prepare_opengl();
+ vo_cocoa_swap_interval(1);
+
+ error = CVOpenGLTextureCacheCreate(NULL, 0, vo_cocoa_cgl_context(), vo_cocoa_cgl_pixel_format(), 0, &textureCache);
+ if(error != kCVReturnSuccess)
+ mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture Cache(%d)\n", error);
+
+ error = CVPixelBufferCreateWithBytes(NULL, image_width, image_height, pixelFormat,
+ image_datas[0], image_width*image_bytes, NULL, NULL, NULL, &frameBuffers[0]);
+ if(error != kCVReturnSuccess)
+ mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create Pixel Buffer(%d)\n", error);
+
+ if (vo_doublebuffering) {
+ error = CVPixelBufferCreateWithBytes(NULL, image_width, image_height, pixelFormat,
+ image_datas[1], image_width*image_bytes, NULL, NULL, NULL, &frameBuffers[1]);
+ if(error != kCVReturnSuccess)
+ mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create Pixel Double Buffer(%d)\n", error);
+ }
+
+ error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, textureCache, frameBuffers[image_page], 0, &texture);
+ if(error != kCVReturnSuccess)
+ mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture(%d)\n", error);
+ } else {
int shm_fd;
mp_msg(MSGT_VO, MSGL_INFO, "[vo_corevideo] writing output to a shared buffer "
"named \"%s\"\n",buffer_name);
// create shared memory
shm_fd = shm_open(buffer_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
- if (shm_fd == -1)
- {
+ if (shm_fd == -1) {
mp_msg(MSGT_VO, MSGL_FATAL,
"[vo_corevideo] failed to open shared memory. Error: %s\n", strerror(errno));
return 1;
}
-
- if (ftruncate(shm_fd, image_width*image_height*image_bytes) == -1)
- {
+ if (ftruncate(shm_fd, image_width*image_height*image_bytes) == -1) {
mp_msg(MSGT_VO, MSGL_FATAL,
"[vo_corevideo] failed to size shared memory, possibly already in use. Error: %s\n", strerror(errno));
close(shm_fd);
@@ -234,8 +242,7 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
close(shm_fd);
- if (image_data == MAP_FAILED)
- {
+ if (image_data == MAP_FAILED) {
mp_msg(MSGT_VO, MSGL_FATAL,
"[vo_corevideo] failed to map shared memory. Error: %s\n", strerror(errno));
shm_unlink(buffer_name);
@@ -243,13 +250,12 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
}
//connect to mplayerosx
- mplayerosxProxy=[NSConnection rootProxyForConnectionWithRegisteredName:[NSString stringWithCString:buffer_name] host:nil];
+ mplayerosxProxy=[NSConnection rootProxyForConnectionWithRegisteredName:[NSString stringWithUTF8String:buffer_name] host:nil];
if ([mplayerosxProxy conformsToProtocol:@protocol(MPlayerOSXVOProto)]) {
[mplayerosxProxy setProtocolForProxy:@protocol(MPlayerOSXVOProto)];
mplayerosxProto = (id <MPlayerOSXVOProto>)mplayerosxProxy;
[mplayerosxProto startWithWidth: image_width withHeight: image_height withBytes: image_bytes withAspect:d_width*100/d_height];
- }
- else {
+ } else {
[mplayerosxProxy release];
mplayerosxProxy = nil;
mplayerosxProto = nil;
@@ -260,8 +266,11 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_
static void check_events(void)
{
- if (mpGLView)
- [mpGLView check_events];
+ if (!shared_buffer) {
+ int e = vo_cocoa_check_events(global_vo);
+ if (e & VO_EVENT_RESIZE)
+ resize(global_vo->dwidth, global_vo->dheight);
+ }
}
static void draw_osd(void)
@@ -269,6 +278,34 @@ static void draw_osd(void)
vo_draw_text(image_width, image_height, draw_alpha);
}
+static void prepare_texture(void)
+{
+ CVReturn error;
+ CVOpenGLTextureRelease(texture);
+ error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, textureCache, frameBuffers[image_page], 0, &texture);
+ if(error != kCVReturnSuccess)
+ mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture(%d)\n", error);
+
+ CVOpenGLTextureGetCleanTexCoords(texture, lowerLeft, lowerRight, upperRight, upperLeft);
+}
+
+static void do_render(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(CVOpenGLTextureGetTarget(texture));
+ glBindTexture(CVOpenGLTextureGetTarget(texture), CVOpenGLTextureGetName(texture));
+
+ glColor3f(1,1,1);
+ glBegin(GL_QUADS);
+ glTexCoord2f(upperLeft[0], upperLeft[1]); glVertex2i(textureFrame.origin.x-(vo_panscan_x >> 1), textureFrame.origin.y-(vo_panscan_y >> 1));
+ glTexCoord2f(lowerLeft[0], lowerLeft[1]); glVertex2i(textureFrame.origin.x-(vo_panscan_x >> 1), NSMaxY(textureFrame)+(vo_panscan_y >> 1));
+ glTexCoord2f(lowerRight[0], lowerRight[1]); glVertex2i(NSMaxX(textureFrame)+(vo_panscan_x >> 1), NSMaxY(textureFrame)+(vo_panscan_y >> 1));
+ glTexCoord2f(upperRight[0], upperRight[1]); glVertex2i(NSMaxX(textureFrame)+(vo_panscan_x >> 1), textureFrame.origin.y-(vo_panscan_y >> 1));
+ glEnd();
+ glDisable(CVOpenGLTextureGetTarget(texture));
+}
+
static void flip_page(void)
{
if(shared_buffer) {
@@ -276,12 +313,13 @@ static void flip_page(void)
[mplayerosxProto render];
[pool release];
} else {
- [mpGLView setCurrentTexture];
- [mpGLView render];
+ prepare_texture();
+ do_render();
if (vo_doublebuffering) {
image_page = 1 - image_page;
image_data = image_datas[image_page];
}
+ vo_cocoa_swap_buffers();
}
}
@@ -331,20 +369,13 @@ static int query_format(uint32_t format)
static void uninit(void)
{
- SetSystemUIMode( kUIModeNormal, 0);
+ SetSystemUIMode(kUIModeNormal, 0);
CGDisplayShowCursor(kCGDirectMainDisplay);
free_file_specific();
- if(mpGLView)
- {
- NSAutoreleasePool *finalPool;
- mpGLView = nil;
- [autoreleasepool release];
- finalPool = [[NSAutoreleasePool alloc] init];
- [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
- [finalPool release];
- }
+ if (!shared_buffer)
+ vo_cocoa_uninit(global_vo);
free(buffer_name);
buffer_name = NULL;
@@ -359,7 +390,6 @@ static const opt_t subopts[] = {
static int preinit(const char *arg)
{
-
// set defaults
screen_id = -1;
shared_buffer = false;
@@ -389,688 +419,45 @@ static int preinit(const char *arg)
else
shared_buffer = true;
- if(!shared_buffer)
- {
- NSApplicationLoad();
- NSApp = [NSApplication sharedApplication];
- isLeopardOrLater = floor(NSAppKitVersionNumber) > 824;
-
- osx_foreground_hack();
-
- if(!mpGLView)
- {
- mpGLView = [[MPlayerOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:[MPlayerOpenGLView defaultPixelFormat]];
- [mpGLView autorelease];
- }
- // Install an event handler so the Quit menu entry works
- // The proper way using NSApp setDelegate: and
- // applicationShouldTerminate: does not work,
- // probably NSApplication never installs its handler.
- [[NSAppleEventManager sharedAppleEventManager]
- setEventHandler:mpGLView
- andSelector:@selector(handleQuitEvent:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEQuitApplication];
-
- [mpGLView display];
- [mpGLView preinit];
- }
+ if (!shared_buffer)
+ vo_cocoa_init(global_vo);
return 0;
}
static int control(uint32_t request, void *data)
{
- switch (request)
- {
+ switch (request) {
case VOCTRL_DRAW_IMAGE: return draw_image(data);
- case VOCTRL_PAUSE: return int_pause = 1;
- case VOCTRL_RESUME: return int_pause = 0;
case VOCTRL_QUERY_FORMAT: return query_format(*(uint32_t*)data);
- case VOCTRL_ONTOP: vo_ontop = !vo_ontop; if(!shared_buffer){ [mpGLView ontop]; } else { [mplayerosxProto ontop]; } return VO_TRUE;
- case VOCTRL_ROOTWIN: vo_rootwin = !vo_rootwin; [mpGLView rootwin]; return VO_TRUE;
- case VOCTRL_FULLSCREEN: vo_fs = !vo_fs; if(!shared_buffer){ [mpGLView fullscreen: NO]; } else { [mplayerosxProto toggleFullscreen]; } return VO_TRUE;
- case VOCTRL_GET_PANSCAN: return VO_TRUE;
- case VOCTRL_SET_PANSCAN: [mpGLView panscan]; return VO_TRUE;
- case VOCTRL_UPDATE_SCREENINFO: update_screen_info(); return VO_TRUE;
+ case VOCTRL_ONTOP:
+ if (!shared_buffer) {
+ vo_cocoa_ontop(global_vo);
+ } else {
+ vo_ontop = !vo_ontop;
+ [mplayerosxProto ontop];
+ }
+ return VO_TRUE;
+ case VOCTRL_FULLSCREEN:
+ if (!shared_buffer) {
+ vo_cocoa_fullscreen(global_vo);
+ resize(global_vo->dwidth, global_vo->dheight);
+ } else {
+ [mplayerosxProto toggleFullscreen];
+ }
+ return VO_TRUE;
+ case VOCTRL_GET_PANSCAN:
+ return VO_TRUE;
+ case VOCTRL_SET_PANSCAN:
+ panscan_calc_windowed();
+ return VO_TRUE;
+ case VOCTRL_UPDATE_SCREENINFO:
+ if (!shared_buffer) {
+ vo_cocoa_update_xinerama_info(global_vo);
+ return VO_TRUE;
+ } else {
+ return VO_NOTIMPL;
+ }
}
return VO_NOTIMPL;
}
-
-//////////////////////////////////////////////////////////////////////////
-// NSOpenGLView Subclass
-//////////////////////////////////////////////////////////////////////////
-@implementation MPlayerOpenGLView
-- (void) preinit
-{
- NSOpenGLContext *glContext;
- GLint swapInterval = 1;
- CVReturn error;
-
- //init menu
- [self initMenu];
-
- //create window
- window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
- styleMask:NSTitledWindowMask|NSTexturedBackgroundWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask
- backing:NSBackingStoreBuffered defer:NO];
-
- [window autorelease];
- [window setDelegate:mpGLView];
- [window setContentView:mpGLView];
- [window setInitialFirstResponder:mpGLView];
- [window setAcceptsMouseMovedEvents:YES];
- [window setTitle:@"MPlayer - The Movie Player"];
-
- isFullscreen = 0;
- winSizeMult = 1;
-
- //create OpenGL Context
- glContext = [[NSOpenGLContext alloc] initWithFormat:[NSOpenGLView defaultPixelFormat] shareContext:nil];
-
- [self setOpenGLContext:glContext];
- [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
- [glContext setView:self];
- [glContext makeCurrentContext];
- [glContext release];
-
- error = CVOpenGLTextureCacheCreate(NULL, 0, [glContext CGLContextObj], [[self pixelFormat] CGLPixelFormatObj], 0, &textureCache);
- if(error != kCVReturnSuccess)
- mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture Cache(%d)\n", error);
-}
-
-- (void) releaseVideoSpecific
-{
- CVPixelBufferRelease(frameBuffers[0]);
- frameBuffers[0] = NULL;
- CVPixelBufferRelease(frameBuffers[1]);
- frameBuffers[1] = NULL;
- CVOpenGLTextureRelease(texture);
- texture = NULL;
-}
-
-- (void) dealloc
-{
- [self releaseVideoSpecific];
- CVOpenGLTextureCacheRelease(textureCache);
- textureCache = NULL;
- [self setOpenGLContext:nil];
- [super dealloc];
-}
-
-- (void) config
-{
- NSRect visibleFrame;
- CVReturn error = kCVReturnSuccess;
-
- //config window
- [window setContentSize:NSMakeSize(vo_dwidth, vo_dheight)];
-
- // Use visibleFrame to position the window taking the menu bar and dock into account.
- // Also flip vo_dy since the screen origin is in the bottom left on OSX.
- update_screen_info();
- visibleFrame = [screen_handle visibleFrame];
- [window setFrameTopLeftPoint:NSMakePoint(
- visibleFrame.origin.x + vo_dx,
- visibleFrame.origin.y + visibleFrame.size.height - vo_dy)];
-
- [self releaseVideoSpecific];
- error = CVPixelBufferCreateWithBytes(NULL, image_width, image_height, pixelFormat, image_datas[0], image_width*image_bytes, NULL, NULL, NULL, &frameBuffers[0]);
- if(error != kCVReturnSuccess)
- mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create Pixel Buffer(%d)\n", error);
- if (vo_doublebuffering) {
- error = CVPixelBufferCreateWithBytes(NULL, image_width, image_height, pixelFormat, image_datas[1], image_width*image_bytes, NULL, NULL, NULL, &frameBuffers[1]);
- if(error != kCVReturnSuccess)
- mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create Pixel Double Buffer(%d)\n", error);
- }
-
- error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, textureCache, frameBuffers[image_page], 0, &texture);
- if(error != kCVReturnSuccess)
- mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture(%d)\n", error);
-
- //show window
- [window makeKeyAndOrderFront:mpGLView];
-
- if(vo_rootwin)
- [mpGLView rootwin];
-
- if(vo_fs)
- [mpGLView fullscreen: NO];
-
- if(vo_ontop)
- [mpGLView ontop];
-}
-
-/*
- Init Menu
-*/
-- (void)initMenu
-{
- NSMenu *menu, *aspectMenu;
- NSMenuItem *menuItem;
-
- menu = [[NSMenu new] autorelease];
- menuItem = [[NSMenuItem new] autorelease];
- [menu addItem: menuItem];
- [NSApp setMainMenu: menu];
-
-//Create Movie Menu
- menu = [[NSMenu alloc] initWithTitle:@"Movie"];
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Half Size" action:@selector(menuAction:) keyEquivalent:@"0"]; [menu addItem:menuItem];
- kHalfScreenCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Normal Size" action:@selector(menuAction:) keyEquivalent:@"1"]; [menu addItem:menuItem];
- kNormalScreenCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Double Size" action:@selector(menuAction:) keyEquivalent:@"2"]; [menu addItem:menuItem];
- kDoubleScreenCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Full Size" action:@selector(menuAction:) keyEquivalent:@"f"]; [menu addItem:menuItem];
- kFullScreenCmd = menuItem;
- menuItem = [NSMenuItem separatorItem]; [menu addItem:menuItem];
-
- aspectMenu = [[NSMenu alloc] initWithTitle:@"Aspect Ratio"];
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Keep" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem];
- if(vo_keepaspect) [menuItem setState:NSOnState];
- kKeepAspectCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Pan-Scan" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem];
- if(vo_panscan) [menuItem setState:NSOnState];
- kPanScanCmd = menuItem;
- menuItem = [NSMenuItem separatorItem]; [aspectMenu addItem:menuItem];
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Original" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem];
- kAspectOrgCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"4:3" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem];
- kAspectFullCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"16:9" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem];
- kAspectWideCmd = menuItem;
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Aspect Ratio" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:aspectMenu];
- [menu addItem:menuItem];
- [aspectMenu release];
-
- //Add to menubar
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Movie" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
-
-//Create Window Menu
- menu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [menu addItem:menuItem];
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; [menu addItem:menuItem];
-
- //Add to menubar
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
- [NSApp setWindowsMenu:menu];
-
- [menu release];
- [menuItem release];
-}
-
-- (void)set_winSizeMult:(float)mult
-{
- NSRect frame;
- int d_width, d_height;
- aspect(&d_width, &d_height, A_NOZOOM);
-
- if (isFullscreen) {
- vo_fs = !vo_fs;
- [self fullscreen:NO];
- }
-
- winSizeMult = mult;
- frame.size.width = d_width * mult;
- frame.size.height = d_height * mult;
- [window setContentSize: frame.size];
- [self reshape];
-}
-
-/*
- Menu Action
- */
-- (void)menuAction:(id)sender
-{
- if(sender == kHalfScreenCmd)
- [self set_winSizeMult: 0.5];
- if(sender == kNormalScreenCmd)
- [self set_winSizeMult: 1];
- if(sender == kDoubleScreenCmd)
- [self set_winSizeMult: 2];
- if(sender == kFullScreenCmd)
- {
- vo_fs = !vo_fs;
- [self fullscreen:NO];
- }
-
- if(sender == kKeepAspectCmd)
- {
- vo_keepaspect = !vo_keepaspect;
- if(vo_keepaspect)
- [kKeepAspectCmd setState:NSOnState];
- else
- [kKeepAspectCmd setState:NSOffState];
-
- [self reshape];
- }
-
- if(sender == kPanScanCmd)
- {
- vo_panscan = !vo_panscan;
- if(vo_panscan)
- [kPanScanCmd setState:NSOnState];
- else
- [kPanScanCmd setState:NSOffState];
-
- [self panscan];
- }
-
- if(sender == kAspectOrgCmd)
- change_movie_aspect(-1);
-
- if(sender == kAspectFullCmd)
- change_movie_aspect(4.0f/3.0f);
-
- if(sender == kAspectWideCmd)
- change_movie_aspect(16.0f/9.0f);
-}
-
-/*
- Setup OpenGL
-*/
-- (void)prepareOpenGL
-{
- glEnable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_CULL_FACE);
- [self reshape];
-}
-
-/*
- reshape OpenGL viewport
-*/
-- (void)reshape
-{
- int d_width, d_height;
-
- NSRect frame = [self frame];
- vo_dwidth = frame.size.width;
- vo_dheight = frame.size.height;
-
- glViewport(0, 0, frame.size.width, frame.size.height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, frame.size.width, frame.size.height, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- //set texture frame
- if(vo_keepaspect)
- {
- aspect(&d_width, &d_height, A_WINZOOM);
-
- textureFrame = NSMakeRect((vo_dwidth - d_width) / 2, (vo_dheight - d_height) / 2, d_width, d_height);
- }
- else
- {
- textureFrame = frame;
- }
-}
-
-/*
- Render frame
-*/
-- (void) render
-{
- glClear(GL_COLOR_BUFFER_BIT);
-
- glEnable(CVOpenGLTextureGetTarget(texture));
- glBindTexture(CVOpenGLTextureGetTarget(texture), CVOpenGLTextureGetName(texture));
-
- glColor3f(1,1,1);
- glBegin(GL_QUADS);
- glTexCoord2f(upperLeft[0], upperLeft[1]); glVertex2i( textureFrame.origin.x-(vo_panscan_x >> 1), textureFrame.origin.y-(vo_panscan_y >> 1));
- glTexCoord2f(lowerLeft[0], lowerLeft[1]); glVertex2i(textureFrame.origin.x-(vo_panscan_x >> 1), NSMaxY(textureFrame)+(vo_panscan_y >> 1));
- glTexCoord2f(lowerRight[0], lowerRight[1]); glVertex2i(NSMaxX(textureFrame)+(vo_panscan_x >> 1), NSMaxY(textureFrame)+(vo_panscan_y >> 1));
- glTexCoord2f(upperRight[0], upperRight[1]); glVertex2i(NSMaxX(textureFrame)+(vo_panscan_x >> 1), textureFrame.origin.y-(vo_panscan_y >> 1));
- glEnd();
- glDisable(CVOpenGLTextureGetTarget(texture));
-
- //render resize box
- if(!isFullscreen)
- {
- NSRect frame = [self frame];
-
- glBegin(GL_LINES);
- glColor4f(0.2, 0.2, 0.2, 0.5);
- glVertex2i(frame.size.width-1, frame.size.height-1); glVertex2i(frame.size.width-1, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-5); glVertex2i(frame.size.width-5, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-9); glVertex2i(frame.size.width-9, frame.size.height-1);
-
- glColor4f(0.4, 0.4, 0.4, 0.5);
- glVertex2i(frame.size.width-1, frame.size.height-2); glVertex2i(frame.size.width-2, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-6); glVertex2i(frame.size.width-6, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-10); glVertex2i(frame.size.width-10, frame.size.height-1);
-
- glColor4f(0.6, 0.6, 0.6, 0.5);
- glVertex2i(frame.size.width-1, frame.size.height-3); glVertex2i(frame.size.width-3, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-7); glVertex2i(frame.size.width-7, frame.size.height-1);
- glVertex2i(frame.size.width-1, frame.size.height-11); glVertex2i(frame.size.width-11, frame.size.height-1);
- glEnd();
- }
-
- glFlush();
-}
-
-/*
- Create OpenGL texture from current frame & set texco
-*/
-- (void) setCurrentTexture
-{
- CVReturn error = kCVReturnSuccess;
-
- CVOpenGLTextureRelease(texture);
- error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, textureCache, frameBuffers[image_page], 0, &texture);
- if(error != kCVReturnSuccess)
- mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture(%d)\n", error);