vaapipostproc: add initial support for deinterlacing with VPP.

Allow basic bob-deinterlacing to work when VPP is enabled. Currently,
this only covers bob-deinterlacing when the output pixel format is
explicitly set.
This commit is contained in:
Gwenole Beauchesne 2013-11-15 19:04:07 +01:00
parent 2aab27b8de
commit be7a2ed64c

View file

@ -379,7 +379,11 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
GstVaapiVideoMeta *inbuf_meta, *outbuf_meta;
GstVaapiSurface *inbuf_surface, *outbuf_surface;
GstVaapiFilterStatus status;
guint flags;
GstClockTime timestamp;
GstFlowReturn ret;
GstBuffer *fieldbuf;
guint flags, deint_flags;
gboolean tff, deint;
/* Validate filters */
if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_FORMAT) &&
@ -391,21 +395,72 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
goto error_invalid_buffer;
inbuf_surface = gst_vaapi_video_meta_get_surface(inbuf_meta);
timestamp = GST_BUFFER_TIMESTAMP(inbuf);
tff = GST_BUFFER_FLAG_IS_SET(inbuf, GST_VIDEO_BUFFER_FLAG_TFF);
deint = is_interlaced_buffer(postproc, inbuf);
flags = gst_vaapi_video_meta_get_render_flags(inbuf_meta) &
~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD|
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);
/* First field */
if (postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE) {
fieldbuf = create_output_buffer(postproc);
if (!fieldbuf)
goto error_create_buffer;
outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool);
if (!outbuf_meta)
goto error_create_meta;
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
if (deint) {
deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TFF : 0);
if (!gst_vaapi_filter_set_deinterlacing(postproc->filter,
postproc->deinterlace_method, deint_flags))
goto error_op_deinterlace;
}
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);
if (ret != GST_FLOW_OK)
goto error_push_buffer;
}
fieldbuf = NULL;
/* Second field */
outbuf_meta = gst_vaapi_video_meta_new_from_pool(postproc->filter_pool);
if (!outbuf_meta)
goto error_create_meta;
outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
if (deint) {
deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TFF);
if (!gst_vaapi_filter_set_deinterlacing(postproc->filter,
postproc->deinterlace_method, deint_flags))
goto error_op_deinterlace;
}
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_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
if (!(postproc->flags & GST_VAAPI_POSTPROC_FLAG_DEINTERLACE))
gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
else {
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);
return GST_FLOW_OK;
@ -416,18 +471,38 @@ error_invalid_buffer:
GST_ERROR("failed to validate source buffer");
return GST_FLOW_ERROR;
}
error_create_buffer:
{
GST_ERROR("failed to create output buffer");
return GST_FLOW_ERROR;
}
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_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:
{
if (ret != GST_FLOW_FLUSHING)
GST_ERROR("failed to push output buffer to video sink");
return GST_FLOW_ERROR;
}
}
static GstFlowReturn