diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.c index d630436ddd..787db028a0 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.c @@ -1196,61 +1196,71 @@ gst_gl_color_convert_caps_transform_format_info (GstGLContext * context, st = gst_caps_get_structure (caps, i); f = gst_caps_get_features (caps, i); + /* If this is already expressed by the existing caps + * skip this structure */ + if (i > 0 && gst_caps_is_subset_structure_full (res, st, f)) + continue; + format = gst_structure_get_value (st, "format"); st = gst_structure_copy (st); - if (GST_VALUE_HOLDS_LIST (format)) { - gboolean have_rgb_formats = FALSE; - GValue passthrough_formats = G_VALUE_INIT; - gint j, len; - g_value_init (&passthrough_formats, GST_TYPE_LIST); - len = gst_value_list_get_size (format); - for (j = 0; j < len; j++) { - const GValue *val; + /* Only remove format info for the cases when we can actually convert */ + if (!gst_caps_features_is_any (f) && + gst_caps_features_contains (f, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) { + if (GST_VALUE_HOLDS_LIST (format)) { + gboolean have_rgb_formats = FALSE; + GValue passthrough_formats = G_VALUE_INIT; + gint j, len; - val = gst_value_list_get_value (format, j); - if (G_VALUE_HOLDS_STRING (val)) { - const gchar *format_str = g_value_get_string (val); - GstVideoFormat v_format = gst_video_format_from_string (format_str); - const GstVideoFormatInfo *t_info = - gst_video_format_get_info (v_format); - if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & (GST_VIDEO_FORMAT_FLAG_YUV - | GST_VIDEO_FORMAT_FLAG_GRAY)) { - gst_value_list_append_value (&passthrough_formats, val); - } else if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & - GST_VIDEO_FORMAT_FLAG_RGB) { - have_rgb_formats = TRUE; - break; + g_value_init (&passthrough_formats, GST_TYPE_LIST); + len = gst_value_list_get_size (format); + for (j = 0; j < len; j++) { + const GValue *val; + + val = gst_value_list_get_value (format, j); + if (G_VALUE_HOLDS_STRING (val)) { + const gchar *format_str = g_value_get_string (val); + GstVideoFormat v_format = gst_video_format_from_string (format_str); + const GstVideoFormatInfo *t_info = + gst_video_format_get_info (v_format); + if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & + (GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_GRAY)) { + gst_value_list_append_value (&passthrough_formats, val); + } else if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & + GST_VIDEO_FORMAT_FLAG_RGB) { + have_rgb_formats = TRUE; + break; + } } } + if (have_rgb_formats) { + gst_structure_set_value (st, "format", &supported_formats); + } else { + /* add passthrough structure, then the rgb conversion structure */ + gst_structure_set_value (st, "format", &passthrough_formats); + gst_caps_append_structure_full (res, gst_structure_copy (st), + gst_caps_features_copy (f)); + gst_structure_set_value (st, "format", &supported_rgb_formats); + } + g_value_unset (&passthrough_formats); + } else if (G_VALUE_HOLDS_STRING (format)) { + const gchar *format_str = g_value_get_string (format); + GstVideoFormat v_format = gst_video_format_from_string (format_str); + const GstVideoFormatInfo *t_info = gst_video_format_get_info (v_format); + if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & (GST_VIDEO_FORMAT_FLAG_YUV | + GST_VIDEO_FORMAT_FLAG_GRAY)) { + /* add passthrough structure, then the rgb conversion structure */ + gst_structure_set_value (st, "format", format); + gst_caps_append_structure_full (res, gst_structure_copy (st), + gst_caps_features_copy (f)); + gst_structure_set_value (st, "format", &supported_rgb_formats); + } else { /* RGB */ + gst_structure_set_value (st, "format", &supported_formats); + } } - if (have_rgb_formats) { - gst_structure_set_value (st, "format", &supported_formats); - } else { - /* add passthrough structure, then the rgb conversion structure */ - gst_structure_set_value (st, "format", &passthrough_formats); - gst_caps_append_structure_full (res, gst_structure_copy (st), - gst_caps_features_copy (f)); - gst_structure_set_value (st, "format", &supported_rgb_formats); - } - g_value_unset (&passthrough_formats); - } else if (G_VALUE_HOLDS_STRING (format)) { - const gchar *format_str = g_value_get_string (format); - GstVideoFormat v_format = gst_video_format_from_string (format_str); - const GstVideoFormatInfo *t_info = gst_video_format_get_info (v_format); - if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & (GST_VIDEO_FORMAT_FLAG_YUV | - GST_VIDEO_FORMAT_FLAG_GRAY)) { - /* add passthrough structure, then the rgb conversion structure */ - gst_structure_set_value (st, "format", format); - gst_caps_append_structure_full (res, gst_structure_copy (st), - gst_caps_features_copy (f)); - gst_structure_set_value (st, "format", &supported_rgb_formats); - } else { /* RGB */ - gst_structure_set_value (st, "format", &supported_formats); - } + gst_structure_remove_fields (st, "colorimetry", "chroma-site", + "texture-target", NULL); } - gst_structure_remove_fields (st, "colorimetry", "chroma-site", - "texture-target", NULL); gst_caps_append_structure_full (res, st, gst_caps_features_copy (f)); } @@ -1354,8 +1364,6 @@ score_format_target (const GstVideoFormatInfo * in_info, guint targets_mask, /* can only passthrough external-oes textures */ other_targets_mask &= ~(1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES); - if (other_targets_mask == 0) - return; /* try to keep the same target */ if (targets_mask & other_targets_mask) other_targets_mask = targets_mask & other_targets_mask; @@ -1416,11 +1424,9 @@ score_format_target (const GstVideoFormatInfo * in_info, guint targets_mask, if (loss < *min_loss) { GstGLTextureTarget target = _texture_target_demask (other_targets_mask); - if (target != 0) { - *out_info = t_info; - *min_loss = loss; - *result = target; - } + *out_info = t_info; + *min_loss = loss; + *result = target; } } @@ -1441,9 +1447,8 @@ gst_gl_color_convert_fixate_format_target (GstCaps * caps, GstCaps * result) if (!in_format) return; targets = gst_structure_get_value (ins, "texture-target"); - targets_mask = gst_gl_value_get_texture_target_mask (targets); - if (!targets_mask) - return; + if (targets) + targets_mask = gst_gl_value_get_texture_target_mask (targets); in_info = gst_video_format_get_info (gst_video_format_from_string (in_format)); @@ -1462,12 +1467,13 @@ gst_gl_color_convert_fixate_format_target (GstCaps * caps, GstCaps * result) tests = gst_caps_get_structure (result, i); format = gst_structure_get_value (tests, "format"); - other_targets = gst_structure_get_value (tests, "texture-target"); /* should not happen */ - if (format == NULL || other_targets == NULL) + if (format == NULL) continue; - other_targets_mask = gst_gl_value_get_texture_target_mask (other_targets); + other_targets = gst_structure_get_value (tests, "texture-target"); + if (other_targets) + other_targets_mask = gst_gl_value_get_texture_target_mask (other_targets); if (GST_VALUE_HOLDS_LIST (format)) { gint j, len; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.h b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.h index 1b3b1de585..cd97e62ce7 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.h @@ -129,7 +129,9 @@ struct _GstGLColorConvertClass "width = " GST_VIDEO_SIZE_RANGE ", " \ "height = " GST_VIDEO_SIZE_RANGE ", " \ "framerate = " GST_VIDEO_FPS_RANGE ", " \ - "texture-target = (string) { 2D, rectangle, external-oes }" + "texture-target = (string) { 2D, rectangle, external-oes }" \ + " ; " \ + GST_VIDEO_DMA_DRM_CAPS_MAKE GST_GL_API GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context); diff --git a/subprojects/gst-plugins-base/tests/check/libs/gstglcolorconvert.c b/subprojects/gst-plugins-base/tests/check/libs/gstglcolorconvert.c index b64ba7726c..8bfbfe9941 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/gstglcolorconvert.c +++ b/subprojects/gst-plugins-base/tests/check/libs/gstglcolorconvert.c @@ -68,6 +68,18 @@ static TestFrame test_rgba_reorder[] = { {1, 1, GST_VIDEO_FORMAT_BGR, {(gchar *) & bgr_reorder_data}}, }; +#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) { @@ -252,6 +264,65 @@ GST_START_TEST (test_reorder_buffer) 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_color_convert_transform_caps (context, + GST_PAD_SINK, in_caps, NULL); + tmp_caps2 = gst_gl_color_convert_transform_caps (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_color_convert_suite (void) { @@ -261,6 +332,7 @@ gst_gl_color_convert_suite (void) suite_add_tcase (s, tc_chain); tcase_add_checked_fixture (tc_chain, setup, teardown); tcase_add_test (tc_chain, test_reorder_buffer); + tcase_add_test (tc_chain, test_passthrough); /* FIXME add YUV <--> RGB conversion tests */ return s;