vaapisink: add support for GST_TAG_IMAGE_ORIENTATION
authorHyunjun Ko <zzoon@igalia.com>
Fri, 1 Jul 2016 07:00:46 +0000 (16:00 +0900)
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
Tue, 5 Jul 2016 18:17:12 +0000 (20:17 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=765798

gst-libs/gst/vaapi/gstvaapitypes.h
gst-libs/gst/vaapi/gstvaapivalue.c
gst/vaapi/gstvaapisink.c
gst/vaapi/gstvaapisink.h

index 33d7619..cf486a4 100644 (file)
@@ -128,12 +128,14 @@ typedef enum {
  * @GST_VAAPI_ROTATION_90: the VA display is rotated by 90°, clockwise.
  * @GST_VAAPI_ROTATION_180: the VA display is rotated by 180°, clockwise.
  * @GST_VAAPI_ROTATION_270: the VA display is rotated by 270°, clockwise.
+ * @GST_VAAPI_ROTATION_AUTOMATIC: the VA display is rotated by image-orientating tag.
  */
 typedef enum {
     GST_VAAPI_ROTATION_0   = 0,
     GST_VAAPI_ROTATION_90  = 90,
     GST_VAAPI_ROTATION_180 = 180,
     GST_VAAPI_ROTATION_270 = 270,
+    GST_VAAPI_ROTATION_AUTOMATIC = 360,
 } GstVaapiRotation;
 
 /**
index 5ca01ce..2185e7e 100644 (file)
@@ -113,6 +113,8 @@ gst_vaapi_rotation_get_type (void)
         "Rotated by 180°, clockwise", "180"},
     {GST_VAAPI_ROTATION_270,
         "Rotated by 270°, clockwise", "270"},
+    {GST_VAAPI_ROTATION_AUTOMATIC,
+        "Rotated by image-orientating tag°", "Automatic"},
     {0, NULL, NULL},
   };
 
index 472b873..68f21c0 100644 (file)
@@ -1114,6 +1114,26 @@ gst_vaapisink_ensure_colorbalance (GstVaapiSink * sink)
   return cb_sync_values_to_display (sink, GST_VAAPI_PLUGIN_BASE_DISPLAY (sink));
 }
 
+
+static void
+gst_vaapisink_set_rotation (GstVaapiSink * sink, GstVaapiRotation rotation,
+    gboolean from_tag)
+{
+  GST_OBJECT_LOCK (sink);
+
+  if (from_tag)
+    sink->rotation_tag = rotation;
+  else
+    sink->rotation_prop = rotation;
+
+  if (sink->rotation_prop == GST_VAAPI_ROTATION_AUTOMATIC)
+    sink->rotation_req = sink->rotation_tag;
+  else
+    sink->rotation_req = sink->rotation_prop;
+
+  GST_OBJECT_UNLOCK (sink);
+}
+
 static gboolean
 gst_vaapisink_ensure_rotation (GstVaapiSink * sink,
     gboolean recalc_display_rect)
@@ -1533,7 +1553,7 @@ gst_vaapisink_set_property (GObject * object,
       sink->view_id = g_value_get_int (value);
       break;
     case PROP_ROTATION:
-      sink->rotation_req = g_value_get_enum (value);
+      gst_vaapisink_set_rotation (sink, g_value_get_enum (value), FALSE);
       break;
     case PROP_FORCE_ASPECT_RATIO:
       sink->keep_aspect = g_value_get_boolean (value);
@@ -1616,6 +1636,51 @@ gst_vaapisink_unlock_stop (GstBaseSink * base_sink)
   return TRUE;
 }
 
+static gboolean
+gst_vaapisink_event (GstBaseSink * base_sink, GstEvent * event)
+{
+  gboolean res = TRUE;
+  GstTagList *taglist;
+  gchar *orientation;
+
+  GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink);
+
+  GST_DEBUG_OBJECT (sink, "handling event %s", GST_EVENT_TYPE_NAME (event));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_TAG:
+      gst_event_parse_tag (event, &taglist);
+
+      if (gst_tag_list_get_string (taglist, GST_TAG_IMAGE_ORIENTATION,
+              &orientation)) {
+        if (!g_strcmp0 ("rotate-0", orientation)) {
+          gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_0, TRUE);
+        } else if (!g_strcmp0 ("rotate-90", orientation)) {
+          gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_90, TRUE);
+        } else if (!g_strcmp0 ("rotate-180", orientation)) {
+          gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_180, TRUE);
+        } else if (!g_strcmp0 ("rotate-270", orientation)) {
+          gst_vaapisink_set_rotation (sink, GST_VAAPI_ROTATION_270, TRUE);
+        }
+
+        /* Do not support for flip yet.
+         * It should be implemented in the near future.
+         * See https://bugs.freedesktop.org/show_bug.cgi?id=90654
+         */
+        g_free (orientation);
+      }
+      break;
+    default:
+      break;
+  }
+
+  res =
+      GST_BASE_SINK_CLASS (gst_vaapisink_parent_class)->event (base_sink,
+      event);
+
+  return res;
+}
+
 static void
 gst_vaapisink_set_bus (GstElement * element, GstBus * bus)
 {
@@ -1659,6 +1724,7 @@ gst_vaapisink_class_init (GstVaapiSinkClass * klass)
   basesink_class->propose_allocation = gst_vaapisink_propose_allocation;
   basesink_class->unlock = gst_vaapisink_unlock;
   basesink_class->unlock_stop = gst_vaapisink_unlock_stop;
+  basesink_class->event = gst_vaapisink_event;
 
   videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame);
 
@@ -1829,6 +1895,7 @@ gst_vaapisink_init (GstVaapiSink * sink)
   sink->handle_events = TRUE;
   sink->rotation = DEFAULT_ROTATION;
   sink->rotation_req = DEFAULT_ROTATION;
+  sink->rotation_tag = DEFAULT_ROTATION;
   sink->keep_aspect = TRUE;
   sink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
   gst_video_info_init (&sink->video_info);
index 3ba3dfc..1fb6e83 100644 (file)
@@ -94,6 +94,8 @@ struct _GstVaapiSink
   GstVaapiRectangle display_rect;
   GstVaapiRotation rotation;
   GstVaapiRotation rotation_req;
+  GstVaapiRotation rotation_tag;
+  GstVaapiRotation rotation_prop;
   guint color_standard;
   gint32 view_id;
   GThread *event_thread;