decoder: propagate MVC metadata ("view-id", head of multiview set).
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapisurfaceproxy.c
index 86168eb..ab8f508 100644 (file)
@@ -2,7 +2,9 @@
  *  gstvaapisurfaceproxy.c - VA surface proxy
  *
  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
- *  Copyright (C) 2011-2012 Intel Corporation
+ *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
+ *  Copyright (C) 2011-2014 Intel Corporation
+ *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public License
 static void
 gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy)
 {
-    if (proxy->destroy_func)
-        proxy->destroy_func(proxy->destroy_data);
-
     if (proxy->surface) {
-        if (proxy->pool)
+        if (proxy->pool && !proxy->parent)
             gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
         gst_vaapi_object_unref(proxy->surface);
         proxy->surface = NULL;
     }
     gst_vaapi_video_pool_replace(&proxy->pool, NULL);
+    gst_vaapi_surface_proxy_replace(&proxy->parent, NULL);
+
+    /* Notify the user function that the object is now destroyed */
+    if (proxy->destroy_func)
+        proxy->destroy_func(proxy->destroy_data);
 }
 
 static inline const GstVaapiMiniObjectClass *
@@ -58,25 +62,39 @@ gst_vaapi_surface_proxy_class(void)
     return &GstVaapiSurfaceProxyClass;
 }
 
+/**
+ * gst_vaapi_surface_proxy_new_from_pool:
+ * @pool: a #GstVaapiSurfacePool
+ *
+ * Allocates a new surface from the supplied surface @pool and creates
+ * the wrapped surface proxy object from it. When the last reference
+ * to the proxy object is released, then the underlying VA surface is
+ * pushed back to its parent pool.
+ *
+ * Returns: The same newly allocated @proxy object, or %NULL on error
+ */
 GstVaapiSurfaceProxy *
 gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
 {
     GstVaapiSurfaceProxy *proxy;
 
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL);
+    g_return_val_if_fail(pool != NULL, NULL);
 
     proxy = (GstVaapiSurfaceProxy *)
         gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class());
     if (!proxy)
         return NULL;
 
+    proxy->parent = NULL;
+    proxy->destroy_func = NULL;
     proxy->pool = gst_vaapi_video_pool_ref(pool);
     proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool);
     if (!proxy->surface)
         goto error;
+    proxy->view_id = 0;
     proxy->timestamp = GST_CLOCK_TIME_NONE;
     proxy->duration = GST_CLOCK_TIME_NONE;
-    proxy->destroy_func = NULL;
+    proxy->has_crop_rect = FALSE;
     gst_vaapi_object_ref(proxy->surface);
     return proxy;
 
@@ -85,6 +103,48 @@ error:
     return NULL;
 }
 
