Mercurial > mplayer.hg
changeset 12120:56e4423f16be
Quartz/MacOSX video output module by Nicolas Plourde
author | alex |
---|---|
date | Mon, 05 Apr 2004 21:20:19 +0000 |
parents | a035d2616e0b |
children | 6d4212840048 |
files | configure libvo/video_out.c libvo/vo_quartz.c libvo/vo_quartz.h |
diffstat | 4 files changed, 668 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/configure Mon Apr 05 15:32:01 2004 +0000 +++ b/configure Mon Apr 05 21:20:19 2004 +0000 @@ -2725,6 +2725,7 @@ _macosx=no _def_macosx='#undef MACOSX' _noaomodules="macosx $_noaomodules" + _novomodules="quartz $_novomodules" fi fi if test "$_macosx" = yes ; then @@ -2744,10 +2745,13 @@ _def_macosx='#define MACOSX 1' _aosrc="$_aosrc ao_macosx.c" _aomodules="macosx $_aomodules" + _vosrc="$_vosrc vo_quartz.c" + _vomodules="quartz $_vomodules" else _macosx=no _def_macosx='#undef MACOSX' _noaomodules="macosx $_noaomodules" + _novomodules="quartz $_novomodules" fi fi echores "$_macosx"
--- a/libvo/video_out.c Mon Apr 05 15:32:01 2004 +0000 +++ b/libvo/video_out.c Mon Apr 05 21:20:19 2004 +0000 @@ -118,6 +118,9 @@ #ifdef HAVE_TGA extern vo_functions_t video_out_tga; #endif +#ifdef MACOSX +extern vo_functions_t video_out_quartz; +#endif vo_functions_t* video_out_drivers[] = { @@ -228,6 +231,9 @@ #ifdef HAVE_TGA &video_out_tga, #endif +#ifdef MACOSX + &video_out_quartz, +#endif NULL };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/vo_quartz.c Mon Apr 05 21:20:19 2004 +0000 @@ -0,0 +1,529 @@ +/* + * vo_quartz.c + * + * Copyright (c) Nicolas Plourde - January 2004 + * + * MPlayer Mac OSX Quartz video out module. + * + * TODO: -Fullscreen + * -Better event handling + * + * Note on performance: + * Right now i can play fullsize dvd video with -framedrop on my + * iBook G4 800mhz. YUV to RGB converstion will speed up thing alot. + * Another thing is the slow fps when you maximize the window, I was + * not expecting that. I will fix this a.s.a.p. Im new to Mac + * programming so help is welcome. + */ + +//SYS +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <errno.h> + +//OSX +#include <Carbon/Carbon.h> +#include <QuickTime/QuickTime.h> + +//MPLAYER +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" +#include "aspect.h" + +#include "../input/input.h" +#include "../input/mouse.h" + +#include "vo_quartz.h" + +static vo_info_t info = { + "MacOS X (Quartz)", + "quartz", + "Nicolas Plourde <nicolasplourde@hotmail.com>", + "" +}; + +LIBVO_EXTERN (quartz) +static unsigned char *ImageData = NULL; + +static uint32_t image_width; +static uint32_t image_height; +static uint32_t image_depth; +static uint32_t image_bytes; +static uint32_t image_format; + +static int int_pause = 0; + +int screen_width, screen_height; + +WindowRef theWindow; +CGContextRef context; +CGRect bounds; +CGRect winBounds; +Rect contentRect; +CGImageRef image; +CGDataProviderRef dataProviderRef; +Ptr oldscreenstate; +RGBColor black = { 0, 0, 0 }; +float winAlpha = 1; + +#include "../osdep/keycodes.h" +extern void mplayer_put_key (int code); + +//PROTOTYPE///////////////////////////////////////////////////////////////// +void resize_window (uint32_t width, uint32_t height); +static OSStatus MainWindowEventHandler (EventHandlerCallRef nextHandler, + EventRef event, void *userData); +static OSStatus MainKeyEventHandler (EventHandlerCallRef nextHandler, + EventRef event, void *userData); + + +//default window event handler +static OSStatus +MainWindowEventHandler (EventHandlerCallRef nextHandler, EventRef event, + void *userData) +{ + OSStatus err = noErr; + WindowRef window; + Rect rectPort = { 0, 0, 0, 0 }; + OSStatus result = eventNotHandledErr; + UInt32 class = GetEventClass (event); + UInt32 kind = GetEventKind (event); + + GetEventParameter (event, kEventParamDirectObject, typeWindowRef, NULL, + sizeof (WindowRef), NULL, &window); + if (window) + { + GetWindowPortBounds (window, &rectPort); + } + + switch (kind) + { + case kEventWindowActivated: + + case kEventWindowDrawContent: + break; + + case kEventWindowClosed: + HideWindow (window); + mplayer_put_key (KEY_ESC); + break; + + case kEventWindowShown: + InvalWindowRect (window, &rectPort); + break; + + case kEventWindowBoundsChanged: + resize_window (rectPort.right, rectPort.bottom); + break; + + case kEventWindowZoomed: + resize_window (rectPort.right, rectPort.bottom); + break; + + default: + err = eventNotHandledErr; + break; + } + + return err; +} + +//keyboard event handler +static OSStatus +MainKeyEventHandler (EventHandlerCallRef nextHandler, EventRef event, + void *userData) +{ + OSStatus err = noErr; + UInt32 macKeyCode; + + GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, + sizeof (macKeyCode), NULL, &macKeyCode); + + switch (GetEventKind (event)) + { + case kEventRawKeyDown: + { + switch (macKeyCode) + { + case QZ_RETURN: + mplayer_put_key (KEY_ENTER); + break; + case QZ_ESCAPE: + EndFullScreen (oldscreenstate, 0); + QuitApplicationEventLoop (); + mplayer_put_key (KEY_ESC); + break; + case QZ_q: + mplayer_put_key ('q'); + break; + case QZ_F1: + mplayer_put_key (KEY_F + 1); + break; + case QZ_F2: + mplayer_put_key (KEY_F + 2); + break; + case QZ_F3: + mplayer_put_key (KEY_F + 3); + break; + case QZ_F4: + mplayer_put_key (KEY_F + 4); + break; + case QZ_F5: + mplayer_put_key (KEY_F + 5); + break; + case QZ_F6: + mplayer_put_key (KEY_F + 6); + break; + case QZ_F7: + mplayer_put_key (KEY_F + 7); + break; + case QZ_F8: + mplayer_put_key (KEY_F + 8); + break; + case QZ_F9: + mplayer_put_key (KEY_F + 9); + break; + case QZ_F10: + mplayer_put_key (KEY_F + 10); + break; + case QZ_F11: + mplayer_put_key (KEY_F + 11); + break; + case QZ_F12: + mplayer_put_key (KEY_F + 12); + break; + case QZ_o: + mplayer_put_key ('o'); + break; + case QZ_SPACE: + mplayer_put_key (' '); + break; + case QZ_p: + mplayer_put_key ('p'); + break; + //case QZ_7: mplayer_put_key(shift_key?'/':'7'); + //case QZ_PLUS: mplayer_put_key(shift_key?'*':'+'); + case QZ_KP_PLUS: + mplayer_put_key ('+'); + break; + case QZ_MINUS: + case QZ_KP_MINUS: + mplayer_put_key ('-'); + break; + case QZ_TAB: + mplayer_put_key ('\t'); + break; + case QZ_PAGEUP: + mplayer_put_key (KEY_PAGE_UP); + break; + case QZ_PAGEDOWN: + mplayer_put_key (KEY_PAGE_DOWN); + break; + case QZ_UP: + mplayer_put_key (KEY_UP); + break; + case QZ_DOWN: + mplayer_put_key (KEY_DOWN); + break; + case QZ_LEFT: + mplayer_put_key (KEY_LEFT); + break; + case QZ_RIGHT: + mplayer_put_key (KEY_RIGHT); + break; + //case QZ_LESS: mplayer_put_key(shift_key?'>':'<'); break; + //case QZ_GREATER: mplayer_put_key('>'); break; + //case QZ_ASTERISK: + case QZ_KP_MULTIPLY: + mplayer_put_key ('*'); + break; + case QZ_SLASH: + case QZ_KP_DIVIDE: + mplayer_put_key ('/'); + break; + case QZ_KP0: + mplayer_put_key (KEY_KP0); + break; + case QZ_KP1: + mplayer_put_key (KEY_KP1); + break; + case QZ_KP2: + mplayer_put_key (KEY_KP2); + break; + case QZ_KP3: + mplayer_put_key (KEY_KP3); + break; + case QZ_KP4: + mplayer_put_key (KEY_KP4); + break; + case QZ_KP5: + mplayer_put_key (KEY_KP5); + break; + case QZ_KP6: + mplayer_put_key (KEY_KP6); + break; + case QZ_KP7: + mplayer_put_key (KEY_KP7); + break; + case QZ_KP8: + mplayer_put_key (KEY_KP8); + break; + case QZ_KP9: + mplayer_put_key (KEY_KP9); + break; + case QZ_KP_PERIOD: + mplayer_put_key (KEY_KPDEC); + break; + case QZ_KP_ENTER: + mplayer_put_key (KEY_KPENTER); + break; + case QZ_LEFTBRACKET: + SetWindowAlpha (theWindow, winAlpha -= 0.05); + break; + case QZ_RIGHTBRACKET: + SetWindowAlpha (theWindow, winAlpha += 0.05); + break; + case QZ_f: + break; + default: + break; + } + } + break; + default: + err = eventNotHandledErr; + break; + } + + return err; +} + +static uint32_t +config (uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, + uint32_t flags, char *title, uint32_t format) +{ + WindowAttributes windowAttrs; + CFStringRef titleKey; + CFStringRef windowTitle; + OSStatus result; + GDHandle deviceHdl; + Rect deviceRect; + + //Get Main device info/////////////////////////////////////////////////// + deviceHdl = GetMainDevice (); + deviceRect = (*deviceHdl)->gdRect; + + screen_width = deviceRect.right; + screen_height = deviceRect.bottom; + + //misc mplayer setup///////////////////////////////////////////////////// + image_width = width; + image_height = height; + image_depth = IMGFMT_RGB_DEPTH (format); + image_bytes = (IMGFMT_RGB_DEPTH (format) + 7) / 8; + + aspect_save_orig (width, height); + aspect_save_prescale (d_width, d_height); + aspect_save_screenres (screen_width, screen_height); + + aspect (&d_width, &d_height, A_NOZOOM); + + if (ImageData) + free (ImageData); + ImageData = malloc (image_width * image_height * image_bytes); + + //Create player window////////////////////////////////////////////////// + windowAttrs = kWindowStandardDocumentAttributes + | kWindowMetalAttribute + | kWindowStandardHandlerAttribute + | kWindowInWindowMenuAttribute + | kWindowLiveResizeAttribute | kWindowCompositingAttribute; + + SetRect (&contentRect, 0, 0, d_width, d_height); + CreateNewWindow (kDocumentWindowClass, windowAttrs, &contentRect, + &theWindow); + + titleKey = CFSTR ("MPlayer"); + windowTitle = CFCopyLocalizedString (titleKey, NULL); + result = SetWindowTitleWithCFString (theWindow, windowTitle); + CFRelease (titleKey); + CFRelease (windowTitle); + + const EventTypeSpec winEvents[] = { + {kEventClassWindow, kEventWindowActivated}, + {kEventClassWindow, kEventWindowDrawContent}, + {kEventClassWindow, kEventWindowClosed}, + {kEventClassWindow, kEventWindowShown}, + {kEventClassWindow, kEventWindowBoundsChanged}, + {kEventClassWindow, kEventWindowZoomed} + }; + + const EventTypeSpec keyEvents[] = + { {kEventClassKeyboard, kEventRawKeyDown} }; + InstallWindowEventHandler (theWindow, + NewEventHandlerUPP (MainWindowEventHandler), + GetEventTypeCount (winEvents), winEvents, + theWindow, NULL); + InstallWindowEventHandler (theWindow, + NewEventHandlerUPP (MainKeyEventHandler), + GetEventTypeCount (keyEvents), keyEvents, + theWindow, NULL); + + RepositionWindow (theWindow, NULL, kWindowCascadeOnMainScreen); + ShowWindow (theWindow); + + //Setup Quartz context + CreateCGContextForPort (GetWindowPort (theWindow), &context); + + //set size and aspect for current window + resize_window (d_width, d_height); + + return 0; +} + +//resize drawing context to fit window +void +resize_window (uint32_t width, uint32_t height) +{ + //this is a "wow it work". Need some improvement. + uint32_t d_width; + uint32_t d_height; + uint32_t size; + Rect tmpRect; + + float aspectX; + float aspectY; + + aspect (&d_width, &d_height, A_NOZOOM); + + aspectX = (float) ((float) d_width * (width / (float) d_width)); + aspectY = (float) ((float) d_height * (width / (float) d_width)); + + if (aspectY > height) + { + aspectX = (float) ((float) d_width * (height / (float) d_height)); + aspectY = (float) ((float) d_height * (height / (float) d_height)); + + bounds = CGRectMake ((width - aspectX) / 2, 0, aspectX, aspectY); + } + else + { + bounds = CGRectMake (0, (height - aspectY) / 2, aspectX, aspectY); + } + + //create a graphic context for the window + GetWindowPortBounds (theWindow, &tmpRect); + SetPortBounds (GetWindowPort (theWindow), &tmpRect); + CreateCGContextForPort (GetWindowPort (theWindow), &context); + + //fill background with black + winBounds = + CGRectMake (tmpRect.top, tmpRect.left, tmpRect.right, tmpRect.bottom); + CGContextSetRGBFillColor (context, 0.0, 0.0, 0.0, 1.0); + CGContextFillRect (context, winBounds); +} + +static void +check_events (void) +{ + EventRef theEvent; + EventTargetRef theTarget; + + theTarget = GetEventDispatcherTarget (); + + ReceiveNextEvent (0, NULL, kEventDurationNoWait, true, &theEvent); + SendEventToEventTarget (theEvent, theTarget); + ReleaseEvent (theEvent); + + //if(VO_EVENT_RESIZE) resize_window(vo_dwidth,vo_dheight); + if (VO_EVENT_EXPOSE && int_pause) + flip_page (); +} + +static void +draw_osd (void) +{ +} + +static void +flip_page (void) +{ + CGContextFlush (context); +} + +static uint32_t +draw_slice (uint8_t * src[], int stride[], int w, int h, int x, int y) +{ + return -1; +} + +static uint32_t +draw_frame (uint8_t * src[]) +{ + //this is very slow. I have to find another way. + CGImageAlphaInfo alphaInfo; + + dataProviderRef = + CGDataProviderCreateWithData (0, src[0], + image_width * image_height * image_bytes, + 0); + + if (image_format == IMGFMT_RGB24) + alphaInfo = kCGImageAlphaNone; + else if (image_format == IMGFMT_RGB32) + alphaInfo = kCGImageAlphaNoneSkipFirst; + + image = CGImageCreate (image_width, + image_height, + 8, + image_depth, + ((image_width * image_depth) + 7) / 8, + CGColorSpaceCreateDeviceRGB (), + alphaInfo, + dataProviderRef, 0, 0, kCGRenderingIntentDefault); + + CGContextDrawImage (context, bounds, image); + + return 0; +} + +static uint32_t +query_format (uint32_t format) +{ + image_format = format; + + //Curently supporting only rgb format. + if ((format == IMGFMT_RGB24) || (format == IMGFMT_RGB32)) + return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; + return 0; +} + + +static void +uninit (void) +{ +} + +static uint32_t +preinit (const char *arg) +{ + return 0; +} + +static uint32_t +control (uint32_t request, void *data, ...) +{ + switch (request) + { + case VOCTRL_PAUSE: + return (int_pause = 1); + case VOCTRL_RESUME: + return (int_pause = 0); + case VOCTRL_QUERY_FORMAT: + return query_format (*((uint32_t *) data)); + } + return VO_NOTIMPL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/vo_quartz.h Mon Apr 05 21:20:19 2004 +0000 @@ -0,0 +1,129 @@ +/* + * vo_quartz.h + * Mac keyboard def taken from SDL + */ + +#ifndef VO_QUARTZ_H +#define VO_QUARTZ_H 1 + +/* These are the Macintosh key scancode constants -- from Inside Macintosh */ +#define QZ_ESCAPE 0x35 +#define QZ_F1 0x7A +#define QZ_F2 0x78 +#define QZ_F3 0x63 +#define QZ_F4 0x76 +#define QZ_F5 0x60 +#define QZ_F6 0x61 +#define QZ_F7 0x62 +#define QZ_F8 0x64 +#define QZ_F9 0x65 +#define QZ_F10 0x6D +#define QZ_F11 0x67 +#define QZ_F12 0x6F +#define QZ_PRINT 0x69 +#define QZ_SCROLLOCK 0x6B +#define QZ_PAUSE 0x71 +#define QZ_POWER 0x7F +#define QZ_BACKQUOTE 0x32 +#define QZ_1 0x12 +#define QZ_2 0x13 +#define QZ_3 0x14 +#define QZ_4 0x15 +#define QZ_5 0x17 +#define QZ_6 0x16 +#define QZ_7 0x1A +#define QZ_8 0x1C +#define QZ_9 0x19 +#define QZ_0 0x1D +#define QZ_MINUS 0x1B +#define QZ_EQUALS 0x18 +#define QZ_BACKSPACE 0x33 +#define QZ_INSERT 0x72 +#define QZ_HOME 0x73 +#define QZ_PAGEUP 0x74 +#define QZ_NUMLOCK 0x47 +#define QZ_KP_EQUALS 0x51 +#define QZ_KP_DIVIDE 0x4B +#define QZ_KP_MULTIPLY 0x43 +#define QZ_TAB 0x30 +#define QZ_q 0x0C +#define QZ_w 0x0D +#define QZ_e 0x0E +#define QZ_r 0x0F +#define QZ_t 0x11 +#define QZ_y 0x10 +#define QZ_u 0x20 +#define QZ_i 0x22 +#define QZ_o 0x1F +#define QZ_p 0x23 +#define QZ_LEFTBRACKET 0x21 +#define QZ_RIGHTBRACKET 0x1E +#define QZ_BACKSLASH 0x2A +#define QZ_DELETE 0x75 +#define QZ_END 0x77 +#define QZ_PAGEDOWN 0x79 +#define QZ_KP7 0x59 +#define QZ_KP8 0x5B +#define QZ_KP9 0x5C +#define QZ_KP_MINUS 0x4E +#define QZ_CAPSLOCK 0x39 +#define QZ_a 0x00 +#define QZ_s 0x01 +#define QZ_d 0x02 +#define QZ_f 0x03 +#define QZ_g 0x05 +#define QZ_h 0x04 +#define QZ_j 0x26 +#define QZ_k 0x28 +#define QZ_l 0x25 +#define QZ_SEMICOLON 0x29 +#define QZ_QUOTE 0x27 +#define QZ_RETURN 0x24 +#define QZ_KP4 0x56 +#define QZ_KP5 0x57 +#define QZ_KP6 0x58 +#define QZ_KP_PLUS 0x45 +#define QZ_LSHIFT 0x38 +#define QZ_z 0x06 +#define QZ_x 0x07 +#define QZ_c 0x08 +#define QZ_v 0x09 +#define QZ_b 0x0B +#define QZ_n 0x2D +#define QZ_m 0x2E +#define QZ_COMMA 0x2B +#define QZ_PERIOD 0x2F +#define QZ_SLASH 0x2C +/* These are the same as the left versions - use left by default */ +#if 0 +#define QZ_RSHIFT 0x38 +#endif +#define QZ_UP 0x7E +#define QZ_KP1 0x53 +#define QZ_KP2 0x54 +#define QZ_KP3 0x55 +#define QZ_KP_ENTER 0x4C +#define QZ_LCTRL 0x3B +#define QZ_LALT 0x3A +#define QZ_LMETA 0x37 +#define QZ_SPACE 0x31 +/* These are the same as the left versions - use left by default */ +#if 0 +#define QZ_RMETA 0x37 +#define QZ_RALT 0x3A +#define QZ_RCTRL 0x3B +#endif +#define QZ_LEFT 0x7B +#define QZ_DOWN 0x7D +#define QZ_RIGHT 0x7C +#define QZ_KP0 0x52 +#define QZ_KP_PERIOD 0x41 + +/* Wierd, these keys are on my iBook under MacOS X */ +#define QZ_IBOOK_ENTER 0x34 +#define QZ_IBOOK_LEFT 0x3B +#define QZ_IBOOK_RIGHT 0x3C +#define QZ_IBOOK_DOWN 0x3D +#define QZ_IBOOK_UP 0x3E + +#endif /* VO_QUARTZ_H */