GstGLMemory *in_tex[GST_VIDEO_MAX_PLANES];
GstGLMemory *out_tex[GST_VIDEO_MAX_PLANES];
+ GstVideoGLTextureType in_tex_types[GST_VIDEO_MAX_PLANES];
+
GLuint vao;
GLuint vertex_buffer;
GLuint vbo_indices;
}
static void
-gst_gl_color_convert_reset (GstGLColorConvert * convert)
+gst_gl_color_convert_reset_shader (GstGLColorConvert * convert)
{
- guint i;
-
- if (convert->fbo || convert->depth_buffer) {
- gst_gl_context_del_fbo (convert->context, convert->fbo,
- convert->depth_buffer);
- convert->fbo = 0;
- convert->depth_buffer = 0;
- }
-
- for (i = 0; i < convert->priv->convert_info.out_n_textures; i++) {
- if (convert->priv->out_tex[i])
- gst_memory_unref ((GstMemory *) convert->priv->out_tex[i]);
- convert->priv->out_tex[i] = NULL;
- }
-
convert->priv->convert_info.chroma_sampling[0] = 1.0f;
convert->priv->convert_info.chroma_sampling[1] = 1.0f;
convert->shader = NULL;
}
+ convert->initted = FALSE;
+}
+
+static void
+gst_gl_color_convert_reset (GstGLColorConvert * convert)
+{
+ guint i;
+
+ if (convert->fbo || convert->depth_buffer) {
+ gst_gl_context_del_fbo (convert->context, convert->fbo,
+ convert->depth_buffer);
+ convert->fbo = 0;
+ convert->depth_buffer = 0;
+ }
+
+ for (i = 0; i < convert->priv->convert_info.out_n_textures; i++) {
+ if (convert->priv->out_tex[i])
+ gst_memory_unref ((GstMemory *) convert->priv->out_tex[i]);
+ convert->priv->out_tex[i] = NULL;
+ }
+
if (convert->priv->pool) {
convert->priv->pool_started = FALSE;
gst_object_unref (convert->priv->pool);
convert->priv->pool = NULL;
}
+
gst_caps_replace (&convert->priv->in_caps, NULL);
gst_caps_replace (&convert->priv->out_caps, NULL);
gst_gl_context_thread_add (convert->context,
(GstGLContextThreadFunc) _reset_gl, convert);
}
+
+ gst_gl_color_convert_reset_shader (convert);
}
static gboolean
GST_BUFFER_POOL_OPTION_GL_SYNC_META);
params = gst_gl_video_allocation_params_new (convert->context, NULL, &vinfo,
- 0, NULL, convert->priv->to_texture_target);
+ 0, NULL, convert->priv->to_texture_target, 0);
gst_buffer_pool_config_set_gl_allocation_params (config,
(GstGLAllocationParams *) params);
gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
return g_string_free (ret, discard_output);
}
+static guint
+_get_n_textures (GstVideoFormat v_format)
+{
+ switch (v_format) {
+ case GST_VIDEO_FORMAT_RGBA:
+ case GST_VIDEO_FORMAT_RGBx:
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_BGRx:
+ case GST_VIDEO_FORMAT_ABGR:
+ case GST_VIDEO_FORMAT_xBGR:
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_AYUV:
+ case GST_VIDEO_FORMAT_GRAY8:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ case GST_VIDEO_FORMAT_YUY2:
+ case GST_VIDEO_FORMAT_UYVY:
+ return 1;
+ case GST_VIDEO_FORMAT_NV12:
+ case GST_VIDEO_FORMAT_NV21:
+ return 2;
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_Y444:
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_Y41B:
+ case GST_VIDEO_FORMAT_YV12:
+ return 3;
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
static void
_RGB_to_RGB (GstGLColorConvert * convert)
{
gchar *pixel_order = _RGB_pixel_order (in_format_str, out_format_str);
gchar *alpha = NULL;
- info->in_n_textures = 1;
- info->out_n_textures = 1;
if (_is_RGBx (in_format)) {
int i;
char input_alpha_channel = 'a';
GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
const gchar *out_format_str = gst_video_format_to_string (out_format);
gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
- gboolean texture_rg =
- gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
- || gst_gl_context_check_gl_version (convert->context, GST_GL_API_GLES2, 3,
- 0)
- || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg")
- || gst_gl_context_check_gl_version (convert->context, GST_GL_API_OPENGL3,
- 3, 0);
gboolean apple_ycbcr = gst_gl_context_check_feature (convert->context,
"GL_APPLE_ycbcr_422");
gboolean in_tex_rectangular = FALSE;
info->frag_body =
g_strdup_printf (info->templ->body, pixel_order[0], pixel_order[1],
pixel_order[2], pixel_order[3]);
- info->in_n_textures = 1;
info->shader_tex_names[0] = "tex";
} else {
switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) {
info->templ = &templ_AYUV_to_RGB;
info->frag_body = g_strdup_printf (info->templ->body, pixel_order[0],
pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 1;
info->shader_tex_names[0] = "tex";
break;
case GST_VIDEO_FORMAT_I420:
info->frag_body =
g_strdup_printf (info->templ->body, pixel_order[0],
pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 3;
info->shader_tex_names[0] = "Ytex";
info->shader_tex_names[1] = "Utex";
info->shader_tex_names[2] = "Vtex";
info->frag_body =
g_strdup_printf (info->templ->body, pixel_order[0],
pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 3;
info->shader_tex_names[0] = "Ytex";
info->shader_tex_names[1] = "Vtex";
info->shader_tex_names[2] = "Utex";
break;
case GST_VIDEO_FORMAT_YUY2:
{
- char uv_val = texture_rg ? 'g' : 'a';
+ char uv_val =
+ convert->priv->in_tex_types[0] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_YUY2_UYVY_to_RGB;
info->frag_body = g_strdup_printf (info->templ->body, 'r', uv_val,
uv_val, 'g', 'a', pixel_order[0], pixel_order[1], pixel_order[2],
pixel_order[3]);
- info->in_n_textures = 1;
info->shader_tex_names[0] = "Ytex";
break;
}
case GST_VIDEO_FORMAT_UYVY:
{
- char y_val = texture_rg ? 'g' : 'a';
+ char y_val =
+ convert->priv->in_tex_types[0] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_YUY2_UYVY_to_RGB;
info->frag_body = g_strdup_printf (info->templ->body, y_val, 'g',
'g', 'r', 'b', pixel_order[0], pixel_order[1], pixel_order[2],
pixel_order[3]);
- info->in_n_textures = 1;
info->shader_tex_names[0] = "Ytex";
break;
}
case GST_VIDEO_FORMAT_NV12:
{
- char val2 = texture_rg ? 'g' : 'a';
+ char val2 =
+ convert->priv->in_tex_types[1] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_NV12_NV21_to_RGB;
info->frag_body = g_strdup_printf (info->templ->body, 'r', val2,
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 2;
info->shader_tex_names[0] = "Ytex";
info->shader_tex_names[1] = "UVtex";
break;
}
case GST_VIDEO_FORMAT_NV21:
{
- char val2 = texture_rg ? 'g' : 'a';
+ char val2 =
+ convert->priv->in_tex_types[1] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_NV12_NV21_to_RGB;
info->frag_body = g_strdup_printf (info->templ->body, val2, 'r',
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 2;
info->shader_tex_names[0] = "Ytex";
info->shader_tex_names[1] = "UVtex";
break;
const gchar *alpha;
info->frag_prog = NULL;
- info->in_n_textures = 1;
info->shader_tex_names[0] = "tex";
gchar *pixel_order = _RGB_pixel_order (in_format_str, "rgba");
gchar *alpha = NULL;
- info->in_n_textures = 1;
info->out_n_textures = 1;
info->shader_tex_names[0] = "tex";
GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
const gchar *out_format_str = gst_video_format_to_string (out_format);
gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
- gboolean texture_rg =
- gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
- || gst_gl_context_check_gl_version (convert->context, GST_GL_API_GLES2, 3,
- 0)
- || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg")
- || gst_gl_context_check_gl_version (convert->context, GST_GL_API_OPENGL3,
- 3, 0);
- info->in_n_textures = 1;
- info->out_n_textures = 1;
info->shader_tex_names[0] = "tex";
switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) {
break;
case GST_VIDEO_FORMAT_GRAY16_LE:
{
- char val2 = texture_rg ? 'g' : 'a';
+ char val2 =
+ convert->priv->in_tex_types[0] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_COMPOSE;
info->frag_body = g_strdup_printf (info->templ->body, val2, 'r',
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
}
case GST_VIDEO_FORMAT_GRAY16_BE:
{
- char val2 = texture_rg ? 'g' : 'a';
+ char val2 =
+ convert->priv->in_tex_types[0] ==
+ GST_VIDEO_GL_TEXTURE_TYPE_RG ? 'g' : 'a';
info->templ = &templ_COMPOSE;
info->frag_body = g_strdup_printf (info->templ->body, 'r', val2,
pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
gst_gl_context_clear_shader (convert->context);
- if (!_init_convert_fbo (convert)) {
+ if (convert->fbo == 0 && !_init_convert_fbo (convert)) {
goto error;
}
_do_convert (GstGLContext * context, GstGLColorConvert * convert)
{
GstVideoInfo *in_info = &convert->in_info;
+ struct ConvertInfo *c_info = &convert->priv->convert_info;
gboolean res = TRUE;
gint views, v;
GstVideoOverlayCompositionMeta *composition_meta;
convert->outbuf = NULL;
+ if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
+ GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
+ views = GST_VIDEO_INFO_VIEWS (in_info);
+ else
+ views = 1;
+
+ c_info->in_n_textures =
+ _get_n_textures (GST_VIDEO_INFO_FORMAT (&convert->in_info));
+ c_info->out_n_textures =
+ _get_n_textures (GST_VIDEO_INFO_FORMAT (&convert->out_info));
+
+ {
+ gboolean tex_type_change = FALSE;
+ guint i, v;
+
+ for (v = 0; v < views; v++) {
+ for (i = 0; i < c_info->in_n_textures; i++) {
+ guint j = v * c_info->in_n_textures + i;
+ GstGLMemory *in_tex =
+ (GstGLMemory *) gst_buffer_peek_memory (convert->inbuf, j);
+ if (!gst_is_gl_memory ((GstMemory *) in_tex)) {
+ GST_ERROR_OBJECT (convert, "input must be GstGLMemory");
+ convert->priv->result = FALSE;
+ return;
+ }
+
+ if (j >= GST_VIDEO_MAX_PLANES)
+ /* our arrays aren't that big */
+ g_assert_not_reached ();
+
+ if (v > 0 && in_tex->tex_type != convert->priv->in_tex_types[i]) {
+ GST_ERROR_OBJECT (convert, "Cannot convert textures with "
+ "different types");
+ convert->priv->result = FALSE;
+ return;
+ }
+
+ if (convert->priv->in_tex_types[j] != in_tex->tex_type)
+ tex_type_change = TRUE;
+
+ convert->priv->in_tex_types[j] = in_tex->tex_type;
+ }
+ }
+
+ if (tex_type_change)
+ gst_gl_color_convert_reset_shader (convert);
+ }
+
if (!_init_convert (convert)) {
convert->priv->result = FALSE;
return;
return;
}
- if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
- GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
- views = GST_VIDEO_INFO_VIEWS (in_info);
- else
- views = 1;
-
gst_gl_insert_debug_marker (context, "%s converting from %s to %s",
GST_OBJECT_NAME (convert),
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)),