+
+/**
+ * gst_vaapi_surface_proxy_copy:
+ * @proxy: the parent #GstVaapiSurfaceProxy
+ *
+ * Creates are new VA surface proxy object from the supplied parent
+ * @proxy object with the same initial information, e.g. timestamp,
+ * duration.
+ *
+ * Note: the destroy notify function is not copied into the new
+ * surface proxy object.
+ *
+ * Returns: The same newly allocated @proxy object, or %NULL on error
+ */
+GstVaapiSurfaceProxy *
+gst_vaapi_surface_proxy_copy(GstVaapiSurfaceProxy *proxy)
+{
+    GstVaapiSurfaceProxy *copy;
+
+    g_return_val_if_fail(proxy != NULL, NULL);
+
+    copy = (GstVaapiSurfaceProxy *)
+        gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class());
+    if (!copy)
+        return NULL;
+
+    GST_VAAPI_SURFACE_PROXY_FLAGS(copy) =
+        GST_VAAPI_SURFACE_PROXY_FLAGS(proxy);
+
+    copy->parent = gst_vaapi_surface_proxy_ref(proxy->parent ?
+        proxy->parent : proxy);
+    copy->pool = gst_vaapi_video_pool_ref(proxy->pool);
+    copy->surface = gst_vaapi_object_ref(proxy->surface);
+    copy->timestamp = proxy->timestamp;
+    copy->duration = proxy->duration;
+    copy->destroy_func = NULL;
+    copy->has_crop_rect = proxy->has_crop_rect;
+    if (copy->has_crop_rect)
+        copy->crop_rect = proxy->crop_rect;
+    return copy;
+}
+
 /**
  * gst_vaapi_surface_proxy_ref:
  * @proxy: a #GstVaapiSurfaceProxy
@@ -96,7 +156,7 @@ error:
 GstVaapiSurfaceProxy *
 gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
+    g_return_val_if_fail(proxy != NULL, NULL);
 
     return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref(
                                        GST_VAAPI_MINI_OBJECT(proxy)));
@@ -112,7 +172,7 @@ gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy)
 void
 gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
+    g_return_if_fail(proxy != NULL);
 
     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy));
 }
@@ -147,7 +207,7 @@ gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr,
 GstVaapiSurface *
 gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
+    g_return_val_if_fail(proxy != NULL, NULL);
 
     return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy);
 }
@@ -164,7 +224,7 @@ gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy)
 guint
 gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
+    g_return_val_if_fail(proxy != NULL, 0);
     
     return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy);
 }
@@ -180,13 +240,29 @@ gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy)
 GstVaapiID
 gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE);
-    g_return_val_if_fail(proxy->surface != NULL, GST_VAAPI_ID_NONE);
+    g_return_val_if_fail(proxy != NULL, VA_INVALID_ID);
+    g_return_val_if_fail(proxy->surface != NULL, VA_INVALID_ID);
 
     return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy);
 }
 
 /**
+ * gst_vaapi_surface_proxy_get_view_id:
+ * @proxy: a #GstVaapiSurfaceProxy
+ *
+ * Returns the decoded view-id stored in the @proxy.
+ *
+ * Return value: the #GstVaapiID
+ */
+guintptr
+gst_vaapi_surface_proxy_get_view_id(GstVaapiSurfaceProxy *proxy)
+{
+    g_return_val_if_fail(proxy != NULL, 0);
+
+    return GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy);
+}
+
+/**
  * gst_vaapi_surface_proxy_get_timestamp:
  * @proxy: a #GstVaapiSurfaceProxy
  *
@@ -197,7 +273,7 @@ gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy)
 GstClockTime
 gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
+    g_return_val_if_fail(proxy != NULL, 0);
     
     return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
 }
@@ -213,7 +289,7 @@ gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy)
 GstClockTime
 gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy)
 {
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
+    g_return_val_if_fail(proxy != NULL, 0);
     
     return GST_VAAPI_SURFACE_PROXY_DURATION(proxy);
 }
@@ -233,8 +309,48 @@ void
 gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy,
     GDestroyNotify destroy_func, gpointer user_data)
 {
-    g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
+    g_return_if_fail(proxy != NULL);
 
     proxy->destroy_func = destroy_func;
     proxy->destroy_data = user_data;
 }
+
+/**
+ * gst_vaapi_surface_proxy_get_crop_rect:
+ * @proxy: a #GstVaapiSurfaceProxy
+ *
+ * Returns the #GstVaapiRectangle stored in the @proxy and that
+ * represents the cropping rectangle for the underlying surface to be
+ * used for rendering.
+ *
+ * If no cropping rectangle was associated with the @proxy, then this
+ * function returns %NULL.
+ *
+ * Return value: the #GstVaapiRectangle, or %NULL if none was
+ *   associated with the surface proxy
+ */
+const GstVaapiRectangle *
+gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy)
+{
+    g_return_val_if_fail(proxy != NULL, NULL);
+
+    return GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy);
+}
+
+/**
+ * gst_vaapi_surface_proxy_set_crop_rect:
+ * @proxy: #GstVaapiSurfaceProxy
+ * @crop_rect: the #GstVaapiRectangle to be stored in @proxy
+ *
+ * Associates the @crop_rect with the @proxy
+ */
+void
+gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy,
+    const GstVaapiRectangle *crop_rect)
+{
+    g_return_if_fail(proxy != NULL);
+
+    proxy->has_crop_rect = crop_rect != NULL;
+    if (proxy->has_crop_rect)
+        proxy->crop_rect = *crop_rect;
+}