vo_macosx.m

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· M 代码 · 共 1,027 行 · 第 1/2 页

M
1,027
字号
/*	vo_macosx.m	by Nicolas Plourde <nicolasplourde@gmail.com>		MPlayer Mac OSX video out module. 	Copyright (c) Nicolas Plourde - 2005*/#import "vo_macosx.h"#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>//MPLAYER#include "config.h"#include "fastmemcpy.h"#include "video_out.h"#include "video_out_internal.h"#include "aspect.h"#include "mp_msg.h"#include "m_option.h"#include "input/input.h"#include "input/mouse.h"#include "osdep/keycodes.h"//CocoaNSProxy *mplayerosxProxy;MPlayerOpenGLView *mpGLView;NSAutoreleasePool *autoreleasepool;OSType pixelFormat;//shared memoryint shm_id;struct shmid_ds shm_desc;BOOL shared_buffer = false;//Screenint screen_id;BOOL screen_force;NSRect screen_frame;NSScreen *screen_handle;NSArray *screen_array;//imageunsigned char *image_data;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;//vostatic int isFullscreen;static int isOntop;static int isRootwin;extern float monitor_aspect;extern float movie_aspect;static float old_movie_aspect;static float winAlpha = 1;static int int_pause = 0;static vo_info_t info = {	"Mac OSX Core Video",	"macosx",	"Nicolas Plourde <nicolas.plourde@gmail.com>",	""};LIBVO_EXTERN(macosx)extern void mplayer_put_key(int code);extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride){	switch (image_format)	{		case IMGFMT_RGB32:			vo_draw_alpha_rgb32(w,h,src,srca,stride,image_data+4*(y0*image_width+x0),4*image_width);			break;		case IMGFMT_YUY2:			vo_draw_alpha_yuy2(w,h,src,srca,stride,image_data + (x0 + y0 * image_width) * 2,image_width*2);			break;	}}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){		//init screen	screen_array = [NSScreen screens];	if(screen_id < [screen_array count])	{		screen_handle = [screen_array objectAtIndex:screen_id];	}	else	{		mp_msg(MSGT_VO, MSGL_FATAL, "Get device error: Device ID %d do not exist, falling back to main device.\n", screen_id);		screen_handle = [screen_array objectAtIndex:0];		screen_id = 0;	}	screen_frame = [screen_handle frame];	//misc mplayer setup	image_width = width;	image_height = height;	switch (image_format) 	{		case IMGFMT_BGR32:		case IMGFMT_RGB32:			image_depth = 32;			break;		case IMGFMT_YUY2:			image_depth = 16;			break;	}	image_bytes = (image_depth + 7) / 8;	image_data = malloc(image_width*image_height*image_bytes);			if(!shared_buffer)	{				monitor_aspect = (float)screen_frame.size.width/(float)screen_frame.size.height;				//set aspect		panscan_init();		aspect_save_orig(width,height);		aspect_save_prescale(d_width,d_height);		aspect_save_screenres(screen_frame.size.width, screen_frame.size.height);		aspect((int *)&d_width,(int *)&d_height,A_NOZOOM);				movie_aspect = (float)d_width/(float)d_height;		old_movie_aspect = movie_aspect;				vo_fs = flags & VOFLAG_FULLSCREEN;					//config OpenGL View		[mpGLView config];		[mpGLView reshape];	}	else	{		movie_aspect = (float)d_width/(float)d_height;						shm_id = shmget(9849, image_width*image_height*image_bytes, IPC_CREAT | 0666);		if (shm_id == -1)		{			perror("vo_mplayer shmget: ");			return 1;		}				image_data = shmat(shm_id, NULL, 0);		if (!image_data)		{				perror("vo_mplayer shmat: ");			return 1;		}				//connnect to mplayerosx		mplayerosxProxy=[NSConnection rootProxyForConnectionWithRegisteredName:@"mplayerosx" host:nil];		[mplayerosxProxy startWithWidth: image_width withHeight: image_height withBytes: image_bytes withAspect:(int)(movie_aspect*100)];	}	return 0;}static void check_events(void){	[mpGLView check_events];}static void draw_osd(void){	vo_draw_text(image_width, image_height, draw_alpha);}static void flip_page(void){	if(shared_buffer)		[mplayerosxProxy render];	else		[mpGLView render];}static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y){	[mpGLView setCurrentTexture];	return 0;}static int draw_frame(uint8_t *src[]){	switch (image_format)	{		case IMGFMT_BGR32:		case IMGFMT_RGB32:			fast_memcpy(image_data, src[0], image_width*image_height*image_bytes);			break;		case IMGFMT_YUY2:			memcpy_pic(image_data, src[0], image_width * 2, image_height, image_width * 2, image_width * 2);			break;	}		if(!shared_buffer)		[mpGLView setCurrentTexture];		return 0;}static int query_format(uint32_t format){	image_format = format;	    switch(format)	{		case IMGFMT_YUY2:			pixelFormat = kYUVSPixelFormat;			return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;				case IMGFMT_RGB32:		case IMGFMT_BGR32:			pixelFormat = k32ARGBPixelFormat;			return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;    }    return 0;}static void uninit(void){	if(shared_buffer)	{		[mplayerosxProxy stop];		if (shmdt(image_data) == -1)			mp_msg(MSGT_VO, MSGL_FATAL, "uninit: shmdt failed\n");			if (shmctl(shm_id, IPC_RMID, &shm_desc) == -1)			mp_msg(MSGT_VO, MSGL_FATAL, "uninit: shmctl failed\n");	}    SetSystemUIMode( kUIModeNormal, 0);    CGDisplayShowCursor(kCGDirectMainDisplay);        if(mpGLView)    {        [autoreleasepool release];    }}static int preinit(const char *arg){	int parse_err = 0;    if(arg)     {        char *parse_pos = (char *)&arg[0];        while (parse_pos[0] && !parse_err) 		{			if (strncmp (parse_pos, "device_id=", 10) == 0)			{				parse_pos = &parse_pos[10];				screen_id = strtol(parse_pos, &parse_pos, 0);				screen_force = YES;            }			if (strncmp (parse_pos, "shared_buffer", 13) == 0)			{				parse_pos = &parse_pos[13];				shared_buffer = YES;            }            if (parse_pos[0] == ':') parse_pos = &parse_pos[1];            else if (parse_pos[0]) parse_err = 1;        }    }	NSApplicationLoad();	autoreleasepool = [[NSAutoreleasePool alloc] init];	NSApp = [NSApplication sharedApplication];		if(!shared_buffer)	{		#if !defined (MACOSX_FINDER_SUPPORT) || !defined (HAVE_SDL)		//this chunk of code is heavily based off SDL_macosx.m from SDL 		//it uses an Apple private function to request foreground operation		void CPSEnableForegroundOperation(ProcessSerialNumber* psn);		ProcessSerialNumber myProc, frProc;		Boolean sameProc;		if (GetFrontProcess(&frProc) == noErr)		{			if (GetCurrentProcess(&myProc) == noErr)			{				if (SameProcess(&frProc, &myProc, &sameProc) == noErr && !sameProc)				{					CPSEnableForegroundOperation(&myProc);				}				SetFrontProcess(&myProc);			}		}		#endif		if(!mpGLView)		{			mpGLView = [[MPlayerOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:[MPlayerOpenGLView defaultPixelFormat]];			[mpGLView autorelease];		}			[mpGLView display];		[mpGLView preinit];	}	    return 0;}static int 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));		case VOCTRL_ONTOP: vo_ontop = (!(vo_ontop)); [mpGLView 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 { [mplayerosxProxy toggleFullscreen]; } return VO_TRUE;		case VOCTRL_GET_PANSCAN: return VO_TRUE;		case VOCTRL_SET_PANSCAN: [mpGLView panscan]; return VO_TRUE;	}	return VO_NOTIMPL;}//////////////////////////////////////////////////////////////////////////// NSOpenGLView Subclass//////////////////////////////////////////////////////////////////////////@implementation MPlayerOpenGLView- (void) preinit{	//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;}- (void) config{	uint32_t d_width;	uint32_t d_height;		long swapInterval = 1;		NSRect frame;	CVReturn error = kCVReturnSuccess;		//config window	aspect((int *)&d_width, (int *)&d_height,A_NOZOOM);	frame = NSMakeRect(0, 0, d_width, d_height);	[window setContentSize: frame.size];		//create OpenGL Context	glContext = [[NSOpenGLContext alloc] initWithFormat:[NSOpenGLView defaultPixelFormat] shareContext:nil];			[self setOpenGLContext:glContext];	[glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];	[glContext setView:self];	[glContext makeCurrentContext];			error = CVPixelBufferCreateWithBytes( NULL, image_width, image_height, pixelFormat, image_data, image_width*image_bytes, NULL, NULL, NULL, &currentFrameBuffer);	if(error != kCVReturnSuccess)		mp_msg(MSGT_VO, MSGL_ERR,"Failed to create Pixel Buffer(%d)\n", error);		error = CVOpenGLTextureCacheCreate(NULL, 0, [glContext CGLContextObj], [[self pixelFormat] CGLPixelFormatObj], 0, &textureCache);	if(error != kCVReturnSuccess)		mp_msg(MSGT_VO, MSGL_ERR,"Failed to create OpenGL texture Cache(%d)\n", error);		error = CVOpenGLTextureCacheCreateTextureFromImage(	NULL, textureCache, currentFrameBuffer, 0, &texture);	if(error != kCVReturnSuccess)		mp_msg(MSGT_VO, MSGL_ERR,"Failed to create OpenGL texture(%d)\n", error);		//show window	[window center];	[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;		[NSApp setMainMenu:[[NSMenu alloc] init]];//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 *)[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 *)[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];}/*	Menu Action */- (void)menuAction:(id)sender{	uint32_t d_width;	uint32_t d_height;	NSRect frame;		aspect((int *)&d_width, (int *)&d_height,A_NOZOOM);		if(sender == kQuitCmd)	{		mplayer_put_key(KEY_ESC);	}		if(sender == kHalfScreenCmd)	{		if(isFullscreen) {			vo_fs = (!(vo_fs)); [self fullscreen:NO];		}				winSizeMult = 0.5;		frame.size.width = (d_width*winSizeMult);		frame.size.height = ((d_width/movie_aspect)*winSizeMult);		[window setContentSize: frame.size];		[self reshape];	}	if(sender == kNormalScreenCmd)	{		if(isFullscreen) {			vo_fs = (!(vo_fs)); [self fullscreen:NO];		}				winSizeMult = 1;		frame.size.width = d_width;		frame.size.height = d_width/movie_aspect;		[window setContentSize: frame.size];		[self reshape];	}	if(sender == kDoubleScreenCmd)	{		if(isFullscreen) {			vo_fs = (!(vo_fs)); [self fullscreen:NO];		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?