diff --git a/sys/osxvideo/cocoawindow.h b/sys/osxvideo/cocoawindow.h index 04f64c8229..049bb5f9ee 100644 --- a/sys/osxvideo/cocoawindow.h +++ b/sys/osxvideo/cocoawindow.h @@ -43,6 +43,7 @@ struct _GstOSXImage; char* data; int width, height; BOOL fullscreen; + BOOL keepAspectRatio; NSOpenGLContext* fullScreenContext; NSOpenGLContext* actualContext; NSTrackingArea *trackingArea; @@ -57,6 +58,7 @@ struct _GstOSXImage; - (void) displayTexture; - (char*) getTextureBuffer; - (void) setFullScreen: (BOOL) flag; +- (void) setKeepAspectRatio: (BOOL) flag; - (void) reshape; - (void) setVideoSize: (int) w: (int) h; - (BOOL) haveSuperview; diff --git a/sys/osxvideo/cocoawindow.m b/sys/osxvideo/cocoawindow.m index 543d5cdd8b..b41b20d0d2 100644 --- a/sys/osxvideo/cocoawindow.m +++ b/sys/osxvideo/cocoawindow.m @@ -142,6 +142,9 @@ - (void) reshape { NSRect bounds; + gdouble frame_par, view_par; + gint view_height, view_width, c_height, c_width, c_x, c_y; + GST_LOG ("reshaping"); @@ -152,9 +155,32 @@ [actualContext makeCurrentContext]; bounds = [self bounds]; + view_width = bounds.size.width; + view_height = bounds.size.height; - glViewport (0, 0, (GLint) bounds.size.width, (GLint) bounds.size.height); + frame_par = (gdouble) width / height; + view_par = (gdouble) view_width / view_height; + if (!keepAspectRatio) + view_par = frame_par; + if (frame_par == view_par) { + c_height = view_height; + c_width = view_width; + c_x = 0; + c_y = 0; + } else if (frame_par < view_par) { + c_height = view_height; + c_width = c_height * frame_par; + c_x = (view_width - c_width) / 2; + c_y = 0; + } else { + c_width = view_width; + c_height = c_width / frame_par; + c_x = 0; + c_y = (view_height - c_height) / 2; + } + + glViewport (c_x, c_y, (GLint) c_width, (GLint) c_height); } - (void) initTextures { @@ -374,6 +400,12 @@ // data = g_malloc0 (2 * w * h); [self initTextures]; + [self reshape]; +} + +- (void) setKeepAspectRatio: (BOOL) flag { + keepAspectRatio = flag; + [self reshape]; } - (void) haveSuperviewReal:(NSMutableArray *)closure { diff --git a/sys/osxvideo/osxvideosink.h b/sys/osxvideo/osxvideosink.h index 4a68b13378..6c65ee9e21 100644 --- a/sys/osxvideo/osxvideosink.h +++ b/sys/osxvideo/osxvideosink.h @@ -76,6 +76,7 @@ struct _GstOSXVideoSink { void *osxvideosinkobject; NSView *superview; guint cocoa_timeout; + gboolean keep_par; }; struct _GstOSXVideoSinkClass { diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m index 9fbe53358b..eaa531d010 100644 --- a/sys/osxvideo/osxvideosink.m +++ b/sys/osxvideo/osxvideosink.m @@ -66,6 +66,7 @@ enum { ARG_0, ARG_EMBED, + ARG_FORCE_PAR, }; static void gst_osx_video_sink_osxwindow_destroy (GstOSXVideoSink * osxvideosink); @@ -278,6 +279,7 @@ gst_osx_video_sink_osxwindow_create (GstOSXVideoSink * osxvideosink, gint width, } } [osxwindow->gstview setNavigation: GST_NAVIGATION(osxvideosink)]; + [osxvideosink->osxwindow->gstview setKeepAspectRatio: osxvideosink->keep_par]; [pool release]; @@ -446,6 +448,12 @@ gst_osx_video_sink_set_property (GObject * object, guint prop_id, case ARG_EMBED: /* Ignore, just here for backwards compatibility */ break; + case ARG_FORCE_PAR: + osxvideosink->keep_par = g_value_get_boolean(value); + if (osxvideosink->osxwindow) + [osxvideosink->osxwindow->gstview + setKeepAspectRatio: osxvideosink->keep_par]; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -466,6 +474,9 @@ gst_osx_video_sink_get_property (GObject * object, guint prop_id, case ARG_EMBED: g_value_set_boolean (value, TRUE); break; + case ARG_FORCE_PAR: + g_value_set_boolean (value, osxvideosink->keep_par); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -481,6 +492,7 @@ gst_osx_video_sink_init (GstOSXVideoSink * osxvideosink) osxvideosink->osxvideosinkobject = [[GstOSXVideoSinkObject alloc] initWithSink:osxvideosink]; osxvideosink->app_started = FALSE; + osxvideosink->keep_par = FALSE; } static void @@ -543,6 +555,18 @@ gst_osx_video_sink_class_init (GstOSXVideoSinkClass * klass) g_object_class_install_property (gobject_class, ARG_EMBED, g_param_spec_boolean ("embed", "embed", "For ABI compatiblity only, do not use", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstOSXVideoSink:force-aspect-ratio + * + * When enabled, scaling will respect original aspect ratio. + * + **/ + + g_object_class_install_property (gobject_class, ARG_FORCE_PAR, + g_param_spec_boolean ("force-aspect-ratio", "force aspect ration", + "When enabled, scaling will respect original aspect ration", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static gboolean