From c4f68de1456ddb561f322b84e2ba1b790eec4c28 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 13 Aug 2012 12:08:22 +0200 Subject: TOOLS: add script for osx bundle generation Add a make task and python script to create a Mac OS X Application Bundle to be used when compiling with the --enable-macosx-finder and --enable-macosx-bundle configure flags. The main svg icon was created by me and heavily inspired by Apple's iTunes and AppStore icon designs. We are still looking for something better. For the audio, movie and subtitles icons I added the main logo to MPlayer OSX Extended icons. Use with `make osxbundle` after running configure and make. --- .gitignore | 1 + Makefile | 3 + TOOLS/osxbundle.py | 89 ++++ TOOLS/osxbundle/mpv.app/Contents/Info.plist | 248 +++++++++ TOOLS/osxbundle/mpv.app/Contents/MacOS/.gitkeep | 0 .../osxbundle/mpv.app/Contents/MacOS/lib/.gitkeep | 0 TOOLS/osxbundle/mpv.app/Contents/PkgInfo | 1 + .../mpv.app/Contents/Resources/audio.icns | Bin 0 -> 64076 bytes .../osxbundle/mpv.app/Contents/Resources/icon.icns | Bin 0 -> 142486 bytes .../mpv.app/Contents/Resources/movie.icns | Bin 0 -> 157126 bytes .../mpv.app/Contents/Resources/subtitles.icns | Bin 0 -> 63323 bytes TOOLS/osxbundle/version.sh | 15 + etc/mpv-icon-source.svg | 556 +++++++++++++++++++++ 13 files changed, 913 insertions(+) create mode 100755 TOOLS/osxbundle.py create mode 100644 TOOLS/osxbundle/mpv.app/Contents/Info.plist create mode 100644 TOOLS/osxbundle/mpv.app/Contents/MacOS/.gitkeep create mode 100644 TOOLS/osxbundle/mpv.app/Contents/MacOS/lib/.gitkeep create mode 100644 TOOLS/osxbundle/mpv.app/Contents/PkgInfo create mode 100644 TOOLS/osxbundle/mpv.app/Contents/Resources/audio.icns create mode 100644 TOOLS/osxbundle/mpv.app/Contents/Resources/icon.icns create mode 100644 TOOLS/osxbundle/mpv.app/Contents/Resources/movie.icns create mode 100644 TOOLS/osxbundle/mpv.app/Contents/Resources/subtitles.icns create mode 100755 TOOLS/osxbundle/version.sh create mode 100644 etc/mpv-icon-source.svg diff --git a/.gitignore b/.gitignore index 45b6ab2b9b..56bc6b1fa6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /config.mak /config.log /mpv +/mpv.app /version.h /codecs.conf.h /input/input_conf.h diff --git a/Makefile b/Makefile index c6dc0f6090..271c3f5624 100644 --- a/Makefile +++ b/Makefile @@ -481,6 +481,9 @@ TAGS: tags: $(RM) $@; find . -name '*.[chS]' -o -name '*.asm' | xargs ctags -a +osxbundle: + @TOOLS/osxbundle.py mpv + -include $(DEP_FILES) .PHONY: all locales *install* diff --git a/TOOLS/osxbundle.py b/TOOLS/osxbundle.py new file mode 100755 index 0000000000..9f2f29d88b --- /dev/null +++ b/TOOLS/osxbundle.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +import os +import re +import shutil +import sys + +def sh(command): + return os.popen(command).read() + +def dylib_lst(input_file): + return sh("otool -L %s | grep -e '\t' | awk '{ print $1 }'" % input_file) + +sys_re = re.compile("/System") +exe_re = re.compile("@executable_path") +binary_name = sys.argv[1] + +def is_user_lib(libname, input_file): + return not sys_re.match(libname) and \ + not exe_re.match(libname) and \ + not "libobjc" in libname and \ + not "libSystem" in libname and \ + not "libgcc" in libname and \ + not os.path.basename(input_file) in libname and \ + not libname == '' + +def user_dylib_lst(input_file): + return [lib for lib in dylib_lst(input_file).split("\n") if + is_user_lib(lib, input_file)] + +def bundle_name(): + return "%s.app" % binary_name + +def target_plist(): + return os.path.join(bundle_name(), 'Contents', 'Info.plist') + +def target_directory(): + return os.path.join(bundle_name(), 'Contents', 'MacOS') + +def target_binary(): + return os.path.join(target_directory(), binary_name) + +def copy_bundle(): + if os.path.isdir(bundle_name()): + shutil.rmtree(bundle_name()) + shutil.copytree( + os.path.join('TOOLS', 'osxbundle', bundle_name()), + bundle_name()) + +def copy_binary(): + shutil.copy(binary_name, target_binary()) + +def run_install_name_tool(target_file, dylib_path, destination_directory): + new_dylib_path = os.path.join("@executable_path", "lib", + os.path.basename(dylib_path)) + + sh("install_name_tool -change %s %s %s" % \ + (dylib_path, new_dylib_path, target_file)) + sh("install_name_tool -id %s %s" % \ + (new_dylib_path, os.path.join(destination_directory, + os.path.basename(dylib_path)))) + +def cp_dylibs(target_file, destination_directory): + for dylib_path in user_dylib_lst(target_file): + dylib_destination_path = os.path.join(destination_directory, + os.path.basename(dylib_path)) + shutil.copy(dylib_path, dylib_destination_path) + os.chmod(dylib_destination_path, 0o755) + cp_dylibs(dylib_destination_path, destination_directory) + +def fix_dylibs_paths(target_file, destination_directory): + for dylib_path in user_dylib_lst(target_file): + dylib_destination_path = os.path.join(destination_directory, + os.path.basename(dylib_path)) + run_install_name_tool(target_file, dylib_path, destination_directory) + fix_dylibs_paths(dylib_destination_path, destination_directory) + +def apply_plist_template(plist_file, version): + sh("sed -i -e 's/{{VERSION}}/%s/g' %s" % (version, plist_file)) + +version = sh("TOOLS/osxbundle/version.sh").strip() + +print("Creating Mac OS X application bundle (version: %s)..." % version) + +copy_bundle() +copy_binary() +apply_plist_template(target_plist(), version) +cp_dylibs(sys.argv[1], os.path.join(target_directory(), "lib")) +fix_dylibs_paths(target_binary(), os.path.join(target_directory(), "lib")) diff --git a/TOOLS/osxbundle/mpv.app/Contents/Info.plist b/TOOLS/osxbundle/mpv.app/Contents/Info.plist new file mode 100644 index 0000000000..472542fe92 --- /dev/null +++ b/TOOLS/osxbundle/mpv.app/Contents/Info.plist @@ -0,0 +1,248 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + AAC + AC3 + AIFF + M4A + MKA + MP3 + OGG + PCM + VAW + WAV + WAW + WMA + aac + ac3 + aiff + m4a + mka + mp3 + ogg + pcm + vaw + wav + waw + wma + + CFBundleTypeIconFile + audio.icns + CFBundleTypeName + Audio file + CFBundleTypeRole + Viewer + LSTypeIsPackage + + NSPersistentStoreTypeKey + XML + + + CFBundleTypeExtensions + + * + * + 3GP + 3IV + 3gp + 3iv + ASF + AVI + CPK + DAT + DIVX + DV + FLAC + FLI + FLV + H264 + I263 + M2TS + M4V + MKV + MOV + MP2 + MP4 + MPEG + MPG + MPG2 + MPG4 + NSV + NUT + NUV + OGG + OGM + QT + RM + RMVB + VCD + VFW + VOB + WMV + asf + avi + cpk + dat + divx + dv + flac + fli + flv + h264 + i263 + m2ts + m4v + mkv + mov + mp2 + mp4 + mpeg + mpg + mpg2 + mpg4 + nsv + nut + nuv + ogg + ogm + qt + rm + rmvb + vcd + vfw + vob + wmv + + CFBundleTypeIconFile + movie.icns + CFBundleTypeName + Movie file + CFBundleTypeRole + Viewer + LSTypeIsPackage + + NSPersistentStoreTypeKey + XML + + + CFBundleTypeExtensions + + AQT + ASS + JSS + RT + SMI + SRT + SSA + SUB + TXT + UTF + aqt + ass + jss + rt + smi + srt + ssa + sub + txt + utf + + CFBundleTypeIconFile + subtitles.icns + CFBundleTypeName + Subtitles file + CFBundleTypeRole + Viewer + LSTypeIsPackage + + NSPersistentStoreTypeKey + XML + + + CFBundleExecutable + mpv + CFBundleIconFile + icon + CFBundleIdentifier + org.mpv-player.standalone + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + mpv + CFBundlePackageType + APPL + CFBundleShortVersionString + {{VERSION}} + NSHighResolutionCapable + + CFBundleURLTypes + + + CFBundleTypeRole + Viewer + CFBundleURLName + Real Time (Streaming) Protocol + CFBundleURLSchemes + + rtp + rtsp + + + + CFBundleTypeRole + Viewer + CFBundleURLName + File over HTTP/FTP/UDP + CFBundleURLSchemes + + icyx + udp + ftp + http_proxy + http + + + + CFBundleTypeRole + Viewer + CFBundleURLName + Microsoft Media Services + CFBundleURLSchemes + + mms + + + + CFBundleTypeRole + Viewer + CFBundleURLName + Cuesheet + CFBundleURLSchemes + + cue + + + + CFBundleTypeRole + Viewer + CFBundleURLName + CD/DVD Media + CFBundleURLSchemes + + dvdnav + dvd + vcd + + + + + diff --git a/TOOLS/osxbundle/mpv.app/Contents/MacOS/.gitkeep b/TOOLS/osxbundle/mpv.app/Contents/MacOS/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TOOLS/osxbundle/mpv.app/Contents/MacOS/lib/.gitkeep b/TOOLS/osxbundle/mpv.app/Contents/MacOS/lib/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TOOLS/osxbundle/mpv.app/Contents/PkgInfo b/TOOLS/osxbundle/mpv.app/Contents/PkgInfo new file mode 100644 index 0000000000..bd04210fb4 --- /dev/null +++ b/TOOLS/osxbundle/mpv.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/TOOLS/osxbundle/mpv.app/Contents/Resources/audio.icns b/TOOLS/osxbundle/mpv.app/Contents/Resources/audio.icns new file mode 100644 index 0000000000..239b9bab12 Binary files /dev/null and b/TOOLS/osxbundle/mpv.app/Contents/Resources/audio.icns differ diff --git a/TOOLS/osxbundle/mpv.app/Contents/Resources/icon.icns b/TOOLS/osxbundle/mpv.app/Contents/Resources/icon.icns new file mode 100644 index 0000000000..eb056f5a15 Binary files /dev/null and b/TOOLS/osxbundle/mpv.app/Contents/Resources/icon.icns differ diff --git a/TOOLS/osxbundle/mpv.app/Contents/Resources/movie.icns b/TOOLS/osxbundle/mpv.app/Contents/Resources/movie.icns new file mode 100644 index 0000000000..8c495894a4 Binary files /dev/null and b/TOOLS/osxbundle/mpv.app/Contents/Resources/movie.icns differ diff --git a/TOOLS/osxbundle/mpv.app/Contents/Resources/subtitles.icns b/TOOLS/osxbundle/mpv.app/Contents/Resources/subtitles.icns new file mode 100644 index 0000000000..f4c7270691 Binary files /dev/null and b/TOOLS/osxbundle/mpv.app/Contents/Resources/subtitles.icns differ diff --git a/TOOLS/osxbundle/version.sh b/TOOLS/osxbundle/version.sh new file mode 100755 index 0000000000..ff6bb1b5fd --- /dev/null +++ b/TOOLS/osxbundle/version.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# Extract revision number from file used by daily tarball snapshots +# or from "git describe" output +git_revision=$(cat snapshot_version 2> /dev/null) +test $git_revision || test ! -d .git || \ +git_revision=`git describe --match "v[0-9]*" --always` +git_revision=$(expr "$git_revision" : v*'\(.*\)') +test $git_revision || git_revision=UNKNOWN + +# releases extract the version number from the VERSION file +version=$(cat VERSION 2> /dev/null) +test $version || version=$git_revision + +echo $version diff --git a/etc/mpv-icon-source.svg b/etc/mpv-icon-source.svg new file mode 100644 index 0000000000..6d0453bc5f --- /dev/null +++ b/etc/mpv-icon-source.svg @@ -0,0 +1,556 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 511d5478f91f06ad3bc1354db68b114771c89812 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 30 Aug 2012 10:40:32 +0200 Subject: codecs: add Video Decode Acceleration Framework codec Video Decode Acceleration Framework is a framework by Apple to provide GPU assisted H.264 decoding. It is available on Mac OS X v10.6.3 and later with Mac models equipped with the NVIDIA GeForce 9400M, GeForce 320M, GeForce GT 330M, ATI HD Radeon GFX, Intel HD Graphics and others. This commit uses the new video decoder added in FFmpeg based upon this framework. --- etc/codecs.conf | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/etc/codecs.conf b/etc/codecs.conf index ab9267c5a9..9d4e8c9e0c 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -732,6 +732,22 @@ videocodec ffh264crystalhd driver ffmpeg dll h264_crystalhd +videocodec ffh264vda + info "FFmpeg H.264 (VDA)" + status working + fourcc H264,h264 + fourcc X264,x264 + fourcc avc1,AVC1 + fourcc davc,DAVC + fourcc vvvc ; only one sample using this fourcc + fourcc ai55,ai15 ; flip4mac avc intra + fourcc ai1q,ai5q ; flip4mac avc intra + fourcc ai12 ;AVC Intra 100 / 1080 + format 0x10000005 + driver ffmpeg + dll h264_vda + out YUY2,UYVY,YV12,NV12 + videocodec ffsvq3 info "FFmpeg Sorenson Video v3 (SVQ3)" status working -- cgit v1.2.3 From b94619724327e555a348e2cdcd4c6d2ccde8f8b1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 13 Sep 2012 09:32:59 +0200 Subject: cocoa_common: save state in the vo struct Save the cocoa state in an instance variable for the Objective-C part of the code and use a field in the vo struct for the raw C part of the code. --- libvo/cocoa_common.h | 10 +++-- libvo/cocoa_common.m | 124 ++++++++++++++++++++++++++++++--------------------- libvo/gl_common.c | 8 ++-- libvo/video_out.h | 1 + libvo/vo_corevideo.m | 4 +- 5 files changed, 85 insertions(+), 62 deletions(-) diff --git a/libvo/cocoa_common.h b/libvo/cocoa_common.h index 943a5fb8ba..a158a501fd 100644 --- a/libvo/cocoa_common.h +++ b/libvo/cocoa_common.h @@ -22,6 +22,8 @@ #include "video_out.h" +struct vo_cocoa_state; + bool vo_cocoa_gui_running(void); void *vo_cocoa_glgetaddr(const char *s); @@ -35,7 +37,7 @@ int vo_cocoa_create_window(struct vo *vo, uint32_t d_width, uint32_t d_height, uint32_t flags, int gl3profile); -void vo_cocoa_swap_buffers(void); +void vo_cocoa_swap_buffers(struct vo *vo); int vo_cocoa_check_events(struct vo *vo); void vo_cocoa_fullscreen(struct vo *vo); void vo_cocoa_ontop(struct vo *vo); @@ -43,9 +45,9 @@ 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); +void *vo_cocoa_cgl_context(struct vo *vo); +void *vo_cocoa_cgl_pixel_format(struct vo *vo); -int vo_cocoa_cgl_color_size(void); +int vo_cocoa_cgl_color_size(struct vo *vo); #endif /* MPLAYER_COCOA_COMMON_H */ diff --git a/libvo/cocoa_common.m b/libvo/cocoa_common.m index 331072afcf..e88d2d49ae 100644 --- a/libvo/cocoa_common.m +++ b/libvo/cocoa_common.m @@ -62,7 +62,10 @@ @end #endif -@interface GLMPlayerWindow : NSWindow +@interface GLMPlayerWindow : NSWindow { + struct vo *_vo; +} +- (void) setVideoOutput:(struct vo *)vo; - (BOOL) canBecomeKeyWindow; - (BOOL) canBecomeMainWindow; - (void) fullscreen; @@ -107,22 +110,15 @@ struct vo_cocoa_state { bool out_fs_resize; }; -struct vo_cocoa_state *s; - -struct vo *l_vo; +static int _instances = 0; -// local function definitions -struct vo_cocoa_state *vo_cocoa_init_state(void); -void vo_set_level(int ontop); -void update_screen_info(void); -void resize_window(struct vo *vo); -void vo_cocoa_display_cursor(int requested_state); -void create_menu(void); +static void create_menu(void); -struct vo_cocoa_state *vo_cocoa_init_state(void) +static struct vo_cocoa_state *vo_cocoa_init_state(struct vo *vo) { - struct vo_cocoa_state *s = talloc_ptrtype(NULL, s); + struct vo_cocoa_state *s = talloc_ptrtype(vo, s); *s = (struct vo_cocoa_state){ + .pool = [[NSAutoreleasePool alloc] init], .did_resize = NO, .current_video_size = {0,0}, .previous_video_size = {0,0}, @@ -132,6 +128,7 @@ struct vo_cocoa_state *vo_cocoa_init_state(void) .windowed_frame = {{0,0},{0,0}}, .out_fs_resize = NO, .display_cursor = 1, + .cursor_autohide_delay = vo->opts->cursor_autohide_delay, }; return s; } @@ -145,7 +142,7 @@ static bool supports_hidpi(NSView *view) bool vo_cocoa_gui_running(void) { - return !!s; + return _instances > 0; } void *vo_cocoa_glgetaddr(const char *s) @@ -163,9 +160,9 @@ void *vo_cocoa_glgetaddr(const char *s) int vo_cocoa_init(struct vo *vo) { - s = vo_cocoa_init_state(); - s->pool = [[NSAutoreleasePool alloc] init]; - s->cursor_autohide_delay = vo->opts->cursor_autohide_delay; + vo->cocoa = vo_cocoa_init_state(vo); + _instances++; + NSApplicationLoad(); NSApp = [NSApplication sharedApplication]; [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; @@ -175,6 +172,7 @@ int vo_cocoa_init(struct vo *vo) void vo_cocoa_uninit(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; CGDisplayShowCursor(kCGDirectMainDisplay); [NSApp setPresentationOptions:NSApplicationPresentationDefault]; @@ -185,19 +183,20 @@ void vo_cocoa_uninit(struct vo *vo) [s->pool release]; s->pool = nil; - talloc_free(s); - s = nil; + _instances--; } -static int current_screen_has_dock_or_menubar(void) +static int current_screen_has_dock_or_menubar(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; NSRect f = s->screen_frame; NSRect vf = [s->screen_handle visibleFrame]; return f.size.height > vf.size.height || f.size.width > vf.size.width; } -void update_screen_info(void) +static void update_screen_info(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; s->screen_array = [NSScreen screens]; if (xinerama_screen >= (int)[s->screen_array count]) { mp_msg(MSGT_VO, MSGL_INFO, "[cocoa] Device ID %d does not exist, falling back to main device\n", xinerama_screen); @@ -216,7 +215,8 @@ void update_screen_info(void) void vo_cocoa_update_xinerama_info(struct vo *vo) { - update_screen_info(); + struct vo_cocoa_state *s = vo->cocoa; + update_screen_info(vo); aspect_save_screenres(vo, s->screen_frame.size.width, s->screen_frame.size.height); } @@ -225,8 +225,9 @@ int vo_cocoa_change_attributes(struct vo *vo) return 0; } -void resize_window(struct vo *vo) +static void resize_window(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; NSView *view = [s->window contentView]; NSRect frame; @@ -241,8 +242,9 @@ void resize_window(struct vo *vo) [s->glContext update]; } -void vo_set_level(int ontop) +static void vo_set_level(struct vo *vo, int ontop) { + struct vo_cocoa_state *s = vo->cocoa; if (ontop) { s->windowed_window_level = NSNormalWindowLevel + 1; } else { @@ -257,14 +259,16 @@ void vo_cocoa_ontop(struct vo *vo) { struct MPOpts *opts = vo->opts; opts->vo_ontop = !opts->vo_ontop; - vo_set_level(opts->vo_ontop); + vo_set_level(vo, opts->vo_ontop); } int vo_cocoa_create_window(struct vo *vo, uint32_t d_width, uint32_t d_height, uint32_t flags, int gl3profile) { + struct vo_cocoa_state *s = vo->cocoa; struct MPOpts *opts = vo->opts; + if (s->current_video_size.width > 0 || s->current_video_size.height > 0) s->previous_video_size = s->current_video_size; s->current_video_size = NSMakeSize(d_width, d_height); @@ -327,7 +331,7 @@ int vo_cocoa_create_window(struct vo *vo, uint32_t d_width, if (flags & VOFLAG_FULLSCREEN) vo_cocoa_fullscreen(vo); - vo_set_level(opts->vo_ontop); + vo_set_level(vo, opts->vo_ontop); } else { if (s->current_video_size.width != s->previous_video_size.width || s->current_video_size.height != s->previous_video_size.height) { @@ -354,13 +358,15 @@ int vo_cocoa_create_window(struct vo *vo, uint32_t d_width, return 0; } -void vo_cocoa_swap_buffers() +void vo_cocoa_swap_buffers(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; [s->glContext flushBuffer]; } -void vo_cocoa_display_cursor(int requested_state) +static void vo_cocoa_display_cursor(struct vo *vo, int requested_state) { + struct vo_cocoa_state *s = vo->cocoa; if (requested_state) { if (!vo_fs || s->cursor_autohide_delay > -2) { s->display_cursor = requested_state; @@ -376,6 +382,7 @@ void vo_cocoa_display_cursor(int requested_state) int vo_cocoa_check_events(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; NSEvent *event; float curTime = TickCount()/60; int msCurTime = (int) (curTime * 1000); @@ -383,7 +390,7 @@ int vo_cocoa_check_events(struct vo *vo) // automatically hide mouse cursor if (vo_fs && s->display_cursor && (msCurTime - s->cursor_timer >= s->cursor_autohide_delay)) { - vo_cocoa_display_cursor(0); + vo_cocoa_display_cursor(vo, 0); s->cursor_timer = msCurTime; } @@ -399,7 +406,7 @@ int vo_cocoa_check_events(struct vo *vo) inMode:NSEventTrackingRunLoopMode dequeue:YES]; if (event == nil) return 0; - l_vo = vo; + [s->window setVideoOutput:vo]; [NSApp sendEvent:event]; if (s->did_resize) { @@ -420,30 +427,33 @@ int vo_cocoa_check_events(struct vo *vo) void vo_cocoa_fullscreen(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; [s->window fullscreen]; resize_window(vo); } int vo_cocoa_swap_interval(int enabled) { - [s->glContext setValues:&enabled forParameter:NSOpenGLCPSwapInterval]; + [[NSOpenGLContext currentContext] setValues:&enabled + forParameter:NSOpenGLCPSwapInterval]; return 0; } -void *vo_cocoa_cgl_context(void) +void *vo_cocoa_cgl_context(struct vo *vo) { + struct vo_cocoa_state *s = vo->cocoa; return [s->glContext CGLContextObj]; } -void *vo_cocoa_cgl_pixel_format(void) +void *vo_cocoa_cgl_pixel_format(struct vo *vo) { - return CGLGetPixelFormat(vo_cocoa_cgl_context()); + return CGLGetPixelFormat(vo_cocoa_cgl_context(vo)); } -int vo_cocoa_cgl_color_size(void) +int vo_cocoa_cgl_color_size(struct vo *vo) { GLint value; - CGLDescribePixelFormat(vo_cocoa_cgl_pixel_format(), 0, + CGLDescribePixelFormat(vo_cocoa_cgl_pixel_format(vo), 0, kCGLPFAColorSize, &value); switch (value) { case 32: @@ -506,18 +516,24 @@ void create_menu() } @implementation GLMPlayerWindow +- (void) setVideoOutput:(struct vo *)vo +{ + _vo = vo; +} - (void) windowDidResize:(NSNotification *) notification { - if (l_vo) + struct vo_cocoa_state *s = _vo->cocoa; + if (_vo) s->did_resize = YES; } - (void) fullscreen { + struct vo_cocoa_state *s = _vo->cocoa; if (!vo_fs) { - update_screen_info(); - if (current_screen_has_dock_or_menubar()) + update_screen_info(_vo); + if (current_screen_has_dock_or_menubar(_vo)) [NSApp setPresentationOptions:NSApplicationPresentationHideDock|NSApplicationPresentationHideMenuBar]; s->windowed_frame = [self frame]; [self setHasShadow:NO]; @@ -525,7 +541,7 @@ void create_menu() [self setFrame:s->screen_frame display:YES animate:NO]; [self setLevel:s->fullscreen_window_level]; vo_fs = VO_TRUE; - vo_cocoa_display_cursor(0); + vo_cocoa_display_cursor(_vo, 0); [self setMovableByWindowBackground: NO]; } else { [NSApp setPresentationOptions:NSApplicationPresentationDefault]; @@ -540,7 +556,7 @@ void create_menu() [self setContentAspectRatio:s->current_video_size]; [self setLevel:s->windowed_window_level]; vo_fs = VO_FALSE; - vo_cocoa_display_cursor(1); + vo_cocoa_display_cursor(_vo, 1); [self setMovableByWindowBackground: YES]; } } @@ -552,7 +568,7 @@ void create_menu() - (BOOL) resignFirstResponder { return YES; } - (BOOL) windowShouldClose:(id)sender { - mplayer_put_key(l_vo->key_fifo, KEY_CLOSE_WIN); + mplayer_put_key(_vo->key_fifo, KEY_CLOSE_WIN); // We have to wait for MPlayer to handle this, // otherwise we are in trouble if the // KEY_CLOSE_WIN handler is disabled @@ -567,7 +583,7 @@ void create_menu() - (void) handleQuitEvent:(NSAppleEventDescriptor*)e withReplyEvent:(NSAppleEventDescriptor*)r { - mplayer_put_key(l_vo->key_fifo, KEY_CLOSE_WIN); + mplayer_put_key(_vo->key_fifo, KEY_CLOSE_WIN); } - (void) keyDown:(NSEvent *)theEvent @@ -589,14 +605,14 @@ void create_menu() key |= KEY_MODIFIER_ALT; if ([theEvent modifierFlags] & NSCommandKeyMask) key |= KEY_MODIFIER_META; - mplayer_put_key(l_vo->key_fifo, key); + mplayer_put_key(_vo->key_fifo, key); } } - (void) mouseMoved: (NSEvent *) theEvent { if (vo_fs) - vo_cocoa_display_cursor(1); + vo_cocoa_display_cursor(_vo, 1); } - (void) mouseDragged:(NSEvent *)theEvent @@ -637,9 +653,9 @@ void create_menu() - (void) scrollWheel:(NSEvent *)theEvent { if ([theEvent deltaY] > 0) - mplayer_put_key(l_vo->key_fifo, MOUSE_BTN3); + mplayer_put_key(_vo->key_fifo, MOUSE_BTN3); else - mplayer_put_key(l_vo->key_fifo, MOUSE_BTN4); + mplayer_put_key(_vo->key_fifo, MOUSE_BTN4); } - (void) mouseEvent:(NSEvent *)theEvent @@ -653,17 +669,17 @@ void create_menu() case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: - mplayer_put_key(l_vo->key_fifo, (MOUSE_BTN0 + buttonNumber) | MP_KEY_DOWN); + mplayer_put_key(_vo->key_fifo, (MOUSE_BTN0 + buttonNumber) | MP_KEY_DOWN); // Looks like Cocoa doesn't create MouseUp events when we are // doing the second click in a double click. Put in the key_fifo // the key that would be put from the MouseUp handling code. if([theEvent clickCount] == 2) - mplayer_put_key(l_vo->key_fifo, MOUSE_BTN0 + buttonNumber); + mplayer_put_key(_vo->key_fifo, MOUSE_BTN0 + buttonNumber); break; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: - mplayer_put_key(l_vo->key_fifo, MOUSE_BTN0 + buttonNumber); + mplayer_put_key(_vo->key_fifo, MOUSE_BTN0 + buttonNumber); break; } } @@ -672,9 +688,10 @@ void create_menu() - (void) applicationWillBecomeActive:(NSNotification *)aNotification { if (vo_fs) { + struct vo_cocoa_state *s = _vo->cocoa; [s->window makeKeyAndOrderFront:s->window]; [s->window setLevel:s->fullscreen_window_level]; - if (current_screen_has_dock_or_menubar()) + if (current_screen_has_dock_or_menubar(_vo)) [NSApp setPresentationOptions:NSApplicationPresentationHideDock| NSApplicationPresentationHideMenuBar]; } @@ -683,6 +700,7 @@ void create_menu() - (void) applicationWillResignActive:(NSNotification *)aNotification { if (vo_fs) { + struct vo_cocoa_state *s = _vo->cocoa; [NSApp setPresentationOptions:NSApplicationPresentationDefault]; [s->window setLevel:s->windowed_window_level]; [s->window orderBack:s->window]; @@ -704,8 +722,9 @@ void create_menu() - (void) normalSize { + struct vo_cocoa_state *s = _vo->cocoa; if (!vo_fs) - [self setContentSize:s->current_video_size keepCentered:YES]; + [self setContentSize:s->current_video_size keepCentered:YES]; } - (void) halfSize { [self mulSize:0.5f];} @@ -715,6 +734,7 @@ void create_menu() - (void) mulSize:(float)multiplier { if (!vo_fs) { + struct vo_cocoa_state *s = _vo->cocoa; NSSize size = [[self contentView] frame].size; size.width = s->current_video_size.width * (multiplier); size.height = s->current_video_size.height * (multiplier); diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 8af486d4eb..43df55ea9b 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -1951,9 +1951,9 @@ static bool create_window_cocoa(struct MPGLContext *ctx, uint32_t d_width, getFunctions(ctx->gl, (void *)vo_cocoa_glgetaddr, NULL, gl3); if (gl3) { - ctx->depth_r = vo_cocoa_cgl_color_size(); - ctx->depth_g = vo_cocoa_cgl_color_size(); - ctx->depth_b = vo_cocoa_cgl_color_size(); + ctx->depth_r = vo_cocoa_cgl_color_size(ctx->vo); + ctx->depth_g = vo_cocoa_cgl_color_size(ctx->vo); + ctx->depth_b = vo_cocoa_cgl_color_size(ctx->vo); } if (!ctx->gl->SwapInterval) @@ -1980,7 +1980,7 @@ static void releaseGlContext_cocoa(MPGLContext *ctx) static void swapGlBuffers_cocoa(MPGLContext *ctx) { - vo_cocoa_swap_buffers(); + vo_cocoa_swap_buffers(ctx->vo); } static int cocoa_check_events(struct vo *vo) diff --git a/libvo/video_out.h b/libvo/video_out.h index 5ab5f96301..a36c56aa90 100644 --- a/libvo/video_out.h +++ b/libvo/video_out.h @@ -249,6 +249,7 @@ struct vo { struct MPOpts *opts; struct vo_x11_state *x11; struct vo_w32_state *w32; + struct vo_cocoa_state *cocoa; struct mp_fifo *key_fifo; struct encode_lavc_context *encode_lavc_ctx; struct input_ctx *input_ctx; diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index d92e11ca1c..19a9003b9e 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -319,8 +319,8 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) CVReturn error; if (!p->textureCache || !p->pixelBuffer) { - error = CVOpenGLTextureCacheCreate(NULL, 0, vo_cocoa_cgl_context(), - vo_cocoa_cgl_pixel_format(), 0, &p->textureCache); + error = CVOpenGLTextureCacheCreate(NULL, 0, vo_cocoa_cgl_context(vo), + vo_cocoa_cgl_pixel_format(vo), 0, &p->textureCache); if(error != kCVReturnSuccess) mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL" " texture Cache(%d)\n", error); -- cgit v1.2.3 From f5de0aac96621b584bdb5fd1ca5916529d219b0a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 16 Sep 2012 20:53:04 +0200 Subject: cocoa_common: use IOKit to perform power management This allows to remove the call to the deprecated `UpdateSystemActivity`. The additional benefit is power management is disabled only if the video is really playing. A paused video will not stop the system from idling. --- configure | 4 ++-- libvo/cocoa_common.h | 2 ++ libvo/cocoa_common.m | 52 +++++++++++++++++++++++++++++++++++++++++---------- libvo/gl_common.c | 2 ++ libvo/gl_common.h | 2 ++ libvo/vo_corevideo.m | 10 ++++++++++ libvo/vo_opengl.c | 10 ++++++++++ libvo/vo_opengl_old.c | 10 ++++++++++ 8 files changed, 80 insertions(+), 12 deletions(-) diff --git a/configure b/configure index a8753ec3b0..3af45d6798 100755 --- a/configure +++ b/configure @@ -1980,10 +1980,10 @@ int main(void) { } EOF _cocoa=no - cc_check -framework Cocoa -framework OpenGL && _cocoa=yes + cc_check -framework IOKit -framework Cocoa -framework OpenGL && _cocoa=yes fi if test "$_cocoa" = yes ; then - libs_mplayer="$libs_mplayer -framework Cocoa -framework OpenGL" + libs_mplayer="$libs_mplayer -framework IOKit -framework Cocoa -framework OpenGL" def_cocoa='#define CONFIG_COCOA 1' else def_cocoa='#undef CONFIG_COCOA' diff --git a/libvo/cocoa_common.h b/libvo/cocoa_common.h index a158a501fd..079e497441 100644 --- a/libvo/cocoa_common.h +++ b/libvo/cocoa_common.h @@ -41,6 +41,8 @@ void vo_cocoa_swap_buffers(struct vo *vo); int vo_cocoa_check_events(struct vo *vo); void vo_cocoa_fullscreen(struct vo *vo); void vo_cocoa_ontop(struct vo *vo); +void vo_cocoa_pause(struct vo *vo); +void vo_cocoa_resume(struct vo *vo); // returns an int to conform to the gl extensions from other platforms int vo_cocoa_swap_interval(int enabled); diff --git a/libvo/cocoa_common.m b/libvo/cocoa_common.m index e88d2d49ae..aba18140ba 100644 --- a/libvo/cocoa_common.m +++ b/libvo/cocoa_common.m @@ -21,6 +21,7 @@ #import #import #import // for CGDisplayHideCursor +#import #include #include "cocoa_common.h" @@ -62,6 +63,11 @@ @end #endif +// add power management assertion not available on OSX versions prior to 10.7 +#ifndef kIOPMAssertionTypePreventUserIdleDisplaySleep +#define kIOPMAssertionTypePreventUserIdleDisplaySleep CFSTR("PreventUserIdleDisplaySleep") +#endif + @interface GLMPlayerWindow : NSWindow { struct vo *_vo; } @@ -100,14 +106,14 @@ struct vo_cocoa_state { NSInteger windowed_window_level; NSInteger fullscreen_window_level; - int last_screensaver_update; - int display_cursor; int cursor_timer; int cursor_autohide_delay; bool did_resize; bool out_fs_resize; + + IOPMAssertionID power_mgmt_assertion; }; static int _instances = 0; @@ -129,6 +135,7 @@ static struct vo_cocoa_state *vo_cocoa_init_state(struct vo *vo) .out_fs_resize = NO, .display_cursor = 1, .cursor_autohide_delay = vo->opts->cursor_autohide_delay, + .power_mgmt_assertion = kIOPMNullAssertionID, }; return s; } @@ -158,6 +165,27 @@ void *vo_cocoa_glgetaddr(const char *s) return ret; } +static void enable_power_management(struct vo *vo) +{ + struct vo_cocoa_state *s = vo->cocoa; + if (!s->power_mgmt_assertion) return; + IOPMAssertionRelease(s->power_mgmt_assertion); + s->power_mgmt_assertion = kIOPMNullAssertionID; +} + +static void disable_power_management(struct vo *vo) +{ + struct vo_cocoa_state *s = vo->cocoa; + if (s->power_mgmt_assertion) return; + + CFStringRef assertion_type = kIOPMAssertionTypeNoDisplaySleep; + if (is_osx_version_at_least(10, 7, 0)) + assertion_type = kIOPMAssertionTypePreventUserIdleDisplaySleep; + + IOPMAssertionCreateWithName(assertion_type, kIOPMAssertionLevelOn, + CFSTR("org.mplayer2.power_mgmt"), &s->power_mgmt_assertion); +} + int vo_cocoa_init(struct vo *vo) { vo->cocoa = vo_cocoa_init_state(vo); @@ -166,6 +194,7 @@ int vo_cocoa_init(struct vo *vo) NSApplicationLoad(); NSApp = [NSApplication sharedApplication]; [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular]; + disable_power_management(vo); return 1; } @@ -174,6 +203,7 @@ void vo_cocoa_uninit(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; CGDisplayShowCursor(kCGDirectMainDisplay); + enable_power_management(vo); [NSApp setPresentationOptions:NSApplicationPresentationDefault]; [s->window release]; @@ -186,6 +216,16 @@ void vo_cocoa_uninit(struct vo *vo) _instances--; } +void vo_cocoa_pause(struct vo *vo) +{ + enable_power_management(vo); +} + +void vo_cocoa_resume(struct vo *vo) +{ + disable_power_management(vo); +} + static int current_screen_has_dock_or_menubar(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; @@ -394,14 +434,6 @@ int vo_cocoa_check_events(struct vo *vo) s->cursor_timer = msCurTime; } - //update activity every 30 seconds to prevent - //screensaver from starting up. - if ((int)curTime - s->last_screensaver_update >= 30 || s->last_screensaver_update == 0) - { - UpdateSystemActivity(UsrActivity); - s->last_screensaver_update = (int)curTime; - } - event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES]; if (event == nil) diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 43df55ea9b..fabd4e23d7 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -2492,6 +2492,8 @@ MPGLContext *mpgl_init(enum MPGLType type, struct vo *vo) ctx->fullscreen = cocoa_fullscreen; ctx->ontop = vo_cocoa_ontop; ctx->vo_init = vo_cocoa_init; + ctx->pause = vo_cocoa_pause; + ctx->resume = vo_cocoa_resume; ctx->vo_uninit = vo_cocoa_uninit; break; #endif diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 7f9dc28083..4add21bb62 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -212,6 +212,8 @@ typedef struct MPGLContext { uint32_t d_height, uint32_t flags); // optional + void (*pause)(struct vo *vo); + void (*resume)(struct vo *vo); void (*ontop)(struct vo *vo); void (*border)(struct vo *vo); void (*update_xinerama_info)(struct vo *vo); diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index 19a9003b9e..0db161fd18 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -423,6 +423,16 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_ONTOP: p->mpglctx->ontop(vo); return VO_TRUE; + case VOCTRL_PAUSE: + if (!p->mpglctx->pause) + break; + p->mpglctx->pause(vo); + return VO_TRUE; + case VOCTRL_RESUME: + if (!p->mpglctx->resume) + break; + p->mpglctx->resume(vo); + return VO_TRUE; case VOCTRL_FULLSCREEN: p->mpglctx->fullscreen(vo); resize(vo, vo->dwidth, vo->dheight); diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c index b6f2ddd811..7f400ce62c 100644 --- a/libvo/vo_opengl.c +++ b/libvo/vo_opengl.c @@ -1941,6 +1941,16 @@ static int control(struct vo *vo, uint32_t request, void *data) break; p->glctx->ontop(vo); return VO_TRUE; + case VOCTRL_PAUSE: + if (!p->glctx->pause) + break; + p->glctx->pause(vo); + return VO_TRUE; + case VOCTRL_RESUME: + if (!p->glctx->resume) + break; + p->glctx->resume(vo); + return VO_TRUE; case VOCTRL_FULLSCREEN: p->glctx->fullscreen(vo); resize(p); diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c index d3a9c0e170..d302504846 100644 --- a/libvo/vo_opengl_old.c +++ b/libvo/vo_opengl_old.c @@ -1442,6 +1442,16 @@ static int control(struct vo *vo, uint32_t request, void *data) if (vo_doublebuffering) do_render(vo); return true; + case VOCTRL_PAUSE: + if (!p->glctx->pause) + break; + p->glctx->pause(vo); + return VO_TRUE; + case VOCTRL_RESUME: + if (!p->glctx->resume) + break; + p->glctx->resume(vo); + return VO_TRUE; case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; if (args->full_window) -- cgit v1.2.3 From 5931e53dcca9a2066566e939d9e4cb27383cc818 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 13 Sep 2012 12:17:02 +0200 Subject: cocoa_common: replace TickCount() with NSProcessInfo#systemUptime TickCount is depracted in OS X 10.8. Substitute it with a public Cocoa API call available since OS X 10.6. --- libvo/cocoa_common.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libvo/cocoa_common.m b/libvo/cocoa_common.m index aba18140ba..20bfab5533 100644 --- a/libvo/cocoa_common.m +++ b/libvo/cocoa_common.m @@ -424,14 +424,13 @@ int vo_cocoa_check_events(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; NSEvent *event; - float curTime = TickCount()/60; - int msCurTime = (int) (curTime * 1000); + int ms_time = (int) ([[NSProcessInfo processInfo] systemUptime] * 1000); // automatically hide mouse cursor if (vo_fs && s->display_cursor && - (msCurTime - s->cursor_timer >= s->cursor_autohide_delay)) { + (ms_time - s->cursor_timer >= s->cursor_autohide_delay)) { vo_cocoa_display_cursor(vo, 0); - s->cursor_timer = msCurTime; + s->cursor_timer = ms_time; } event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil -- cgit v1.2.3 From 539021c779c12881fd0f83ed4b8d43822598a6b4 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 13 Sep 2012 14:55:08 +0200 Subject: cocoa_common: remove useless import QuartzCore was probably forgot after extracting the code from `vo_corevideo`. The OpenGL.h include can be avoided with no warnings/errors. --- libvo/cocoa_common.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/libvo/cocoa_common.m b/libvo/cocoa_common.m index 20bfab5533..4f94f146be 100644 --- a/libvo/cocoa_common.m +++ b/libvo/cocoa_common.m @@ -18,8 +18,6 @@ */ #import -#import -#import #import // for CGDisplayHideCursor #import #include -- cgit v1.2.3 From 5db96c083706970f2c297e83afe20d74c4ecc5d1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 16 Sep 2012 11:24:38 +0200 Subject: gl_common: remove useless cocoa wrapper functions --- libvo/gl_common.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/libvo/gl_common.c b/libvo/gl_common.c index fabd4e23d7..44188481b9 100644 -