diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/convertframe.c b/subprojects/gst-plugins-base/gst-libs/gst/video/convertframe.c index ee1dc07bf5..58bd3d5c40 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/convertframe.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/convertframe.c @@ -113,6 +113,82 @@ fail: return encoder; } +static GstElement * +build_convert_frame_pipeline_d3d11 (GstElement ** src_element, + GstElement ** sink_element, GstCaps * from_caps, GstCaps * to_caps, + GError ** err) +{ + GstElement *pipeline = NULL; + GstElement *appsrc = NULL; + GstElement *d3d11_convert = NULL; + GstElement *d3d11_download = NULL; + GstElement *convert = NULL; + GstElement *enc = NULL; + GstElement *appsink = NULL; + GError *error = NULL; + + if (!create_element ("appsrc", &appsrc, &error) || + !create_element ("d3d11convert", &d3d11_convert, &error) || + !create_element ("d3d11download", &d3d11_download, &error) || + !create_element ("videoconvert", &convert, &error) || + !create_element ("appsink", &appsink, &error)) { + GST_ERROR ("Could not create element"); + goto failed; + } + + if (caps_are_raw (to_caps)) { + if (!create_element ("identity", &enc, &error)) { + GST_ERROR ("Could not create identity element"); + goto failed; + } + } else { + enc = get_encoder (to_caps, &error); + if (!enc) { + GST_ERROR ("Could not create encoder"); + goto failed; + } + } + + g_object_set (appsrc, "caps", from_caps, "emit-signals", TRUE, + "format", GST_FORMAT_TIME, NULL); + g_object_set (appsink, "caps", to_caps, "emit-signals", TRUE, NULL); + + pipeline = gst_pipeline_new ("d3d11-convert-frame-pipeline"); + gst_bin_add_many (GST_BIN (pipeline), appsrc, d3d11_convert, d3d11_download, + convert, enc, appsink, NULL); + + if (!gst_element_link_many (appsrc, + d3d11_convert, d3d11_download, convert, enc, appsink, NULL)) { + /* Now pipeline takes ownership of all elements, so only top-level + * pipeline should be cleared */ + appsrc = d3d11_convert = convert = enc = appsink = NULL; + + error = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, + "Could not configure pipeline for conversion"); + } + + *src_element = appsrc; + *sink_element = appsink; + + return pipeline; + +failed: + if (err) + *err = error; + else + g_clear_error (&error); + + gst_clear_object (&pipeline); + gst_clear_object (&appsrc); + gst_clear_object (&d3d11_convert); + gst_clear_object (&d3d11_download); + gst_clear_object (&convert); + gst_clear_object (&enc); + gst_clear_object (&appsink); + + return NULL; +} + static GstElement * build_convert_frame_pipeline (GstElement ** src_element, GstElement ** sink_element, GstCaps * from_caps, @@ -123,11 +199,16 @@ build_convert_frame_pipeline (GstElement ** src_element, GstElement *dl = NULL; GstVideoInfo info; GError *error = NULL; -#ifdef HAVE_GL GstCapsFeatures *features; features = gst_caps_get_features (from_caps, 0); - if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) + if (features && gst_caps_features_contains (features, "memory:D3D11Memory")) { + return build_convert_frame_pipeline_d3d11 (src_element, sink_element, + from_caps, to_caps, err); + } +#ifdef HAVE_GL + if (features && + gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) if (!create_element ("gldownload", &dl, &error)) goto no_elements; #endif