Mercurial > mplayer.hg
diff libvo/vo_quartz.c @ 12487:deec5d737a61
re-use same window when playing multiple files
author | nplourde |
---|---|
date | Tue, 18 May 2004 20:49:44 +0000 |
parents | 77cca80b1f27 |
children | 4c42b1fb183f |
line wrap: on
line diff
--- a/libvo/vo_quartz.c Tue May 18 19:13:15 2004 +0000 +++ b/libvo/vo_quartz.c Tue May 18 20:49:44 2004 +0000 @@ -49,8 +49,6 @@ LIBVO_EXTERN(quartz) -static uint32_t image_width; -static uint32_t image_height; static uint32_t image_depth; static uint32_t image_format; static uint32_t image_size; @@ -59,7 +57,7 @@ static ImageSequence seqId; static CodecType image_qtcodec; -static PlanarPixmapInfoYUV420 *P; +static PlanarPixmapInfoYUV420 *P = NULL; static struct { ImageDescriptionHandle desc; @@ -70,25 +68,26 @@ } yuv_qt_stuff; static MatrixRecord matrix; static int EnterMoviesDone = 0; +static int get_image_done = 0; extern int vo_ontop; -extern int vo_fs; +extern int vo_fs; // user want fullscreen +static int vo_quartz_fs; // we are in fullscreen -int int_pause = 0; -float winAlpha = 1; +static int int_pause = 0; +static float winAlpha = 1; -int device_width; -int device_height; +static int device_width; +static int device_height; -WindowRef theWindow; - -GWorldPtr imgGWorld; +static WindowRef theWindow = NULL; -Rect imgRect; -Rect dstRect; -Rect winRect; +static Rect imgRect; // size of the original image (unscaled) +static Rect dstRect; // size of the displayed image (after scaling) +static Rect winRect; // size of the window containg the displayed image (include padding) +static Rect oldWinRect; // size of the window containg the displayed image (include padding) when NOT in FS mode -CGContextRef context; +static CGContextRef context; #include "../osdep/keycodes.h" extern void mplayer_put_key(int code); @@ -112,15 +111,15 @@ case IMGFMT_YV12: case IMGFMT_IYUV: case IMGFMT_I420: - vo_draw_alpha_yv12(w,h,src,srca,stride, ((char*)P) + P->componentInfoY.offset + x0 + y0 * image_width, image_width); + vo_draw_alpha_yv12(w,h,src,srca,stride, ((char*)P) + P->componentInfoY.offset + x0 + y0 * imgRect.right, imgRect.right); break; case IMGFMT_UYVY: - //vo_draw_alpha_uyvy(w,h,src,srca,stride,((char*)P) + (x0 + y0 * image_width) * 2,image_width*2); + //vo_draw_alpha_uyvy(w,h,src,srca,stride,((char*)P) + (x0 + y0 * imgRect.right) * 2,imgRect.right*2); break; case IMGFMT_YUY2: - vo_draw_alpha_yuy2(w,h,src,srca,stride,((char*)P) + (x0 + y0 * image_width) * 2,image_width*2); + vo_draw_alpha_yuy2(w,h,src,srca,stride,((char*)P) + (x0 + y0 * imgRect.right) * 2,imgRect.right*2); break; - } + } } //default window event handler @@ -291,12 +290,38 @@ return err; } +static void quartz_CreateWindow(uint32_t d_width, uint32_t d_height, WindowAttributes windowAttrs) +{ + CFStringRef titleKey; + CFStringRef windowTitle; + OSStatus result; + + SetRect(&winRect, 0, 0, d_width, d_height); + SetRect(&oldWinRect, 0, 0, d_width, d_height); + SetRect(&dstRect, 0, 0, d_width, d_height); + + CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow); + + //Set window title + titleKey = CFSTR("MPlayer"); + windowTitle = CFCopyLocalizedString(titleKey, NULL); + result = SetWindowTitleWithCFString(theWindow, windowTitle); + CFRelease(titleKey); + CFRelease(windowTitle); + + //Install event handler + const EventTypeSpec winEvents[] = { { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseWheelMoved }, + { kEventClassWindow, kEventWindowClosed }, + { kEventClassWindow, kEventWindowBoundsChanged } }; + + InstallApplicationEventHandler (NewEventHandlerUPP (MainEventHandler), GetEventTypeCount(winEvents), winEvents, 0, NULL); +} + 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; OSErr qterr; @@ -309,8 +334,7 @@ device_height = deviceRect.bottom; //misc mplayer setup///////////////////////////////////////////////////// - image_width = width; - image_height = height; + SetRect(&imgRect, 0, 0, width, height); switch (image_format) { case IMGFMT_RGB32: @@ -324,7 +348,7 @@ image_depth = 16; break; } - image_size = ((image_width*image_height*image_depth)+7)/8; + image_size = ((imgRect.right*imgRect.bottom*image_depth)+7)/8; vo_fs = flags & VOFLAG_FULLSCREEN; @@ -342,28 +366,27 @@ windowAttrs &= (~kWindowResizableAttribute); - SetRect(&winRect, 0, 0, d_width, d_height); - SetRect(&dstRect, 0, 0, d_width, d_height); - SetRect(&imgRect, 0, 0, image_width, image_height); - - CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow); + if (theWindow == NULL) + { + quartz_CreateWindow(d_width, d_height, windowAttrs); + + if (theWindow == NULL) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: Couldn't create window !!!!!\n"); + return -1; + } + } + else + { + HideWindow(theWindow); + ChangeWindowAttributes(theWindow, ~windowAttrs, windowAttrs); + SetRect(&winRect, 0, 0, d_width, d_height); + SetRect(&oldWinRect, 0, 0, d_width, d_height); + SizeWindow (theWindow, d_width, d_height, 1); + } + + get_image_done = 0; - //Set window title - titleKey = CFSTR("MPlayer"); - windowTitle = CFCopyLocalizedString(titleKey, NULL); - result = SetWindowTitleWithCFString(theWindow, windowTitle); - CFRelease(titleKey); - CFRelease(windowTitle); - - //Install event handler - const EventTypeSpec winEvents[] = { { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseWheelMoved }, - { kEventClassWindow, kEventWindowClosed }, - { kEventClassWindow, kEventWindowBoundsChanged } }; - - //InstallWindowEventHandler (theWindow, NewEventHandlerUPP (MainEventHandler), GetEventTypeCount(winEvents), winEvents, theWindow, NULL); - InstallApplicationEventHandler (NewEventHandlerUPP (MainEventHandler), GetEventTypeCount(winEvents), winEvents, 0, NULL); if (!EnterMoviesDone) { qterr = EnterMovies(); @@ -375,6 +398,7 @@ if (qterr) { mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: EnterMovies (%d)\n", qterr); + return -1; } SetPort(GetWindowPort(theWindow)); @@ -390,9 +414,9 @@ case IMGFMT_RGB32: { ImageDescriptionHandle desc; - + GWorldPtr imgGWorld; image_data = calloc(sizeof(image_size),1); - NewGWorldFromPtr (&imgGWorld, k32ARGBPixelFormat, &imgRect, 0, 0, 0, image_data, image_width * 4); + NewGWorldFromPtr (&imgGWorld, k32ARGBPixelFormat, &imgRect, 0, 0, 0, image_data, imgRect.right * 4); MakeImageDescriptionForPixMap(GetGWorldPixMap(imgGWorld), &desc); DisposeGWorld(imgGWorld); @@ -409,9 +433,12 @@ 0, codecLosslessQuality, bestSpeedCodec); + free(image_data); + image_data = NULL; if (qterr) { mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceBeginS (%d)\n", qterr); + return -1; } } break; @@ -435,9 +462,9 @@ ((FieldInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_fiel))->fieldOrderings = 0; yuv_qt_stuff.extension_clap = NewHandleClear(sizeof(CleanApertureImageDescriptionExtension)); - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureWidthN = image_width; + ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureWidthN = imgRect.right; ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureWidthD = 1; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureHeightN = image_height; + ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureHeightN = imgRect.bottom; ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureHeightD = 1; ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->horizOffN = 0; ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->horizOffD = 1; @@ -453,8 +480,8 @@ (*yuv_qt_stuff.desc)->version = 2; (*yuv_qt_stuff.desc)->revisionLevel = 0; (*yuv_qt_stuff.desc)->vendor = 'mpla'; - (*yuv_qt_stuff.desc)->width = image_width; - (*yuv_qt_stuff.desc)->height = image_height; + (*yuv_qt_stuff.desc)->width = imgRect.right; + (*yuv_qt_stuff.desc)->height = imgRect.bottom; (*yuv_qt_stuff.desc)->hRes = Long2Fix(72); (*yuv_qt_stuff.desc)->vRes = Long2Fix(72); (*yuv_qt_stuff.desc)->temporalQuality = 0; @@ -467,27 +494,29 @@ qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_colr, kColorInfoImageDescriptionExtension); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: AddImageDescriptionExtension [colr] (%d)\n", qterr); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [colr] (%d)\n", qterr); } qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_fiel, kFieldInfoImageDescriptionExtension); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: AddImageDescriptionExtension [fiel] (%d)\n", qterr); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [fiel] (%d)\n", qterr); } qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_clap, kCleanApertureImageDescriptionExtension); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: AddImageDescriptionExtension [clap] (%d)\n", qterr); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [clap] (%d)\n", qterr); } qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_pasp, kCleanApertureImageDescriptionExtension); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: AddImageDescriptionExtension [pasp] (%d)\n", qterr); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [pasp] (%d)\n", qterr); } - + if (P != NULL) { // second or subsequent movie + free(P); + } P = calloc(sizeof(PlanarPixmapInfoYUV420) + image_size, 1); switch (image_format) { @@ -497,9 +526,9 @@ P->componentInfoY.offset = sizeof(PlanarPixmapInfoYUV420); P->componentInfoCb.offset = P->componentInfoY.offset + image_size / 2; P->componentInfoCr.offset = P->componentInfoCb.offset + image_size / 4; - P->componentInfoY.rowBytes = image_width; - P->componentInfoCb.rowBytes = image_width / 2; - P->componentInfoCr.rowBytes = image_width / 2; + P->componentInfoY.rowBytes = imgRect.right; + P->componentInfoCb.rowBytes = imgRect.right / 2; + P->componentInfoCr.rowBytes = imgRect.right / 2; image_buffer_size = image_size + sizeof(PlanarPixmapInfoYUV420); break; case IMGFMT_UYVY: @@ -526,6 +555,7 @@ if (qterr) { mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceBeginS (%d)\n", qterr); + return -1; } } break; @@ -577,7 +607,7 @@ static void draw_osd(void) { - vo_draw_text(image_width,image_height,draw_alpha); + vo_draw_text(imgRect.right,imgRect.bottom,draw_alpha); } static void flip_page(void) @@ -586,7 +616,7 @@ { case IMGFMT_RGB32: { - if (EnterMoviesDone) + if (EnterMoviesDone && (image_data != NULL)) { OSErr qterr; CodecFlags flags = 0; @@ -598,10 +628,10 @@ &flags, NULL, NULL); - + image_data = NULL; if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); } } } @@ -625,7 +655,7 @@ NULL); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); } } break; @@ -636,22 +666,22 @@ { switch (image_format) { - case IMGFMT_YV12: - case IMGFMT_I420: - memcpy_pic(((char*)P) + P->componentInfoY.offset + x + image_width * y, src[0], w, h, image_width, stride[0]); - x=x/2;y=y/2;w=w/2;h=h/2; - - memcpy_pic(((char*)P) + P->componentInfoCb.offset + x + image_width / 2 * y, src[1], w, h, image_width / 2, stride[1]); - memcpy_pic(((char*)P) + P->componentInfoCr.offset + x + image_width / 2 * y, src[2], w, h, image_width / 2, stride[2]); - return 0; - - case IMGFMT_IYUV: - memcpy_pic(((char*)P) + P->componentInfoY.offset + x + image_width * y, src[0], w, h, image_width, stride[0]); - x=x/2;y=y/2;w=w/2;h=h/2; - - memcpy_pic(((char*)P) + P->componentInfoCr.offset + x + image_width / 2 * y, src[1], w, h, image_width / 2, stride[1]); - memcpy_pic(((char*)P) + P->componentInfoCb.offset + x + image_width / 2 * y, src[2], w, h, image_width / 2, stride[2]); - return 0; + case IMGFMT_YV12: + case IMGFMT_I420: + memcpy_pic(((char*)P) + 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) + P->componentInfoCb.offset + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); + memcpy_pic(((char*)P) + 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) + 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) + P->componentInfoCr.offset + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); + memcpy_pic(((char*)P) + P->componentInfoCb.offset + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]); + return 0; } return -1; } @@ -666,7 +696,7 @@ case IMGFMT_UYVY: case IMGFMT_YUY2: - memcpy_pic(((char*)P), src[0], image_width * 2, image_height, image_width * 2, image_width * 2); + memcpy_pic(((char*)P), src[0], imgRect.right * 2, imgRect.bottom, imgRect.right * 2, imgRect.right * 2); return 0; } return -1; @@ -679,25 +709,25 @@ if (format == IMGFMT_RGB32) { - return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_SWSCALE; + 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_SWSCALE | VFCAP_ACCEPT_STRIDE; + 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_SWSCALE; + 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_SWSCALE; + return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; } return 0; @@ -712,7 +742,7 @@ qterr = CDSequenceEnd(seqId); if (qterr) { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: CDSequenceEnd (%d)\n", qterr); + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: CDSequenceEnd (%d)\n", qterr); } } @@ -729,7 +759,7 @@ // ATM we're only called for planar IMGFMT // drawing is done directly in P // and displaying is in flip_page. - return VO_TRUE; + return get_image_done ? VO_TRUE : VO_FALSE; } static uint32_t get_yuv_image(mp_image_t *mpi) @@ -747,27 +777,28 @@ } mpi->planes[0]=((char*)P) + P->componentInfoY.offset; - mpi->stride[0]=image_width; - mpi->width=image_width; + mpi->stride[0]=imgRect.right; + mpi->width=imgRect.right; if(mpi->flags&MP_IMGFLAG_SWAPPED) { // I420 mpi->planes[1]=((char*)P) + P->componentInfoCb.offset; mpi->planes[2]=((char*)P) + P->componentInfoCr.offset; - mpi->stride[1]=image_width/2; - mpi->stride[2]=image_width/2; + mpi->stride[1]=imgRect.right/2; + mpi->stride[2]=imgRect.right/2; } else { // YV12 mpi->planes[1]=((char*)P) + P->componentInfoCr.offset; mpi->planes[2]=((char*)P) + P->componentInfoCb.offset; - mpi->stride[1]=image_width/2; - mpi->stride[2]=image_width/2; + 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 @@ -780,9 +811,10 @@ } mpi->planes[0] = (char*)P; - mpi->stride[0] = image_width * 2; - mpi->width=image_width; + 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; @@ -803,8 +835,12 @@ 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) @@ -812,8 +848,12 @@ 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; @@ -857,11 +897,11 @@ CGContextFillRect(context, winBounds); CGContextFlush(context); - long scale_X = FixDiv(Long2Fix(dstRect.right - dstRect.left),Long2Fix(image_width)); - long scale_Y = FixDiv(Long2Fix(dstRect.bottom - dstRect.top),Long2Fix(image_height)); + 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) != image_width) || ((dstRect.bottom - dstRect.right) != image_height)) + if (((dstRect.right - dstRect.left) != imgRect.right) || ((dstRect.bottom - dstRect.right) != imgRect.bottom)) { ScaleMatrix(&matrix, scale_X, scale_Y, 0, 0); @@ -884,7 +924,6 @@ void window_fullscreen() { - static Rect oldRect; GDHandle deviceHdl; Rect deviceRect; @@ -894,7 +933,8 @@ HideMenuBar(); //save old window size - GetWindowPortBounds(theWindow, &oldRect); + if (!vo_quartz_fs) + GetWindowPortBounds(theWindow, &oldWinRect); //hide mouse cursor HideCursor(); @@ -904,6 +944,8 @@ MoveWindow (theWindow, 0, 0, 1); SizeWindow(theWindow, device_width, device_height,1); + + vo_quartz_fs = 1; } else //go back to windowed mode { @@ -915,8 +957,10 @@ //revert window to previous setting //ChangeWindowAttributes(theWindow, kWindowResizableAttribute, 0); - SizeWindow(theWindow, oldRect.right, oldRect.bottom,1); + SizeWindow(theWindow, oldWinRect.right, oldWinRect.bottom,1); RepositionWindow(theWindow, NULL, kWindowCascadeOnMainScreen); + + vo_quartz_fs = 0; } window_resized();