mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
video: convertframe: Add D3D11 specific conversion path
Add d3d11 conversion path to make gst_video_convert_sample() work for GstD3D11Memory. Note that just adding "d3d11download" to the exisitng code is suboptimal from GstD3D11 point of view because: * d3d11convert element can support crop/colorspace-conversion/scale all at once while existing software pipeline needs intermediate steps for the conversion * "Process everything on GPU then download it to CPU memory" would be likely faster than "download GPU memory to CPU then processing it on CPU" Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2715>
This commit is contained in:
parent
9554a5c7fa
commit
a8bf19deda
1 changed files with 83 additions and 2 deletions
|
@ -113,6 +113,82 @@ fail:
|
||||||
return encoder;
|
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 *
|
static GstElement *
|
||||||
build_convert_frame_pipeline (GstElement ** src_element,
|
build_convert_frame_pipeline (GstElement ** src_element,
|
||||||
GstElement ** sink_element, GstCaps * from_caps,
|
GstElement ** sink_element, GstCaps * from_caps,
|
||||||
|
@ -123,11 +199,16 @@ build_convert_frame_pipeline (GstElement ** src_element,
|
||||||
GstElement *dl = NULL;
|
GstElement *dl = NULL;
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
#ifdef HAVE_GL
|
|
||||||
GstCapsFeatures *features;
|
GstCapsFeatures *features;
|
||||||
|
|
||||||
features = gst_caps_get_features (from_caps, 0);
|
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))
|
if (!create_element ("gldownload", &dl, &error))
|
||||||
goto no_elements;
|
goto no_elements;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue