vaapidecode: add support for VideoAlignment bufferpool option.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 25 Jul 2014 13:52:06 +0000 (15:52 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 25 Jul 2014 13:52:06 +0000 (15:52 +0200)
Always add VideoAlignment bufferpool option if the downstream element
expects its own pool to be used but does not offer it through a proper
propose_allocation() implementation for instance, and that the ALLOCATION
query does not expose the availability of the Video Meta API.

This fixes propagation of video buffer stride information to Firefox.

gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapivideobufferpool.c

index 848290f..b5f7a40 100644 (file)
@@ -516,6 +516,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
     guint size, min, max;
     gboolean need_pool, update_pool;
     gboolean has_video_meta = FALSE;
+    gboolean has_video_alignment = FALSE;
     GstVideoCodecState *state;
 #if GST_CHECK_VERSION(1,1,0) && USE_GLX
     gboolean has_texture_upload_meta = FALSE;
@@ -572,6 +573,11 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
         gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max);
         size = MAX(size, vi.size);
         update_pool = TRUE;
+
+        /* Check whether downstream element proposed a bufferpool but did
+           not provide a correct propose_allocation() implementation */
+        has_video_alignment = gst_buffer_pool_has_option(pool,
+            GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
     }
     else {
         pool = NULL;
@@ -609,6 +615,12 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
 #endif
         gst_buffer_pool_set_config(pool, config);
     }
+    else if (has_video_alignment) {
+        config = gst_buffer_pool_get_config(pool);
+        gst_buffer_pool_config_add_option(config,
+            GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
+        gst_buffer_pool_set_config(pool, config);
+    }
 
     if (update_pool)
         gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max);
index 894ba6b..fe5c2a3 100644 (file)
@@ -47,6 +47,7 @@ struct _GstVaapiVideoBufferPoolPrivate {
     GstAllocator       *allocator;
     GstVaapiDisplay    *display;
     guint               has_video_meta          : 1;
+    guint               has_video_alignment     : 1;
     guint               has_texture_upload_meta : 1;
 };
 
@@ -101,6 +102,19 @@ gst_vaapi_video_buffer_pool_get_property(GObject *object, guint prop_id,
     }
 }
 
+static void
+fill_video_alignment(GstVaapiVideoBufferPool *pool, GstVideoAlignment *align)
+{
+    GstVideoInfo * const vip =
+        &GST_VAAPI_VIDEO_ALLOCATOR_CAST(pool->priv->allocator)->image_info;
+    guint i;
+
+    gst_video_alignment_reset(align);
+    for (i = 0; i < GST_VIDEO_INFO_N_PLANES(vip); i++)
+        align->stride_align[i] =
+            (1U << g_bit_nth_lsf(GST_VIDEO_INFO_PLANE_STRIDE(vip, i), 0)) - 1;
+}
+
 static const gchar **
 gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool)
 {
@@ -108,6 +122,7 @@ gst_vaapi_video_buffer_pool_get_options(GstBufferPool *pool)
         GST_BUFFER_POOL_OPTION_VIDEO_META,
         GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META,
         GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META,
+        GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT,
         NULL,
     };
     return g_options;
@@ -122,6 +137,7 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool,
     GstCaps *caps = NULL;
     GstVideoInfo * const cur_vip = &priv->video_info[priv->video_info_index];
     GstVideoInfo * const new_vip = &priv->video_info[!priv->video_info_index];
+    GstVideoAlignment align;
     GstAllocator *allocator;
     gboolean changed_caps;
 
@@ -152,6 +168,13 @@ gst_vaapi_video_buffer_pool_set_config(GstBufferPool *pool,
     priv->has_video_meta = gst_buffer_pool_config_has_option(config,
         GST_BUFFER_POOL_OPTION_VIDEO_META);
 
+    priv->has_video_alignment = gst_buffer_pool_config_has_option(config,
+        GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
+    if (priv->has_video_alignment) {
+        fill_video_alignment(GST_VAAPI_VIDEO_BUFFER_POOL(pool), &align);
+        gst_buffer_pool_config_set_video_alignment(config, &align);
+    }
+
     priv->has_texture_upload_meta = gst_buffer_pool_config_has_option(config,
         GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);