From c8f2358479c89106e5ec25c1fed7c633d1a594d4 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Tue, 28 Aug 2012 02:45:22 -0400 Subject: [PATCH] vaapisink: add video rotation support. Signed-off-by: Gwenole Beauchesne --- gst/vaapi/gstvaapisink.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++- gst/vaapi/gstvaapisink.h | 3 ++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index fea9e56..c4b6260 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #if USE_DRM # include @@ -104,10 +105,12 @@ enum { PROP_DISPLAY_TYPE, PROP_FULLSCREEN, PROP_SYNCHRONOUS, - PROP_USE_REFLECTION + PROP_USE_REFLECTION, + PROP_ROTATION, }; #define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY +#define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 /* GstImplementsInterface interface */ @@ -312,6 +315,9 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink) gst_vaapi_display_get_render_mode(sink->display, &render_mode) && render_mode == GST_VAAPI_RENDER_MODE_OVERLAY; GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture"); + + sink->use_rotation = gst_vaapi_display_has_property( + sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION); } return TRUE; } @@ -462,6 +468,45 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id) #endif static gboolean +gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect) +{ + gboolean success = FALSE; + + g_return_val_if_fail(sink->display, FALSE); + + if (sink->rotation == sink->rotation_req) + return TRUE; + + if (!sink->use_rotation) { + GST_WARNING("VA display does not support rotation"); + goto end; + } + + gst_vaapi_display_lock(sink->display); + success = gst_vaapi_display_set_rotation(sink->display, sink->rotation_req); + gst_vaapi_display_unlock(sink->display); + if (!success) { + GST_ERROR("failed to change VA display rotation mode"); + goto end; + } + + if (((sink->rotation + sink->rotation_req) % 180) == 90) { + /* Orientation changed */ + G_PRIMITIVE_SWAP(guint, sink->video_width, sink->video_height); + G_PRIMITIVE_SWAP(gint, sink->video_par_n, sink->video_par_d); + } + + if (recalc_display_rect && !sink->foreign_window) + gst_vaapisink_ensure_render_rect(sink, sink->window_width, + sink->window_height); + success = TRUE; + +end: + sink->rotation = sink->rotation_req; + return success; +} + +static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { GstVaapiSink * const sink = GST_VAAPISINK(base_sink); @@ -513,6 +558,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapisink_ensure_display(sink)) return FALSE; + gst_vaapisink_ensure_rotation(sink, FALSE); + gst_vaapi_display_get_size(sink->display, &display_width, &display_height); if (sink->foreign_window) { win_width = sink->window_width; @@ -740,6 +787,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer) if (!sink->window) return GST_FLOW_UNEXPECTED; + gst_vaapisink_ensure_rotation(sink, TRUE); + surface = gst_vaapi_video_buffer_get_surface(vbuffer); if (!surface) return GST_FLOW_UNEXPECTED; @@ -827,6 +876,9 @@ gst_vaapisink_set_property( case PROP_USE_REFLECTION: sink->use_reflection = g_value_get_boolean(value); break; + case PROP_ROTATION: + sink->rotation_req = g_value_get_enum(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -856,6 +908,9 @@ gst_vaapisink_get_property( case PROP_USE_REFLECTION: g_value_set_boolean(value, sink->use_reflection); break; + case PROP_ROTATION: + g_value_set_enum(value, sink->rotation); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -940,6 +995,21 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass) "Toggles X display synchronous mode", FALSE, G_PARAM_READWRITE)); + + /** + * GstVaapiSink:rotation: + * + * The VA display rotation mode, expressed as a #GstVaapiRotation. + */ + g_object_class_install_property + (object_class, + PROP_ROTATION, + g_param_spec_enum(GST_VAAPI_DISPLAY_PROP_ROTATION, + "rotation", + "The display rotation mode", + GST_VAAPI_TYPE_ROTATION, + DEFAULT_ROTATION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -960,6 +1030,9 @@ gst_vaapisink_init(GstVaapiSink *sink) sink->fullscreen = FALSE; sink->synchronous = FALSE; sink->display_type = DEFAULT_DISPLAY_TYPE; + sink->rotation = DEFAULT_ROTATION; + sink->rotation_req = DEFAULT_ROTATION; sink->use_reflection = FALSE; sink->use_overlay = FALSE; + sink->use_rotation = FALSE; } diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index eae1665..a2e8bff 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -80,11 +80,14 @@ struct _GstVaapiSink { gint video_par_n; gint video_par_d; GstVaapiRectangle display_rect; + GstVaapiRotation rotation; + GstVaapiRotation rotation_req; guint foreign_window : 1; guint fullscreen : 1; guint synchronous : 1; guint use_reflection : 1; guint use_overlay : 1; + guint use_rotation : 1; }; struct _GstVaapiSinkClass { -- 2.7.4