plugins: allow download capability to vaapidecode element.

Fix support for VA surface download capability in vaapidecode element
for GStreamer >= 1.2. This is a fix to supporting libva-vdpau-driver,
but also the libva-intel-driver while performing hardware accelerated
conversions from the native VA surface format (NV12) to the desired
output VA image format.

For instance, this fixes pipelines involving vaapidecode ! xvimagesink.

https://bugzilla.gnome.org/show_bug.cgi?id=733243
This commit is contained in:
Gwenole Beauchesne 2014-07-22 18:54:29 +02:00
parent 00ca734ebf
commit dc6d529830
2 changed files with 28 additions and 7 deletions

View file

@ -155,6 +155,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
GstVideoCodecState *state;
GstVideoInfo *vi, vis;
GstVideoFormat format, out_format;
#if GST_CHECK_VERSION(1,1,0)
GstCapsFeatures *features = NULL;
GstVaapiCapsFeature feature;
@ -164,17 +165,28 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
GST_VIDEO_INFO_FORMAT(&ref_state->info));
#endif
state = gst_video_decoder_set_output_state(vdec,
GST_VIDEO_INFO_FORMAT(&ref_state->info),
format = GST_VIDEO_INFO_FORMAT(&ref_state->info);
state = gst_video_decoder_set_output_state(vdec, format,
ref_state->info.width, ref_state->info.height,
(GstVideoCodecState *)ref_state);
if (!state)
return FALSE;
vi = &state->info;
if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) {
out_format = format;
if (format == GST_VIDEO_FORMAT_ENCODED) {
#if GST_CHECK_VERSION(1,1,0)
out_format = GST_VIDEO_FORMAT_NV12;
if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY) {
/* XXX: intercept with the preferred output format.
Anyway, I420 is the minimum format that drivers
should support to be useful */
out_format = GST_VIDEO_FORMAT_I420;
}
#endif
gst_video_info_init(&vis);
gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12,
gst_video_info_set_format(&vis, out_format,
GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
vi->size = vis.size;
}
@ -190,12 +202,12 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
break;
default:
if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) {
if (format == GST_VIDEO_FORMAT_ENCODED) {
/* XXX: this is a workaround until auto-plugging is fixed when
format=ENCODED + memory:VASurface caps feature are provided.
Meanwhile, providing a random format here works but this is
a terribly wrong thing per se. */
gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_NV12,
gst_vaapidecode_video_info_change_format(&vis, out_format,
GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
#if GST_CHECK_VERSION(1,3,0)
if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE)

View file

@ -51,6 +51,11 @@ ensure_image(GstVaapiVideoMemory *mem)
GST_WARNING("failed to derive image, fallbacking to copy");
mem->use_direct_rendering = FALSE;
}
else if (gst_vaapi_surface_get_format(mem->surface) !=
GST_VIDEO_INFO_FORMAT(mem->image_info)) {
gst_vaapi_object_replace(&mem->image, NULL);
mem->use_direct_rendering = FALSE;
}
}
if (!mem->image) {
@ -142,10 +147,14 @@ gst_video_meta_map_vaapi_memory(GstVideoMeta *meta, guint plane,
goto error_ensure_image;
// Check that we can actually map the surface, or image
if ((flags & GST_MAP_READWRITE) != GST_MAP_WRITE &&
if ((flags & GST_MAP_READWRITE) == GST_MAP_WRITE &&
!mem->use_direct_rendering)
goto error_unsupported_map;
// Load VA image from surface
if ((flags & GST_MAP_READ) && !mem->use_direct_rendering)
gst_vaapi_surface_get_image(mem->surface, mem->image);
if (!gst_vaapi_image_map(mem->image))
goto error_map_image;
mem->map_type = GST_VAAPI_VIDEO_MEMORY_MAP_TYPE_PLANAR;