mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
plugins: distinguish allocation and negotiation caps
The vaapi video decoders might have different allocation caps from the negotiation caps, thus the GstVideoMeta shall use the negotiation caps, not the allocation caps. This was done before reusing gst_allocator_get_vaapi_video_info(), storing there the negotiation caps if they differ from the allocation ones, but this strategy felt short when the allocator had to be reset in the vaapi buffer pool, since we need both. This patch adds gst_allocator_set_vaapi_negotiated_video_info() and gst_allocator_get_vaapi_negotiated_video_info() to store the negotiated video info in the allocator, and distinguish it from the allocation video info. https://bugzilla.gnome.org/show_bug.cgi?id=783599
This commit is contained in:
parent
36cf510ce8
commit
7a20692364
4 changed files with 98 additions and 40 deletions
|
@ -567,24 +567,10 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
|
|||
GstCaps * caps)
|
||||
{
|
||||
gboolean different_caps;
|
||||
GstVideoInfo vi;
|
||||
GstVaapiImageUsageFlags usage_flag =
|
||||
GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;
|
||||
|
||||
/* the received caps are the "allocation caps" which may be
|
||||
* different from the "negotiation caps". In this case, we should
|
||||
* indicate the allocator to store the negotiation caps since they
|
||||
* are the one should be used for frame mapping with GstVideoMeta */
|
||||
different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps &&
|
||||
!gst_caps_is_strictly_equal (plugin->srcpad_caps, caps);
|
||||
|
||||
if (different_caps) {
|
||||
vi = plugin->srcpad_info;
|
||||
} else {
|
||||
vi = *vinfo;
|
||||
}
|
||||
|
||||
if (!reset_allocator (plugin->srcpad_allocator, &vi))
|
||||
if (!reset_allocator (plugin->srcpad_allocator, vinfo))
|
||||
return TRUE;
|
||||
|
||||
plugin->srcpad_allocator = NULL;
|
||||
|
@ -609,22 +595,33 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
|
|||
if (!plugin->srcpad_allocator)
|
||||
goto error_create_allocator;
|
||||
|
||||
/* the received caps are the "allocation caps" which may be
|
||||
* different from the "negotiation caps". In this case, we should
|
||||
* indicate the allocator to store the negotiation caps since they
|
||||
* are the one should be used for frame mapping with GstVideoMeta */
|
||||
different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps &&
|
||||
!gst_caps_is_strictly_equal (plugin->srcpad_caps, caps);
|
||||
|
||||
if (different_caps) {
|
||||
guint i, flags = 0;
|
||||
const GstVideoInfo *alloc_vi =
|
||||
gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, &flags);
|
||||
/* update the planes and the size with the allocator image info,
|
||||
* but not the resolution */
|
||||
if (alloc_vi) {
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (alloc_vi); i++) {
|
||||
GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) =
|
||||
GST_VIDEO_INFO_PLANE_OFFSET (alloc_vi, i);
|
||||
GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) =
|
||||
GST_VIDEO_INFO_PLANE_STRIDE (alloc_vi, i);
|
||||
}
|
||||
GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (alloc_vi);
|
||||
gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, flags);
|
||||
guint i;
|
||||
GstVideoInfo vi = plugin->srcpad_info;
|
||||
const GstVideoInfo *image_info =
|
||||
gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL);
|
||||
|
||||
g_assert (image_info); /* both allocators should set its video
|
||||
* info */
|
||||
|
||||
/* update the planes and the size with the allocator image/surface
|
||||
* info, but not the resolution */
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) {
|
||||
GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) =
|
||||
GST_VIDEO_INFO_PLANE_OFFSET (image_info, i);
|
||||
GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) =
|
||||
GST_VIDEO_INFO_PLANE_STRIDE (image_info, i);
|
||||
}
|
||||
GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info);
|
||||
gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator,
|
||||
&vi);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -137,6 +137,7 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
|||
GstCaps *caps;
|
||||
GstVideoInfo new_allocation_vinfo;
|
||||
const GstVideoInfo *allocator_vinfo;
|
||||
const GstVideoInfo *negotiated_vinfo;
|
||||
GstVideoAlignment align;
|
||||
GstAllocator *allocator;
|
||||
gboolean ret, updated = FALSE;
|
||||
|
@ -176,9 +177,16 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
|||
gst_allocator_set_vaapi_video_info (allocator, &new_allocation_vinfo,
|
||||
surface_alloc_flags);
|
||||
} else if (!priv->use_dmabuf_memory && (vinfo_changed || !allocator)) {
|
||||
negotiated_vinfo =
|
||||
gst_allocator_get_vaapi_negotiated_video_info (allocator);
|
||||
|
||||
/* let's destroy the other allocator and create a new one */
|
||||
allocator = gst_vaapi_video_allocator_new (priv->display,
|
||||
&new_allocation_vinfo, surface_alloc_flags, 0);
|
||||
if (negotiated_vinfo) {
|
||||
gst_allocator_set_vaapi_negotiated_video_info (allocator,
|
||||
negotiated_vinfo);
|
||||
}
|
||||
gst_buffer_pool_config_set_allocator (config, allocator, NULL);
|
||||
gst_object_unref (allocator);
|
||||
}
|
||||
|
@ -197,11 +205,10 @@ gst_vaapi_video_buffer_pool_set_config (GstBufferPool * pool,
|
|||
gst_object_unref (priv->allocator);
|
||||
if ((priv->allocator = allocator))
|
||||
gst_object_ref (allocator);
|
||||
allocator_vinfo =
|
||||
gst_allocator_get_vaapi_video_info (priv->allocator, NULL);
|
||||
if (!allocator_vinfo)
|
||||
goto error_create_allocator_info;
|
||||
priv->vmeta_vinfo = *allocator_vinfo;
|
||||
negotiated_vinfo =
|
||||
gst_allocator_get_vaapi_negotiated_video_info (priv->allocator);
|
||||
priv->vmeta_vinfo = (negotiated_vinfo) ?
|
||||
*negotiated_vinfo : priv->allocation_vinfo;
|
||||
}
|
||||
if (GST_VIDEO_INFO_SIZE (&priv->vmeta_vinfo) != size) {
|
||||
gst_buffer_pool_config_set_params (config, caps,
|
||||
|
@ -273,12 +280,6 @@ error_no_vaapi_video_meta_option:
|
|||
GST_ERROR_OBJECT (pool, "no GstVaapiVideoMeta option in config");
|
||||
return FALSE;
|
||||
}
|
||||
error_create_allocator_info:
|
||||
{
|
||||
GST_ERROR_OBJECT (pool,
|
||||
"failed to create GstVaapiVideoAllocator `video-info'");
|
||||
return FALSE;
|
||||
}
|
||||
error_no_allocator:
|
||||
{
|
||||
GST_ERROR_OBJECT (pool, "no allocator defined");
|
||||
|
|
|
@ -1185,6 +1185,19 @@ surface_alloc_flags_quark_get (void)
|
|||
return g_quark;
|
||||
}
|
||||
|
||||
#define NEGOTIATED_VINFO_QUARK negotiated_vinfo_quark_get ()
|
||||
static GQuark
|
||||
negotiated_vinfo_quark_get (void)
|
||||
{
|
||||
static gsize g_quark;
|
||||
|
||||
if (g_once_init_enter (&g_quark)) {
|
||||
gsize quark = (gsize) g_quark_from_static_string ("negotiated-vinfo");
|
||||
g_once_init_leave (&g_quark, quark);
|
||||
}
|
||||
return g_quark;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_allocator_get_vaapi_video_info:
|
||||
* @allocator: a #GstAllocator
|
||||
|
@ -1254,6 +1267,44 @@ gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_allocator_set_vaapi_negotiated_video_info:
|
||||
* @allocator: a #GstAllocator
|
||||
* @negotiated_vinfo: the negotiated #GstVideoInfo to store
|
||||
*
|
||||
* Stores as GObject's qdata the @negotiated_vinfo in the allocator
|
||||
* instance.
|
||||
*
|
||||
* The @negotiated_vinfo is different of the @alloc_info from
|
||||
* gst_allocator_set_vaapi_video_info(), and might not be set.
|
||||
**/
|
||||
void
|
||||
gst_allocator_set_vaapi_negotiated_video_info (GstAllocator * allocator,
|
||||
const GstVideoInfo * negotiated_vinfo)
|
||||
{
|
||||
g_return_if_fail (allocator && GST_IS_ALLOCATOR (allocator));
|
||||
g_return_if_fail (negotiated_vinfo);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK,
|
||||
gst_video_info_copy (negotiated_vinfo),
|
||||
(GDestroyNotify) gst_video_info_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_allocator_get_vaapi_negotiated_video_info:
|
||||
* @allocator: a #GstAllocator
|
||||
*
|
||||
* Returns: the stored negotiation #GstVideoInfo, if it was stored
|
||||
* previously. Otherwise, %NULL
|
||||
**/
|
||||
GstVideoInfo *
|
||||
gst_allocator_get_vaapi_negotiated_video_info (GstAllocator * allocator)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_ALLOCATOR (allocator), NULL);
|
||||
|
||||
return g_object_get_qdata (G_OBJECT (allocator), NEGOTIATED_VINFO_QUARK);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_is_dmabuf_allocator:
|
||||
* @allocator: an #GstAllocator
|
||||
|
|
|
@ -278,6 +278,15 @@ gboolean
|
|||
gst_allocator_set_vaapi_video_info (GstAllocator * allocator,
|
||||
const GstVideoInfo * alloc_info, guint surface_alloc_flags);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void
|
||||
gst_allocator_set_vaapi_negotiated_video_info (GstAllocator * allocator,
|
||||
const GstVideoInfo * negotiated_vinfo);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVideoInfo *
|
||||
gst_allocator_get_vaapi_negotiated_video_info (GstAllocator * allocator);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean
|
||||
gst_vaapi_is_dmabuf_allocator (GstAllocator * allocator);
|
||||
|
|
Loading…
Reference in a new issue