vo_quartz.c

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

C
1,431
字号
		CGContextMoveToPoint( context, winRect.right-1, 6); CGContextAddLineToPoint( context, winRect.right-6, 1);		CGContextMoveToPoint( context, winRect.right-1, 10); CGContextAddLineToPoint( context, winRect.right-10, 1);		CGContextStrokePath( context );			//line black		CGContextSetRGBStrokeColor (context, 0.6, 0.6, 0.6, 0.5);		CGContextMoveToPoint( context, winRect.right-1, 3); CGContextAddLineToPoint( context, winRect.right-3, 1);			CGContextMoveToPoint( context, winRect.right-1, 7); CGContextAddLineToPoint( context, winRect.right-7, 1);		CGContextMoveToPoint( context, winRect.right-1, 11); CGContextAddLineToPoint( context, winRect.right-11, 1);		CGContextStrokePath( context );				//CGContextRestoreGState( context );		CGContextFlush (context);	}	//auto hide mouse cursor and futur on-screen control?	if(vo_quartz_fs && !mouseHide)	{		int curTime = TickCount()/60;		static int lastTime = 0;				if( ((curTime - lastTime) >= 5) || (lastTime == 0) )		{			CGDisplayHideCursor(kCGDirectMainDisplay);			mouseHide = TRUE;			lastTime = curTime;		}	}	//update activity every 30 seconds to prevent	//screensaver from starting up.	curTime  = TickCount()/60;	lastTime = 0;			if( ((curTime/ - lastTime) >= 5) || (lastTime == 0) )	{		UpdateSystemActivity(UsrActivity);		lastTime = curTime;	}}static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y){	switch (image_format)	{  		case IMGFMT_YV12:  		case IMGFMT_I420: 			memcpy_pic(((char*)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]);  			x=x/2;y=y/2;w=w/2;h=h/2;   			memcpy_pic(((char*)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); 			memcpy_pic(((char*)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]);  			return 0;    		case IMGFMT_IYUV: 			memcpy_pic(((char*)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]);  			x=x/2;y=y/2;w=w/2;h=h/2;  			 			memcpy_pic(((char*)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); 			memcpy_pic(((char*)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]);  			return 0;	}	return -1;}static int draw_frame(uint8_t *src[]){	switch (image_format)	{		case IMGFMT_RGB32:			fast_memcpy(image_data,src[0],image_size);			return 0;					case IMGFMT_UYVY:		case IMGFMT_YUY2:			memcpy_pic(((char*)P), src[0], imgRect.right * 2, imgRect.bottom, imgRect.right * 2, imgRect.right * 2);			return 0;	}	return -1;}static int query_format(uint32_t format){	image_format = format;	image_qtcodec = 0;	if (format == IMGFMT_RGB32)	{		return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;    }        if ((format == IMGFMT_YV12) || (format == IMGFMT_IYUV) || (format == IMGFMT_I420))	{		image_qtcodec = kMpegYUV420CodecType; //kYUV420CodecType ?;		return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;    }    if (format == IMGFMT_YUY2)	{		image_qtcodec = kComponentVideoUnsigned;		return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;    }        if (format == IMGFMT_UYVY)	{		image_qtcodec = k422YpCbCr8CodecType;		return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;	}    return 0;}static void uninit(void){	OSErr qterr;		switch (image_format)	{		case IMGFMT_YV12:		case IMGFMT_IYUV:		case IMGFMT_I420:		case IMGFMT_UYVY:		case IMGFMT_YUY2:		{			if (EnterMoviesDone)			{				qterr = CDSequenceEnd(seqId);				if (qterr)				{					mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: CDSequenceEnd (%d)\n", qterr);				}			}			break;		}		default:			break;	}	ShowMenuBar();}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];                device_id = strtol(parse_pos, &parse_pos, 0);            }            if (strncmp (parse_pos, "fs_res=", 7) == 0)            {				parse_pos = &parse_pos[7];				fs_res_x = strtol(parse_pos, &parse_pos, 0);				parse_pos = &parse_pos[1];				fs_res_y = strtol(parse_pos, &parse_pos, 0);            }            if (parse_pos[0] == ':') parse_pos = &parse_pos[1];            else if (parse_pos[0]) parse_err = 1;        }    }	#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    return 0;}static uint32_t draw_yuv_image(mp_image_t *mpi){	// ATM we're only called for planar IMGFMT	// drawing is done directly in P	// and displaying is in flip_page.	return get_image_done ? VO_TRUE : VO_FALSE;  }static uint32_t get_yuv_image(mp_image_t *mpi){	if(mpi->type!=MP_IMGTYPE_EXPORT) return VO_FALSE;  	if(mpi->imgfmt!=image_format) return VO_FALSE;  	if(mpi->flags&MP_IMGFLAG_PLANAR)	{		if (mpi->num_planes != 3)		{			mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 3 planes allowed in get_yuv_image for planar (%d) \n", mpi->num_planes);			return VO_FALSE;		}		mpi->planes[0]=((char*)P) + be2me_32(P->componentInfoY.offset);		mpi->stride[0]=imgRect.right;		mpi->width=imgRect.right;		if(mpi->flags&MP_IMGFLAG_SWAPPED)		{			// I420			mpi->planes[1]=((char*)P) + be2me_32(P->componentInfoCb.offset);			mpi->planes[2]=((char*)P) + be2me_32(P->componentInfoCr.offset);			mpi->stride[1]=imgRect.right/2;			mpi->stride[2]=imgRect.right/2;		} 		else 		{			// YV12			mpi->planes[1]=((char*)P) + be2me_32(P->componentInfoCr.offset);			mpi->planes[2]=((char*)P) + be2me_32(P->componentInfoCb.offset);			mpi->stride[1]=imgRect.right/2;			mpi->stride[2]=imgRect.right/2;		}				mpi->flags|=MP_IMGFLAG_DIRECT;		get_image_done = 1;		return VO_TRUE;	}	else 	{ 		// doesn't work yet		if (mpi->num_planes != 1)		{			mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 1 plane allowed in get_yuv_image for packed (%d) \n", mpi->num_planes);			return VO_FALSE;		}		mpi->planes[0] = (char*)P;		mpi->stride[0] = imgRect.right * 2;		mpi->width=imgRect.right;		mpi->flags|=MP_IMGFLAG_DIRECT;		get_image_done = 1;		return VO_TRUE;	}	return VO_FALSE;}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_FULLSCREEN: vo_fs = (!(vo_fs)); window_fullscreen(); return VO_TRUE;		case VOCTRL_ONTOP: vo_ontop = (!(vo_ontop)); window_ontop(); return VO_TRUE;		case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data));		case VOCTRL_GET_PANSCAN: return VO_TRUE;		case VOCTRL_SET_PANSCAN: window_panscan(); return VO_TRUE;					case VOCTRL_GET_IMAGE:			switch (image_format)			{				case IMGFMT_YV12:				case IMGFMT_IYUV:				case IMGFMT_I420:				case IMGFMT_UYVY:				case IMGFMT_YUY2:					return get_yuv_image(data);					break;				default:					break;			}		case VOCTRL_DRAW_IMAGE:			switch (image_format)			{				case IMGFMT_YV12:				case IMGFMT_IYUV:				case IMGFMT_I420:				case IMGFMT_UYVY:				case IMGFMT_YUY2:					return draw_yuv_image(data);					break;				default:					break;			}	}	return VO_NOTIMPL;}void window_resized(){	float aspectX;	float aspectY;		int padding = 0;		uint32_t d_width;	uint32_t d_height;		CGRect tmpBounds;	GetPortBounds( GetWindowPort(theWindow), &winRect );	if(vo_keepaspect)	{	aspect( &d_width, &d_height, A_NOZOOM);	d_height = ((float)d_width/movie_aspect);		aspectX = (float)((float)winRect.right/(float)d_width);	aspectY = (float)((float)(winRect.bottom)/(float)d_height);		if((d_height*aspectX)>(winRect.bottom))	{		padding = (winRect.right - d_width*aspectY)/2;		SetRect(&dstRect, padding, 0, d_width*aspectY+padding, d_height*aspectY);	}	else	{		padding = ((winRect.bottom) - d_height*aspectX)/2;		SetRect(&dstRect, 0, padding, (d_width*aspectX), d_height*aspectX+padding);	}	}	else	{		SetRect(&dstRect, 0, 0, winRect.right, winRect.bottom);	}		switch (image_format)	{		case IMGFMT_RGB32:		{			bounds = CGRectMake(dstRect.left, dstRect.top, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top);			CreateCGContextForPort (GetWindowPort (theWindow), &context);			break;		}		case IMGFMT_YV12:		case IMGFMT_IYUV:		case IMGFMT_I420:		case IMGFMT_UYVY:		case IMGFMT_YUY2:		{			long scale_X = FixDiv(Long2Fix(dstRect.right - dstRect.left),Long2Fix(imgRect.right));			long scale_Y = FixDiv(Long2Fix(dstRect.bottom - dstRect.top),Long2Fix(imgRect.bottom));						SetIdentityMatrix(&matrix);			if (((dstRect.right - dstRect.left)   != imgRect.right) || ((dstRect.bottom - dstRect.right) != imgRect.bottom))			{				ScaleMatrix(&matrix, scale_X, scale_Y, 0, 0);								if (padding > 0)				{					TranslateMatrix(&matrix, Long2Fix(dstRect.left), Long2Fix(dstRect.top));				}			}						SetDSequenceMatrix(seqId, &matrix);			break;		}		default:			break;	}		//Clear Background	tmpBounds = CGRectMake( 0, 0, winRect.right, winRect.bottom);	CreateCGContextForPort(GetWindowPort(theWindow),&context);	CGContextFillRect(context, tmpBounds);}void window_ontop(){	if(!vo_quartz_fs)	{	//Cycle between level	winLevel++;	if(winLevel>2)		winLevel = 1;	}	SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel]));}void window_fullscreen(){	static Ptr restoreState = NULL;	//go fullscreen	if(vo_fs)	{		if(winLevel != 0)		{			if(device_id == 0)			{				SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);				CGDisplayHideCursor(kCGDirectMainDisplay);				mouseHide = TRUE;			}						if(fs_res_x != 0 || fs_res_y != 0)			{				BeginFullScreen( &restoreState, deviceHdl, &fs_res_x, &fs_res_y, NULL, NULL, NULL);								//Get Main device info///////////////////////////////////////////////////				deviceRect = (*deviceHdl)->gdRect;        				device_width = deviceRect.right;				device_height = deviceRect.bottom;			}		}		//save old window size 		if (!vo_quartz_fs)		{			GetWindowPortBounds(theWindow, &oldWinRect);			GetWindowBounds(theWindow, kWindowContentRgn, &oldWinBounds);		}				//go fullscreen		panscan_calc();		ChangeWindowAttributes(theWindow, kWindowNoShadowAttribute, 0);		MoveWindow(theWindow, deviceRect.left-(vo_panscan_x >> 1), deviceRect.top-(vo_panscan_y >> 1), 1);		SizeWindow(theWindow, device_width+vo_panscan_x, device_height+vo_panscan_y,1);		vo_quartz_fs = 1;	}	else //go back to windowed mode	{		vo_quartz_fs = 0;		if(restoreState != NULL)		{			EndFullScreen(restoreState, NULL);					//Get Main device info///////////////////////////////////////////////////			deviceRect = (*deviceHdl)->gdRect;        			device_width = deviceRect.right;			device_height = deviceRect.bottom;			restoreState = NULL;		}		SetSystemUIMode( kUIModeNormal, NULL);		//show mouse cursor		CGDisplayShowCursor(kCGDirectMainDisplay);		mouseHide = FALSE;				//revert window to previous setting		ChangeWindowAttributes(theWindow, 0, kWindowNoShadowAttribute);		SizeWindow(theWindow, oldWinRect.right, oldWinRect.bottom,1);		MoveWindow(theWindow, oldWinBounds.left, oldWinBounds.top, 1);	}	window_resized();}void window_panscan(){	panscan_calc();		if(vo_panscan > 0)		CheckMenuItem (aspectMenu, 2, 1);	else		CheckMenuItem (aspectMenu, 2, 0);		if(vo_quartz_fs)	{		MoveWindow(theWindow, deviceRect.left-(vo_panscan_x >> 1), deviceRect.top-(vo_panscan_y >> 1), 1);		SizeWindow(theWindow, device_width+vo_panscan_x, device_height+vo_panscan_y,1);	}}

⌨️ 快捷键说明

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