eglglessink: Fix handling of caps changes by only releasing what needs to be released

And not terminating the display connection
This commit is contained in:
Sebastian Dröge 2012-10-04 15:47:54 +02:00
parent 310e5111b7
commit c91238a2af

View File

@ -378,7 +378,8 @@ static inline gboolean got_gl_error (const char *wtf);
static inline void show_egl_error (const char *wtf); static inline void show_egl_error (const char *wtf);
static void gst_eglglessink_wipe_fmt (gpointer data); static void gst_eglglessink_wipe_fmt (gpointer data);
static inline gboolean egl_init (GstEglGlesSink * eglglessink); static inline gboolean egl_init (GstEglGlesSink * eglglessink);
static gboolean gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink, gboolean bind, gboolean streaming_thread); static gboolean gst_eglglessink_context_make_current (GstEglGlesSink *
eglglessink, gboolean bind, gboolean streaming_thread);
static GstBufferClass *gsteglglessink_buffer_parent_class = NULL; static GstBufferClass *gsteglglessink_buffer_parent_class = NULL;
#define GST_TYPE_EGLGLESBUFFER (gst_eglglesbuffer_get_type()) #define GST_TYPE_EGLGLESBUFFER (gst_eglglesbuffer_get_type())
@ -1444,7 +1445,7 @@ static pthread_key_t context_key;
static void static void
detach_context (void *data) detach_context (void *data)
{ {
GstEglGlesSink * eglglessink = data; GstEglGlesSink *eglglessink = data;
GST_DEBUG_OBJECT (eglglessink, GST_DEBUG_OBJECT (eglglessink,
"Detaching current context from streaming thread"); "Detaching current context from streaming thread");
@ -1453,7 +1454,8 @@ detach_context (void *data)
} }
static gboolean static gboolean
gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink, gboolean bind, gboolean streaming_thread) gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink,
gboolean bind, gboolean streaming_thread)
{ {
g_assert (eglglessink->eglglesctx->display != NULL); g_assert (eglglessink->eglglesctx->display != NULL);
@ -1469,7 +1471,8 @@ gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink, gboolean bin
GST_DEBUG_OBJECT (eglglessink, "Attaching context to streaming thread"); GST_DEBUG_OBJECT (eglglessink, "Attaching context to streaming thread");
if (!eglMakeCurrent (eglglessink->eglglesctx->display, if (!eglMakeCurrent (eglglessink->eglglesctx->display,
eglglessink->eglglesctx->surface, eglglessink->eglglesctx->surface, eglglessink->eglglesctx->surface,
eglglessink->eglglesctx->surface,
eglglessink->eglglesctx->eglcontext)) { eglglessink->eglglesctx->eglcontext)) {
show_egl_error ("eglMakeCurrent"); show_egl_error ("eglMakeCurrent");
GST_ERROR_OBJECT (eglglessink, "Couldn't bind context"); GST_ERROR_OBJECT (eglglessink, "Couldn't bind context");
@ -1482,7 +1485,8 @@ gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink, gboolean bin
} else { } else {
GST_DEBUG_OBJECT (eglglessink, "Attaching context"); GST_DEBUG_OBJECT (eglglessink, "Attaching context");
if (!eglMakeCurrent (eglglessink->eglglesctx->display, if (!eglMakeCurrent (eglglessink->eglglesctx->display,
eglglessink->eglglesctx->surface, eglglessink->eglglesctx->surface, eglglessink->eglglesctx->surface,
eglglessink->eglglesctx->surface,
eglglessink->eglglesctx->eglcontext)) { eglglessink->eglglesctx->eglcontext)) {
show_egl_error ("eglMakeCurrent"); show_egl_error ("eglMakeCurrent");
GST_ERROR_OBJECT (eglglessink, "Couldn't bind context"); GST_ERROR_OBJECT (eglglessink, "Couldn't bind context");
@ -1492,8 +1496,7 @@ gst_eglglessink_context_make_current (GstEglGlesSink * eglglessink, gboolean bin
} else { } else {
GST_DEBUG_OBJECT (eglglessink, "Detaching context"); GST_DEBUG_OBJECT (eglglessink, "Detaching context");
if (!eglMakeCurrent (eglglessink->eglglesctx->display, if (!eglMakeCurrent (eglglessink->eglglesctx->display,
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
EGL_NO_CONTEXT)) {
show_egl_error ("eglMakeCurrent"); show_egl_error ("eglMakeCurrent");
GST_ERROR_OBJECT (eglglessink, "Couldn't unbind context"); GST_ERROR_OBJECT (eglglessink, "Couldn't unbind context");
return FALSE; return FALSE;
@ -1793,7 +1796,8 @@ gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
} }
if (!eglInitialize (eglglessink->eglglesctx->display, if (!eglInitialize (eglglessink->eglglesctx->display,
&eglglessink->eglglesctx->egl_major, &eglglessink->eglglesctx->egl_minor)) { &eglglessink->eglglesctx->egl_major,
&eglglessink->eglglesctx->egl_minor)) {
show_egl_error ("eglInitialize"); show_egl_error ("eglInitialize");
GST_ERROR_OBJECT (eglglessink, "Could not init EGL display connection"); GST_ERROR_OBJECT (eglglessink, "Could not init EGL display connection");
goto HANDLE_EGL_ERROR; goto HANDLE_EGL_ERROR;
@ -2120,17 +2124,18 @@ gst_eglglessink_render_and_display (GstEglGlesSink * eglglessink,
eglglessink->eglglesctx->surface_height; eglglessink->eglglesctx->surface_height;
} else { } else {
if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, w, h, if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, w, h,
eglglessink->par_n, eglglessink->par_d, eglglessink->par_n, eglglessink->par_d,
eglglessink->eglglesctx->pixel_aspect_ratio, EGL_DISPLAY_SCALING)) { eglglessink->eglglesctx->pixel_aspect_ratio,
EGL_DISPLAY_SCALING)) {
GST_WARNING_OBJECT (eglglessink, "Could not compute resulting DAR"); GST_WARNING_OBJECT (eglglessink, "Could not compute resulting DAR");
frame.w = w; frame.w = w;
frame.h = h; frame.h = h;
} else { } else {
/* Find suitable matching new size acording to dar & par /* Find suitable matching new size acording to dar & par
* rationale for prefering leaving the height untouched * rationale for prefering leaving the height untouched
* comes from interlacing considerations. * comes from interlacing considerations.
* XXX: Move this to gstutils? * XXX: Move this to gstutils?
*/ */
if (h % dar_d == 0) { if (h % dar_d == 0) {
frame.w = gst_util_uint64_scale_int (h, dar_n, dar_d); frame.w = gst_util_uint64_scale_int (h, dar_n, dar_d);
frame.h = h; frame.h = h;
@ -2286,6 +2291,10 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
GST_DEBUG_OBJECT (eglglessink, "Caps are not compatible, reconfiguring"); GST_DEBUG_OBJECT (eglglessink, "Caps are not compatible, reconfiguring");
/* Cleanup */ /* Cleanup */
if (!gst_eglglessink_context_make_current (eglglessink, TRUE, TRUE))
return FALSE;
if (eglglessink->rendering_path == GST_EGLGLESSINK_RENDER_SLOW) { if (eglglessink->rendering_path == GST_EGLGLESSINK_RENDER_SLOW) {
glUseProgram (0); glUseProgram (0);
@ -2315,6 +2324,9 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
} }
} }
if (!gst_eglglessink_context_make_current (eglglessink, FALSE, TRUE))
return FALSE;
if (eglglessink->eglglesctx->surface) { if (eglglessink->eglglesctx->surface) {
eglDestroySurface (eglglessink->eglglesctx->display, eglDestroySurface (eglglessink->eglglesctx->display,
eglglessink->eglglesctx->surface); eglglessink->eglglesctx->surface);
@ -2328,25 +2340,6 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
eglglessink->eglglesctx->eglcontext = NULL; eglglessink->eglglesctx->eglcontext = NULL;
} }
/* Terminate display connection */
if (eglMakeCurrent (eglglessink->eglglesctx->display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE) {
show_egl_error ("eglMakeCurrent");
goto HANDLE_ERROR;
}
if (eglTerminate (eglglessink->eglglesctx->display) == EGL_FALSE) {
show_egl_error ("eglTerminate");
goto HANDLE_ERROR;
}
eglglessink->eglglesctx->display = NULL;
if (!gst_eglglessink_init_egl_display (eglglessink)) {
GST_ERROR_OBJECT (eglglessink, "Could not reinit display connection");
goto HANDLE_ERROR;
}
g_mutex_lock (eglglessink->flow_lock); g_mutex_lock (eglglessink->flow_lock);
/* Reset display region /* Reset display region
* XXX: Should probably keep old ones if set_render_rect() * XXX: Should probably keep old ones if set_render_rect()