mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
eglglessink: Clean-up gl/egl allocations at _stop()
Also, conditionaly destroy window if the sink created its own.
This commit is contained in:
parent
99765c3333
commit
63d8cd88c7
2 changed files with 62 additions and 42 deletions
|
@ -1007,17 +1007,32 @@ gst_eglglessink_wipe_fmt (gpointer data)
|
||||||
g_free (format);
|
g_free (format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: Should implement */
|
/* Drafted */
|
||||||
gboolean
|
gboolean
|
||||||
gst_eglglessink_stop (GstBaseSink * sink)
|
gst_eglglessink_stop (GstBaseSink * sink)
|
||||||
{
|
{
|
||||||
GstEglGlesSink *eglglessink = GST_EGLGLESSINK (sink);
|
GstEglGlesSink *eglglessink = GST_EGLGLESSINK (sink);
|
||||||
|
|
||||||
platform_destroy_native_window (eglglessink->display, eglglessink->window);
|
|
||||||
|
|
||||||
eglglessink->selected_fmt = NULL;
|
eglglessink->selected_fmt = NULL;
|
||||||
g_list_free_full (eglglessink->supported_fmts, gst_eglglessink_wipe_fmt);
|
g_list_free_full (eglglessink->supported_fmts, gst_eglglessink_wipe_fmt);
|
||||||
|
|
||||||
|
/* EGL/GLES2 cleanup */
|
||||||
|
|
||||||
|
if (eglglessink->rendering_path == GST_EGLGLESSINK_RENDER_SLOW) {
|
||||||
|
glDeleteBuffers (1, &eglglessink->vdata);
|
||||||
|
glDeleteBuffers (1, &eglglessink->tdata);
|
||||||
|
glDeleteBuffers (1, &eglglessink->idata);
|
||||||
|
|
||||||
|
glDeleteShader (eglglessink->fragshader);
|
||||||
|
glDeleteShader (eglglessink->vertshader);
|
||||||
|
|
||||||
|
glDeleteTextures (eglglessink->n_textures, eglglessink->texture);
|
||||||
|
glDeleteProgram (eglglessink->program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eglglessink->using_own_window)
|
||||||
|
platform_destroy_native_window (eglglessink->display, eglglessink->window);
|
||||||
|
|
||||||
g_mutex_free (eglglessink->flow_lock);
|
g_mutex_free (eglglessink->flow_lock);
|
||||||
eglglessink->flow_lock = NULL;
|
eglglessink->flow_lock = NULL;
|
||||||
|
|
||||||
|
@ -1313,10 +1328,8 @@ static gboolean
|
||||||
gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
{
|
{
|
||||||
GLint test;
|
GLint test;
|
||||||
GLuint verthandle, fraghandle, prog;
|
|
||||||
GLboolean ret;
|
GLboolean ret;
|
||||||
GLchar *info_log;
|
GLchar *info_log;
|
||||||
gint n_textures = 0;
|
|
||||||
const gchar *texnames[3] = { NULL, };
|
const gchar *texnames[3] = { NULL, };
|
||||||
gchar *tmp_prog = NULL;
|
gchar *tmp_prog = NULL;
|
||||||
|
|
||||||
|
@ -1367,70 +1380,70 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
verthandle = glCreateShader (GL_VERTEX_SHADER);
|
eglglessink->vertshader = glCreateShader (GL_VERTEX_SHADER);
|
||||||
GST_DEBUG_OBJECT (eglglessink, "sending %s to handle %d", vert_COPY_prog,
|
GST_DEBUG_OBJECT (eglglessink, "sending %s to handle %d", vert_COPY_prog,
|
||||||
verthandle);
|
eglglessink->vertshader);
|
||||||
glShaderSource (verthandle, 1, &vert_COPY_prog, NULL);
|
glShaderSource (eglglessink->vertshader, 1, &vert_COPY_prog, NULL);
|
||||||
if (got_gl_error ("glShaderSource vertex"))
|
if (got_gl_error ("glShaderSource vertex"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
|
|
||||||
glCompileShader (verthandle);
|
glCompileShader (eglglessink->vertshader);
|
||||||
if (got_gl_error ("glCompileShader vertex"))
|
if (got_gl_error ("glCompileShader vertex"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
|
|
||||||
glGetShaderiv (verthandle, GL_COMPILE_STATUS, &test);
|
glGetShaderiv (eglglessink->vertshader, GL_COMPILE_STATUS, &test);
|
||||||
if (test != GL_FALSE)
|
if (test != GL_FALSE)
|
||||||
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled vertex shader");
|
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled vertex shader");
|
||||||
else {
|
else {
|
||||||
GST_ERROR_OBJECT (eglglessink, "Couldn't compile vertex shader");
|
GST_ERROR_OBJECT (eglglessink, "Couldn't compile vertex shader");
|
||||||
glGetShaderiv (verthandle, GL_INFO_LOG_LENGTH, &test);
|
glGetShaderiv (eglglessink->vertshader, GL_INFO_LOG_LENGTH, &test);
|
||||||
info_log = g_new0 (GLchar, test);
|
info_log = g_new0 (GLchar, test);
|
||||||
glGetShaderInfoLog (verthandle, test, NULL, info_log);
|
glGetShaderInfoLog (eglglessink->vertshader, test, NULL, info_log);
|
||||||
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
|
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
|
||||||
g_free (info_log);
|
g_free (info_log);
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fraghandle = glCreateShader (GL_FRAGMENT_SHADER);
|
eglglessink->fragshader = glCreateShader (GL_FRAGMENT_SHADER);
|
||||||
switch (eglglessink->format) {
|
switch (eglglessink->format) {
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
glShaderSource (fraghandle, 1, &frag_AYUV_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, &frag_AYUV_prog, NULL);
|
||||||
n_textures = 1;
|
eglglessink->n_textures = 1;
|
||||||
texnames[0] = "tex";
|
texnames[0] = "tex";
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
case GST_VIDEO_FORMAT_YV12:
|
case GST_VIDEO_FORMAT_YV12:
|
||||||
glShaderSource (fraghandle, 1, &frag_I420_YV12_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, &frag_I420_YV12_prog, NULL);
|
||||||
n_textures = 3;
|
eglglessink->n_textures = 3;
|
||||||
texnames[0] = "Ytex";
|
texnames[0] = "Ytex";
|
||||||
texnames[1] = "Utex";
|
texnames[1] = "Utex";
|
||||||
texnames[2] = "Vtex";
|
texnames[2] = "Vtex";
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
tmp_prog = g_strdup_printf (frag_YUY2_UYVY_prog, 'r', 'g', 'a');
|
tmp_prog = g_strdup_printf (frag_YUY2_UYVY_prog, 'r', 'g', 'a');
|
||||||
glShaderSource (fraghandle, 1, (const GLchar **) &tmp_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, (const GLchar **) &tmp_prog, NULL);
|
||||||
n_textures = 2;
|
eglglessink->n_textures = 2;
|
||||||
texnames[0] = "Ytex";
|
texnames[0] = "Ytex";
|
||||||
texnames[1] = "UVtex";
|
texnames[1] = "UVtex";
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_UYVY:
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
tmp_prog = g_strdup_printf (frag_YUY2_UYVY_prog, 'a', 'r', 'b');
|
tmp_prog = g_strdup_printf (frag_YUY2_UYVY_prog, 'a', 'r', 'b');
|
||||||
glShaderSource (fraghandle, 1, (const GLchar **) &tmp_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, (const GLchar **) &tmp_prog, NULL);
|
||||||
n_textures = 2;
|
eglglessink->n_textures = 2;
|
||||||
texnames[0] = "Ytex";
|
texnames[0] = "Ytex";
|
||||||
texnames[1] = "UVtex";
|
texnames[1] = "UVtex";
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_NV12:
|
case GST_VIDEO_FORMAT_NV12:
|
||||||
tmp_prog = g_strdup_printf (frag_NV12_NV21_prog, 'r', 'a');
|
tmp_prog = g_strdup_printf (frag_NV12_NV21_prog, 'r', 'a');
|
||||||
glShaderSource (fraghandle, 1, (const GLchar **) &tmp_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, (const GLchar **) &tmp_prog, NULL);
|
||||||
n_textures = 2;
|
eglglessink->n_textures = 2;
|
||||||
texnames[0] = "Ytex";
|
texnames[0] = "Ytex";
|
||||||
texnames[1] = "UVtex";
|
texnames[1] = "UVtex";
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_NV21:
|
case GST_VIDEO_FORMAT_NV21:
|
||||||
tmp_prog = g_strdup_printf (frag_NV12_NV21_prog, 'a', 'r');
|
tmp_prog = g_strdup_printf (frag_NV12_NV21_prog, 'a', 'r');
|
||||||
glShaderSource (fraghandle, 1, (const GLchar **) &tmp_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, (const GLchar **) &tmp_prog, NULL);
|
||||||
n_textures = 2;
|
eglglessink->n_textures = 2;
|
||||||
texnames[0] = "Ytex";
|
texnames[0] = "Ytex";
|
||||||
texnames[1] = "UVtex";
|
texnames[1] = "UVtex";
|
||||||
break;
|
break;
|
||||||
|
@ -1438,8 +1451,8 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
case GST_VIDEO_FORMAT_RGBx:
|
case GST_VIDEO_FORMAT_RGBx:
|
||||||
case GST_VIDEO_FORMAT_RGBA:
|
case GST_VIDEO_FORMAT_RGBA:
|
||||||
case GST_VIDEO_FORMAT_RGB16:
|
case GST_VIDEO_FORMAT_RGB16:
|
||||||
glShaderSource (fraghandle, 1, &frag_COPY_prog, NULL);
|
glShaderSource (eglglessink->fragshader, 1, &frag_COPY_prog, NULL);
|
||||||
n_textures = 1;
|
eglglessink->n_textures = 1;
|
||||||
texnames[0] = "tex";
|
texnames[0] = "tex";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1450,34 +1463,34 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
if (got_gl_error ("glShaderSource fragment"))
|
if (got_gl_error ("glShaderSource fragment"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
|
|
||||||
glCompileShader (fraghandle);
|
glCompileShader (eglglessink->fragshader);
|
||||||
if (got_gl_error ("glCompileShader fragment"))
|
if (got_gl_error ("glCompileShader fragment"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
|
|
||||||
glGetShaderiv (fraghandle, GL_COMPILE_STATUS, &test);
|
glGetShaderiv (eglglessink->fragshader, GL_COMPILE_STATUS, &test);
|
||||||
if (test != GL_FALSE)
|
if (test != GL_FALSE)
|
||||||
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled fragment shader");
|
GST_DEBUG_OBJECT (eglglessink, "Successfully compiled fragment shader");
|
||||||
else {
|
else {
|
||||||
GST_ERROR_OBJECT (eglglessink, "Couldn't compile fragment shader");
|
GST_ERROR_OBJECT (eglglessink, "Couldn't compile fragment shader");
|
||||||
glGetShaderiv (fraghandle, GL_INFO_LOG_LENGTH, &test);
|
glGetShaderiv (eglglessink->fragshader, GL_INFO_LOG_LENGTH, &test);
|
||||||
info_log = g_new0 (GLchar, test);
|
info_log = g_new0 (GLchar, test);
|
||||||
glGetShaderInfoLog (fraghandle, test, NULL, info_log);
|
glGetShaderInfoLog (eglglessink->fragshader, test, NULL, info_log);
|
||||||
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
|
GST_INFO_OBJECT (eglglessink, "Compilation info log:\n%s", info_log);
|
||||||
g_free (info_log);
|
g_free (info_log);
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
prog = glCreateProgram ();
|
eglglessink->program = glCreateProgram ();
|
||||||
if (got_gl_error ("glCreateProgram"))
|
if (got_gl_error ("glCreateProgram"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
glAttachShader (prog, verthandle);
|
glAttachShader (eglglessink->program, eglglessink->vertshader);
|
||||||
if (got_gl_error ("glAttachShader vertices"))
|
if (got_gl_error ("glAttachShader vertices"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
glAttachShader (prog, fraghandle);
|
glAttachShader (eglglessink->program, eglglessink->fragshader);
|
||||||
if (got_gl_error ("glAttachShader fragments"))
|
if (got_gl_error ("glAttachShader fragments"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
glLinkProgram (prog);
|
glLinkProgram (eglglessink->program);
|
||||||
glGetProgramiv (prog, GL_LINK_STATUS, &test);
|
glGetProgramiv (eglglessink->program, GL_LINK_STATUS, &test);
|
||||||
if (test != GL_FALSE)
|
if (test != GL_FALSE)
|
||||||
GST_DEBUG_OBJECT (eglglessink, "GLES: Successfully linked program");
|
GST_DEBUG_OBJECT (eglglessink, "GLES: Successfully linked program");
|
||||||
else {
|
else {
|
||||||
|
@ -1485,12 +1498,12 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
glUseProgram (prog);
|
glUseProgram (eglglessink->program);
|
||||||
if (got_gl_error ("glUseProgram"))
|
if (got_gl_error ("glUseProgram"))
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
|
|
||||||
eglglessink->coord_pos = glGetAttribLocation (prog, "position");
|
eglglessink->coord_pos = glGetAttribLocation (eglglessink->program, "position");
|
||||||
eglglessink->tex_pos = glGetAttribLocation (prog, "texpos");
|
eglglessink->tex_pos = glGetAttribLocation (eglglessink->program, "texpos");
|
||||||
|
|
||||||
/* Generate and bind texture */
|
/* Generate and bind texture */
|
||||||
if (!eglglessink->have_texture) {
|
if (!eglglessink->have_texture) {
|
||||||
|
@ -1500,7 +1513,7 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
|
|
||||||
g_mutex_lock (eglglessink->flow_lock);
|
g_mutex_lock (eglglessink->flow_lock);
|
||||||
|
|
||||||
for (i = 0; i < n_textures; i++) {
|
for (i = 0; i < eglglessink->n_textures; i++) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
glActiveTexture (GL_TEXTURE0);
|
glActiveTexture (GL_TEXTURE0);
|
||||||
else if (i == 1)
|
else if (i == 1)
|
||||||
|
@ -1516,7 +1529,8 @@ gst_eglglessink_init_egl_surface (GstEglGlesSink * eglglessink)
|
||||||
if (got_gl_error ("glBindTexture"))
|
if (got_gl_error ("glBindTexture"))
|
||||||
goto HANDLE_ERROR_LOCKED;
|
goto HANDLE_ERROR_LOCKED;
|
||||||
|
|
||||||
eglglessink->tex_uniform[i] = glGetUniformLocation (prog, texnames[i]);
|
eglglessink->tex_uniform[i] = glGetUniformLocation (eglglessink->program,
|
||||||
|
texnames[i]);
|
||||||
glUniform1i (eglglessink->tex_uniform[i], i);
|
glUniform1i (eglglessink->tex_uniform[i], i);
|
||||||
|
|
||||||
/* Set 2D resizing params */
|
/* Set 2D resizing params */
|
||||||
|
@ -2033,6 +2047,9 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
GST_ERROR_OBJECT (eglglessink, "Internal window creation failed!");
|
GST_ERROR_OBJECT (eglglessink, "Internal window creation failed!");
|
||||||
goto HANDLE_ERROR;
|
goto HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
g_mutex_lock (eglglessink->flow_lock);
|
||||||
|
eglglessink->using_own_window = TRUE;
|
||||||
|
g_mutex_unlock (eglglessink->flow_lock);
|
||||||
gst_eglglessink_set_window_handle (GST_X_OVERLAY (eglglessink),
|
gst_eglglessink_set_window_handle (GST_X_OVERLAY (eglglessink),
|
||||||
(guintptr) window);
|
(guintptr) window);
|
||||||
}
|
}
|
||||||
|
@ -2211,6 +2228,7 @@ gst_eglglessink_init (GstEglGlesSink * eglglessink,
|
||||||
eglglessink->can_create_window = TRUE;
|
eglglessink->can_create_window = TRUE;
|
||||||
eglglessink->force_rendering_slow = FALSE;
|
eglglessink->force_rendering_slow = FALSE;
|
||||||
eglglessink->keep_aspect_ratio = TRUE;
|
eglglessink->keep_aspect_ratio = TRUE;
|
||||||
|
eglglessink->using_own_window = FALSE;
|
||||||
eglglessink->flow_lock = g_mutex_new ();
|
eglglessink->flow_lock = g_mutex_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,10 +143,12 @@ struct _GstEglGlesSink
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLNativeWindowType window;
|
EGLNativeWindowType window;
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
|
GLuint fragshader, vertshader, program;
|
||||||
GLuint texture[3];
|
GLuint texture[3];
|
||||||
|
gint n_textures;
|
||||||
|
|
||||||
gboolean have_window;
|
gboolean have_window;
|
||||||
|
gboolean using_own_window;
|
||||||
gboolean have_surface;;
|
gboolean have_surface;;
|
||||||
gboolean have_vbo;
|
gboolean have_vbo;
|
||||||
gboolean have_texture;
|
gboolean have_texture;
|
||||||
|
|
Loading…
Reference in a new issue