mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
glcolorbalance: Support OES textures for input/passthrough
glcolorbalance is in the default GL path inside glimagesink, so has been causing an possibly-unnecessary extra texture copy on Android for a while now. If we're just doing passthrough, we can support OES directly. If not, they'll be transformed to 2D textures and colourbalanced.
This commit is contained in:
parent
1e28cba088
commit
567bbe3c07
1 changed files with 82 additions and 5 deletions
|
@ -54,17 +54,55 @@ GST_DEBUG_CATEGORY_STATIC (glcolorbalance_debug);
|
||||||
#define DEFAULT_PROP_HUE 0.0
|
#define DEFAULT_PROP_HUE 0.0
|
||||||
#define DEFAULT_PROP_SATURATION 1.0
|
#define DEFAULT_PROP_SATURATION 1.0
|
||||||
|
|
||||||
|
#define GST_GL_COLOR_BALANCE_VIDEO_CAPS \
|
||||||
|
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \
|
||||||
|
"format = (string) RGBA, " \
|
||||||
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
||||||
|
"texture-target = (string) { 2D, external-oes } " \
|
||||||
|
" ; " \
|
||||||
|
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
|
||||||
|
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
|
||||||
|
"format = (string) RGBA, " \
|
||||||
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
||||||
|
"texture-target = (string) { 2D, external-oes }"
|
||||||
|
|
||||||
|
static GstStaticPadTemplate gst_gl_color_balance_element_src_pad_template =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS (GST_GL_COLOR_BALANCE_VIDEO_CAPS));
|
||||||
|
|
||||||
|
static GstStaticPadTemplate gst_gl_color_balance_element_sink_pad_template =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS (GST_GL_COLOR_BALANCE_VIDEO_CAPS));
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
static const gchar *color_balance_frag =
|
static const gchar color_balance_frag_OES_preamble[] =
|
||||||
|
"#extension GL_OES_EGL_image_external : require\n"
|
||||||
|
"#ifdef GL_ES\n"
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"#endif\n"
|
||||||
|
"uniform samplerExternalOES tex;\n";
|
||||||
|
|
||||||
|
static const gchar color_balance_frag_2D_preamble[] =
|
||||||
"#ifdef GL_ES\n"
|
"#ifdef GL_ES\n"
|
||||||
"precision mediump float;\n"
|
"precision mediump float;\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
"uniform sampler2D tex;\n";
|
||||||
|
|
||||||
|
static const gchar color_balance_frag_templ[] =
|
||||||
|
"%s\n" // Preamble
|
||||||
"uniform float brightness;\n"
|
"uniform float brightness;\n"
|
||||||
"uniform float contrast;\n"
|
"uniform float contrast;\n"
|
||||||
"uniform float saturation;\n"
|
"uniform float saturation;\n"
|
||||||
"uniform float hue;\n"
|
"uniform float hue;\n"
|
||||||
"varying vec2 v_texcoord;\n"
|
"varying vec2 v_texcoord;\n"
|
||||||
"uniform sampler2D tex;\n"
|
|
||||||
"#define from_yuv_bt601_offset vec3(-0.0625, -0.5, -0.5)\n"
|
"#define from_yuv_bt601_offset vec3(-0.0625, -0.5, -0.5)\n"
|
||||||
"#define from_yuv_bt601_rcoeff vec3(1.164, 0.000, 1.596)\n"
|
"#define from_yuv_bt601_rcoeff vec3(1.164, 0.000, 1.596)\n"
|
||||||
"#define from_yuv_bt601_gcoeff vec3(1.164,-0.391,-0.813)\n"
|
"#define from_yuv_bt601_gcoeff vec3(1.164,-0.391,-0.813)\n"
|
||||||
|
@ -105,7 +143,7 @@ static const gchar *color_balance_frag =
|
||||||
* blend-function-src-rgb=src-color and blend-function-dst-rgb=dst-color */
|
* blend-function-src-rgb=src-color and blend-function-dst-rgb=dst-color */
|
||||||
" float hue_cos = cos (PI * hue);\n"
|
" float hue_cos = cos (PI * hue);\n"
|
||||||
" float hue_sin = sin (PI * hue);\n"
|
" float hue_sin = sin (PI * hue);\n"
|
||||||
" vec4 rgba = texture2D (tex, v_texcoord);\n"
|
" vec4 rgba = %s (tex, v_texcoord);\n" /* texture2D / texture2DOES */
|
||||||
" yuv = rgb_to_yuv (rgba.rgb);\n"
|
" yuv = rgb_to_yuv (rgba.rgb);\n"
|
||||||
" yuv.x = clamp (luma_to_narrow (luma_to_full(yuv.x) * contrast) + brightness, 0.0, 1.0);\n"
|
" yuv.x = clamp (luma_to_narrow (luma_to_full(yuv.x) * contrast) + brightness, 0.0, 1.0);\n"
|
||||||
" vec2 uv = yuv.yz;\n"
|
" vec2 uv = yuv.yz;\n"
|
||||||
|
@ -139,6 +177,28 @@ G_DEFINE_TYPE_WITH_CODE (GstGLColorBalance, gst_gl_color_balance,
|
||||||
G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
|
G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
|
||||||
gst_gl_color_balance_colorbalance_init));
|
gst_gl_color_balance_colorbalance_init));
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
gcb_transform_internal_caps (GstGLFilter * filter,
|
||||||
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter_caps)
|
||||||
|
{
|
||||||
|
GstCaps *tmp = gst_caps_make_writable (caps);
|
||||||
|
gint i;
|
||||||
|
/* If we're not in passthrough mode, we can only output 2D textures,
|
||||||
|
* but can always receive any compatible texture.
|
||||||
|
* This function is not called in passthrough mode, so we can do the
|
||||||
|
* transform unconditionally */
|
||||||
|
for (i = 0; i < gst_caps_get_size (tmp); i++) {
|
||||||
|
GstStructure *outs = gst_caps_get_structure (tmp, i);
|
||||||
|
if (direction == GST_PAD_SINK) {
|
||||||
|
gst_structure_set (outs, "texture-target", G_TYPE_STRING,
|
||||||
|
gst_gl_texture_target_to_string (GST_GL_TEXTURE_TARGET_2D), NULL);
|
||||||
|
} else {
|
||||||
|
gst_structure_remove_field (outs, "texture-target");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_color_balance_is_passthrough (GstGLColorBalance * glcolorbalance)
|
gst_gl_color_balance_is_passthrough (GstGLColorBalance * glcolorbalance)
|
||||||
{
|
{
|
||||||
|
@ -169,22 +229,35 @@ _create_shader (GstGLColorBalance * balance)
|
||||||
GstGLBaseFilter *base_filter = GST_GL_BASE_FILTER (balance);
|
GstGLBaseFilter *base_filter = GST_GL_BASE_FILTER (balance);
|
||||||
GstGLFilter *filter = GST_GL_FILTER (balance);
|
GstGLFilter *filter = GST_GL_FILTER (balance);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
gchar *frag_str;
|
||||||
|
|
||||||
if (balance->shader)
|
if (balance->shader)
|
||||||
gst_object_unref (balance->shader);
|
gst_object_unref (balance->shader);
|
||||||
|
|
||||||
|
/* Can support rectangle textures in the future if needed */
|
||||||
|
if (filter->in_texture_target == GST_GL_TEXTURE_TARGET_2D)
|
||||||
|
frag_str =
|
||||||
|
g_strdup_printf (color_balance_frag_templ,
|
||||||
|
color_balance_frag_2D_preamble, "texture2D");
|
||||||
|
else
|
||||||
|
frag_str =
|
||||||
|
g_strdup_printf (color_balance_frag_templ,
|
||||||
|
color_balance_frag_OES_preamble, "texture2D");
|
||||||
|
|
||||||
if (!(balance->shader =
|
if (!(balance->shader =
|
||||||
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
|
gst_gl_shader_new_link_with_stages (base_filter->context, &error,
|
||||||
gst_glsl_stage_new_default_vertex (base_filter->context),
|
gst_glsl_stage_new_default_vertex (base_filter->context),
|
||||||
gst_glsl_stage_new_with_string (base_filter->context,
|
gst_glsl_stage_new_with_string (base_filter->context,
|
||||||
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
|
GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE,
|
||||||
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
|
GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
|
||||||
color_balance_frag), NULL))) {
|
frag_str), NULL))) {
|
||||||
|
g_free (frag_str);
|
||||||
GST_ELEMENT_ERROR (balance, RESOURCE, NOT_FOUND, ("%s",
|
GST_ELEMENT_ERROR (balance, RESOURCE, NOT_FOUND, ("%s",
|
||||||
"Failed to initialize colorbalance shader"), ("%s",
|
"Failed to initialize colorbalance shader"), ("%s",
|
||||||
error ? error->message : "Unknown error"));
|
error ? error->message : "Unknown error"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
g_free (frag_str);
|
||||||
|
|
||||||
filter->draw_attr_position_loc =
|
filter->draw_attr_position_loc =
|
||||||
gst_gl_shader_get_attribute_location (balance->shader, "a_position");
|
gst_gl_shader_get_attribute_location (balance->shader, "a_position");
|
||||||
|
@ -292,7 +365,10 @@ gst_gl_color_balance_class_init (GstGLColorBalanceClass * klass)
|
||||||
GST_DEBUG_CATEGORY_INIT (glcolorbalance_debug, "glcolorbalance", 0,
|
GST_DEBUG_CATEGORY_INIT (glcolorbalance_debug, "glcolorbalance", 0,
|
||||||
"glcolorbalance");
|
"glcolorbalance");
|
||||||
|
|
||||||
gst_gl_filter_add_rgba_pad_templates (GST_GL_FILTER_CLASS (klass));
|
gst_element_class_add_static_pad_template (gstelement_class,
|
||||||
|
&gst_gl_color_balance_element_src_pad_template);
|
||||||
|
gst_element_class_add_static_pad_template (gstelement_class,
|
||||||
|
&gst_gl_color_balance_element_sink_pad_template);
|
||||||
|
|
||||||
gobject_class->finalize = gst_gl_color_balance_finalize;
|
gobject_class->finalize = gst_gl_color_balance_finalize;
|
||||||
gobject_class->set_property = gst_gl_color_balance_set_property;
|
gobject_class->set_property = gst_gl_color_balance_set_property;
|
||||||
|
@ -329,6 +405,7 @@ gst_gl_color_balance_class_init (GstGLColorBalanceClass * klass)
|
||||||
|
|
||||||
filter_class->filter_texture =
|
filter_class->filter_texture =
|
||||||
GST_DEBUG_FUNCPTR (gst_gl_color_balance_filter_texture);
|
GST_DEBUG_FUNCPTR (gst_gl_color_balance_filter_texture);
|
||||||
|
filter_class->transform_internal_caps = gcb_transform_internal_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue