mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
vaapiencode: fix support for raw YUV sink buffers.
Allow vaapiencode plug-in elements to encode from raw YUV buffers. The most efficient way to do so is to let the vaapiencode elements allocate a buffer pool, and subsequently buffers from it. This means that upstream elements are expected to honour downstream pools. If upstream elements insist on providing their own allocated buffers to the vaapiencode elements, then it possibly would be more efficient to insert a vaapipostproc element before the vaapiencode element. This is because vaapipostproc currently has better support than other elements for "foreign" raw YUV buffers.
This commit is contained in:
parent
139c99bb77
commit
84af151796
3 changed files with 59 additions and 37 deletions
|
@ -541,13 +541,13 @@ gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode,
|
||||
GstBuffer * src_buffer, GstBuffer ** out_buffer_ptr)
|
||||
get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer,
|
||||
GstBuffer ** out_buffer_ptr)
|
||||
{
|
||||
GstVaapiVideoMeta *meta;
|
||||
GstBuffer *out_buffer;
|
||||
GstVideoFrame src_frame, out_frame;
|
||||
GstFlowReturn ret;
|
||||
gboolean success;
|
||||
|
||||
*out_buffer_ptr = NULL;
|
||||
meta = gst_buffer_get_vaapi_video_meta (src_buffer);
|
||||
|
@ -556,12 +556,8 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode,
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) {
|
||||
GST_ERROR ("unsupported video buffer");
|
||||
return GST_FLOW_EOS;
|
||||
}
|
||||
|
||||
GST_DEBUG ("buffer %p not from our pool, copying", src_buffer);
|
||||
if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info))
|
||||
goto error_invalid_buffer;
|
||||
|
||||
if (!encode->video_buffer_pool)
|
||||
goto error_no_pool;
|
||||
|
@ -569,9 +565,10 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode,
|
|||
if (!gst_buffer_pool_set_active (encode->video_buffer_pool, TRUE))
|
||||
goto error_activate_pool;
|
||||
|
||||
ret = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool,
|
||||
&out_buffer, NULL);
|
||||
if (ret != GST_FLOW_OK)
|
||||
out_buffer = NULL;
|
||||
success = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool,
|
||||
&out_buffer, NULL) == GST_FLOW_OK;
|
||||
if (!success)
|
||||
goto error_create_buffer;
|
||||
|
||||
if (!gst_video_frame_map (&src_frame, &encode->sink_video_info, src_buffer,
|
||||
|
@ -582,30 +579,56 @@ gst_vaapiencode_get_vaapi_buffer (GstVaapiEncode * encode,
|
|||
GST_MAP_WRITE))
|
||||
goto error_map_dst_buffer;
|
||||
|
||||
gst_video_frame_copy (&out_frame, &src_frame);
|
||||
success = gst_video_frame_copy (&out_frame, &src_frame);
|
||||
gst_video_frame_unmap (&out_frame);
|
||||
gst_video_frame_unmap (&src_frame);
|
||||
if (!success)
|
||||
goto error_copy_buffer;
|
||||
|
||||
gst_buffer_copy_into (out_buffer, src_buffer, GST_BUFFER_COPY_TIMESTAMPS, 0,
|
||||
-1);
|
||||
|
||||
*out_buffer_ptr = out_buffer;
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* ERRORS */
|
||||
error_invalid_buffer:
|
||||
{
|
||||
GST_ERROR ("unsupported video buffer");
|
||||
return GST_FLOW_EOS;
|
||||
}
|
||||
error_no_pool:
|
||||
GST_ERROR ("no buffer pool was negotiated");
|
||||
return GST_FLOW_ERROR;
|
||||
{
|
||||
GST_ERROR ("no buffer pool was negotiated");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_activate_pool:
|
||||
GST_ERROR ("failed to activate buffer pool");
|
||||
return GST_FLOW_ERROR;
|
||||
{
|
||||
GST_ERROR ("failed to activate buffer pool");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
error_create_buffer:
|
||||
GST_WARNING ("failed to create image. Skipping this frame");
|
||||
return GST_FLOW_OK;
|
||||
{
|
||||
GST_WARNING ("failed to create buffer. Skipping this frame");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
error_map_dst_buffer:
|
||||
gst_video_frame_unmap (&src_frame);
|
||||
// fall-through
|
||||
{
|
||||
gst_video_frame_unmap (&src_frame);
|
||||
// fall-through
|
||||
}
|
||||
error_map_src_buffer:
|
||||
GST_WARNING ("failed to map buffer. Skipping this frame");
|
||||
gst_buffer_unref (out_buffer);
|
||||
return GST_FLOW_OK;
|
||||
{
|
||||
GST_WARNING ("failed to map buffer. Skipping this frame");
|
||||
gst_buffer_unref (out_buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
error_copy_buffer:
|
||||
{
|
||||
GST_WARNING ("failed to upload buffer to VA surface. Skipping this frame");
|
||||
gst_buffer_unref (out_buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
|
@ -651,19 +674,17 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
|
|||
GstVaapiEncode *const encode = GST_VAAPIENCODE (venc);
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstVaapiEncoderStatus encoder_ret = GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
GstBuffer *vaapi_buf = NULL;
|
||||
GstBuffer *buf;
|
||||
gpointer user_data;
|
||||
|
||||
g_assert (encode && encode->encoder);
|
||||
g_assert (frame && frame->input_buffer);
|
||||
|
||||
ret =
|
||||
gst_vaapiencode_get_vaapi_buffer (encode, frame->input_buffer,
|
||||
&vaapi_buf);
|
||||
GST_VAAPI_ENCODER_CHECK_STATUS (ret == GST_FLOW_OK, ret,
|
||||
"convert to vaapi buffer failed");
|
||||
ret = get_source_buffer (encode, frame->input_buffer, &buf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
user_data = _create_user_data (vaapi_buf);
|
||||
user_data = _create_user_data (buf);
|
||||
GST_VAAPI_ENCODER_CHECK_STATUS (user_data,
|
||||
ret, "create frame user data failed");
|
||||
|
||||
|
@ -679,7 +700,7 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
|
|||
|
||||
end:
|
||||
gst_video_codec_frame_unref (frame);
|
||||
gst_buffer_replace (&vaapi_buf, NULL);
|
||||
gst_buffer_replace (&buf, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@ static const char gst_vaapiencode_h264_sink_caps_str[] =
|
|||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE,
|
||||
"{ ENCODED, NV12, I420, YV12 }") ", "
|
||||
#else
|
||||
GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", "
|
||||
GST_CAPS_INTERLACED_FALSE "; "
|
||||
GST_VAAPI_SURFACE_CAPS ", "
|
||||
#endif
|
||||
GST_CAPS_INTERLACED_FALSE "; "
|
||||
GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", "
|
||||
GST_CAPS_INTERLACED_FALSE;
|
||||
|
||||
static const char gst_vaapiencode_h264_src_caps_str[] =
|
||||
|
|
|
@ -42,11 +42,12 @@ static const char gst_vaapiencode_mpeg2_sink_caps_str[] =
|
|||
#if GST_CHECK_VERSION(1,1,0)
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE,
|
||||
"{ ENCODED, NV12, I420, YV12 }") ", "
|
||||
GST_CAPS_INTERLACED_FALSE;
|
||||
#else
|
||||
GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) "; "
|
||||
GST_VAAPI_SURFACE_CAPS;
|
||||
GST_VAAPI_SURFACE_CAPS ", "
|
||||
#endif
|
||||
GST_CAPS_INTERLACED_FALSE "; "
|
||||
GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL) ", "
|
||||
GST_CAPS_INTERLACED_FALSE;
|
||||
|
||||
static const char gst_vaapiencode_mpeg2_src_caps_str[] =
|
||||
GST_CAPS_CODEC ("video/mpeg,"
|
||||
|
|
Loading…
Reference in a new issue