mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
libs: window: add gst_vaapi_window_vpp_convert_internal()
If a backend doesn't support specific format, we can use vpp for conversion and make it playing. This api is originated from GstVaapiWindowWayland and moved to GstVaapiWindow, so that GstVaapiWindowX11 could use it. https://bugzilla.gnome.org/show_bug.cgi?id=759533
This commit is contained in:
parent
4752f68a37
commit
ccfbca733d
2 changed files with 117 additions and 0 deletions
|
@ -57,6 +57,60 @@ gst_vaapi_window_ensure_size (GstVaapiWindow * window)
|
|||
window->height == window->display_height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_filter (GstVaapiWindow * window)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window);
|
||||
|
||||
/* Ensure VPP pipeline is built */
|
||||
if (window->filter)
|
||||
return TRUE;
|
||||
|
||||
window->filter = gst_vaapi_filter_new (display);
|
||||
if (!window->filter)
|
||||
goto error_create_filter;
|
||||
if (!gst_vaapi_filter_set_format (window->filter, window->surface_format))
|
||||
goto error_unsupported_format;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error_create_filter:
|
||||
{
|
||||
GST_WARNING ("failed to create VPP filter. Disabling");
|
||||
window->has_vpp = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
error_unsupported_format:
|
||||
{
|
||||
GST_ERROR ("unsupported render target format %s",
|
||||
gst_vaapi_video_format_to_string (window->surface_format));
|
||||
window->has_vpp = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_filter_surface_pool (GstVaapiWindow * window)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window);
|
||||
|
||||
if (window->surface_pool)
|
||||
goto ensure_filter;
|
||||
|
||||
/* Ensure VA surface pool is created */
|
||||
/* XXX: optimize the surface format to use. e.g. YUY2 */
|
||||
window->surface_pool = gst_vaapi_surface_pool_new (display,
|
||||
window->surface_format, window->width, window->height);
|
||||
if (!window->surface_pool) {
|
||||
GST_WARNING ("failed to create surface pool for conversion");
|
||||
return FALSE;
|
||||
}
|
||||
gst_vaapi_filter_replace (&window->filter, NULL);
|
||||
|
||||
ensure_filter:
|
||||
return ensure_filter (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height)
|
||||
{
|
||||
|
@ -77,6 +131,8 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height)
|
|||
static void
|
||||
gst_vaapi_window_finalize (GstVaapiWindow * window)
|
||||
{
|
||||
gst_vaapi_video_pool_replace (&window->surface_pool, NULL);
|
||||
gst_vaapi_filter_replace (&window->filter, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -112,6 +168,10 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class,
|
|||
|
||||
window->use_foreign_window = id != GST_VAAPI_ID_INVALID;
|
||||
GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0;
|
||||
window->surface_format = GST_VIDEO_FORMAT_ENCODED;
|
||||
window->has_vpp =
|
||||
GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window));
|
||||
|
||||
if (!gst_vaapi_window_create (window, width, height))
|
||||
goto error;
|
||||
return window;
|
||||
|
@ -124,6 +184,48 @@ error:
|
|||
}
|
||||
}
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window,
|
||||
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect,
|
||||
const GstVaapiRectangle * dst_rect, guint flags)
|
||||
{
|
||||
GstVaapiSurface *vpp_surface = NULL;
|
||||
GstVaapiFilterStatus status;
|
||||
|
||||
if (!window->has_vpp)
|
||||
return NULL;
|
||||
|
||||
if (!ensure_filter_surface_pool (window))
|
||||
return NULL;
|
||||
|
||||
if (src_rect)
|
||||
if (!gst_vaapi_filter_set_cropping_rectangle (window->filter, src_rect))
|
||||
return NULL;
|
||||
if (dst_rect)
|
||||
if (!gst_vaapi_filter_set_target_rectangle (window->filter, dst_rect))
|
||||
return NULL;
|
||||
|
||||
/* Post-process the decoded source surface */
|
||||
vpp_surface = gst_vaapi_video_pool_get_object (window->surface_pool);
|
||||
if (!vpp_surface)
|
||||
return NULL;
|
||||
|
||||
status =
|
||||
gst_vaapi_filter_process (window->filter, surface, vpp_surface, flags);
|
||||
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
|
||||
goto error_process_filter;
|
||||
return vpp_surface;
|
||||
|
||||
/* ERRORS */
|
||||
error_process_filter:
|
||||
{
|
||||
GST_ERROR ("failed to process surface %" GST_VAAPI_ID_FORMAT " (error %d)",
|
||||
GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (surface)), status);
|
||||
gst_vaapi_video_pool_put_object (window->surface_pool, vpp_surface);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
|
@ -389,6 +491,8 @@ gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height)
|
|||
if (!GST_VAAPI_WINDOW_GET_CLASS (window)->resize (window, width, height))
|
||||
return;
|
||||
|
||||
gst_vaapi_video_pool_replace (&window->surface_pool, NULL);
|
||||
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#define GST_VAAPI_WINDOW_PRIV_H
|
||||
|
||||
#include "gstvaapiobject_priv.h"
|
||||
#include "gstvaapifilter.h"
|
||||
#include "gstvaapisurfacepool.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -75,6 +77,12 @@ struct _GstVaapiWindow
|
|||
guint use_foreign_window:1;
|
||||
guint is_fullscreen:1;
|
||||
guint check_geometry:1;
|
||||
|
||||
/* for conversion */
|
||||
GstVideoFormat surface_format;
|
||||
GstVaapiVideoPool *surface_pool;
|
||||
GstVaapiFilter *filter;
|
||||
gboolean has_vpp;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -120,6 +128,11 @@ GstVaapiWindow *
|
|||
gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class,
|
||||
GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window,
|
||||
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect,
|
||||
const GstVaapiRectangle * dst_rect, guint flags);
|
||||
|
||||
void
|
||||
gst_vaapi_window_class_init (GstVaapiWindowClass * klass);
|
||||
|
||||
|
|
Loading…
Reference in a new issue