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 + -
显示快捷键?