vaapipostproc: handle system allocated buffers when required

When downstream can't handle GstVideoMeta it is required to send
system allocated buffers.

The system allocated buffers are produced in prepare_output_buffer()
vmethod if downstream can't handl GstVideoMeta.

At transform() vmethod if the buffer is a system allocated buffer,
a VA buffer is instanciated and replaces the out buffer. Later
the VA buffer is copied to the system allocate buffer and it
replaces the output buffer.

https://bugzilla.gnome.org/show_bug.cgi?id=785054
This commit is contained in:
Víctor Manuel Jáquez Leal 2018-02-15 19:32:37 +01:00
parent 2c36610748
commit 188434f251

View file

@ -392,6 +392,16 @@ error_create_buffer:
}
}
static inline GstBuffer *
create_output_dump_buffer (GstVaapiPostproc * postproc)
{
GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc);
return gst_buffer_new_allocate (plugin->other_srcpad_allocator,
GST_VIDEO_INFO_SIZE (&plugin->srcpad_info),
&plugin->other_allocator_params);
}
static gboolean
append_output_buffer_metadata (GstVaapiPostproc * postproc, GstBuffer * outbuf,
GstBuffer * inbuf, guint flags)
@ -600,6 +610,31 @@ gst_vaapipostproc_set_passthrough (GstBaseTransform * trans)
&& !filter_updated);
}
static gboolean
replace_to_dumb_buffer_if_required (GstVaapiPostproc * postproc,
GstBuffer ** fieldbuf)
{
GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc);
GstBuffer *newbuf;
if (!GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (postproc))
return TRUE;
newbuf = create_output_dump_buffer (postproc);
if (!newbuf)
return FALSE;
if (!gst_vaapi_plugin_copy_va_buffer (plugin, *fieldbuf, newbuf)) {
gst_buffer_unref (newbuf);
return FALSE;
}
gst_buffer_replace (fieldbuf, newbuf);
gst_buffer_unref (newbuf);
return TRUE;
}
static GstFlowReturn
gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
@ -727,6 +762,9 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
discont = FALSE;
}
if (!replace_to_dumb_buffer_if_required (postproc, &fieldbuf))
goto error_copy_buffer;
ret = gst_pad_push (trans->srcpad, fieldbuf);
if (ret != GST_FLOW_OK)
goto error_push_buffer;
@ -824,6 +862,12 @@ error_process_vpp:
gst_buffer_replace (&fieldbuf, NULL);
return GST_FLOW_ERROR;
}
error_copy_buffer:
{
GST_ERROR_OBJECT (postproc, "failed to copy field buffer to dumb buffer");
gst_buffer_replace (&fieldbuf, NULL);
return GST_FLOW_ERROR;
}
error_push_buffer:
{
GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s",
@ -871,6 +915,10 @@ gst_vaapipostproc_process (GstBaseTransform * trans, GstBuffer * inbuf,
GST_BUFFER_TIMESTAMP (fieldbuf) = timestamp;
GST_BUFFER_DURATION (fieldbuf) = postproc->field_duration;
if (!replace_to_dumb_buffer_if_required (postproc, &fieldbuf))
goto error_copy_buffer;
ret = gst_pad_push (trans->srcpad, fieldbuf);
if (ret != GST_FLOW_OK)
goto error_push_buffer;
@ -901,6 +949,12 @@ error_create_buffer:
GST_ERROR_OBJECT (postproc, "failed to create output buffer");
return GST_FLOW_EOS;
}
error_copy_buffer:
{
GST_ERROR_OBJECT (postproc, "failed to copy field buffer to dumb buffer");
gst_buffer_replace (&fieldbuf, NULL);
return GST_FLOW_ERROR;
}
error_push_buffer:
{
GST_DEBUG_OBJECT (postproc, "failed to push output buffer: %s",
@ -1211,15 +1265,24 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans);
GstBuffer *buf;
GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (postproc);
GstBuffer *buf, *sys_buf = NULL;
GstFlowReturn ret;
ret =
gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (postproc),
inbuf, &buf);
ret = gst_vaapi_plugin_base_get_input_buffer (plugin, inbuf, &buf);
if (ret != GST_FLOW_OK)
return GST_FLOW_ERROR;
if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) {
GstBuffer *va_buf = create_output_buffer (postproc);
if (!va_buf) {
ret = GST_FLOW_ERROR;
goto done;
}
sys_buf = outbuf;
outbuf = va_buf;
}
ret = GST_FLOW_NOT_SUPPORTED;
if (postproc->flags) {
/* Use VA/VPP extensions to process this frame */
@ -1245,6 +1308,15 @@ gst_vaapipostproc_transform (GstBaseTransform * trans, GstBuffer * inbuf,
done:
gst_buffer_unref (buf);
if (sys_buf) {
if (!gst_vaapi_plugin_copy_va_buffer (plugin, outbuf, sys_buf))
return GST_FLOW_ERROR;
gst_buffer_unref (outbuf);
outbuf = sys_buf;
}
return ret;
}
@ -1259,7 +1331,12 @@ gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans,
return GST_FLOW_OK;
}
if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) {
*outbuf_ptr = create_output_dump_buffer (postproc);
} else {
*outbuf_ptr = create_output_buffer (postproc);
}
return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR;
}