diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c index 246e6c6168..fd20c53b65 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c @@ -315,6 +315,85 @@ struct _UploadMethod void (*free) (gpointer impl); } _UploadMethod; +struct PassthroughUpload +{ + GstGLUpload *upload; +}; + +static gpointer +_passthrough_upload_new (GstGLUpload * upload) +{ + struct PassthroughUpload *passthrough = g_new0 (struct PassthroughUpload, 1); + + passthrough->upload = upload; + + return passthrough; +} + +static GstStaticCaps _passthrough_upload_caps = +GST_STATIC_CAPS (GST_VIDEO_DMA_DRM_CAPS_MAKE); + +static GstCaps * +_passthrough_upload_transform_caps (gpointer impl, GstGLContext * context, + GstPadDirection direction, GstCaps * caps) +{ + GstCaps *passthrough_caps = gst_static_caps_get (&_passthrough_upload_caps); + GstCaps *out_caps; + + out_caps = gst_caps_intersect_full (caps, passthrough_caps, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (passthrough_caps); + + return out_caps; +} + +static gboolean +_passthrough_upload_accept (gpointer impl, GstBuffer * buffer, + GstCaps * in_caps, GstCaps * out_caps) +{ + GstCaps *caps; + gboolean res; + + caps = gst_caps_intersect (in_caps, out_caps); + res = !gst_caps_is_empty (caps); + gst_caps_unref (caps); + + return res; +} + +static void +_passthrough_upload_propose_allocation (gpointer impl, GstQuery * decide_query, + GstQuery * query) +{ +} + +static GstGLUploadReturn +_passthrough_upload_perform (gpointer impl, GstBuffer * buffer, + GstBuffer ** outbuf) +{ + *outbuf = gst_buffer_ref (buffer); + + return GST_GL_UPLOAD_DONE; +} + +static void +_passthrough_upload_free (gpointer impl) +{ + g_free (impl); +} + +static const UploadMethod _passthrough_upload = { + "Dmabuf Passthrough", + 0, + &_passthrough_upload_caps, + &_passthrough_upload_new, + &_passthrough_upload_transform_caps, + &_passthrough_upload_accept, + &_passthrough_upload_propose_allocation, + &_passthrough_upload_perform, + &_passthrough_upload_free +}; + struct GLMemoryUpload { GstGLUpload *upload; @@ -3115,7 +3194,9 @@ static const UploadMethod _nvmm_upload = { #endif /* HAVE_NVMM */ -static const UploadMethod *upload_methods[] = { &_gl_memory_upload, +static const UploadMethod *upload_methods[] = { + &_passthrough_upload, + &_gl_memory_upload, #if GST_GL_HAVE_DMABUF &_direct_dma_buf_upload, &_direct_dma_buf_external_upload, diff --git a/subprojects/gst-plugins-base/tests/check/libs/gstglupload.c b/subprojects/gst-plugins-base/tests/check/libs/gstglupload.c index eff2f18ba5..523f05a561 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/gstglupload.c +++ b/subprojects/gst-plugins-base/tests/check/libs/gstglupload.c @@ -70,6 +70,18 @@ static gchar rgba_data[] = RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED }; +#ifndef GST_CAPS_FEATURE_MEMORY_DMABUF +#define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf" +#endif + +static GstVideoFormat test_passthrough_formats[] = { + GST_VIDEO_FORMAT_DMA_DRM, +}; + +static const gchar *test_passthrough_features[] = { + GST_CAPS_FEATURE_MEMORY_DMABUF, +}; + static void setup (void) { @@ -417,6 +429,64 @@ GST_START_TEST (test_upload_gl_memory) GST_END_TEST; +GST_START_TEST (test_passthrough) +{ + guint formats_size = G_N_ELEMENTS (test_passthrough_formats); + guint features_size = G_N_ELEMENTS (test_passthrough_features); + gint i, j, k, l; + + for (i = 0; i < formats_size; i++) { + GstVideoFormat in_format = test_passthrough_formats[i]; + + for (j = 0; j < formats_size; j++) { + GstVideoFormat out_format = test_passthrough_formats[j]; + + for (k = 0; k < features_size; k++) { + const gchar *in_feature = test_passthrough_features[k]; + GstCaps *in_caps; + + in_caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, + gst_video_format_to_string (in_format), NULL); + gst_caps_set_features_simple (in_caps, + gst_caps_features_from_string (in_feature)); + + + for (l = 0; l < features_size; l++) { + const gchar *out_feature = test_passthrough_features[l]; + GstCaps *out_caps; + + out_caps = gst_caps_new_simple ("video/x-raw", "format", + G_TYPE_STRING, gst_video_format_to_string (out_format), NULL); + gst_caps_set_features_simple (out_caps, + gst_caps_features_from_string (out_feature)); + + if (gst_caps_is_equal (in_caps, out_caps)) { + GstCaps *tmp_caps, *tmp_caps2, *tmp_caps3; + + tmp_caps = gst_gl_upload_transform_caps (upload, context, + GST_PAD_SINK, in_caps, NULL); + tmp_caps2 = gst_gl_upload_transform_caps (upload, context, + GST_PAD_SRC, out_caps, NULL); + + tmp_caps3 = gst_caps_intersect (tmp_caps, tmp_caps2); + + fail_unless (!gst_caps_is_empty (tmp_caps3)); + + gst_caps_unref (tmp_caps); + gst_caps_unref (tmp_caps2); + gst_caps_unref (tmp_caps3); + } + + gst_caps_unref (out_caps); + } + + gst_caps_unref (in_caps); + } + } + } +} + +GST_END_TEST; static Suite * gst_gl_upload_suite (void) @@ -428,6 +498,7 @@ gst_gl_upload_suite (void) tcase_add_checked_fixture (tc_chain, setup, teardown); tcase_add_test (tc_chain, test_upload_data); tcase_add_test (tc_chain, test_upload_gl_memory); + tcase_add_test (tc_chain, test_passthrough); return s; }