vaapipostproc: fix support for raw YUV data upload on GStreamer 1.0.

Fix raw YUV data uploaded as in the following pipeline:
$ gst-launch-1.0 filesrc video.yuv ! videoparse ! vaapipostproc ! vaapisink

The main reason why it failed was that the videoparse element simply
allocates GstBuffer with raw data chunk'ed off the sink pad without
any prior knowledge of the actual frame info. i.e. it basically just
calls gst_adapter_take_buffer().

We could avoid the extra copy performed in vaapipostproc if the videoparse
element was aware of the downstream pool and bothers copying line by
line, for each plane. This means that, for a single frame per buffer,
the optimizatin will be to allocate the video buffer downstream, map
it, and copy each line that is coming through until we need to fills
in the successive planes.

Still, optimized raw YUV uploads already worked with the following:
$ gst-launch-1.0 videotestsrc ! vaapipostproc ! vaapisink

https://bugzilla.gnome.org/show_bug.cgi?id=711250

[clean-ups, fixed error cases to unmap and unref outbuf]
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
Wind Yuan 2013-11-01 13:43:11 +08:00 committed by Gwenole Beauchesne
parent cc055b72ce
commit b62bd57bda

View file

@ -1030,14 +1030,43 @@ get_source_buffer(GstVaapiPostproc *postproc, GstBuffer *inbuf)
{
GstVaapiVideoMeta *meta;
GstBuffer *outbuf;
#if GST_CHECK_VERSION(1,0,0)
GstVideoFrame src_frame, out_frame;
#endif
meta = gst_buffer_get_vaapi_video_meta(inbuf);
if (meta)
return gst_buffer_ref(inbuf);
#if GST_CHECK_VERSION(1,0,0)
if (!postproc->is_raw_yuv)
goto error_invalid_buffer;
if (!postproc->sinkpad_buffer_pool)
goto error_no_pool;
if (!gst_buffer_pool_set_active(postproc->sinkpad_buffer_pool, TRUE))
goto error_active_pool;
outbuf = NULL;
goto error_invalid_buffer;
if (gst_buffer_pool_acquire_buffer(postproc->sinkpad_buffer_pool,
&outbuf, NULL) != GST_FLOW_OK)
goto error_create_buffer;
if (!gst_video_frame_map(&src_frame, &postproc->sinkpad_info, inbuf,
GST_MAP_READ))
goto error_map_src_buffer;
if (!gst_video_frame_map(&out_frame, &postproc->sinkpad_info, outbuf,
GST_MAP_WRITE))
goto error_map_dst_buffer;
if (!gst_video_frame_copy(&out_frame, &src_frame))
goto error_copy_buffer;
gst_video_frame_unmap(&out_frame);
gst_video_frame_unmap(&src_frame);
gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
return outbuf;
/* ERRORS */
@ -1046,6 +1075,27 @@ error_invalid_buffer:
GST_ERROR("failed to validate source buffer");
return NULL;
}
error_no_pool:
{
GST_ERROR("no buffer pool was negotiated");
return NULL;
}
error_active_pool:
{
GST_ERROR("failed to activate buffer pool");
return NULL;
}
error_map_dst_buffer:
{
gst_video_frame_unmap(&src_frame);
// fall-through
}
error_map_src_buffer:
{
GST_ERROR("failed to map buffer");
gst_buffer_unref(outbuf);
return NULL;
}
#else
outbuf = gst_vaapi_uploader_get_buffer(postproc->uploader);
if (!outbuf)
@ -1056,6 +1106,7 @@ error_invalid_buffer:
gst_buffer_copy_metadata(outbuf, inbuf,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
return outbuf;
#endif
/* ERRORS */
error_create_buffer:
@ -1066,10 +1117,13 @@ error_create_buffer:
error_copy_buffer:
{
GST_ERROR("failed to upload buffer to VA surface");
#if GST_CHECK_VERSION(1,0,0)
gst_video_frame_unmap(&out_frame);
gst_video_frame_unmap(&src_frame);
#endif
gst_buffer_unref(outbuf);
return NULL;
}
#endif
}
static GstFlowReturn