mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
decoder: simplify acquisition/release of spare surface.
Introduce gst_vaapi_surface_proxy_new_from_pool() to allocate a new surface proxy from the context surface pool. This change also makes sure to retain the parent surface pool in the proxy. Besides, it was also totally useless to attach/detach parent context to VA surface each time we acquire/release it. Since the whole context owns all associated VA surfaces, we can mark this as such only once and for all.
This commit is contained in:
parent
e76089f98b
commit
e22a863084
7 changed files with 71 additions and 22 deletions
|
@ -401,6 +401,7 @@ gst_vaapi_context_get_profile
|
|||
gst_vaapi_context_set_profile
|
||||
gst_vaapi_context_get_entrypoint
|
||||
gst_vaapi_context_get_size
|
||||
gst_vaapi_context_get_surface_proxy
|
||||
gst_vaapi_context_get_surface
|
||||
gst_vaapi_context_get_surface_count
|
||||
gst_vaapi_context_put_surface
|
||||
|
@ -528,6 +529,7 @@ gst_vaapi_surface_proxy_get_surface
|
|||
gst_vaapi_surface_proxy_get_surface_id
|
||||
gst_vaapi_surface_proxy_get_user_data
|
||||
gst_vaapi_surface_proxy_new
|
||||
gst_vaapi_surface_proxy_new_from_pool
|
||||
gst_vaapi_surface_proxy_ref
|
||||
gst_vaapi_surface_proxy_replace
|
||||
gst_vaapi_surface_proxy_set_context
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "gstvaapisurface.h"
|
||||
#include "gstvaapisurface_priv.h"
|
||||
#include "gstvaapisurfacepool.h"
|
||||
#include "gstvaapisurfaceproxy.h"
|
||||
#include "gstvaapiimage.h"
|
||||
#include "gstvaapisubpicture.h"
|
||||
#include "gstvaapiminiobject.h"
|
||||
|
@ -503,6 +504,7 @@ gst_vaapi_context_create_surfaces(GstVaapiContext *context)
|
|||
);
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
gst_vaapi_surface_set_parent_context(surface, context);
|
||||
g_ptr_array_add(priv->surfaces, surface);
|
||||
if (!gst_vaapi_video_pool_add_object(priv->surfaces_pool, surface))
|
||||
return FALSE;
|
||||
|
@ -998,6 +1000,30 @@ gst_vaapi_context_get_size(
|
|||
*pheight = context->priv->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface_proxy:
|
||||
* @context: a #GstVaapiContext
|
||||
*
|
||||
* Acquires a free surface, wrapped into a #GstVaapiSurfaceProxy. The
|
||||
* returned surface will be automatically released when the proxy is
|
||||
* destroyed. So, it is enough to call gst_vaapi_surface_proxy_unref()
|
||||
* after usage.
|
||||
*
|
||||
* This function returns %NULL if there is no free surface available
|
||||
* in the pool. The surfaces are pre-allocated during context creation
|
||||
* though.
|
||||
*
|
||||
* Return value: a free surface, or %NULL if none is available
|
||||
*/
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_context_get_surface_proxy(GstVaapiContext *context)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
||||
|
||||
return gst_vaapi_surface_proxy_new_from_pool(
|
||||
GST_VAAPI_SURFACE_POOL(context->priv->surfaces_pool));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_context_get_surface:
|
||||
* @context: a #GstVaapiContext
|
||||
|
@ -1012,16 +1038,9 @@ gst_vaapi_context_get_size(
|
|||
GstVaapiSurface *
|
||||
gst_vaapi_context_get_surface(GstVaapiContext *context)
|
||||
{
|
||||
GstVaapiSurface *surface;
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
|
||||
|
||||
surface = gst_vaapi_video_pool_get_object(context->priv->surfaces_pool);
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
gst_vaapi_surface_set_parent_context(surface, context);
|
||||
return surface;
|
||||
return gst_vaapi_video_pool_get_object(context->priv->surfaces_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1053,7 +1072,6 @@ gst_vaapi_context_put_surface(GstVaapiContext *context, GstVaapiSurface *surface
|
|||
g_return_if_fail(GST_VAAPI_IS_CONTEXT(context));
|
||||
g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
|
||||
|
||||
gst_vaapi_surface_set_parent_context(surface, NULL);
|
||||
gst_vaapi_video_pool_put_object(context->priv->surfaces_pool, surface);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,6 +143,9 @@ gst_vaapi_context_get_size(
|
|||
guint *pheight
|
||||
);
|
||||
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_context_get_surface_proxy(GstVaapiContext *context);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_context_get_surface(GstVaapiContext *context);
|
||||
|
||||
|
|
|
@ -75,10 +75,6 @@ gst_vaapi_picture_destroy(GstVaapiPicture *picture)
|
|||
gst_vaapi_surface_proxy_unref(picture->proxy);
|
||||
picture->proxy = NULL;
|
||||
}
|
||||
else if (picture->surface) {
|
||||
/* Explicitly release any surface that was not bound to a proxy */
|
||||
gst_vaapi_context_put_surface(GET_CONTEXT(picture), picture->surface);
|
||||
}
|
||||
picture->surface_id = VA_INVALID_ID;
|
||||
picture->surface = NULL;
|
||||
|
||||
|
@ -103,7 +99,6 @@ gst_vaapi_picture_create(
|
|||
GstVaapiPicture * const parent_picture = GST_VAAPI_PICTURE(args->data);
|
||||
|
||||
picture->proxy = gst_vaapi_surface_proxy_ref(parent_picture->proxy);
|
||||
picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy);
|
||||
picture->type = parent_picture->type;
|
||||
picture->pts = parent_picture->pts;
|
||||
picture->poc = parent_picture->poc;
|
||||
|
@ -137,18 +132,15 @@ gst_vaapi_picture_create(
|
|||
picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
|
||||
picture->pts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture));
|
||||
if (!picture->surface)
|
||||
return FALSE;
|
||||
|
||||
picture->proxy =
|
||||
gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface);
|
||||
gst_vaapi_context_get_surface_proxy(GET_CONTEXT(picture));
|
||||
if (!picture->proxy)
|
||||
return FALSE;
|
||||
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_FF);
|
||||
}
|
||||
picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy);
|
||||
picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
|
||||
|
||||
picture->param_id = VA_INVALID_ID;
|
||||
|
|
|
@ -140,6 +140,7 @@ typedef enum {
|
|||
typedef struct _GstVaapiSurface GstVaapiSurface;
|
||||
typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate;
|
||||
typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass;
|
||||
typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy;
|
||||
|
||||
/**
|
||||
* GstVaapiSurface:
|
||||
|
|
|
@ -43,6 +43,7 @@ struct _GstVaapiSurfaceProxy {
|
|||
/*< private >*/
|
||||
GstVaapiMiniObject parent_instance;
|
||||
|
||||
GstVaapiVideoPool *pool;
|
||||
GstVaapiContext *context;
|
||||
GstVaapiSurface *surface;
|
||||
};
|
||||
|
@ -87,11 +88,37 @@ gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface)
|
|||
if (!proxy)
|
||||
return NULL;
|
||||
|
||||
proxy->pool = NULL;
|
||||
proxy->context = g_object_ref(context);
|
||||
proxy->surface = g_object_ref(surface);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
|
||||
{
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL);
|
||||
|
||||
proxy = (GstVaapiSurfaceProxy *)
|
||||
gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class());
|
||||
if (!proxy)
|
||||
return NULL;
|
||||
|
||||
proxy->pool = g_object_ref(pool);
|
||||
proxy->context = NULL;
|
||||
proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool);
|
||||
if (!proxy->surface)
|
||||
goto error;
|
||||
g_object_ref(proxy->surface);
|
||||
return proxy;
|
||||
|
||||
error:
|
||||
gst_vaapi_surface_proxy_unref(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_surface_proxy_ref:
|
||||
* @proxy: a #GstVaapiSurfaceProxy
|
||||
|
@ -272,12 +299,16 @@ gst_vaapi_surface_proxy_set_surface(
|
|||
g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
|
||||
|
||||
if (proxy->surface) {
|
||||
if (proxy->context)
|
||||
if (proxy->pool)
|
||||
gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
|
||||
else if (proxy->context)
|
||||
gst_vaapi_context_put_surface(proxy->context, proxy->surface);
|
||||
g_object_unref(proxy->surface);
|
||||
proxy->surface = NULL;
|
||||
}
|
||||
|
||||
g_clear_object(&proxy->pool);
|
||||
|
||||
if (surface)
|
||||
proxy->surface = g_object_ref(surface);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
|
||||
#include <gst/vaapi/gstvaapicontext.h>
|
||||
#include <gst/vaapi/gstvaapisurface.h>
|
||||
#include <gst/vaapi/gstvaapisurfacepool.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy;
|
||||
|
||||
/**
|
||||
* GST_VAAPI_SURFACE_PROXY_SURFACE:
|
||||
* @surface: a #GstVaapiSurfaceProxy
|
||||
|
@ -42,6 +41,9 @@ typedef struct _GstVaapiSurfaceProxy GstVaapiSurfaceProxy;
|
|||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface);
|
||||
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool);
|
||||
|
||||
GstVaapiSurfaceProxy *
|
||||
gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy);
|
||||
|
||||
|
|
Loading…
Reference in a new issue