diff options
author | Andre Pang <athp@users.sourceforge.net> | 2004-06-19 15:25:01 +0000 |
---|---|---|
committer | Andre Pang <athp@users.sourceforge.net> | 2004-06-19 15:25:01 +0000 |
commit | f44a5b7a414ecc1e1d07d95f63cafab3bf110a46 (patch) | |
tree | 2e897d2d464eea264610339a0046433a5b85a1bd | |
parent | 63af1d1a064fb92f28334917497c5561153cc005 (diff) | |
download | xine-lib-f44a5b7a414ecc1e1d07d95f63cafab3bf110a46.tar.gz xine-lib-f44a5b7a414ecc1e1d07d95f63cafab3bf110a46.tar.bz2 |
Mac OS X video output driver:
XineVideoWindow now properly keeps aspect ratio if requested
Moved set{Half,Normal,Double}Size methods from XineVideoWindow to
XineOpenGLView, since they more logically belong there
Changed setVideoSize in XineOpenGLView to only set the video size (and not
the view size)
Added setViewSize method to XineOpenGLView, to change the view size
Internal refactorings:
Removed width/height fields from XineVideoWindow: they were unnecessary,
since the width and height could be obtained via [self frame]
Renamed width/height fields to video_width/video_height in XineOpenGLView,
to reflect that they represent the height of the actual video, rather than the
view's size (which can always be obtained with [self frame] or [self bounds])
Added videoSize method to XineOpenGLView to get the actual video size
Changed isFullScreen, keepsAspectRatio, and initDone fields in
XineOpenGLView to BOOL rather than int
Apologies for the numerous changes in this one patch which may have been better
as a number of smaller, different patches. Much of the original intent of the
patch -- to fix the bugs that occured with aspect ratios -- dictated the
refactorings which took place. On the bright side, this patch 100%
regression-tested!
CVS patchset: 6706
CVS date: 2004/06/19 15:25:01
-rw-r--r-- | src/video_out/macosx/video_window.h | 24 | ||||
-rw-r--r-- | src/video_out/macosx/video_window.m | 259 | ||||
-rw-r--r-- | src/video_out/video_out_macosx.m | 7 |
3 files changed, 142 insertions, 148 deletions
diff --git a/src/video_out/macosx/video_window.h b/src/video_out/macosx/video_window.h index 3fb9c1eb5..54250a971 100644 --- a/src/video_out/macosx/video_window.h +++ b/src/video_out/macosx/video_window.h @@ -29,11 +29,11 @@ typedef enum { @interface XineOpenGLView : NSOpenGLView { IBOutlet id delegate; - int width, height; + int video_width, video_height; char * texture_buffer; unsigned long i_texture; - int initDone; - int isFullScreen; + BOOL initDone; + BOOL isFullScreen; XineVideoWindowFullScreenMode fullscreen_mode; NSOpenGLContext * opengl_context; NSOpenGLContext * fullScreenContext; @@ -45,12 +45,17 @@ typedef enum { - (void) drawRect: (NSRect) rect; - (void) goFullScreen: (XineVideoWindowFullScreenMode) mode; - (void) exitFullScreen; -- (int) isFullScreen; +- (BOOL) isFullScreen; - (void) reshape; - (void) initTextures; - (void) reloadTexture; - (char *) getTextureBuffer; -- (void) setVideoSizeInMainThread:(int)w height:(int)h; +- (void) setVideoSize:(NSSize)size; +- (void) setViewSizeInMainThread:(NSSize)size; +- (void) setNormalSize; +- (void) setHalfSize; +- (void) setDoubleSize; +- (NSSize) videoSize; /* Delegate methods */ - (id) delegate; @@ -61,20 +66,15 @@ typedef enum { @interface XineVideoWindow : NSWindow { int width, height; - int keepAspectRatio; + BOOL keepAspectRatio; XineOpenGLView *openGLView; } - (void) setContentSize: (NSSize) size; - (void) displayTexture; - (XineOpenGLView *) getGLView; -- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode; -- (void) exitFullScreen; -- (void) setNormalSize; -- (void) setHalfSize; -- (void) setDoubleSize; - (void) fitToScreen; -- (void) setKeepsAspectRatio: (int) i; +- (void) setKeepsAspectRatio: (BOOL) i; - (int) keepsAspectRatio; @end diff --git a/src/video_out/macosx/video_window.m b/src/video_out/macosx/video_window.m index 348f2e314..64ec864b1 100644 --- a/src/video_out/macosx/video_window.m +++ b/src/video_out/macosx/video_window.m @@ -35,13 +35,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; - (void) setContentSize: (NSSize) size { - width = size.width; - height = size.height; - - [openGLView setVideoSizeInMainThread: width height: height]; - - if (keepAspectRatio) - [self setAspectRatio: size]; + [openGLView setViewSizeInMainThread:size]; [super setContentSize: size]; } @@ -64,7 +58,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; [self setContentView: openGLView]; [self setTitle: @"xine video output"]; - keepAspectRatio = 0; + keepAspectRatio = NO; return self; } @@ -73,53 +67,9 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; return openGLView; } -- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode { - [openGLView goFullScreen: mode]; -} - -- (void) exitFullScreen { - [openGLView exitFullScreen]; -} - -- (void) setNormalSize { - NSSize size; - - if ([openGLView isFullScreen]) - return; - - size.width = width; - size.height = height; - - [super setContentSize: size]; -} - -- (void) setHalfSize { - NSSize size; - - if ([openGLView isFullScreen]) - return; - - size.width = width / 2; - size.height = height / 2; - - [super setContentSize: size]; -} - -- (void) setDoubleSize { - NSSize size; - - if ([openGLView isFullScreen]) - return; - - size.width = width * 2; - size.height = height * 2; - - [super setContentSize: size]; -} - - (void) fitToScreen { - NSSize size; - int screen_width, screen_height; + NSSize size, video_size; + float screen_width, screen_height; if ([openGLView isFullScreen]) return; @@ -127,24 +77,29 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; screen_width = CGDisplayPixelsWide (kCGDirectMainDisplay); screen_height = CGDisplayPixelsHigh (kCGDirectMainDisplay) - 40; - if (((float) screen_width / (float) screen_height) > ((float) width / (float) height)) { - size.width = (float) width * ((float) screen_height / (float) height); + video_size = [openGLView videoSize]; + + if ((screen_width / screen_height) > (video_size.width / video_size.height)) { + size.width = video_size.width * (screen_height / video_size.height); size.height = screen_height; } else { size.width = screen_width; - size.height = (float) height * ((float) screen_width / (float) width); + size.height = video_size.height * (screen_width / video_size.width); } [super setContentSize: size]; } -- (void) setKeepsAspectRatio: (int) i { - if (i) - [self setAspectRatio:NSMakeSize(width, height)]; - else +- (void) setKeepsAspectRatio: (BOOL) flag { + if (flag) { + NSSize size = [self frame].size; + [self setAspectRatio:size]; + } + else { [self setResizeIncrements:NSMakeSize(1.0, 1.0)]; - - keepAspectRatio = i; + } + + keepAspectRatio = flag; } - (int) keepsAspectRatio { @@ -177,6 +132,10 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; return YES; } +- (NSSize)videoSize { + return NSMakeSize(video_width, video_height); +} + - (void) displayTexture { if ([self lockFocusIfCanDraw]) { [self drawRect: [self bounds]]; @@ -216,10 +175,10 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; glClearColor (0.0, 0.0, 0.0, 0.0); i_texture = 0; - initDone = 0; - isFullScreen = 0; - width = frame.size.width; - height = frame.size.height; + initDone = NO; + isFullScreen = NO; + video_width = frame.size.width; + video_height = frame.size.height; texture_buffer = nil; [self initTextures]; @@ -237,6 +196,42 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; glViewport (0, 0, bounds.size.width, bounds.size.height); } +- (void) setNormalSize { + NSSize size; + + if (isFullScreen) + return; + + size.width = video_width; + size.height = video_height; + + [self setViewSizeInMainThread:size]; +} + +- (void) setHalfSize { + NSSize size; + + if (isFullScreen) + return; + + size.width = video_width / 2; + size.height = video_height / 2; + + [self setViewSizeInMainThread:size]; +} + +- (void) setDoubleSize { + NSSize size; + + if (isFullScreen) + return; + + size.width = video_width * 2; + size.height = video_height * 2; + + [self setViewSizeInMainThread:size]; +} + - (void) initTextures { [currentContext makeCurrentContext]; @@ -246,9 +241,11 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; glDeleteTextures (1, &i_texture); if (texture_buffer) - texture_buffer = realloc (texture_buffer, sizeof (char) * width * height * 2); + texture_buffer = realloc (texture_buffer, sizeof (char) * + video_width * video_height * 2); else - texture_buffer = malloc (sizeof (char) * width * height * 2); + texture_buffer = malloc (sizeof (char) * + video_width * video_height * 2); /* Create textures */ glGenTextures (1, &i_texture); @@ -281,11 +278,11 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, - width, height, 0, + video_width, video_height, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, texture_buffer); - initDone = 1; + initDone = YES; } - (void) reloadTexture { @@ -300,7 +297,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; * http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/TextureRange/MainOpenGLView.m.htm */ glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, - width, height, + video_width, video_height, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, texture_buffer); } @@ -313,27 +310,27 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; switch (fullscreen_mode) { case XINE_FULLSCREEN_OVERSCAN: - if (((float) fs_width / (float) fs_height) > ((float) width / (float) height)) { - w = (float) width * ((float) fs_height / (float) height); + if (((float) fs_width / (float) fs_height) > ((float) video_width / (float) video_height)) { + w = (float) video_width * ((float) fs_height / (float) video_height); h = fs_height; x = (fs_width - w) / 2; y = 0; } else { w = fs_width; - h = (float) height * ((float) fs_width / (float) width); + h = (float) video_height * ((float) fs_width / (float) video_width); x = 0; y = (fs_height - h) / 2; } break; case XINE_FULLSCREEN_CROP: - if (((float) fs_width / (float) fs_height) > ((float) width / (float) height)) { + if (((float) fs_width / (float) fs_height) > ((float) video_width / (float) video_height)) { w = fs_width; - h = (float) height * ((float) fs_width / (float) width); + h = (float) video_height * ((float) fs_width / (float) video_width); x = 0; y = (fs_height - h) / 2; } else { - w = (float) width * ((float) fs_height / (float) height); + w = (float) video_width * ((float) fs_height / (float) video_height); h = fs_height; x = (fs_width - w) / 2; y = 0; @@ -341,7 +338,8 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; break; } - printf ("MacOSX fullscreen mode: %dx%d => %dx%d @ %d,%d\n", width, height, w, h, x, y); + printf ("MacOSX fullscreen mode: %dx%d => %dx%d @ %d,%d\n", + video_width, video_height, w, h, x, y); glViewport (x, y, w, h); } @@ -394,11 +392,11 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; /* Redraw the last picture */ [self setNeedsDisplay: YES]; - isFullScreen = 1; + isFullScreen = YES; } - (void) exitFullScreen { - initDone = 0; + initDone = NO; currentContext = [self openGLContext]; /* Free current OpenGL context */ @@ -413,8 +411,8 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; /* Redraw the last picture */ [self setNeedsDisplay: YES]; - isFullScreen = 0; - initDone = 1; + isFullScreen = NO; + initDone = YES; } - (void) drawQuad { @@ -425,13 +423,13 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; glTexCoord2f (0.0, 0.0); glVertex2f (-f_x, f_y); /* Bottom left */ - glTexCoord2f (0.0, (float) height); + glTexCoord2f (0.0, (float) video_height); glVertex2f (-f_x, -f_y); /* Bottom right */ - glTexCoord2f ((float) width, (float) height); + glTexCoord2f ((float) video_width, (float) video_height); glVertex2f (f_x, -f_y); /* Top right */ - glTexCoord2f ((float) width, 0.0); + glTexCoord2f ((float) video_width, 0.0); glVertex2f (f_x, f_y); glEnd(); } @@ -465,74 +463,67 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification"; return texture_buffer; } -- (void) setVideoSizeInMainThread:(int)w height:(int)h +- (void) setVideoSize:(NSSize)size +{ + video_width = size.width; + video_height = size.height; +} + +- (void) setViewSizeInMainThread:(NSSize)size { /* create an autorelease pool, since we're running in a xine thread that * may not have a pool of its own */ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSSize size = NSMakeSize(w, h); NSValue *sizeWrapper = [NSValue valueWithBytes:&size objCType:@encode(NSSize)]; - [self performSelectorOnMainThread:@selector(setVideoSize:) + [self performSelectorOnMainThread:@selector(setViewSize:) withObject:sizeWrapper waitUntilDone:NO]; [pool release]; } -- (void) setVideoSize:(NSValue *)sizeWrapper +- (void) setViewSize:(NSValue *)sizeWrapper { - NSSize size; - int w, h; - - [sizeWrapper getValue:&size]; - w = size.width; - h = size.height; - - if (w != width || h != height) { - - NSSize newSize; - NSValue *newSizeWrapper; - - newSize.width = w; - newSize.height = h; - - /* If our delegate handles xineViewWillResize:toSize:, send the - * message to him; otherwise, just resize ourselves */ - if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)]) { - NSSize oldSize = NSMakeSize(width, height); - NSSize proposedSize = NSMakeSize(w, h); - newSize = [delegate xineViewWillResize:oldSize toSize:proposedSize]; - width = newSize.width; - height = newSize.height; - } else { - width = w; - height = h; - } - - /* Resize the window in the main (UI) thread */ - [self setFrameSize:size]; - [self setBoundsSize:size]; - - /* Post a notification that we resized and also notify our delegate */ - NSNotification *note = - [NSNotification notificationWithName:XineViewDidResizeNotification - object:self]; - [[NSNotificationCenter defaultCenter] postNotification:note]; - if ([delegate respondsToSelector:@selector(xineViewDidResize:)]) { - [delegate xineViewDidResize:note]; - } - - if (isFullScreen) - [self calcFullScreenAspect]; + NSSize proposedSize, newSize, currentSize; + + [sizeWrapper getValue:&proposedSize]; + newSize = proposedSize; + + currentSize = [self frame].size; + if (proposedSize.width == currentSize.width && + proposedSize.height == currentSize.height) { + return; } + /* If our delegate handles xineViewWillResize:toSize:, send the + * message to him; otherwise, just resize ourselves */ + if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)]) { + NSSize oldSize = [self frame].size; + newSize = [delegate xineViewWillResize:oldSize toSize:proposedSize]; + } + + [self setFrameSize:newSize]; + [self setBoundsSize:newSize]; + + /* Post a notification that we resized and also notify our delegate */ + NSNotification *note = + [NSNotification notificationWithName:XineViewDidResizeNotification + object:self]; + [[NSNotificationCenter defaultCenter] postNotification:note]; + if ([delegate respondsToSelector:@selector(xineViewDidResize:)]) { + [delegate xineViewDidResize:note]; + } + + if (isFullScreen) + [self calcFullScreenAspect]; + [self initTextures]; } -- (int) isFullScreen { +- (BOOL) isFullScreen { return isFullScreen; } diff --git a/src/video_out/video_out_macosx.m b/src/video_out/video_out_macosx.m index 04151c4a5..3585ed0af 100644 --- a/src/video_out/video_out_macosx.m +++ b/src/video_out/video_out_macosx.m @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_macosx.m,v 1.5 2004/06/19 04:11:53 athp Exp $ + * $Id: video_out_macosx.m,v 1.6 2004/06/19 15:25:01 athp Exp $ * * This output driver makes use of xine's objective-c video_output * classes located in the macosx folder. @@ -118,6 +118,8 @@ static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_fr if((frame->width != width) || (frame->height != height) || (frame->format != format)) { + NSSize video_size = NSMakeSize(width, height); + free_framedata(frame); frame->width = width; @@ -156,7 +158,8 @@ static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_fr } - [this->view setVideoSizeInMainThread:width height:height]; + [this->view setVideoSize:video_size]; + [this->view setViewSizeInMainThread:video_size]; if((format == XINE_IMGFMT_YV12 && (frame->vo_frame.base[0] == NULL |