diff options
author | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2018-02-15 19:32:37 +0100 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2018-02-20 10:58:08 -0600 |
commit | 188434f25112436621661c9f209441bc32aa3907 (patch) | |
tree | 3dc2bebee866c9d0f2d4269a63dbfad95d0ac651 | |
parent | 2c36610748ce2840690601f4ce09fa929f64aa8c (diff) |
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
-rw-r--r-- | gst/vaapi/gstvaapipostproc.c | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 29c8406b4d..8ad3f2866e 100644 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -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; } - *outbuf_ptr = create_output_buffer (postproc); + 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; } |