From b4ba4cc0df16265432fbe6fb5779dce68965b74a Mon Sep 17 00:00:00 2001 From: Andriy Martynets Date: Tue, 12 Dec 2017 16:04:33 +0200 Subject: [PATCH] Engage with TPL to prevent muse-server crash. Fix sink pad caps unref. Change-Id: I8a5c21d44553edcc236e50f20d9000c944accdd2 Signed-off-by: Andriy Martynets --- configure.ac | 38 +++++++++++++++++++++++++-- packaging/gst-plugins-tizen.spec | 11 +++++--- video360/src/Makefile.am | 3 ++- video360/src/gstvideo360-gl.c | 49 +++++++++++++++++++++++++++++++---- video360/src/gstvideo360.c | 38 +++++++++++++-------------- video360/src/gstvideo360.h | 56 ++++++++++++++++++++++++++++------------ 6 files changed, 146 insertions(+), 49 deletions(-) diff --git a/configure.ac b/configure.ac index a385065..a738fab 100644 --- a/configure.ac +++ b/configure.ac @@ -370,12 +370,43 @@ AC_ARG_ENABLE(video360, AC_HELP_STRING([--enable-video360], [using video360]), [GST_TIZEN_USE_VIDEO360=yes]) AM_CONDITIONAL(GST_TIZEN_USE_VIDEO360, test "x$GST_TIZEN_USE_VIDEO360" = "xyes") -dnl video360 related options --------------------------------------------------------------- +dnl video360 related options START -------------------------------------------------------- +AC_ARG_WITH([tizen-platform], AS_HELP_STRING([--with-tizen-platform], + [Build with Tizen Porting Layer(TPL)])) + AC_ARG_WITH([native-formats], AS_HELP_STRING([--with-native-formats], [Build with support for Tizen native video formats])) -AS_IF([test "x$with_native_formats" = "xyes"], [CFLAGS="$CFLAGS -DGST_TIZEN_USE_NATIVE_FORMATS"]) AC_ARG_WITH([gles2], AS_HELP_STRING([--with-gles2], [Build with OpenGL ES 2.0])) + +AS_IF([test "x$with_tizen_platform" = "xyes"], [ + PKG_CHECK_MODULES(TPL, [ + tpl-egl + ], [ + AC_SUBST(TPL_CFLAGS) + AC_SUBST(TPL_LIBS) + ]) + CFLAGS="$CFLAGS -DGST_TIZEN_PLATFORM" +]) + +AS_IF([test "x$with_native_formats" = "xyes" -o "x$with_gles2" = "xyes"], [ + PKG_CHECK_MODULES(MMCOMMON, [ + mm-common + ], [ + AC_SUBST(MMCOMMON_CFLAGS) + ]) + PKG_CHECK_MODULES(TBM, [ + libtbm + ], [ + AC_SUBST(TBM_CFLAGS) + AC_SUBST(TBM_LIBS) + ]) +]) + +AS_IF([test "x$with_native_formats" = "xyes"], [ + CFLAGS="$CFLAGS -DGST_TIZEN_USE_NATIVE_FORMATS" +]) + AS_IF([test "x$with_gles2" = "xyes"], [ PKG_CHECK_MODULES(GLES, [ gles20 @@ -385,6 +416,9 @@ AS_IF([test "x$with_gles2" = "xyes"], [ ]) CFLAGS="$CFLAGS -DGST_TIZEN_GL_API_GLES2" ]) +dnl video360 related options END -------------------------------------------------------- + + dnl use waylandsink -------------------------------------------------------------------------- AC_ARG_ENABLE(waylandsink, AC_HELP_STRING([--enable-waylandsink], [using waylandsink]), diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index 04c045c..20ee3d2 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -38,6 +38,7 @@ BuildRequires: libdrm-devel BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(gles20) +BuildRequires: pkgconfig(tpl-egl) %if %{with wayland} BuildRequires: pkgconfig(wayland-client) >= 1.0.0 BuildRequires: pkgconfig(wayland-tbm-client) @@ -83,8 +84,9 @@ export CFLAGS="$CFLAGS_DEFAULT -DTIZEN_FEATURE_PRODUCT_TM1" --enable-ext-alfec\ --disable-tizenipc\ --disable-static\ - --with-native-formats\ - --with-gles2 + --with-tizen-platform \ + --with-native-formats \ + --with-gles2 make %{?jobs:-j%jobs} @@ -106,8 +108,9 @@ export CFLAGS="$CFLAGS_DEFAULT" --enable-ext-alfec\ --disable-tizenipc\ --disable-static\ - --with-native-formats\ - --with-gles2 + --with-tizen-platform \ + --with-native-formats \ + --with-gles2 make %{?jobs:-j%jobs} diff --git a/video360/src/Makefile.am b/video360/src/Makefile.am index 802ea26..60c4017 100644 --- a/video360/src/Makefile.am +++ b/video360/src/Makefile.am @@ -8,12 +8,13 @@ libgstvideo360_la_SOURCES = gstvideo360.c\ # compiler and linker flags used to compile this plugin, set in configure.ac libgstvideo360_la_CFLAGS = $(GST_CFLAGS)\ + $(TPL_CFLAGS)\ $(TBM_CFLAGS)\ $(MMCOMMON_CFLAGS)\ $(GLES_CFLAGS)\ -Wdouble-promotion\ -fsingle-precision-constant -libgstvideo360_la_LIBADD = $(GST_LIBS) $(TBM_LIBS) $(GLES_LIBS) +libgstvideo360_la_LIBADD = $(GST_LIBS) $(TPL_LIBS) $(TBM_LIBS) $(GLES_LIBS) libgstvideo360_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvideo360_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/video360/src/gstvideo360-gl.c b/video360/src/gstvideo360-gl.c index 123a897..622ebb0 100644 --- a/video360/src/gstvideo360-gl.c +++ b/video360/src/gstvideo360-gl.c @@ -215,18 +215,32 @@ gst_video360_deinit_gl (GstVideo360 * this) eglTerminate (this->egl_display); this->egl_display = EGL_NO_DISPLAY; } +#ifdef GST_TIZEN_PLATFORM + if (this->tpl_display) { + /* Destroy TPL display. + * In Tizen environment TPL stealthy catches the native display handler + * (most probably hooking eglInitialize call) and uses it internally. + * To force TPL to release it before we disconnect (and thus prevent + * possible crash) we force TPL display object destruction by the below + * call. + * This is actually the reason we touch TPL at all. + * */ + tpl_object_unreference ((tpl_object_t *) this->tpl_display); + this->tpl_display = NULL; + } +#endif #ifdef GST_TIZEN_GL_WINDOW_WAYLAND if (this->wl_display) { /* Disconnect from the native display */ wl_display_disconnect (this->wl_display); this->wl_display = NULL; } -#else +#else /* Not GST_TIZEN_GL_WINDOW_WAYLAND */ /* Space for alternate windowing system code */ -#endif /* GL_WINDOW_WAYLAND */ +#endif /* GST_TIZEN_GL_WINDOW_WAYLAND */ #else /* Space for alternate platform code */ -#endif /* GL_PLATFORM_EGL */ +#endif /* GST_TIZEN_GL_PLATFORM_EGL */ } static gboolean @@ -269,9 +283,25 @@ _init_gl_platform (GstVideo360 * this) GST_ERROR ("eglGetDisplay failed"); return FALSE; } -#else +#else /* Not GST_TIZEN_GL_WINDOW_WAYLAND */ /* Space for alternate windowing system code */ -#endif /* GL_WINDOW_WAYLAND */ +#endif /* GST_TIZEN_GL_WINDOW_WAYLAND */ + +#ifdef GST_TIZEN_PLATFORM + /* Note: backend type must be TPL_BACKEND_WAYLAND_THREAD + * (not TPL_BACKEND_WAYLAND) otherwise TPL implicitly creates distinct + * instance of TPL display structure for TPL_BACKEND_WAYLAND_THREAD backend + * and thus we will not get means to synchronize display destruction + * process. Without the synchronization Wayland display derived objects + * (proxies, wrappers, queues, etc.) get deleted after wl_display_disconnect + * call causing muse-server to be killed by SIGSEG. + * */ + this->tpl_display = tpl_display_create (TPL_BACKEND_WAYLAND_THREAD, this->wl_display); + if (this->tpl_display == NULL) { + GST_ERROR ("tpl_display_create failed"); + return FALSE; + } +#endif /* GST_TIZEN_PLATFORM */ /* initialize the EGL display connection */ eglInitialize (this->egl_display, &ver_major, &ver_minor); @@ -401,6 +431,15 @@ _prepare_gl_framebuffer (GstVideo360 * this) EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, (EGLClientBuffer) this->output_tbm_surface, NULL); +#ifdef GST_TIZEN_USE_NATIVE_FORMATS + this->output_frame_buffer_size = + tbm_bo_size (tbm_surface_internal_get_bo (this->output_tbm_surface, 0)); + if (GST_ROUND_UP_N (this->output_frame_buffer_size, 4096) != + this->output_frame_buffer_size) { + GST_WARNING ("TBM BO size isn't aligned by 4k"); + } +#endif + if (this->input_egl_image == EGL_NO_IMAGE_KHR || this->output_egl_image == EGL_NO_IMAGE_KHR) { EGL_ERROR; diff --git a/video360/src/gstvideo360.c b/video360/src/gstvideo360.c index 2d1bd84..0edc77f 100644 --- a/video360/src/gstvideo360.c +++ b/video360/src/gstvideo360.c @@ -329,8 +329,6 @@ gst_video360_init (GstVideo360 * this) gst_pad_use_fixed_caps (this->srcpad); gst_element_add_pad (GST_ELEMENT (this), this->srcpad); - this->sinkpad_caps = NULL; - this->stereo_mode = MODE_MONOSCOPIC; this->pose_yaw_radians = 0.0; this->pose_pitch_radians = 0.0; @@ -348,6 +346,9 @@ gst_video360_init (GstVideo360 * this) this->zoom = 1.0; #ifdef GST_TIZEN_GL_PLATFORM_EGL +#ifdef GST_TIZEN_PLATFORM + this->tpl_display = NULL; +#endif #ifdef GST_TIZEN_GL_WINDOW_WAYLAND this->wl_display = NULL; #endif @@ -537,6 +538,9 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { /* we should handle the format here */ gst_event_parse_caps (event, &caps); + gst_caps_ref (caps); + gst_event_unref (event); + if (!(this->passthrough = this->requested_passthrough)) { structure = gst_caps_get_structure (caps, 0); @@ -669,16 +673,6 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) return FALSE; } - /* Here we save incoming CAPS which might be needed for subsequent - * negotiations. Normally they are present on the PAD and its peer as - * sticky CAPS events and can be obtained by gst_pad_get_current_caps - * call. Unfortunately some elements (e.g. OMX decoder) seems to unref - * these events. - * */ - if (this->sinkpad_caps) - gst_caps_unref (this->sinkpad_caps); - this->sinkpad_caps = gst_caps_ref (caps); - /* Once sink capabilities are negotiated translate them to source pad. * Here we do a kind of transform negotiation as we setup fixed CAPS * on the src PAD. @@ -722,6 +716,7 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) if (ret) gst_pad_check_reconfigure (pad); + gst_caps_unref (caps); break; } default: @@ -830,18 +825,17 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) GstBuffer *out_buf; GstMapInfo in_info, out_info; #ifdef GST_TIZEN_USE_NATIVE_FORMATS - MMVideoBuffer *mm_vbuffer; + MMVideoBuffer *mm_vbuffer = NULL; #else GstMemory *out_mem; #endif GstMemory *in_mem; int ret; - if (gst_pad_check_reconfigure (pad)) { + if (gst_pad_check_reconfigure (pad)) if (!gst_video360_sink_event (pad, parent, - gst_event_new_caps (this->sinkpad_caps))) + gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0))) return GST_FLOW_NOT_NEGOTIATED; - } if (this->passthrough) return gst_pad_push (this->srcpad, in_buf); @@ -853,11 +847,8 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) #endif #ifdef GST_TIZEN_USE_NATIVE_FORMATS - if ((out_buf = gst_buffer_new_wrapped ( - g_malloc (GST_TIZEN_NATIVE_FORMATS_FIRST_MEMORY_SIZE), - GST_TIZEN_NATIVE_FORMATS_FIRST_MEMORY_SIZE)) && + if ((out_buf = gst_buffer_new ()) && (mm_vbuffer = g_malloc0 (sizeof (MMVideoBuffer)))) { - mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO; mm_vbuffer->format = MM_PIXEL_FORMAT_RGBA; mm_vbuffer->plane_num = 1; @@ -871,6 +862,10 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) gst_buffer_append_memory (out_buf, gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, mm_vbuffer, + GST_TIZEN_NATIVE_FORMATS_FIRST_MEMORY_SIZE, 0, + GST_TIZEN_NATIVE_FORMATS_FIRST_MEMORY_SIZE, NULL, NULL)); + gst_buffer_append_memory (out_buf, + gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, mm_vbuffer, sizeof (MMVideoBuffer), 0, sizeof (MMVideoBuffer), mm_vbuffer, mm_vbuffer_free)); #else @@ -925,6 +920,9 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) } } + if (out_buf) + gst_buffer_unref (out_buf); + GST_ERROR ("Frame rendering error: " "Memory allocation / write permission request failed"); diff --git a/video360/src/gstvideo360.h b/video360/src/gstvideo360.h index 143468c..18333af 100644 --- a/video360/src/gstvideo360.h +++ b/video360/src/gstvideo360.h @@ -55,9 +55,24 @@ * #define GST_TIZEN_GL_API_GLES2 * #define GST_TIZEN_GL_API_OPENGL (Not supported yet) * */ + +/* Define below macros to build for EGL as the OpenGL platform: + * */ #define GST_TIZEN_GL_PLATFORM_EGL + +/* Define below macros to build with Tizen Porting Layer(TPL) support: + * #define GST_TIZEN_PLATFORM + * */ + +/* Define below macros to build for Wayland as native display system: + * */ #define GST_TIZEN_GL_WINDOW_WAYLAND + +/* Define below macros to build using EGL_TIZEN_image_native_surface and + * GL_OES_EGL_image_external extensions: + * */ #define GST_TIZEN_USE_EGLIMAGE + /* Define below macros to enable multisample antialiasing * #define GST_TIZEN_USE_MSAA * */ @@ -74,10 +89,21 @@ #include #endif +#include +#include +#include +#include + +#ifdef GST_TIZEN_USE_TIMING +#include +#endif + #include #include #include +#include "video360.h" + #ifdef GST_TIZEN_GL_API_GLES2 #include #include @@ -86,32 +112,26 @@ #include #include +#ifdef GST_TIZEN_PLATFORM +#include +#endif /* GST_TIZEN_PLATFORM */ + #ifdef GST_TIZEN_GL_WINDOW_WAYLAND #include #include -#else /* Not GL_WINDOW_WAYLAND */ +#else /* Not GST_TIZEN_GL_WINDOW_WAYLAND */ #error "Wayland based EGL is the only supported platform" -#endif /* GL_WINDOW_WAYLAND */ +#endif /* GST_TIZEN_GL_WINDOW_WAYLAND */ -#else /* Not GL_PLATFORM_EGL */ +#else /* Not GST_TIZEN_GL_PLATFORM_EGL */ #error "GLES API supported on EGL platform only" -#endif /* GL_PLATFORM_EGL */ +#endif /* GST_TIZEN_GL_PLATFORM_EGL */ -#else /* Not GL_API_GLES2 */ +#else /* Not GST_TIZEN_GL_API_GLES2 */ #error "OpenGL ES2 is the only supported API" #include #include -#endif /* GL_API_GLES2 */ - -#include -#include -#include - -#include "video360.h" - -#ifdef GST_TIZEN_USE_TIMING -#include -#endif +#endif /* GST_TIZEN_GL_API_GLES2 */ #if defined (GST_TIZEN_USE_NATIVE_FORMATS) || defined (GST_TIZEN_USE_EGLIMAGE) #include @@ -178,11 +198,13 @@ struct _GstVideo360 GstElement element; GstPad *sinkpad, *srcpad; - GstCaps *sinkpad_caps; /***************************************************************************** * OpenGL ES related variables * **************************************************************************/ +#ifdef GST_TIZEN_PLATFORM + tpl_display_t *tpl_display; +#endif #ifdef GST_TIZEN_GL_WINDOW_WAYLAND struct wl_display *wl_display; #endif -- 2.7.4