mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
glupload: always add texture-target field to GL caps
1. Various elements/base classes only perform a subset check on accept-caps 2. Some GL elements have texture-target in their pad template 3. When checking subsets, only the caps to check are allowed to contain extra fields. If the 'template' caps have extra fields, the subset fails. Thus without texture-target on the caps, various accept-caps implementations were failing. Also, add some convenience functions for setting and retrieving texture targets to/from GValue. https://bugzilla.gnome.org/show_bug.cgi?id=759860
This commit is contained in:
parent
ec5eb678d0
commit
86110c4765
4 changed files with 200 additions and 37 deletions
|
@ -701,41 +701,6 @@ gst_gl_color_convert_set_caps (GstGLColorConvert * convert,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static guint
|
||||
_get_target_bitmask_from_g_value (const GValue * targets)
|
||||
{
|
||||
guint new_targets = 0;
|
||||
|
||||
if (targets == NULL) {
|
||||
new_targets = 1 << GST_GL_TEXTURE_TARGET_2D;
|
||||
} else if (G_TYPE_CHECK_VALUE_TYPE (targets, G_TYPE_STRING)) {
|
||||
GstGLTextureTarget target;
|
||||
const gchar *str;
|
||||
|
||||
str = g_value_get_string (targets);
|
||||
target = gst_gl_texture_target_from_string (str);
|
||||
|
||||
if (target)
|
||||
new_targets |= 1 << target;
|
||||
} else if (G_TYPE_CHECK_VALUE_TYPE (targets, GST_TYPE_LIST)) {
|
||||
gint j, m;
|
||||
|
||||
m = gst_value_list_get_size (targets);
|
||||
for (j = 0; j < m; j++) {
|
||||
const GValue *val = gst_value_list_get_value (targets, j);
|
||||
GstGLTextureTarget target;
|
||||
const gchar *str;
|
||||
|
||||
str = g_value_get_string (val);
|
||||
target = gst_gl_texture_target_from_string (str);
|
||||
if (target)
|
||||
new_targets |= 1 << target;
|
||||
}
|
||||
}
|
||||
|
||||
return new_targets;
|
||||
}
|
||||
|
||||
/* copies the given caps */
|
||||
static GstCaps *
|
||||
gst_gl_color_convert_caps_remove_format_info (GstCaps * caps)
|
||||
|
@ -809,8 +774,8 @@ gst_gl_color_convert_fixate_caps (GstGLContext * convert,
|
|||
targets = gst_structure_get_value (s, "texture-target");
|
||||
other_targets = gst_structure_get_value (s_other, "texture-target");
|
||||
|
||||
targets_mask = _get_target_bitmask_from_g_value (targets);
|
||||
other_targets_mask = _get_target_bitmask_from_g_value (other_targets);
|
||||
targets_mask = gst_gl_value_get_texture_target_mask (targets);
|
||||
other_targets_mask = gst_gl_value_get_texture_target_mask (other_targets);
|
||||
|
||||
/* XXX: attempt to fixate the format/colorimetry/etc */
|
||||
other = gst_caps_fixate (other);
|
||||
|
|
|
@ -142,6 +142,22 @@ _set_caps_features_with_passthrough (const GstCaps * caps,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
_caps_intersect_texture_target (GstCaps * caps, GstGLTextureTarget target_mask)
|
||||
{
|
||||
GValue targets = G_VALUE_INIT;
|
||||
GstCaps *ret, *target;
|
||||
|
||||
target = gst_caps_copy (caps);
|
||||
gst_gl_value_set_texture_target_from_mask (&targets, target_mask);
|
||||
gst_caps_set_value (target, "texture-target", &targets);
|
||||
|
||||
ret = gst_caps_intersect_full (caps, target, GST_CAPS_INTERSECT_FIRST);
|
||||
|
||||
gst_caps_unref (target);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
METHOD_FLAG_CAN_SHARE_CONTEXT = 1,
|
||||
|
@ -196,6 +212,27 @@ _gl_memory_upload_transform_caps (GstGLContext * context,
|
|||
|
||||
gst_caps_features_free (passthrough);
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstGLTextureTarget target_mask = 0;
|
||||
GstCaps *tmp;
|
||||
|
||||
target_mask |= 1 << GST_GL_TEXTURE_TARGET_2D;
|
||||
target_mask |= 1 << GST_GL_TEXTURE_TARGET_RECTANGLE;
|
||||
target_mask |= 1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
|
||||
tmp = _caps_intersect_texture_target (ret, target_mask);
|
||||
gst_caps_unref (ret);
|
||||
ret = tmp;
|
||||
} else {
|
||||
gint i, n;
|
||||
|
||||
n = gst_caps_get_size (ret);
|
||||
for (i = 0; i < n; i++) {
|
||||
GstStructure *s = gst_caps_get_structure (ret, i);
|
||||
|
||||
gst_structure_remove_fields (s, "texture-target", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -407,9 +444,15 @@ _egl_image_upload_transform_caps (GstGLContext * context,
|
|||
GstCaps *ret;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstCaps *tmp;
|
||||
|
||||
ret =
|
||||
_set_caps_features_with_passthrough (caps,
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough);
|
||||
|
||||
tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D);
|
||||
gst_caps_unref (ret);
|
||||
ret = tmp;
|
||||
} else {
|
||||
gint i, n;
|
||||
|
||||
|
@ -622,9 +665,15 @@ _dma_buf_upload_transform_caps (GstGLContext * context,
|
|||
GstCaps *ret;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstCaps *tmp;
|
||||
|
||||
ret =
|
||||
_set_caps_features_with_passthrough (caps,
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough);
|
||||
|
||||
tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D);
|
||||
gst_caps_unref (ret);
|
||||
ret = tmp;
|
||||
} else {
|
||||
gint i, n;
|
||||
|
||||
|
@ -888,9 +937,15 @@ _upload_meta_upload_transform_caps (GstGLContext * context,
|
|||
GstCaps *ret;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstCaps *tmp;
|
||||
|
||||
ret =
|
||||
_set_caps_features_with_passthrough (caps,
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough);
|
||||
|
||||
tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D);
|
||||
gst_caps_unref (ret);
|
||||
ret = tmp;
|
||||
} else {
|
||||
gint i, n;
|
||||
|
||||
|
@ -1176,9 +1231,18 @@ _raw_data_upload_transform_caps (GstGLContext * context,
|
|||
GstCaps *ret;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstGLTextureTarget target_mask = 0;
|
||||
GstCaps *tmp;
|
||||
|
||||
ret =
|
||||
_set_caps_features_with_passthrough (caps,
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough);
|
||||
|
||||
target_mask |= 1 << GST_GL_TEXTURE_TARGET_2D;
|
||||
target_mask |= 1 << GST_GL_TEXTURE_TARGET_RECTANGLE;
|
||||
tmp = _caps_intersect_texture_target (ret, target_mask);
|
||||
gst_caps_unref (ret);
|
||||
ret = tmp;
|
||||
} else {
|
||||
gint i, n;
|
||||
|
||||
|
|
|
@ -947,3 +947,132 @@ gst_gl_caps_replace_all_caps_features (const GstCaps * caps,
|
|||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_value_get_texture_target_mask:
|
||||
* @value: an initialized #GValue of type G_TYPE_STRING
|
||||
*
|
||||
* See gst_gl_value_set_texture_target_mask() for what entails a mask
|
||||
*
|
||||
* Returns: the mask of #GstGLTextureTarget's in @value
|
||||
*/
|
||||
GstGLTextureTarget
|
||||
gst_gl_value_get_texture_target_mask (const GValue * targets)
|
||||
{
|
||||
guint new_targets = 0;
|
||||
|
||||
g_return_val_if_fail (targets != NULL, GST_GL_TEXTURE_TARGET_NONE);
|
||||
|
||||
if (G_TYPE_CHECK_VALUE_TYPE (targets, G_TYPE_STRING)) {
|
||||
GstGLTextureTarget target;
|
||||
const gchar *str;
|
||||
|
||||
str = g_value_get_string (targets);
|
||||
target = gst_gl_texture_target_from_string (str);
|
||||
|
||||
if (target)
|
||||
new_targets |= 1 << target;
|
||||
} else if (G_TYPE_CHECK_VALUE_TYPE (targets, GST_TYPE_LIST)) {
|
||||
gint j, m;
|
||||
|
||||
m = gst_value_list_get_size (targets);
|
||||
for (j = 0; j < m; j++) {
|
||||
const GValue *val = gst_value_list_get_value (targets, j);
|
||||
GstGLTextureTarget target;
|
||||
const gchar *str;
|
||||
|
||||
str = g_value_get_string (val);
|
||||
target = gst_gl_texture_target_from_string (str);
|
||||
if (target)
|
||||
new_targets |= 1 << target;
|
||||
}
|
||||
}
|
||||
|
||||
return new_targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_value_set_texture_target:
|
||||
* @value: an initialized #GValue of type G_TYPE_STRING
|
||||
* @target: a #GstGLTextureTarget's
|
||||
*
|
||||
* Returns: whether the @target could be set on @value
|
||||
*/
|
||||
gboolean
|
||||
gst_gl_value_set_texture_target (GValue * value, GstGLTextureTarget target)
|
||||
{
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (target != GST_GL_TEXTURE_TARGET_NONE, FALSE);
|
||||
|
||||
if (target == GST_GL_TEXTURE_TARGET_2D) {
|
||||
g_value_set_static_string (value, GST_GL_TEXTURE_TARGET_2D_STR);
|
||||
} else if (target == GST_GL_TEXTURE_TARGET_RECTANGLE) {
|
||||
g_value_set_static_string (value, GST_GL_TEXTURE_TARGET_RECTANGLE_STR);
|
||||
} else if (target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
|
||||
g_value_set_static_string (value, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint64
|
||||
_gst_gl_log2_int64 (guint64 value)
|
||||
{
|
||||
guint64 ret = 0;
|
||||
|
||||
while (value >>= 1)
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_value_set_texture_target_from_mask:
|
||||
* @value: an uninitialized #GValue
|
||||
* @target_mask: a bitwise mask of #GstGLTextureTarget's
|
||||
*
|
||||
* A mask is a bitwise OR of (1 << target) where target is a valid
|
||||
* #GstGLTextureTarget
|
||||
*
|
||||
* Returns: whether the @target_mask could be set on @value
|
||||
*/
|
||||
gboolean
|
||||
gst_gl_value_set_texture_target_from_mask (GValue * value,
|
||||
GstGLTextureTarget target_mask)
|
||||
{
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (target_mask != GST_GL_TEXTURE_TARGET_NONE, FALSE);
|
||||
|
||||
if ((target_mask & (target_mask - 1)) == 0) {
|
||||
/* only one texture target set */
|
||||
g_value_init (value, G_TYPE_STRING);
|
||||
return gst_gl_value_set_texture_target (value,
|
||||
_gst_gl_log2_int64 (target_mask));
|
||||
} else {
|
||||
GValue item = G_VALUE_INIT;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_value_init (value, GST_TYPE_LIST);
|
||||
g_value_init (&item, G_TYPE_STRING);
|
||||
if (target_mask & (1 << GST_GL_TEXTURE_TARGET_2D)) {
|
||||
gst_gl_value_set_texture_target (&item, GST_GL_TEXTURE_TARGET_2D);
|
||||
gst_value_list_append_value (value, &item);
|
||||
ret = TRUE;
|
||||
}
|
||||
if (target_mask & (1 << GST_GL_TEXTURE_TARGET_RECTANGLE)) {
|
||||
gst_gl_value_set_texture_target (&item, GST_GL_TEXTURE_TARGET_RECTANGLE);
|
||||
gst_value_list_append_value (value, &item);
|
||||
ret = TRUE;
|
||||
}
|
||||
if (target_mask & (1 << GST_GL_TEXTURE_TARGET_EXTERNAL_OES)) {
|
||||
gst_gl_value_set_texture_target (&item,
|
||||
GST_GL_TEXTURE_TARGET_EXTERNAL_OES);
|
||||
gst_value_list_append_value (value, &item);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,11 @@ gsize gst_gl_get_plane_start (GstVideoInfo * info, GstVideoAlignment * valign,
|
|||
GstCaps * gst_gl_caps_replace_all_caps_features (const GstCaps * caps,
|
||||
const gchar * feature_name);
|
||||
|
||||
gboolean gst_gl_value_set_texture_target_from_mask (GValue * value,
|
||||
GstGLTextureTarget target_mask);
|
||||
gboolean gst_gl_value_set_texture_target (GValue * value, GstGLTextureTarget target);
|
||||
GstGLTextureTarget gst_gl_value_get_texture_target_mask (const GValue * value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_UTILS_H__ */
|
||||
|
|
Loading…
Reference in a new issue