From dc6d529830b185b557b86a78268becc61f3d2864 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 22 Jul 2014 18:54:29 +0200 Subject: [PATCH] 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 --- gst/vaapi/gstvaapidecode.c | 24 ++++++++++++++++++------ gst/vaapi/gstvaapivideomemory.c | 11 ++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index 1d97c62..1e94561 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -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) diff --git a/gst/vaapi/gstvaapivideomemory.c b/gst/vaapi/gstvaapivideomemory.c index cb953c1..38049b0 100644 --- a/gst/vaapi/gstvaapivideomemory.c +++ b/gst/vaapi/gstvaapivideomemory.c @@ -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; -- 2.7.4