mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
gl: colorconvert: Add DMA_DRM passtrough support
By always passing through caps before adding additional caps supported by conversion. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5948>
This commit is contained in:
parent
46259c634b
commit
143f661318
3 changed files with 141 additions and 61 deletions
|
@ -1196,61 +1196,71 @@ gst_gl_color_convert_caps_transform_format_info (GstGLContext * context,
|
||||||
st = gst_caps_get_structure (caps, i);
|
st = gst_caps_get_structure (caps, i);
|
||||||
f = gst_caps_get_features (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");
|
format = gst_structure_get_value (st, "format");
|
||||||
st = gst_structure_copy (st);
|
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);
|
/* Only remove format info for the cases when we can actually convert */
|
||||||
len = gst_value_list_get_size (format);
|
if (!gst_caps_features_is_any (f) &&
|
||||||
for (j = 0; j < len; j++) {
|
gst_caps_features_contains (f, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
|
||||||
const GValue *val;
|
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);
|
g_value_init (&passthrough_formats, GST_TYPE_LIST);
|
||||||
if (G_VALUE_HOLDS_STRING (val)) {
|
len = gst_value_list_get_size (format);
|
||||||
const gchar *format_str = g_value_get_string (val);
|
for (j = 0; j < len; j++) {
|
||||||
GstVideoFormat v_format = gst_video_format_from_string (format_str);
|
const GValue *val;
|
||||||
const GstVideoFormatInfo *t_info =
|
|
||||||
gst_video_format_get_info (v_format);
|
val = gst_value_list_get_value (format, j);
|
||||||
if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) & (GST_VIDEO_FORMAT_FLAG_YUV
|
if (G_VALUE_HOLDS_STRING (val)) {
|
||||||
| GST_VIDEO_FORMAT_FLAG_GRAY)) {
|
const gchar *format_str = g_value_get_string (val);
|
||||||
gst_value_list_append_value (&passthrough_formats, val);
|
GstVideoFormat v_format = gst_video_format_from_string (format_str);
|
||||||
} else if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) &
|
const GstVideoFormatInfo *t_info =
|
||||||
GST_VIDEO_FORMAT_FLAG_RGB) {
|
gst_video_format_get_info (v_format);
|
||||||
have_rgb_formats = TRUE;
|
if (GST_VIDEO_FORMAT_INFO_FLAGS (t_info) &
|
||||||
break;
|
(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_remove_fields (st, "colorimetry", "chroma-site",
|
||||||
gst_structure_set_value (st, "format", &supported_formats);
|
"texture-target", NULL);
|
||||||
} 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_caps_append_structure_full (res, st, gst_caps_features_copy (f));
|
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 */
|
/* can only passthrough external-oes textures */
|
||||||
other_targets_mask &= ~(1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES);
|
other_targets_mask &= ~(1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES);
|
||||||
if (other_targets_mask == 0)
|
|
||||||
return;
|
|
||||||
/* try to keep the same target */
|
/* try to keep the same target */
|
||||||
if (targets_mask & other_targets_mask)
|
if (targets_mask & other_targets_mask)
|
||||||
other_targets_mask = 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) {
|
if (loss < *min_loss) {
|
||||||
GstGLTextureTarget target = _texture_target_demask (other_targets_mask);
|
GstGLTextureTarget target = _texture_target_demask (other_targets_mask);
|
||||||
|
|
||||||
if (target != 0) {
|
*out_info = t_info;
|
||||||
*out_info = t_info;
|
*min_loss = loss;
|
||||||
*min_loss = loss;
|
*result = target;
|
||||||
*result = target;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1441,9 +1447,8 @@ gst_gl_color_convert_fixate_format_target (GstCaps * caps, GstCaps * result)
|
||||||
if (!in_format)
|
if (!in_format)
|
||||||
return;
|
return;
|
||||||
targets = gst_structure_get_value (ins, "texture-target");
|
targets = gst_structure_get_value (ins, "texture-target");
|
||||||
targets_mask = gst_gl_value_get_texture_target_mask (targets);
|
if (targets)
|
||||||
if (!targets_mask)
|
targets_mask = gst_gl_value_get_texture_target_mask (targets);
|
||||||
return;
|
|
||||||
|
|
||||||
in_info =
|
in_info =
|
||||||
gst_video_format_get_info (gst_video_format_from_string (in_format));
|
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);
|
tests = gst_caps_get_structure (result, i);
|
||||||
|
|
||||||
format = gst_structure_get_value (tests, "format");
|
format = gst_structure_get_value (tests, "format");
|
||||||
other_targets = gst_structure_get_value (tests, "texture-target");
|
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
if (format == NULL || other_targets == NULL)
|
if (format == NULL)
|
||||||
continue;
|
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)) {
|
if (GST_VALUE_HOLDS_LIST (format)) {
|
||||||
gint j, len;
|
gint j, len;
|
||||||
|
|
|
@ -129,7 +129,9 @@ struct _GstGLColorConvertClass
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"framerate = " GST_VIDEO_FPS_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
|
GST_GL_API
|
||||||
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
||||||
|
|
|
@ -68,6 +68,18 @@ static TestFrame test_rgba_reorder[] = {
|
||||||
{1, 1, GST_VIDEO_FORMAT_BGR, {(gchar *) & bgr_reorder_data}},
|
{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
|
static void
|
||||||
setup (void)
|
setup (void)
|
||||||
{
|
{
|
||||||
|
@ -252,6 +264,65 @@ GST_START_TEST (test_reorder_buffer)
|
||||||
|
|
||||||
GST_END_TEST;
|
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 *
|
static Suite *
|
||||||
gst_gl_color_convert_suite (void)
|
gst_gl_color_convert_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -261,6 +332,7 @@ gst_gl_color_convert_suite (void)
|
||||||
suite_add_tcase (s, tc_chain);
|
suite_add_tcase (s, tc_chain);
|
||||||
tcase_add_checked_fixture (tc_chain, setup, teardown);
|
tcase_add_checked_fixture (tc_chain, setup, teardown);
|
||||||
tcase_add_test (tc_chain, test_reorder_buffer);
|
tcase_add_test (tc_chain, test_reorder_buffer);
|
||||||
|
tcase_add_test (tc_chain, test_passthrough);
|
||||||
/* FIXME add YUV <--> RGB conversion tests */
|
/* FIXME add YUV <--> RGB conversion tests */
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
Loading…
Reference in a new issue