mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-04 22:48:54 +00:00
vaapipostproc: use pooled vaapi video meta.
Use pooled GstVaapiVideoMeta information, i.e. always allocate that on video buffer allocation. Also optimize copy of additional metadata info into the resulting video buffer: only copy the video cropping info and the source surface proxy. https://bugzilla.gnome.org/show_bug.cgi?id=720311 Signed-off-by: Sreerenj Balachandran <sreerenj.balachandran@intel.com> [fixed proxy leak, fixed double free on error, optimized meta copy] Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
92fcb38ba6
commit
9ee46ab32e
2 changed files with 72 additions and 27 deletions
|
@ -261,8 +261,9 @@ gst_vaapipostproc_create(GstVaapiPostproc *postproc)
|
|||
return FALSE;
|
||||
if (!gst_vaapipostproc_ensure_uploader(postproc))
|
||||
return FALSE;
|
||||
if (gst_vaapipostproc_ensure_filter(postproc))
|
||||
postproc->use_vpp = TRUE;
|
||||
|
||||
postproc->use_vpp = FALSE;
|
||||
postproc->has_vpp = gst_vaapipostproc_ensure_filter(postproc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -359,7 +360,6 @@ create_output_buffer(GstVaapiPostproc *postproc)
|
|||
#if GST_CHECK_VERSION(1,0,0)
|
||||
GstBufferPool * const pool =
|
||||
GST_VAAPI_PLUGIN_BASE(postproc)->srcpad_buffer_pool;
|
||||
GstBufferPoolAcquireParams params = { 0, };
|
||||
GstFlowReturn ret;
|
||||
|
||||
g_return_val_if_fail(pool != NULL, NULL);
|
||||
|
@ -371,8 +371,7 @@ create_output_buffer(GstVaapiPostproc *postproc)
|
|||
}
|
||||
|
||||
outbuf = NULL;
|
||||
params.flags = GST_VAAPI_VIDEO_BUFFER_POOL_ACQUIRE_FLAG_NO_ALLOC;
|
||||
ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, ¶ms);
|
||||
ret = gst_buffer_pool_acquire_buffer(pool, &outbuf, NULL);
|
||||
if (ret != GST_FLOW_OK || !outbuf)
|
||||
goto error_create_buffer;
|
||||
#else
|
||||
|
@ -401,12 +400,43 @@ error_create_buffer:
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags)
|
||||
static gboolean
|
||||
append_output_buffer_metadata(GstVaapiPostproc *postproc, GstBuffer *outbuf,
|
||||
GstBuffer *inbuf, guint flags)
|
||||
{
|
||||
gst_buffer_copy_into(outbuf, inbuf, flags |
|
||||
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META | GST_BUFFER_COPY_MEMORY,
|
||||
0, -1);
|
||||
GstVaapiVideoMeta *inbuf_meta, *outbuf_meta;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
|
||||
gst_buffer_copy_into(outbuf, inbuf, flags | GST_BUFFER_COPY_FLAGS, 0, -1);
|
||||
|
||||
/* GstVideoCropMeta */
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
if (!postproc->use_vpp) {
|
||||
GstVideoCropMeta * const crop_meta =
|
||||
gst_buffer_get_video_crop_meta(inbuf);
|
||||
if (crop_meta) {
|
||||
GstVideoCropMeta * const out_crop_meta =
|
||||
gst_buffer_add_video_crop_meta(outbuf);
|
||||
if (out_crop_meta)
|
||||
*out_crop_meta = *crop_meta;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* GstVaapiVideoMeta */
|
||||
inbuf_meta = gst_buffer_get_vaapi_video_meta(inbuf);
|
||||
g_return_val_if_fail(inbuf_meta != NULL, FALSE);
|
||||
proxy = gst_vaapi_video_meta_get_surface_proxy(inbuf_meta);
|
||||
|
||||
outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf);
|
||||
g_return_val_if_fail(outbuf_meta != NULL, FALSE);
|
||||
proxy = gst_vaapi_surface_proxy_copy(proxy);
|
||||
if (!proxy)
|
||||
return FALSE;
|
||||
|
||||
gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy);
|
||||
gst_vaapi_surface_proxy_unref(proxy);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -467,6 +497,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
GstVaapiDeinterlaceState * const ds = &postproc->deinterlace_state;
|
||||
GstVaapiVideoMeta *inbuf_meta, *outbuf_meta;
|
||||
GstVaapiSurface *inbuf_surface, *outbuf_surface;
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
GstVaapiFilterStatus status;
|
||||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
|
@ -569,10 +600,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
if (!fieldbuf)
|
||||
goto error_create_buffer;
|
||||
|
||||
outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool);
|
||||
outbuf_meta = gst_buffer_get_vaapi_video_meta(fieldbuf);
|
||||
if (!outbuf_meta)
|
||||
goto error_create_meta;
|
||||
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
|
||||
|
||||
proxy = gst_vaapi_surface_proxy_new_from_pool(
|
||||
GST_VAAPI_SURFACE_POOL(postproc->filter_pool));
|
||||
if (!proxy)
|
||||
goto error_create_proxy;
|
||||
gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy);
|
||||
gst_vaapi_surface_proxy_unref(proxy);
|
||||
|
||||
if (deint) {
|
||||
deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0);
|
||||
|
@ -604,15 +641,13 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
goto error_op_deinterlace;
|
||||
}
|
||||
|
||||
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
|
||||
gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect);
|
||||
status = gst_vaapi_filter_process(postproc->filter, inbuf_surface,
|
||||
outbuf_surface, flags);
|
||||
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
|
||||
goto error_process_vpp;
|
||||
|
||||
gst_buffer_set_vaapi_video_meta(fieldbuf, outbuf_meta);
|
||||
gst_vaapi_video_meta_unref(outbuf_meta);
|
||||
|
||||
GST_BUFFER_TIMESTAMP(fieldbuf) = timestamp;
|
||||
GST_BUFFER_DURATION(fieldbuf) = postproc->field_duration;
|
||||
ret = gst_pad_push(trans->srcpad, fieldbuf);
|
||||
|
@ -622,10 +657,16 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
fieldbuf = NULL;
|
||||
|
||||
/* Second field */
|
||||
outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool);
|
||||
outbuf_meta = gst_buffer_get_vaapi_video_meta(outbuf);
|
||||
if (!outbuf_meta)
|
||||
goto error_create_meta;
|
||||
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
|
||||
|
||||
proxy = gst_vaapi_surface_proxy_new_from_pool(
|
||||
GST_VAAPI_SURFACE_POOL(postproc->filter_pool));
|
||||
if (!proxy)
|
||||
goto error_create_proxy;
|
||||
gst_vaapi_video_meta_set_surface_proxy(outbuf_meta, proxy);
|
||||
gst_vaapi_surface_proxy_unref(proxy);
|
||||
|
||||
if (deint) {
|
||||
deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD);
|
||||
|
@ -643,6 +684,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
postproc->filter, deint_method, 0))
|
||||
goto error_op_deinterlace;
|
||||
|
||||
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
|
||||
gst_vaapi_filter_set_cropping_rectangle(postproc->filter, crop_rect);
|
||||
status = gst_vaapi_filter_process(postproc->filter, inbuf_surface,
|
||||
outbuf_surface, flags);
|
||||
|
@ -655,11 +697,10 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
GST_BUFFER_TIMESTAMP(outbuf) = timestamp + postproc->field_duration;
|
||||
GST_BUFFER_DURATION(outbuf) = postproc->field_duration;
|
||||
}
|
||||
gst_buffer_set_vaapi_video_meta(outbuf, outbuf_meta);
|
||||
gst_vaapi_video_meta_unref(outbuf_meta);
|
||||
|
||||
if (deint && deint_refs)
|
||||
ds_add_buffer(ds, inbuf);
|
||||
postproc->use_vpp = TRUE;
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -677,21 +718,24 @@ error_create_meta:
|
|||
{
|
||||
GST_ERROR("failed to create new output buffer meta");
|
||||
gst_buffer_replace(&fieldbuf, NULL);
|
||||
gst_vaapi_video_meta_unref(outbuf_meta);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_create_proxy:
|
||||
{
|
||||
GST_ERROR("failed to create surface proxy from pool");
|
||||
gst_buffer_replace(&fieldbuf, NULL);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_op_deinterlace:
|
||||
{
|
||||
GST_ERROR("failed to apply deinterlacing filter");
|
||||
gst_buffer_replace(&fieldbuf, NULL);
|
||||
gst_vaapi_video_meta_unref(outbuf_meta);
|
||||
return GST_FLOW_NOT_SUPPORTED;
|
||||
}
|
||||
error_process_vpp:
|
||||
{
|
||||
GST_ERROR("failed to apply VPP filters (error %d)", status);
|
||||
gst_buffer_replace(&fieldbuf, NULL);
|
||||
gst_vaapi_video_meta_unref(outbuf_meta);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_push_buffer:
|
||||
|
@ -729,7 +773,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
fieldbuf = create_output_buffer(postproc);
|
||||
if (!fieldbuf)
|
||||
goto error_create_buffer;
|
||||
append_output_buffer_metadata(fieldbuf, inbuf, 0);
|
||||
append_output_buffer_metadata(postproc, fieldbuf, inbuf, 0);
|
||||
|
||||
meta = gst_buffer_get_vaapi_video_meta(fieldbuf);
|
||||
fieldbuf_flags = flags;
|
||||
|
@ -747,7 +791,7 @@ gst_vaapipostproc_process(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
goto error_push_buffer;
|
||||
|
||||
/* Second field */
|
||||
append_output_buffer_metadata(outbuf, inbuf, 0);
|
||||
append_output_buffer_metadata(postproc, outbuf, inbuf, 0);
|
||||
|
||||
meta = gst_buffer_get_vaapi_video_meta(outbuf);
|
||||
outbuf_flags = flags;
|
||||
|
@ -792,7 +836,8 @@ gst_vaapipostproc_passthrough(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
if (!meta)
|
||||
goto error_invalid_buffer;
|
||||
|
||||
append_output_buffer_metadata(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
|
||||
append_output_buffer_metadata(GST_VAAPIPOSTPROC(trans), outbuf, inbuf,
|
||||
GST_BUFFER_COPY_TIMESTAMPS);
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -1144,14 +1189,13 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf,
|
|||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
if (postproc->flags) {
|
||||
/* Use VA/VPP extensions to process this frame */
|
||||
if (postproc->use_vpp &&
|
||||
if (postproc->has_vpp &&
|
||||
(postproc->flags != GST_VAAPI_POSTPROC_FLAG_DEINTERLACE ||
|
||||
deint_method_is_advanced(postproc->deinterlace_method))) {
|
||||
ret = gst_vaapipostproc_process_vpp(trans, buf, outbuf);
|
||||
if (ret != GST_FLOW_NOT_SUPPORTED)
|
||||
goto done;
|
||||
GST_WARNING("unsupported VPP filters. Disabling");
|
||||
postproc->use_vpp = FALSE;
|
||||
}
|
||||
|
||||
/* Only append picture structure meta data (top/bottom field) */
|
||||
|
|
|
@ -168,6 +168,7 @@ struct _GstVaapiPostproc {
|
|||
gfloat contrast;
|
||||
|
||||
guint get_va_surfaces : 1;
|
||||
guint has_vpp : 1;
|
||||
guint use_vpp : 1;
|
||||
guint keep_aspect : 1;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue