From cd05ad0a81ec48adaae377413d352f9a59c5af7d Mon Sep 17 00:00:00 2001 From: Vladislav Andresov Date: Thu, 31 May 2018 07:59:32 +0300 Subject: [PATCH 01/16] Prepare input I420 image to render video360 frame Change-Id: I3a69e88584fa1b997e8d3402df250ff0150a0508 Signed-off-by: Vladislav Andresov --- video360/src/gstvideo360-formats.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/video360/src/gstvideo360-formats.c b/video360/src/gstvideo360-formats.c index 79ef74c..763d5ad 100644 --- a/video360/src/gstvideo360-formats.c +++ b/video360/src/gstvideo360-formats.c @@ -69,12 +69,18 @@ gst_video360_standard_formats_renderer (GstVideo360 * this, void *in_data, #ifdef GST_TIZEN_GL_PLATFORM_EGL #ifdef GST_TIZEN_USE_EGLIMAGE + tbm_surface_map(this->input_tbm_surface, TBM_SURF_OPTION_WRITE, &this->input_surf_info); + do { memcpy (this->input_image_ptr[i], in_data, this->input_frame_planes[i].size); in_data += this->input_frame_planes[i].size; } while (++i < this->input_surf_info.num_planes); + tbm_surface_unmap(this->input_tbm_surface); + + this->glEGLImageTargetTexture2D(GL_TEXTURE_EXTERNAL_OES, this->input_egl_image); + #ifdef GST_TIZEN_USE_NATIVE_FORMATS if (!(out_tbm_surface = tbm_surface_internal_create_with_flags (this->output_frame_width, -- 2.7.4 From 7c31c958ced3248f73a32a3e810591bfed7262b4 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Tue, 31 Jul 2018 18:21:50 +0900 Subject: [PATCH 02/16] tizenwlsink: Add remove callback func to wayland registry listener Change-Id: I6fa9ca405fc206792ebbd45096672ab2adc1901b Signed-off-by: Hyunil --- tizenwlsink/src/wldisplay.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index 838f529..546c05f 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -330,8 +330,16 @@ registry_handle_global (void *data, struct wl_registry *registry, } } +static void +registry_handle_global_remove (void *data, struct wl_registry *registry, + uint32_t id) +{ + GST_LOG ("Removed global object: id(%d)", id); +} + static const struct wl_registry_listener registry_listener = { - registry_handle_global + registry_handle_global, + registry_handle_global_remove }; static gpointer -- 2.7.4 From f618db7fb6cec31be23b9ce742784d281994adb5 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Fri, 3 Aug 2018 13:08:18 +0900 Subject: [PATCH 03/16] tizenwlsink: Support gst_tizen_wl_sink_set_roi_area() newly instead of gst_tizen_wl_sink_set_render_rectangle() Change-Id: I817b558352134c3aa90a447e8cffc696b509f080 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 13 +++++++------ tizenwlsink/src/wlwindow.c | 10 ++++++---- tizenwlsink/src/wlwindow.h | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 2502fb9..46d6fbd 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -219,7 +219,7 @@ static void gst_tizen_wl_sink_set_window_handle (GstVideoOverlay * overlay, static void gst_tizen_wl_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, guintptr wl_surface_id); -static void gst_tizen_wl_sink_set_render_rectangle (GstVideoOverlay * overlay, +static void gst_tizen_wl_sink_set_roi_area (GstVideoOverlay * overlay, gint x, gint y, gint w, gint h); static void gst_tizen_wl_sink_expose (GstVideoOverlay * overlay); @@ -2365,11 +2365,12 @@ static void gst_tizen_wl_sink_videooverlay_init (GstVideoOverlayInterface * iface) { iface->set_window_handle = gst_tizen_wl_sink_set_window_handle; - iface->set_render_rectangle = gst_tizen_wl_sink_set_render_rectangle; + iface->set_render_rectangle = gst_tizen_wl_sink_set_roi_area; iface->expose = gst_tizen_wl_sink_expose; #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* use unique_id */ iface->set_wl_window_wl_surface_id = gst_tizen_wl_sink_set_wl_window_wl_surface_id; + iface->set_display_roi_area = gst_tizen_wl_sink_set_roi_area; #endif } @@ -2460,8 +2461,8 @@ gst_tizen_wl_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle) } static void -gst_tizen_wl_sink_set_render_rectangle (GstVideoOverlay * overlay, - gint x, gint y, gint w, gint h) +gst_tizen_wl_sink_set_roi_area (GstVideoOverlay * overlay, gint x, gint y, + gint w, gint h) { GstTizenWlSink *sink = GST_TIZEN_WL_SINK (overlay); FUNCTION; @@ -2473,14 +2474,14 @@ gst_tizen_wl_sink_set_render_rectangle (GstVideoOverlay * overlay, if (!sink->window) { g_mutex_unlock (&sink->render_lock); GST_WARNING_OBJECT (sink, - "set_render_rectangle called without window, ignoring"); + "set roi area called without window, ignoring"); return; } GST_WARNING_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d", x, y, w, h); - if (gst_wl_window_set_render_rectangle (sink->window, x, y, w, h)) { + if (gst_wl_window_set_roi_area (sink->window, x, y, w, h)) { sink->video_info_changed = TRUE; if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index b2b934a..617282d 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -150,9 +150,9 @@ gst_wl_window_map_sub_surface (GstWlDisplay * display, GstWlWindow * window, gst_tizen_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0), display, info); if (G_UNLIKELY (!wlbuf)) { - GST_ERROR ("could not create wl_buffer"); - gst_buffer_unref (buf); - return; + GST_ERROR ("could not create wl_buffer"); + gst_buffer_unref (buf); + return; } gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display); @@ -461,6 +461,7 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, } /* set the initial size to be the same as the reported video size */ + width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height); @@ -605,6 +606,7 @@ gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, tizen_viewport_set_source (window->tizen_video_viewport, window->mode_crop.x, window->mode_crop.y, window->mode_crop.w, window->mode_crop.h); + window->mode_crop.changed = FALSE; } @@ -899,7 +901,7 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, #if TIZEN_FEATURE_WLSINK_ENHANCEMENT gboolean -gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, +gst_wl_window_set_roi_area (GstWlWindow * window, gint x, gint y, gint w, gint h) { FUNCTION; diff --git a/tizenwlsink/src/wlwindow.h b/tizenwlsink/src/wlwindow.h index 10c2dac..8eb3c99 100644 --- a/tizenwlsink/src/wlwindow.h +++ b/tizenwlsink/src/wlwindow.h @@ -149,7 +149,7 @@ gboolean gst_wl_window_is_toplevel (GstWlWindow * window); void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT -gboolean gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, +gboolean gst_wl_window_set_roi_area (GstWlWindow * window, gint x, gint y, gint w, gint h); void gst_wl_window_set_video_info (GstWlWindow * window, const GstVideoInfo * info); -- 2.7.4 From bd09ba03b16b5bb7060e056c7b1459c290c544ea Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 9 Aug 2018 19:29:16 +0900 Subject: [PATCH 04/16] [tizencamerasrc] Update color balance functions [Version] 1.0.0-58 [Profile] Common [Issue Type] Update [Dependency module] N/A Change-Id: Ia8d807ea1b495d2aebc5ea304a1b56bcdb15c0aa Signed-off-by: Jeongmo Yang --- packaging/gst-plugins-tizen.spec | 2 +- tizencamerasrc/src/gsttizencamerasrc.c | 2 +- tizencamerasrc/src/gsttizencamerasrccolorbalance.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index f28ba25..cbe1603 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 58 +Release: 59 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ diff --git a/tizencamerasrc/src/gsttizencamerasrc.c b/tizencamerasrc/src/gsttizencamerasrc.c index 8cfb263..3a3a18a 100644 --- a/tizencamerasrc/src/gsttizencamerasrc.c +++ b/tizencamerasrc/src/gsttizencamerasrc.c @@ -154,7 +154,7 @@ static GstStaticPadTemplate src_factory = "width = (int) [ 1, 4096 ], " "height = (int) [ 1, 4096 ]; " "video/x-raw," - "format = (string) { YUYV }, " + "format = (string) { YUY2 }, " "width = (int) [ 1, 4096 ], " "height = (int) [ 1, 4096 ]; ")); diff --git a/tizencamerasrc/src/gsttizencamerasrccolorbalance.c b/tizencamerasrc/src/gsttizencamerasrccolorbalance.c index 3dcc761..98ad56b 100644 --- a/tizencamerasrc/src/gsttizencamerasrccolorbalance.c +++ b/tizencamerasrc/src/gsttizencamerasrccolorbalance.c @@ -72,7 +72,7 @@ void gst_tizencamerasrc_color_balance_set_value(GstTizenCameraSrc *camerasrc, Gs g_return_if_fail(camerasrc); g_return_if_fail(gst_tizencamerasrc_color_balance_contains_channel(camerasrc, camerasrc_color_channel)); - /* TODO */ + camera_hal_interface_set_command(camerasrc->hal_intf_handle, camerasrc_color_channel->id, (void *)value); return; } @@ -86,7 +86,7 @@ gint gst_tizencamerasrc_color_balance_get_value(GstTizenCameraSrc *camerasrc, Gs g_return_val_if_fail(camerasrc, FALSE); g_return_val_if_fail(gst_tizencamerasrc_color_balance_contains_channel(camerasrc, camerasrc_color_channel), FALSE); - /* TODO */ + camera_hal_interface_get_command(camerasrc->hal_intf_handle, camerasrc_color_channel->id, (void **)&value); return value; } -- 2.7.4 From e1155ab4c72b65aeb253697f1e49f535eea1c9f0 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 16 Aug 2018 13:40:00 +0900 Subject: [PATCH 05/16] Apply tizen allocator to video360 plugin Change-Id: Ie449b4f5ca6570f5dbc9b9c792a8fd007c2b20f4 --- configure.ac | 4 ++ video360/src/Makefile.am | 3 +- video360/src/gstvideo360-formats.c | 37 +++---------------- video360/src/gstvideo360.c | 76 ++++++++++++++++++++------------------ video360/src/gstvideo360.h | 5 +++ 5 files changed, 57 insertions(+), 68 deletions(-) diff --git a/configure.ac b/configure.ac index 0c91739..346761b 100644 --- a/configure.ac +++ b/configure.ac @@ -171,6 +171,10 @@ PKG_CHECK_MODULES(MMCOMMON,mm-common) AC_SUBST(MMCOMMON_CFLAGS) AC_SUBST(MMCOMMON_LIBS) +PKG_CHECK_MODULES([GST_ALLOCATORS], [gstreamer-allocators-1.0]) +AC_SUBST(GST_ALLOCATORS_CFLAGS) +AC_SUBST(GST_ALLOCATORS_LIBS) + dnl belows are related to wfdtsdemux AG_GST_ARG_WITH_PACKAGE_NAME AG_GST_ARG_WITH_PACKAGE_ORIGIN diff --git a/video360/src/Makefile.am b/video360/src/Makefile.am index 60c4017..0168475 100644 --- a/video360/src/Makefile.am +++ b/video360/src/Makefile.am @@ -11,10 +11,11 @@ libgstvideo360_la_CFLAGS = $(GST_CFLAGS)\ $(TPL_CFLAGS)\ $(TBM_CFLAGS)\ $(MMCOMMON_CFLAGS)\ + $(GST_ALLOCATORS_CFLAGS)\ $(GLES_CFLAGS)\ -Wdouble-promotion\ -fsingle-precision-constant -libgstvideo360_la_LIBADD = $(GST_LIBS) $(TPL_LIBS) $(TBM_LIBS) $(GLES_LIBS) +libgstvideo360_la_LIBADD = $(GST_LIBS) $(TPL_LIBS) $(TBM_LIBS) $(GLES_LIBS) $(GST_ALLOCATORS_LIBS) libgstvideo360_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvideo360_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/video360/src/gstvideo360-formats.c b/video360/src/gstvideo360-formats.c index 763d5ad..f028ba1 100644 --- a/video360/src/gstvideo360-formats.c +++ b/video360/src/gstvideo360-formats.c @@ -82,12 +82,7 @@ gst_video360_standard_formats_renderer (GstVideo360 * this, void *in_data, this->glEGLImageTargetTexture2D(GL_TEXTURE_EXTERNAL_OES, this->input_egl_image); #ifdef GST_TIZEN_USE_NATIVE_FORMATS - if (!(out_tbm_surface = - tbm_surface_internal_create_with_flags (this->output_frame_width, - this->output_frame_height, TBM_FORMAT_XBGR8888, TBM_BO_WC))) { - GST_ERROR ("tbm_surface_create failed"); - ret = FALSE; - } + out_tbm_surface = (tbm_surface_h) out_data; out_egl_image = this->eglCreateImage (this->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, @@ -135,12 +130,7 @@ gst_video360_standard_formats_renderer (GstVideo360 * this, void *in_data, #ifdef GST_TIZEN_GL_PLATFORM_EGL #ifdef GST_TIZEN_USE_EGLIMAGE -#ifdef GST_TIZEN_USE_NATIVE_FORMATS - ((MMVideoBuffer *) out_data)->handle.bo[0] = - tbm_bo_ref (tbm_surface_internal_get_bo (out_tbm_surface, 0)); - this->eglDestroyImage (this->egl_display, out_egl_image); - tbm_surface_destroy (out_tbm_surface); -#else +#ifndef GST_TIZEN_USE_NATIVE_FORMATS memcpy (out_data, this->output_image_ptr, this->output_frame_buffer_size); #endif #else @@ -202,9 +192,10 @@ gst_video360_native_formats_renderer (GstVideo360 * this, void *in_data, clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start_time); #endif - if (in_data && - ((MMVideoBuffer *) in_data)->type == MM_VIDEO_BUFFER_TYPE_TBM_BO && - ((MMVideoBuffer *) in_data)->size[0]) { + in_tbm_surface = (tbm_surface_h)in_data; + out_tbm_surface = (tbm_surface_h)out_data; + + if (tbm_surface_internal_is_valid (in_tbm_surface) && tbm_surface_internal_is_valid (out_tbm_surface)) { /* Note: omx provides separate BOs for each plane when sprd provides a * single one for both. @@ -212,18 +203,6 @@ gst_video360_native_formats_renderer (GstVideo360 * this, void *in_data, #ifdef GST_TIZEN_GL_PLATFORM_EGL #ifdef GST_TIZEN_USE_EGLIMAGE - if (!(in_tbm_surface = - tbm_surface_internal_create_with_bos (&this->input_surf_info, - (tbm_bo *) ((MMVideoBuffer *) in_data)->handle.bo, - ((MMVideoBuffer *) in_data)->handle.bo[1] ? this-> - input_surf_info.num_planes : 1)) || - !(out_tbm_surface = - tbm_surface_internal_create_with_flags (this->output_frame_width, - this->output_frame_height, TBM_FORMAT_XBGR8888, TBM_BO_WC))) { - GST_ERROR ("tbm_surface_create failed"); - ret = FALSE; - } - in_egl_image = this->eglCreateImage (this->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, (EGLClientBuffer) in_tbm_surface, NULL); @@ -271,12 +250,8 @@ gst_video360_native_formats_renderer (GstVideo360 * this, void *in_data, #ifdef GST_TIZEN_GL_PLATFORM_EGL #ifdef GST_TIZEN_USE_EGLIMAGE - ((MMVideoBuffer *) out_data)->handle.bo[0] = - tbm_bo_ref (tbm_surface_internal_get_bo (out_tbm_surface, 0)); this->eglDestroyImage (this->egl_display, in_egl_image); this->eglDestroyImage (this->egl_display, out_egl_image); - tbm_surface_destroy (in_tbm_surface); - tbm_surface_destroy (out_tbm_surface); #else glReadPixels (0, 0, this->output_frame_width, this->output_frame_height, GL_RGBA, GL_UNSIGNED_BYTE, out_data); diff --git a/video360/src/gstvideo360.c b/video360/src/gstvideo360.c index edc6d66..3151c71 100644 --- a/video360/src/gstvideo360.c +++ b/video360/src/gstvideo360.c @@ -59,6 +59,7 @@ */ #include "gstvideo360.h" +#include /* Debug category definition */ GST_DEBUG_CATEGORY (video360_debug_category); @@ -574,7 +575,7 @@ gst_video360_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) } else if (!strcmp (input_frame_format_srt, "SN12")) { this->input_frame_format = GST_VIDEO_FORMAT_SN12; this->renderer = gst_video360_native_formats_renderer; - this->input_frame_memory_object = 1; + this->input_frame_memory_object = 0; #endif } else if (!strcmp (input_frame_format_srt, "I420")) { this->input_frame_format = GST_VIDEO_FORMAT_I420; @@ -795,18 +796,13 @@ gst_video360_src_event (GstPad * pad, GstObject * parent, GstEvent * event) } #ifdef GST_TIZEN_USE_NATIVE_FORMATS -/* The callback function which releases MMVideoBuffer with attached TBM BO. +/* The callback function which releases tbm surface. * It is used for outgoing frame buffers of SR32 format. * */ static void -mm_vbuffer_free (void * mm_vbuffer) +_buffer_finalize (void *data) { - if (((MMVideoBuffer *) mm_vbuffer)->type == MM_VIDEO_BUFFER_TYPE_TBM_BO && - ((MMVideoBuffer *) mm_vbuffer)->handle.bo[0]) { - tbm_bo_unref (((MMVideoBuffer *) mm_vbuffer)->handle.bo[0]); - } - - g_free (mm_vbuffer); + tbm_surface_internal_unref ((tbm_surface_h)data); } #endif @@ -820,13 +816,14 @@ 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 = NULL; -#else - GstMemory *out_mem; + tbm_surface_h surface; #endif + GstMemory *out_mem; GstMemory *in_mem; GstEvent *event; int ret; + GstVideoInfo info; + GstCaps *caps; if (gst_pad_check_reconfigure (pad)) { event = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0); @@ -848,28 +845,15 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start_time); #endif + caps = gst_pad_get_current_caps (pad); + gst_video_info_from_caps (&info, caps); + gst_caps_unref (caps); #ifdef GST_TIZEN_USE_NATIVE_FORMATS - 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; - mm_vbuffer->width[0] = this->output_frame_width; - mm_vbuffer->height[0] = this->output_frame_height; - mm_vbuffer->stride_width[0] = this->output_frame_width * RGB_BYTES_PER_PIXEL; - mm_vbuffer->stride_height[0] = this->output_frame_height; - mm_vbuffer->size[0] = this->output_frame_buffer_size; - mm_vbuffer->handle_num = 1; - mm_vbuffer->handle_size[0] = this->output_frame_buffer_size; - - 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)); + + if ((out_buf = gst_buffer_new ())) { + surface = tbm_surface_internal_create_with_flags (GST_VIDEO_INFO_WIDTH(&info), GST_VIDEO_INFO_HEIGHT(&info), TBM_FORMAT_ARGB8888, TBM_BO_WC); + out_mem = gst_tizen_allocator_alloc_surface (this->allocator, &info, surface, surface, _buffer_finalize); + gst_buffer_append_memory (out_buf, out_mem); #else if ((out_buf = gst_buffer_new_allocate (NULL, this->output_frame_buffer_size, NULL))) { @@ -885,11 +869,18 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) in_info.data = out_info.data = NULL; in_mem = gst_buffer_peek_memory (in_buf, this->input_frame_memory_object); - gst_memory_map (in_mem, &in_info, GST_MAP_READ); #ifdef GST_TIZEN_USE_NATIVE_FORMATS - out_info.data = (void *) mm_vbuffer; + if (gst_is_tizen_memory (in_mem)) { + GST_DEBUG("tizen memory"); + in_info.data = gst_tizen_memory_get_surface(in_mem); + } else { + gst_memory_map (in_mem, &in_info, GST_MAP_READ); + } + + out_info.data = (tbm_surface_h) surface; #else out_mem = gst_buffer_peek_memory (out_buf, 0); + gst_memory_map (in_mem, &in_info, GST_MAP_READ); gst_memory_map (out_mem, &out_info, GST_MAP_WRITE); #endif @@ -900,9 +891,13 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) pthread_mutex_unlock (&this->gl_mutex); } +#ifdef GST_TIZEN_USE_NATIVE_FORMATS + if (!gst_is_tizen_memory (in_mem)) + gst_memory_unmap (in_mem, &in_info); +#else if (in_info.data) gst_memory_unmap (in_mem, &in_info); -#ifndef GST_TIZEN_USE_NATIVE_FORMATS + if (out_info.data) gst_memory_unmap (out_mem, &out_info); #endif @@ -940,6 +935,10 @@ allocate_local_resources (GstVideo360 * this) GST_ERROR ("Video360 initialization failed: OpenGL initialization failed"); return FALSE; } +#ifdef GST_TIZEN_USE_NATIVE_FORMATS + if (!this->allocator) + this->allocator = gst_tizen_allocator_new (); +#endif return TRUE; } @@ -949,6 +948,11 @@ deallocate_local_resources (GstVideo360 * this) { gst_video360_deinit_gl (this); +#ifdef GST_TIZEN_USE_NATIVE_FORMATS + if (this->allocator) + gst_object_unref (this->allocator); +#endif + #ifdef GST_TIZEN_USE_TIMING if (this->frames_processed) { g_message diff --git a/video360/src/gstvideo360.h b/video360/src/gstvideo360.h index ff49671..ff6b9de 100644 --- a/video360/src/gstvideo360.h +++ b/video360/src/gstvideo360.h @@ -138,6 +138,7 @@ #include #include #include +#include #endif #if (G_BYTE_ORDER == G_BIG_ENDIAN) @@ -230,6 +231,10 @@ struct _GstVideo360 #endif #endif + +#ifdef GST_TIZEN_USE_NATIVE_FORMATS + GstAllocator *allocator; +#endif /* GL extension functions */ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisample; -- 2.7.4 From 6c0d557d45631d02a7f732f8f1cda76140c6767e Mon Sep 17 00:00:00 2001 From: "Hyunil, Park" Date: Mon, 20 Aug 2018 19:31:13 +0900 Subject: [PATCH 06/16] Remove render_rectangle interface Change-Id: I78dbe7d95262dcb4bfc2d92c5980c7e6cb37dede Signed-off-by: Hyunil, Park --- tizenwlsink/src/gsttizenwlsink.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 46d6fbd..2ab4257 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -2365,7 +2365,6 @@ static void gst_tizen_wl_sink_videooverlay_init (GstVideoOverlayInterface * iface) { iface->set_window_handle = gst_tizen_wl_sink_set_window_handle; - iface->set_render_rectangle = gst_tizen_wl_sink_set_roi_area; iface->expose = gst_tizen_wl_sink_expose; #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT /* use unique_id */ iface->set_wl_window_wl_surface_id = -- 2.7.4 From 35ee45a6bbfc801704878d021bdf4abc6f348d85 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Fri, 24 Aug 2018 13:44:27 +0900 Subject: [PATCH 07/16] tizenwlsink: Add property for scaling video source coordinate Change-Id: I715f3afb818c5ba7807fdfc46a2406291837332e Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 265 ++++++++++++++++++++------------------- tizenwlsink/src/gsttizenwlsink.h | 6 +- tizenwlsink/src/wlwindow.c | 24 ++-- tizenwlsink/src/wlwindow.h | 4 +- 4 files changed, 155 insertions(+), 144 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 2ab4257..a219002 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -159,14 +159,14 @@ enum PROP_FLIP, PROP_VISIBLE, PROP_FOLLOW_PARENT_TRANSFORM, - PROP_CROP_X, - PROP_CROP_Y, - PROP_CROP_WIDTH, - PROP_CROP_HEIGHT, + PROP_SCALE_SRC_X, + PROP_SCALE_SRC_Y, + PROP_SCALE_SRC_WIDTH, + PROP_SCALE_SRC_HEIGHT, PROP_RATIO_WIDTH, PROP_RATIO_HEIGHT, - PROP_SCALE_WIDTH, - PROP_SCALE_HEIGHT, + PROP_SCALE_DST_WIDTH, + PROP_SCALE_DST_HEIGHT, PROP_OFFSET_X, PROP_OFFSET_Y, PROP_OFFSET_WIDTH, @@ -233,6 +233,7 @@ static void gst_tizen_wl_sink_begin_geometry_change (GstWaylandVideo * video); static void gst_tizen_wl_sink_end_geometry_change (GstWaylandVideo * video); #endif #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT +static void gst_tizen_wl_sink_calc_source_coordinate (GstTizenWlSink * sink); static gboolean gst_tizen_wl_sink_event (GstBaseSink * bsink, GstEvent * event); static void gst_tizen_wl_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, GstClockTime * start, GstClockTime * end); @@ -356,16 +357,40 @@ gst_tizen_wl_sink_class_init (GstTizenWlSinkClass * klass) "Draws screen or blacks out, true means visible, false blacks out", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_SCALE_SRC_X, + g_param_spec_double ("scale-source-x", "Scale source x", + "x coordinate ratio value of video source area " + "based on video width size", 0.0, 1.0, 0.0, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCALE_SRC_Y, + g_param_spec_double ("scale-source-y", "Scale source y", + "y coordinate ratio value of video source area " + "based on video width size", 0.0, 1.0, 0.0, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCALE_SRC_WIDTH, + g_param_spec_double ("scale-source-width", "Scale source width", + "width ratio value of the video source area " + "based on video width size", G_MINDOUBLE, 1.0, 1.0, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_SCALE_SRC_HEIGHT, + g_param_spec_double ("scale-source-height", "Scale source height", + "height ratio value of the video source area " + "based on video width size", G_MINDOUBLE, 1.0, 1.0, + G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS)); + #ifdef ENABLE_FUNCTION - g_object_class_install_property (gobject_class, PROP_SCALE_WIDTH, - g_param_spec_double ("scale-w", "ratio width", - "scale width for rendering video," + g_object_class_install_property (gobject_class, PROP_SCALE_DST_WIDTH, + g_param_spec_double ("scale-destination-width", "Scales destination width", + "scale width for rendering video, " "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_SCALE_HEIGHT, - g_param_spec_double ("scale-h", "scale height", - "scale width for rendering video, " + g_object_class_install_property (gobject_class, PROP_SCALE_DST_HEIGHT, + g_param_spec_double ("scale-destination-height", "Scales destination height", + "scale height for rendering video, " "Function is not support in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); @@ -376,36 +401,6 @@ gst_tizen_wl_sink_class_init (GstTizenWlSinkClass * klass) "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_CROP_X, - g_param_spec_uint ("crop-x", "crop x", - "x-coordinate for cropping video. " - "Please set crop-x, crop-y, crop-w and crop-h togethrer. " - "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, - G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_CROP_Y, - g_param_spec_uint ("crop-y", "crop y", - "y-coordinate for cropping video. " - "Please set crop-x, crop-y, crop-w and crop-h togethrer. " - "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, - G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_CROP_WIDTH, - g_param_spec_uint ("crop-w", "crop width", - "width for cropping video. " - "If value is not set or is set 0, Width is set to video width after set_caps. " - "Please set crop-x, crop-y, crop-w and crop-h togethrer. " - "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, - G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_CROP_HEIGHT, - g_param_spec_uint ("crop-h", "crop height", - "height for cropping video. " - "If value is not set or is set 0, Hight is set to video height after set_caps. " - "Please set crop-x, crop-y, crop-w and crop-h togethrer. " - "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0, - G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_RATIO_WIDTH, g_param_spec_double ("ratio-w", "ratio width", "ratio width for rendering video," @@ -537,12 +532,15 @@ gst_tizen_wl_sink_init (GstTizenWlSink * sink) sink->flip = DEF_DISPLAY_FLIP; sink->rotate_angle = DEGREE_0; sink->visible = TRUE; - sink->crop_x = sink->crop_y = sink->crop_w = sink->crop_h = 0; + sink->scale_src_x = sink->scale_src_y = 0.0; + sink->scale_src_w = sink->scale_src_h = 1.0; + sink->src_x = sink->src_y = sink->src_w = sink->src_h = 0; + sink->is_set_scale_src = FALSE; #ifdef ENABLE_FUNCTION sink->follow_parent_transform = FALSE; sink->ratio_w = sink->ratio_h = -1.0; //need to set -1.0 for original video ratio sink->align_w = sink->align_h = 0.5; - sink->scale_w = sink->scale_h = 1.0; + sink->scale_dst_w = sink->scale_dst_h = 1.0; sink->offset_x = sink->offset_y = sink->offset_w = sink->offset_h = 0; #endif #endif @@ -976,27 +974,27 @@ gst_tizen_wl_sink_get_property (GObject * object, case PROP_VISIBLE: g_value_set_boolean (value, sink->visible); break; -#ifdef ENABLE_FUNCTION - case PROP_SCALE_WIDTH: - g_value_set_double (value, sink->scale_w); + case PROP_SCALE_SRC_X: + g_value_set_double (value, sink->scale_src_x); break; - case PROP_SCALE_HEIGHT: - g_value_set_double (value, sink->scale_h); + case PROP_SCALE_SRC_Y: + g_value_set_double (value, sink->scale_src_y); break; - case PROP_FOLLOW_PARENT_TRANSFORM: - g_value_set_boolean (value, sink->follow_parent_transform); + case PROP_SCALE_SRC_WIDTH: + g_value_set_double (value, sink->scale_src_w); break; - case PROP_CROP_X: - g_value_set_uint (value, sink->crop_x); + case PROP_SCALE_SRC_HEIGHT: + g_value_set_double (value, sink->scale_src_h); break; - case PROP_CROP_Y: - g_value_set_uint (value, sink->crop_y); +#ifdef ENABLE_FUNCTION + case PROP_SCALE_DST_WIDTH: + g_value_set_double (value, sink->scale_dst_w); break; - case PROP_CROP_WIDTH: - g_value_set_uint (value, sink->crop_w); + case PROP_SCALE_DST_HEIGHT: + g_value_set_double (value, sink->scale_dst_h); break; - case PROP_CROP_HEIGHT: - g_value_set_uint (value, sink->crop_h); + case PROP_FOLLOW_PARENT_TRANSFORM: + g_value_set_boolean (value, sink->follow_parent_transform); break; case PROP_RATIO_WIDTH: g_value_set_double (value, sink->ratio_w); @@ -1151,28 +1149,58 @@ gst_tizen_wl_sink_set_property (GObject * object, } } break; + case PROP_SCALE_SRC_X: + sink->scale_src_x = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-src-x is set (%f)", sink->scale_src_x); + break; + case PROP_SCALE_SRC_Y: + sink->scale_src_y = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-src-y is set (%f)", sink->scale_src_y); + break; + case PROP_SCALE_SRC_WIDTH: + sink->scale_src_w = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-src-width is set (%f)", sink->scale_src_w); + break; + case PROP_SCALE_SRC_HEIGHT: + sink->scale_src_h = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-src-height is set (%f)", sink->scale_src_h); + sink->video_info_changed = TRUE; + if (sink->scale_src_x == 0.0 && sink->scale_src_y == 0.0 + && sink->scale_src_w == 1.0 && sink->scale_src_h == 1.0) { + GST_WARNING_OBJECT (sink, "Video source will be fully scaled"); + sink->is_set_scale_src = FALSE; + } else { + GST_WARNING_OBJECT (sink, "Video source will be scaled"); + sink->is_set_scale_src = TRUE; + } + if (sink->window) { + gst_tizen_wl_sink_calc_source_coordinate (sink); + gst_wl_window_set_source_wl_buffer (sink->window, + sink->src_x, sink->src_y, sink->src_w, sink->src_h); + } + break; #ifdef ENABLE_FUNCTION - case PROP_SCALE_WIDTH: - if (sink->scale_w == g_value_get_double (value) + case PROP_SCALE_DST_WIDTH: + if (sink->scale_dst_w == g_value_get_double (value) || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; - sink->scale_w = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-w is set (%f)", sink->scale_w); + sink->scale_dst_w = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-destination-width is set (%f)", sink->scale_dst_w); sink->video_info_changed = TRUE; if (sink->window) - gst_wl_window_set_destination_mode_scale (sink->window, sink->scale_w, - sink->scale_h); + gst_wl_window_set_destination_mode_scale (sink->window, + sink->scale_dst_w, sink->scale_dst_h); break; - case PROP_SCALE_HEIGHT: - if (sink->scale_h == g_value_get_double (value) + case PROP_SCALE_DST_HEIGHT: + if (sink->scale_dst_h == g_value_get_double (value) || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; - sink->scale_h = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-h is set (%f)", sink->scale_h); + sink->scale_dst_h = g_value_get_double (value); + GST_WARNING_OBJECT (sink, "scale-destination-height is set (%f)", sink->scale_dst_h); sink->video_info_changed = TRUE; if (sink->window) - gst_wl_window_set_destination_mode_scale (sink->window, sink->scale_w, - sink->scale_h); + gst_wl_window_set_destination_mode_scale (sink->window, + sink->scale_dst_w, sink->scale_dst_h); break; case PROP_FOLLOW_PARENT_TRANSFORM: if (sink->follow_parent_transform == g_value_get_boolean (value) @@ -1187,49 +1215,6 @@ gst_tizen_wl_sink_set_property (GObject * object, (sink->window, sink->follow_parent_transform); } break; - case PROP_CROP_X: - if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) - break; - sink->crop_x = g_value_get_uint (value); - GST_WARNING_OBJECT (sink, "crop-x is set (%d)", sink->crop_x); - break; - case PROP_CROP_Y: - if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) - break; - sink->crop_y = g_value_get_uint (value); - GST_WARNING_OBJECT (sink, "crop-y is set (%d)", sink->crop_y); - break; - case PROP_CROP_WIDTH: - if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) - break; - sink->crop_w = g_value_get_uint (value); - GST_WARNING_OBJECT (sink, "crop_w is set (%d)", sink->crop_w); - /* crop-w is unset by 0, set to video width size */ - if (sink->crop_w == 0 && sink->video_info.width > 0) { - sink->crop_w = - gst_util_uint64_scale_int_round (sink->video_info.width, - sink->video_info.par_n, sink->video_info.par_d); - GST_LOG ("crop-w is unset by 0, set to video width size(%d)", - sink->crop_w); - } - break; - case PROP_CROP_HEIGHT: - if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) - break; - sink->crop_h = g_value_get_uint (value); - GST_WARNING_OBJECT (sink, "crop-h is set (%d)", sink->crop_h); - /* crop-h unset by 0, set to video height size */ - if (sink->crop_h == 0 && sink->video_info.height > 0) { - sink->crop_h = sink->video_info.height; - GST_LOG ("crop-h is unset by 0, set to video height size(%d)", - sink->crop_h); - } - sink->video_info_changed = TRUE; - if (sink->window && sink->crop_w > 0 && sink->crop_h > 0) { - gst_wl_window_set_destination_mode_crop_wl_buffer (sink->window, - sink->crop_x, sink->crop_y, sink->crop_w, sink->crop_h); - } - break; case PROP_RATIO_WIDTH: if (sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; @@ -1237,7 +1222,7 @@ gst_tizen_wl_sink_set_property (GObject * object, GST_WARNING_OBJECT (sink, "ratio-w is set (%f)", sink->ratio_w); break; case PROP_RATIO_HEIGHT: - if (sink->scale_w == g_value_get_double (value) + if (sink->ratio_h == g_value_get_double (value) || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; sink->ratio_h = g_value_get_double (value); @@ -1340,6 +1325,35 @@ gst_tizen_wl_sink_finalize (GObject * object) } #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT +static void +gst_tizen_wl_sink_calc_source_coordinate (GstTizenWlSink * sink) +{ + FUNCTION; + g_return_if_fail (sink != NULL); + g_return_if_fail (sink->window != NULL); + g_return_if_fail (sink->scale_src_x >= 0.0 && sink->scale_src_x <= 1.0); + g_return_if_fail (sink->scale_src_y >= 0.0 && sink->scale_src_y <= 1.0); + g_return_if_fail (sink->scale_src_w > 0.0 && sink->scale_src_w <= 1.0); + g_return_if_fail (sink->scale_src_h > 0.0 && sink->scale_src_h <= 1.0); + + sink->src_x = sink->src_y = 0; + sink->src_w = + gst_util_uint64_scale_int_round (sink->video_info.width, + sink->video_info.par_n, sink->video_info.par_d); + sink->src_h = sink->video_info.height; + + if (sink->is_set_scale_src) { + sink->src_x = (double) sink->src_w * sink->scale_src_x; + sink->src_y = (double) sink->src_h * sink->scale_src_y; + sink->src_w = (double) sink->src_w * sink->scale_src_w; + sink->src_h = (double) sink->src_h * sink->scale_src_h; + } + + GST_LOG ("Video source coordinate x(%d) y(%d) w(%d) h(%d)", sink->src_x, + sink->src_y, sink->src_w, sink->src_h); +} + + static gboolean gst_tizen_wl_sink_event (GstBaseSink * bsink, GstEvent * event) { @@ -1773,7 +1787,7 @@ gst_tizen_wl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) sink->fps_d = sink->video_info.fps_d; /* init value for set source */ - sink->crop_x = sink->crop_y = sink->crop_w = sink->crop_h = 0; + sink->src_x = sink->src_y = sink->src_w = sink->src_h = 0; if (GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_SN12 || GST_VIDEO_INFO_FORMAT (&sink->video_info) == GST_VIDEO_FORMAT_ST12 || @@ -1917,21 +1931,17 @@ gst_tizen_wl_sink_update_window_geometry (GstTizenWlSink * sink) gst_wl_window_set_destination_mode (sink->window, sink->display_geometry_method); gst_wl_window_set_flip (sink->window, sink->flip); - if (sink->crop_w == 0 && sink->crop_h == 0) { - sink->crop_w = - gst_util_uint64_scale_int_round (sink->video_info.width, - sink->video_info.par_n, sink->video_info.par_d); - sink->crop_h = sink->video_info.height; - } - gst_wl_window_set_destination_mode_crop_wl_buffer (sink->window, sink->crop_x, - sink->crop_y, sink->crop_w, sink->crop_h); + + gst_tizen_wl_sink_calc_source_coordinate (sink); + gst_wl_window_set_source_wl_buffer (sink->window, sink->src_x, + sink->src_y, sink->src_w, sink->src_h); #ifdef ENABLE_FUNCTION gst_wl_window_set_destination_mode_follow_parent_transform (sink->window, sink->follow_parent_transform); gst_wl_window_set_destination_mode_ratio (sink->window, sink->ratio_w, sink->ratio_h); - gst_wl_window_set_destination_mode_scale (sink->window, sink->scale_w, - sink->scale_h); + gst_wl_window_set_destination_mode_scale (sink->window, sink->scale_dst_w, + sink->scale_dst_h); gst_wl_window_set_destination_mode_offset (sink->window, sink->offset_x, sink->offset_y, sink->offset_w, sink->offset_h); gst_wl_window_set_destination_mode_align (sink->window, sink->align_w, @@ -2472,8 +2482,7 @@ gst_tizen_wl_sink_set_roi_area (GstVideoOverlay * overlay, gint x, gint y, if (!sink->window) { g_mutex_unlock (&sink->render_lock); - GST_WARNING_OBJECT (sink, - "set roi area called without window, ignoring"); + GST_WARNING_OBJECT (sink, "set roi area called without window, ignoring"); return; } diff --git a/tizenwlsink/src/gsttizenwlsink.h b/tizenwlsink/src/gsttizenwlsink.h index 215bbb4..a4f9711 100644 --- a/tizenwlsink/src/gsttizenwlsink.h +++ b/tizenwlsink/src/gsttizenwlsink.h @@ -102,11 +102,13 @@ struct _GstTizenWlSink guint rotate_angle; guint display_geometry_method; guint flip; - guint crop_x, crop_y, crop_w, crop_h; + guint src_x, src_y, src_w, src_h; + gdouble scale_src_x, scale_src_y, scale_src_w, scale_src_h; + gboolean is_set_scale_src; #ifdef ENABLE_FUNCTION guint offset_x, offset_y, offset_w, offset_h; gdouble ratio_w, ratio_h; - gdouble scale_w, scale_h; + gdouble scale_dst_w, scale_dst_h; gdouble align_w, align_h; #endif #endif diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index 617282d..f877c44 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -597,17 +597,17 @@ gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, /* Set source, wayland need to set "tizen_viewport_set_source" always when change video info, aligned video issue=> ex) 854 x 480 video : aligned buffer size 864 x 480, so we need to set original video size by set source */ - if (window->mode_crop.changed) { + if (window->set_source.changed) { /* we have known issue about mobile team kernel, when set orign green line can be shown with tbm */ GST_INFO ("tizen_viewport_set_source (tizen_video_viewport@%p, x@%d, y@%d, w@%d, h@%d)", - window->tizen_video_viewport, window->mode_crop.x, window->mode_crop.y, - window->mode_crop.w, window->mode_crop.h); + window->tizen_video_viewport, window->set_source.x, + window->set_source.y, window->set_source.w, window->set_source.h); tizen_viewport_set_source (window->tizen_video_viewport, - window->mode_crop.x, window->mode_crop.y, window->mode_crop.w, - window->mode_crop.h); + window->set_source.x, window->set_source.y, window->set_source.w, + window->set_source.h); - window->mode_crop.changed = FALSE; + window->set_source.changed = FALSE; } /*set tizen destination mode */ @@ -953,17 +953,17 @@ gst_wl_window_set_flip (GstWlWindow * window, guint flip) } void -gst_wl_window_set_destination_mode_crop_wl_buffer (GstWlWindow * window, +gst_wl_window_set_source_wl_buffer (GstWlWindow * window, guint x, guint y, guint w, guint h) { FUNCTION; g_return_if_fail (window != NULL); GST_WARNING ("set crop x@%d, y@%d, w@%d, h@%d", x, y, w, h); - window->mode_crop.x = x; - window->mode_crop.y = y; - window->mode_crop.w = w; - window->mode_crop.h = h; - window->mode_crop.changed = TRUE; + window->set_source.x = x; + window->set_source.y = y; + window->set_source.w = w; + window->set_source.h = h; + window->set_source.changed = TRUE; } #ifdef ENABLE_FUNCTION diff --git a/tizenwlsink/src/wlwindow.h b/tizenwlsink/src/wlwindow.h index 8eb3c99..61c2f26 100644 --- a/tizenwlsink/src/wlwindow.h +++ b/tizenwlsink/src/wlwindow.h @@ -103,7 +103,7 @@ struct _GstWlWindow WinGeometryValue disp_geo_method; WinGeometryValue rotate_angle; WinGeometryValue flip; - WinGeometryRect mode_crop; + WinGeometryRect set_source; #ifdef ENABLE_FUNCTION WinGeometryValue follow_parent_transform; WinGeometryRect mode_offset; @@ -155,7 +155,7 @@ void gst_wl_window_set_video_info (GstWlWindow * window, const GstVideoInfo * info); void gst_wl_window_set_rotate_angle (GstWlWindow * window, guint rotate_angle); void gst_wl_window_set_flip (GstWlWindow * window, guint flip); -void gst_wl_window_set_destination_mode_crop_wl_buffer (GstWlWindow * window, guint x, guint y, guint w, guint h); +void gst_wl_window_set_source_wl_buffer (GstWlWindow * window, guint x, guint y, guint w, guint h); void gst_wl_window_set_destination_mode (GstWlWindow * window, guint disp_geo_method); #ifdef ENABLE_FUNCTION /* if video mode is set, below function can use */ -- 2.7.4 From 6aa41c036cf2bfd9c5636a96efd45eb538d789fd Mon Sep 17 00:00:00 2001 From: Hyunil Date: Mon, 27 Aug 2018 14:12:49 +0900 Subject: [PATCH 08/16] Add set_video_source_roi_area interface Change-Id: I7cd2e0dcaf4a6c6c362320f24619050144294def Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 84 +++++++++++++++++++++++++++++++++------- tizenwlsink/src/wlwindow.c | 3 +- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index a219002..642303e 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -221,6 +221,9 @@ gst_tizen_wl_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay, guintptr wl_surface_id); static void gst_tizen_wl_sink_set_roi_area (GstVideoOverlay * overlay, gint x, gint y, gint w, gint h); +static void gst_tizen_wl_sink_set_video_source_roi_area (GstVideoOverlay * + overlay, gdouble scale_src_x, gdouble scale_src_y, gdouble scale_src_w, + gdouble scale_src_h); static void gst_tizen_wl_sink_expose (GstVideoOverlay * overlay); /* WaylandVideo interface */ @@ -383,13 +386,15 @@ gst_tizen_wl_sink_class_init (GstTizenWlSinkClass * klass) #ifdef ENABLE_FUNCTION g_object_class_install_property (gobject_class, PROP_SCALE_DST_WIDTH, - g_param_spec_double ("scale-destination-width", "Scales destination width", + g_param_spec_double ("scale-destination-width", + "Scales destination width", "scale width for rendering video, " "Function is not supported in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_SCALE_DST_HEIGHT, - g_param_spec_double ("scale-destination-height", "Scales destination height", + g_param_spec_double ("scale-destination-height", + "Scales destination height", "scale height for rendering video, " "Function is not support in DISP_GEO_METHOD_CUSTOM_ROI. ", 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); @@ -549,6 +554,20 @@ gst_tizen_wl_sink_init (GstTizenWlSink * sink) } #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT +static gboolean +gst_tizen_wl_sink_is_set_scale_src (int scale_src_x, int scale_src_y, + int scale_src_w, int scale_src_h) +{ + if (scale_src_x == 0.0 && scale_src_y == 0.0 && scale_src_w == 1.0 + && scale_src_h == 1.0) { + GST_WARNING ("Video source will be fully scaled"); + return FALSE; + } + + GST_WARNING ("Video source will be scaled"); + return TRUE; +} + static void gst_tizen_wl_sink_recover_display_window_info (GstTizenWlSink * sink) { @@ -1159,20 +1178,17 @@ gst_tizen_wl_sink_set_property (GObject * object, break; case PROP_SCALE_SRC_WIDTH: sink->scale_src_w = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-src-width is set (%f)", sink->scale_src_w); + GST_WARNING_OBJECT (sink, "scale-src-width is set (%f)", + sink->scale_src_w); break; case PROP_SCALE_SRC_HEIGHT: sink->scale_src_h = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-src-height is set (%f)", sink->scale_src_h); + GST_WARNING_OBJECT (sink, "scale-src-height is set (%f)", + sink->scale_src_h); sink->video_info_changed = TRUE; - if (sink->scale_src_x == 0.0 && sink->scale_src_y == 0.0 - && sink->scale_src_w == 1.0 && sink->scale_src_h == 1.0) { - GST_WARNING_OBJECT (sink, "Video source will be fully scaled"); - sink->is_set_scale_src = FALSE; - } else { - GST_WARNING_OBJECT (sink, "Video source will be scaled"); - sink->is_set_scale_src = TRUE; - } + sink->is_set_scale_src = + gst_tizen_wl_sink_is_set_scale_src (sink->scale_src_x, + sink->scale_src_y, sink->scale_src_w, sink->scale_src_h); if (sink->window) { gst_tizen_wl_sink_calc_source_coordinate (sink); gst_wl_window_set_source_wl_buffer (sink->window, @@ -1185,7 +1201,8 @@ gst_tizen_wl_sink_set_property (GObject * object, || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; sink->scale_dst_w = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-destination-width is set (%f)", sink->scale_dst_w); + GST_WARNING_OBJECT (sink, "scale-destination-width is set (%f)", + sink->scale_dst_w); sink->video_info_changed = TRUE; if (sink->window) gst_wl_window_set_destination_mode_scale (sink->window, @@ -1196,7 +1213,8 @@ gst_tizen_wl_sink_set_property (GObject * object, || sink->display_geometry_method == DISP_GEO_METHOD_CUSTOM_ROI) break; sink->scale_dst_h = g_value_get_double (value); - GST_WARNING_OBJECT (sink, "scale-destination-height is set (%f)", sink->scale_dst_h); + GST_WARNING_OBJECT (sink, "scale-destination-height is set (%f)", + sink->scale_dst_h); sink->video_info_changed = TRUE; if (sink->window) gst_wl_window_set_destination_mode_scale (sink->window, @@ -2380,6 +2398,7 @@ gst_tizen_wl_sink_videooverlay_init (GstVideoOverlayInterface * iface) iface->set_wl_window_wl_surface_id = gst_tizen_wl_sink_set_wl_window_wl_surface_id; iface->set_display_roi_area = gst_tizen_wl_sink_set_roi_area; + iface->set_video_roi_area = gst_tizen_wl_sink_set_video_source_roi_area; #endif } @@ -2501,6 +2520,43 @@ gst_tizen_wl_sink_set_roi_area (GstVideoOverlay * overlay, gint x, gint y, } static void +gst_tizen_wl_sink_set_video_source_roi_area (GstVideoOverlay * overlay, + gdouble scale_src_x, gdouble scale_src_y, gdouble scale_src_w, + gdouble scale_src_h) +{ + GstTizenWlSink *sink = GST_TIZEN_WL_SINK (overlay); + FUNCTION; + + g_return_if_fail (sink != NULL); + g_return_if_fail (sink->window != NULL); + g_return_if_fail (scale_src_x >= 0.0 && scale_src_x <= 1.0); + g_return_if_fail (scale_src_y >= 0.0 && scale_src_y <= 1.0); + g_return_if_fail (scale_src_w > 0.0 && scale_src_w <= 1.0); + g_return_if_fail (scale_src_h > 0.0 && scale_src_h <= 1.0); + + g_mutex_lock (&sink->render_lock); + + sink->is_set_scale_src = + gst_tizen_wl_sink_is_set_scale_src (scale_src_x, scale_src_y, scale_src_w, + scale_src_h); + + sink->video_info_changed = TRUE; + sink->scale_src_x = scale_src_x; + sink->scale_src_y = scale_src_y; + sink->scale_src_w = scale_src_w; + sink->scale_src_h = scale_src_h; + + gst_tizen_wl_sink_calc_source_coordinate (sink); + gst_wl_window_set_source_wl_buffer (sink->window, + sink->src_x, sink->src_y, sink->src_w, sink->src_h); + + if (GST_STATE (sink) == GST_STATE_PAUSED) + gst_tizen_wl_sink_update_last_buffer_geometry (sink); + + g_mutex_unlock (&sink->render_lock); +} + +static void gst_tizen_wl_sink_expose (GstVideoOverlay * overlay) { GstTizenWlSink *sink = GST_TIZEN_WL_SINK (overlay); diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index f877c44..7fae499 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -958,7 +958,8 @@ gst_wl_window_set_source_wl_buffer (GstWlWindow * window, { FUNCTION; g_return_if_fail (window != NULL); - GST_WARNING ("set crop x@%d, y@%d, w@%d, h@%d", x, y, w, h); + g_return_if_fail (w > 0 && h > 0); + GST_WARNING ("set video source x@%d, y@%d, w@%d, h@%d", x, y, w, h); window->set_source.x = x; window->set_source.y = y; window->set_source.w = w; -- 2.7.4 From f63d6d216c3aa091514128cdde693391223d84f4 Mon Sep 17 00:00:00 2001 From: SeokHoon Lee Date: Wed, 11 Jul 2018 17:23:30 +0900 Subject: [PATCH 09/16] Uncover MMVideoBuffer in 'waylandsrc'. After this patch, without MMVideoBuffer, TBM is sended by GstBuffer. Signed-off-by: SeokHoon Lee Change-Id: I26782f1fe835f8e962fa52be1e8ea844c75ed99f --- configure.ac | 6 ++ waylandsrc/src/Makefile.am | 21 +++- waylandsrc/src/gstwaylandsrc.c | 222 ++++++++++++++++++++--------------------- waylandsrc/src/gstwaylandsrc.h | 11 ++ 4 files changed, 142 insertions(+), 118 deletions(-) diff --git a/configure.ac b/configure.ac index 0c91739..2e7a8a6 100644 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,12 @@ dnl make _CFLAGS and _LIBS available AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) +PKG_CHECK_MODULES(GST_ALLOCATORS, gstreamer-allocators-$GST_MAJORMINOR >= $GST_REQUIRED) + +dnl make _CFLAGS and _LIBS available +AC_SUBST(GST_ALLOCATORS_CFLAGS) +AC_SUBST(GST_ALLOCATORS_LIBS) + PKG_CHECK_MODULES(DRM, libdrm) AC_SUBST(DRM_CFLAGS) AC_SUBST(DRM_LIBS) diff --git a/waylandsrc/src/Makefile.am b/waylandsrc/src/Makefile.am index 117f402..5b70fb4 100644 --- a/waylandsrc/src/Makefile.am +++ b/waylandsrc/src/Makefile.am @@ -18,8 +18,25 @@ libgstwaylandsrc_la_SOURCES = gstwaylandsrc.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed -libgstwaylandsrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(DRM_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) -libgstwaylandsrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(WAYLAND_CLIENT_LIBS) $(DRM_LIBS) $(TBM_LIBS) +libgstwaylandsrc_la_CFLAGS = $(TBM_CFLAGS) \ + $(GST_CFLAGS) \ + $(GST_BASE_CFLAGS) \ + $(GST_VIDEO_FLAGS) \ + $(GST_ALLOCATORS_FLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(WAYLAND_CLIENT_CFLAGS) \ + $(DRM_CFLAGS) \ + $(MMCOMMON_CFLAGS) + +libgstwaylandsrc_la_LIBADD = $(GST_LIBS) \ + $(GST_BASE_LIBS) \ + $(GST_PLUGINS_BASE_LIBS) \ + $(GST_VIDEO_LIBS) \ + $(GST_ALLOCATORS_LIBS) \ + $(WAYLAND_CLIENT_LIBS) \ + $(DRM_LIBS) \ + $(TBM_LIBS) + libgstwaylandsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # headers we need but don't want installed diff --git a/waylandsrc/src/gstwaylandsrc.c b/waylandsrc/src/gstwaylandsrc.c index 8584a8f..0daf817 100644 --- a/waylandsrc/src/gstwaylandsrc.c +++ b/waylandsrc/src/gstwaylandsrc.c @@ -53,8 +53,8 @@ GST_DEBUG_CATEGORY_STATIC (waylandsrc_debug); #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 480 -//#define DUMP_BUFFER -#define USE_MM_VIDEO_BUFFER +//#define WAYLANDSRC_BUFFER_DUMP +#define WAYLANDSRC_DUMP_FILE "/tmp/waylandsrc.dump" #define C(b,m) (char)(((b) >> (m)) & 0xFF) #define B(c,s) ((((unsigned int)(c)) & 0xff) << (s)) @@ -168,6 +168,48 @@ static const struct tizen_screenmirror_listener mirror_listener = { mirror_handle_stop }; + +#ifdef WAYLANDSRC_BUFFER_DUMP +static int dump_cnt; + +void save_waylandsrc_buffer (output_buffer * out_buffer) +{ + dump_cnt++; + + if (100 < dump_cnt && dump_cnt < 150) { + tbm_bo_handle bo_handle; + FILE *fp = fopen (WAYLANDSRC_DUMP_FILE, "a"); + if (fp == NULL) { + GST_ERROR_OBJECT (src, "Failed to open file: %s", strerror (errno)); + return; + } + + bo_handle = tbm_bo_map (out_buffer->bo[0], TBM_DEVICE_CPU, TBM_OPTION_READ); + + if (bo_handle.ptr) + fwrite ((char *)bo_handle.ptr, tbm_bo_size(out_buffer->bo[0]), 1, fp); + else + GST_ERROR_OBJECT (src, "Failed to get tbm bo[0]'s handle: %s", strerror (errno)); + + tbm_bo_unmap(out_buffer->bo[0]); + + #ifndef TIZEN_FEATURE_PRODUCT_TM1 + bo_handle = tbm_bo_map (out_buffer->bo[1], TBM_DEVICE_CPU, TBM_OPTION_READ); + if (bo_handle.ptr) + fwrite ((char *) bo_handle.ptr, tbm_bo_size(out_buffer->bo[1]), 1, fp); + else + GST_ERROR_OBJECT (src, "Failed to get tbm bo[1]'s handle:: %s", strerror (errno)); + + tbm_bo_unmap(out_buffer->bo[1]); + #endif + + GST_ERROR_OBJECT (src, "Dump (%d):%d %d\n", dump_cnt, out_buffer->size, tbm_bo_size(out_buffer->bo[0])); + + fclose (fp); + } +} +#endif + int new_calc_plane(int width, int height) { int mbX, mbY; @@ -321,107 +363,24 @@ mirror_handle_dequeued (void *data, out_buffer->size, 0, out_buffer->size, (gpointer) out_buffer, gst_wayland_src_gst_buffer_unref)); } else if (src->format == TBM_FORMAT_NV12) { -#ifndef USE_MM_VIDEO_BUFFER - out_buffer->gst_buffer = gst_buffer_new (); - gst_buffer_append_memory (out_buffer->gst_buffer, - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, - tbm_bo_map(out_buffer->bo[0], TBM_DEVICE_CPU, TBM_OPTION_READ).ptr, - tbm_bo_size(out_buffer->bo[0]), 0, tbm_bo_size(out_buffer->bo[0]), - (gpointer) out_buffer, gst_wayland_src_gst_buffer_unref)); - gst_buffer_append_memory (out_buffer->gst_buffer, - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, - tbm_bo_map(out_buffer->bo[1], TBM_DEVICE_CPU, TBM_OPTION_READ).ptr, - tbm_bo_size(out_buffer->bo[1]), 0, tbm_bo_size(out_buffer->bo[1]), - (gpointer) out_buffer, NULL)); -#else - MMVideoBuffer *mm_video_buf = NULL; - mm_video_buf = (MMVideoBuffer *) malloc (sizeof (MMVideoBuffer)); - if (mm_video_buf == NULL) { - GST_ERROR_OBJECT (src, "failed to alloc MMVideoBuffer"); + GstMemory *memory = NULL; + GST_WARNING_OBJECT (src, "Creating memory by tizen allocator"); + memory = gst_tizen_allocator_alloc_surface(src->allocator, + &src->video_info, + out_buffer->surface, + (gpointer)out_buffer, + (GDestroyNotify)gst_wayland_src_gst_buffer_unref); + + if (!memory) { + GST_ERROR_OBJECT (src, "failed to alloc memory by tizen allocator"); goto FUNC_END; } - memset (mm_video_buf, 0x00, sizeof (MMVideoBuffer)); - - mm_video_buf->type = MM_VIDEO_BUFFER_TYPE_TBM_BO; - mm_video_buf->handle.bo[0] = out_buffer->bo[0]; - mm_video_buf->handle.bo[1] = out_buffer->bo[1]; - GST_INFO_OBJECT (src, "BO : %p %p", mm_video_buf->handle.bo[0], mm_video_buf->handle.bo[1]); -#ifndef TIZEN_FEATURE_PRODUCT_TM1 - mm_video_buf->size[0] = gst_calculate_y_size(src->width, src->height); /*(src->width * src->height);*/ - mm_video_buf->size[1] = gst_calculate_uv_size(src->width, src->height); /*(src->width * (src->height >> 1));*/ - GST_INFO_OBJECT (src, "Size : %d %d", mm_video_buf->size[0], mm_video_buf->size[1]); - - mm_video_buf->handle.dmabuf_fd[0] = tbm_bo_get_handle(out_buffer->bo[0], TBM_DEVICE_MM).u32; - mm_video_buf->handle.dmabuf_fd[1] = tbm_bo_get_handle(out_buffer->bo[1], TBM_DEVICE_MM).u32; - - mm_video_buf->handle.paddr[0] = (tbm_bo_map(mm_video_buf->handle.bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE)).ptr; - mm_video_buf->handle.paddr[1] = (tbm_bo_map(mm_video_buf->handle.bo[1], TBM_DEVICE_CPU, TBM_OPTION_WRITE)).ptr; - - tbm_bo_unmap (mm_video_buf->handle.bo[0]); - tbm_bo_unmap (mm_video_buf->handle.bo[1]); -#endif - - mm_video_buf->width[0] = src->width; - mm_video_buf->height[0] = src->height; - mm_video_buf->format = MM_PIXEL_FORMAT_NV12; - mm_video_buf->width[1] = src->width; - mm_video_buf->height[1] = src->height >> 1; - - mm_video_buf->stride_width[0] = GST_ROUND_UP_16 (mm_video_buf->width[0]); - mm_video_buf->stride_height[0] = GST_ROUND_UP_16 (mm_video_buf->height[0]); - mm_video_buf->stride_width[1] = GST_ROUND_UP_16 (mm_video_buf->width[1]); - mm_video_buf->stride_height[1] = GST_ROUND_UP_16 (mm_video_buf->height[1]); - mm_video_buf->is_secured = 0; - -#ifdef TIZEN_FEATURE_PRODUCT_TM1 - mm_video_buf->size[0] = mm_video_buf->stride_width[0] * mm_video_buf->stride_height[0]; - mm_video_buf->size[1] = mm_video_buf->stride_width[1] * mm_video_buf->stride_height[1]; - GST_INFO_OBJECT (src, "Size : %d %d", mm_video_buf->size[0], mm_video_buf->size[1]); - - mm_video_buf->data[0] = (tbm_bo_map(mm_video_buf->handle.bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE)).ptr; - tbm_bo_unmap (mm_video_buf->handle.bo[0]); -#endif - - out_buffer->gst_buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, - out_buffer, sizeof (out_buffer), 0, sizeof (out_buffer), (gpointer) out_buffer, - gst_wayland_src_gst_buffer_unref); - - gst_buffer_append_memory (out_buffer->gst_buffer, - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, - mm_video_buf, sizeof (*mm_video_buf), 0, sizeof (*mm_video_buf), - mm_video_buf, g_free)); - -#ifdef DUMP_BUFFER - static int dump_cnt = 0; - void *data, *data1; - FILE *fp; - - data = tbm_bo_map (out_buffer->bo[0], TBM_DEVICE_CPU, TBM_OPTION_READ).ptr; - if (!data) { - GST_ERROR_OBJECT (src, "get tbm bo handle failed: %s", strerror (errno)); - return; - } - data1 = tbm_bo_map (out_buffer->bo[1], TBM_DEVICE_CPU, TBM_OPTION_READ).ptr; - if (!data1) { - GST_ERROR_OBJECT (src, "get tbm bo handle failed: %s", strerror (errno)); - return; - } - - fp = fopen ("/root/raw.dump", "a"); - if (fp == NULL) - return; - - if (100 < dump_cnt && dump_cnt < 150) { - fwrite ((char *) data, tbm_bo_size(out_buffer->bo[0]), 1, fp); - fwrite ((char *) data1, tbm_bo_size(out_buffer->bo[1]), 1, fp); - GST_ERROR_OBJECT (src, "Dump :%d\n", out_buffer->size); - } - - dump_cnt++; - fclose (fp); -#endif + out_buffer->gst_buffer = gst_buffer_new (); + gst_buffer_append_memory (out_buffer->gst_buffer, memory); +#ifdef WAYLANDSRC_BUFFER_DUMP + save_waylandsrc_buffer (out_buffer); #endif } } else { @@ -677,34 +636,24 @@ tbm_buffer_create (GstWaylandSrc * src) break; case TBM_FORMAT_NV12: case TBM_FORMAT_NV21: - info.width = src->width; - info.height = src->height; - info.format = src->format; - info.bpp = tbm_surface_internal_get_bpp(info.format); - info.num_planes = 2; - info.planes[0].stride = info.width; - info.planes[0].size = gst_calculate_y_size(info.planes[0].stride, info.height);//info.planes[0].stride * info.height - info.planes[0].offset = 0; - info.planes[1].stride = info.width; - info.planes[1].size = gst_calculate_uv_size(info.planes[1].stride, info.height);//info.planes[1].stride * (info.height >> 1); - info.planes[1].offset = 0; - info.size = info.planes[0].size + info.planes[1].size; + + GST_WARNING_OBJECT (src, "BO image size : %d %d %d %d", src->ts_info.planes[0].size, src->ts_info.planes[1].size, src->ts_info.num_planes, src->ts_info.size); #ifdef TIZEN_FEATURE_PRODUCT_TM1 out_buffer->bo[0] = - tbm_bo_alloc (bufmgr, info.size, TBM_BO_DEFAULT); + tbm_bo_alloc (bufmgr, src->ts_info.planes[0].size + src->ts_info.planes[1].size, TBM_BO_DEFAULT); if (out_buffer->bo[0] == NULL) goto failed; bo_num = 1; #else out_buffer->bo[0] = - tbm_bo_alloc (bufmgr, info.planes[0].size, TBM_BO_DEFAULT); + tbm_bo_alloc (bufmgr, src->ts_info.planes[0].size, TBM_BO_DEFAULT); if (out_buffer->bo[0] == NULL) goto failed; out_buffer->bo[1] = - tbm_bo_alloc (bufmgr, info.planes[1].size, TBM_BO_DEFAULT); + tbm_bo_alloc (bufmgr, src->ts_info.planes[1].size, TBM_BO_DEFAULT); if (out_buffer->bo[1] == NULL) goto failed; @@ -712,7 +661,7 @@ tbm_buffer_create (GstWaylandSrc * src) #endif out_buffer->surface = - tbm_surface_internal_create_with_bos(&info, out_buffer->bo, bo_num); + tbm_surface_internal_create_with_bos(&src->ts_info, out_buffer->bo, bo_num); if (out_buffer->surface == NULL) goto failed; @@ -724,7 +673,7 @@ tbm_buffer_create (GstWaylandSrc * src) wl_proxy_set_queue ((struct wl_proxy *)out_buffer->wl_buffer, src->queue); - out_buffer->size = info.size; + out_buffer->size = src->ts_info.size; break; default: GST_WARNING_OBJECT (src, "unknown format"); @@ -885,6 +834,9 @@ gst_wayland_src_init (GstWaylandSrc * src) src->height = DEFAULT_HEIGHT; src->use_tbm = TRUE; + + src->allocator = gst_tizen_allocator_new(); + GST_WARNING_OBJECT (src, "Allocator: New ptr is %" GST_PTR_FORMAT, src->allocator); } static void @@ -941,6 +893,12 @@ gst_wayland_src_finalize (GObject * object) if (src->display) { gst_wayland_src_disconnect (src); } + + if (src->allocator) { + GST_WARNING_OBJECT (src, "Allocator: Unref"); + gst_object_unref(src->allocator); + src->allocator = NULL; + } } static gboolean @@ -1103,6 +1061,8 @@ gst_wayland_src_set_caps (GstBaseSrc * psrc, GstCaps * caps) gint height = 0; gboolean ret = TRUE; const gchar *media_type = NULL; + int tbm_ret = 0; + tbm_surface_h t_surface = NULL; GST_WARNING_OBJECT (src, "set_caps : %" GST_PTR_FORMAT, caps); if (!src->display) @@ -1161,11 +1121,36 @@ gst_wayland_src_set_caps (GstBaseSrc * psrc, GstCaps * caps) if (src->use_tbm && src->format == FOURCC_ARGB) src->format = TBM_FORMAT_ARGB8888; + /* get GstVideoInfo */ + if (!gst_video_info_from_caps(&src->video_info, caps)) { + GST_ERROR_OBJECT(src, "get video info failed (caps[%p,%"GST_PTR_FORMAT"])", caps, caps); + return FALSE; + } + + /* Create tbm_surface_info */ + t_surface = tbm_surface_create(src->width, src->height, TBM_FORMAT_NV12); + if (!t_surface) { + GST_ERROR_OBJECT(src, "tbm surface create failed"); + return FALSE; + } + + memset(&src->ts_info, 0x0, sizeof(tbm_surface_info_s)); + + tbm_ret = tbm_surface_get_info(t_surface, &src->ts_info); + tbm_surface_destroy(t_surface); + t_surface = NULL; + + if (tbm_ret != TBM_SURFACE_ERROR_NONE) { + GST_ERROR_OBJECT(src, "tbm surface info get failed"); + return FALSE; + } + GST_INFO_OBJECT (src, "format:%c%c%c%c, width: %d, height: %d", FOURCC_STR (src->format), src->width, src->height); GST_INFO_OBJECT (src, "FPS %d/%d", src->fps_n, src->fps_d); gst_wayland_src_thread_start (src); + GST_WARNING_OBJECT(src, "LEAVED - ret %d", ret); return TRUE; } @@ -1186,6 +1171,11 @@ gst_wayland_src_start (GstBaseSrc * basesrc) src->last_frame_no = -1; +#ifdef WAYLANDSRC_BUFFER_DUMP + dump_cnt = 0; + remove(WAYLANDSRC_DUMP_FILE); +#endif + return TRUE; } diff --git a/waylandsrc/src/gstwaylandsrc.h b/waylandsrc/src/gstwaylandsrc.h index 16dd1f4..260d7de 100644 --- a/waylandsrc/src/gstwaylandsrc.h +++ b/waylandsrc/src/gstwaylandsrc.h @@ -25,8 +25,15 @@ G_BEGIN_DECLS #include #include +#include +#include +#include + #include #include +#include +#include + #define GST_TYPE_WAYLAND_SRC \ (gst_wayland_src_get_type()) #define GST_WAYLAND_SRC(obj) \ @@ -119,6 +126,10 @@ struct _GstWaylandSrc guint height; guint32 format; struct wayland_tbm_client *tbm_client; + + GstAllocator *allocator; + GstVideoInfo video_info; + tbm_surface_info_s ts_info; }; struct _GstWaylandSrcClass -- 2.7.4 From af2608bd8753f6e8805f3469b2fdd5fa87831bf9 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Mon, 30 Apr 2018 17:12:20 +0900 Subject: [PATCH 10/16] tizenwlsink: Remove MMVideoBuffer and Make wl_buffer directly with tbm_surface from tizen-memory Change-Id: Iba2a08dbc37858377c7041ebd76f81c8814521b4 Signed-off-by: Hyunil --- tizenwlsink/src/Makefile.am | 4 +- tizenwlsink/src/gsttizenwlsink.c | 298 ++++----------------------------- tizenwlsink/src/gsttizenwlsink.h | 2 +- tizenwlsink/src/tizen-wlshmallocator.c | 238 +++++++++++++++----------- tizenwlsink/src/tizen-wlshmallocator.h | 2 + tizenwlsink/src/wlbuffer.c | 20 +-- tizenwlsink/src/wldisplay.h | 23 +-- 7 files changed, 185 insertions(+), 402 deletions(-) diff --git a/tizenwlsink/src/Makefile.am b/tizenwlsink/src/Makefile.am index a90af52..751437e 100644 --- a/tizenwlsink/src/Makefile.am +++ b/tizenwlsink/src/Makefile.am @@ -10,10 +10,10 @@ libgsttizenwlsink_la_SOURCES = \ wlvideoformat.c \ tizen-wlvideoformat.c -libgsttizenwlsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)$ $(GST_PLUGINS_BASE_CFLAGS) $(GST_VIDEO_CFLAGS) \ +libgsttizenwlsink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)$ $(GST_PLUGINS_BASE_CFLAGS) $(GST_VIDEO_CFLAGS) $(GST_ALLOCATORS_CFLAGS)\ $(WAYLAND_CFLAGS) $(DRM_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) libgsttizenwlsink_la_LIBADD = \ - $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_VIDEO_LIBS)\ + $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_VIDEO_LIBS) $(GST_ALLOCATORS_LIBS)\ $(WAYLAND_LIBS) $(DRM_LIBS) $(TBM_LIBS) $(MMCOMMON_LIBS) libgsttizenwlsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgsttizenwlsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 642303e..4940300 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -43,7 +43,6 @@ #include "gsttizenwlsink.h" #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT -#include #include "tizen-wlvideoformat.h" #endif #include "wlvideoformat.h" @@ -58,7 +57,7 @@ #include #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT -#define GST_APP_EVENT_FLUSH_BUFFER_NAME "application/flush-buffer" +#define GST_APP_EVENT_FLUSH_BUFFER_NAME "tizen/flush-buffer" #define GST_TYPE_TIZEN_WL_SINK_DISPLAY_GEOMETRY_METHOD (gst_tizen_wl_sink_display_geometry_method_get_type()) #define GST_TYPE_TIZEN_WL_SINK_ROTATE_ANGLE (gst_tizen_wl_sink_rotate_angle_get_type()) @@ -530,7 +529,7 @@ gst_tizen_wl_sink_init (GstTizenWlSink * sink) sink->signal_handoffs = FALSE; sink->request_camera_flush_buf = FALSE; sink->keep_camera_preview = FALSE; - sink->got_costum_event = FALSE; + sink->got_custum_event = FALSE; sink->USE_TBM = TRUE; sink->is_native_format = FALSE; sink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD; @@ -608,12 +607,13 @@ gst_tizen_wl_sink_stop_video (GstTizenWlSink * sink) } static int -gst_tizen_wl_sink_is_gapless (GstTizenWlSink * sink) +gst_tizen_wl_sink_flush_event_avaliable (GstTizenWlSink * sink) { g_return_val_if_fail (sink != NULL, FALSE); g_return_val_if_fail (sink->display != NULL, FALSE); - if (sink->got_costum_event && sink->USE_TBM + /* request flush buffer for camera, codec and gapless playback */ + if (sink->got_custum_event && sink->USE_TBM && sink->display->is_native_format) return TRUE; @@ -626,7 +626,7 @@ gst_tizen_wl_sink_need_flush_buffer (GstTizenWlSink * sink) g_return_val_if_fail (sink != NULL, FALSE); g_return_val_if_fail (sink->display != NULL, FALSE); - if ((gst_tizen_wl_sink_is_gapless (sink)) + if ((gst_tizen_wl_sink_flush_event_avaliable (sink)) || sink->request_camera_flush_buf || sink->display->flush_request == 1) { sink->display->flush_request = TRUE; return TRUE; @@ -684,233 +684,6 @@ gst_tizen_wl_sink_update_last_buffer_geometry (GstTizenWlSink * sink) } -#ifdef USE_WL_FLUSH_BUFFER -static int -gst_tizen_wl_sink_make_flush_buffer (GstWlDisplay * display, - MMVideoBuffer * mm_video_buf) -{ - GstWlFlushBuffer *flush_buffer = NULL; - tbm_bo bo = NULL; - int bo_size = 0; - int i; - FUNCTION; - - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (mm_video_buf != NULL, FALSE); - display->flush_tbm_bufmgr = - wayland_tbm_client_get_bufmgr (display->tbm_client); - g_return_val_if_fail (display->flush_tbm_bufmgr != NULL, FALSE); - - flush_buffer = (GstWlFlushBuffer *) malloc (sizeof (GstWlFlushBuffer)); - if (G_UNLIKELY (!flush_buffer)) { - GST_ERROR ("GstWlFlushBuffer alloc faile"); - return FALSE; - } - memset (flush_buffer, 0x0, sizeof (GstWlFlushBuffer)); - - for (i = 0; i < display->tbm_bo_num; i++) { - if (mm_video_buf->handle.bo[i] != NULL) { - tbm_bo_handle src; - tbm_bo_handle dst; - gchar err_str[256]; - - /* get bo size */ - bo_size = tbm_bo_size (mm_video_buf->handle.bo[i]); - GST_LOG ("tbm bo size: %d", bo_size); - /* alloc bo */ - bo = tbm_bo_alloc (display->flush_tbm_bufmgr, bo_size, TBM_DEVICE_CPU); - if (G_UNLIKELY (!bo)) { - strerror_r (errno, err_str, sizeof (err_str)); - GST_ERROR ("alloc tbm bo(size:%d) failed: %s(%d)", bo_size, err_str, - errno); - g_free (flush_buffer); - return FALSE; - } - GST_LOG ("flush buffer tbm_bo =(%p)", bo); - flush_buffer->bo[i] = bo; - /* get virtual address */ - src.ptr = dst.ptr = NULL; - /* bo map, we can use tbm_bo_map too. */ - src = - tbm_bo_map (mm_video_buf->handle.bo[i], TBM_DEVICE_CPU, - TBM_OPTION_READ); - dst = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_READ | TBM_OPTION_WRITE); - if (G_UNLIKELY ((!src.ptr || !dst.ptr))) { - strerror_r (errno, err_str, sizeof (err_str)); - GST_ERROR ("get tbm bo handle failed src(%p) dst(%p): %s(%d)", src.ptr, - dst.ptr, err_str, errno); - if (src.ptr) - tbm_bo_unmap (mm_video_buf->handle.bo[i]); - if (dst.ptr) - tbm_bo_unmap (bo); - g_free (flush_buffer); - return FALSE; - } - /* copy */ - memcpy (dst.ptr, src.ptr, bo_size); - /* bo unmap */ - tbm_bo_unmap (mm_video_buf->handle.bo[i]); - tbm_bo_unmap (bo); - } - } - display->flush_buffer = flush_buffer; - return TRUE; -} - -static int -gst_tizen_wl_sink_copy_mm_video_buf_info_to_flush_buffer (GstWlDisplay * - display, MMVideoBuffer * mm_video_buf) -{ - int ret = FALSE; - g_return_val_if_fail (display != NULL, FALSE); - g_return_val_if_fail (mm_video_buf != NULL, FALSE); - FUNCTION; - - display->plane_num = mm_video_buf->plane_num; - display->tbm_bo_num = mm_video_buf->handle_num; - ret = gst_tizen_wl_sink_make_flush_buffer (display, mm_video_buf); - if (ret) { - int i; - for (i = 0; i < display->plane_num; i++) { - if (display->flush_buffer->bo[i] != NULL) { - display->bo[i] = display->flush_buffer->bo[i]; - GST_LOG ("bo %p", display->bo[i]); - } else { - display->bo[i] = 0; - } - display->plane_size[i] = mm_video_buf->size[i]; - display->width[i] = mm_video_buf->width[i]; - display->height[i] = mm_video_buf->height[i]; - display->stride_width[i] = mm_video_buf->stride_width[i]; - display->stride_height[i] = mm_video_buf->stride_height[i]; - display->native_video_size += display->plane_size[i]; - GST_LOG ("TBM bo[%d]:%p", i, display->bo[i]); - GST_LOG ("width[%d]:%d, height[%d]:%d", i, display->width[i], i, - display->height[i]); - GST_LOG ("stride_width[%d]:%d, stride_height[%d]:%d", i, - display->stride_width[i], i, display->stride_height[i]); - GST_LOG ("plane size[%d]:%d", i, display->plane_size[i]); - } - memset (mm_video_buf, 0, sizeof (MMVideoBuffer)); - } - return ret; -} -#endif - -static void -gst_tizen_wl_sink_add_mm_video_buf_info (GstWlDisplay * display, - MMVideoBuffer * mm_video_buf) -{ - int i; - g_return_if_fail (display != NULL); - g_return_if_fail (mm_video_buf != NULL); - FUNCTION; - - display->plane_num = mm_video_buf->plane_num; - display->tbm_bo_num = mm_video_buf->handle_num; - for (i = 0; i < display->plane_num; i++) { - if (mm_video_buf->handle.bo[i] != NULL) { - display->bo[i] = mm_video_buf->handle.bo[i]; - } else { - display->bo[i] = 0; - } - display->plane_size[i] = mm_video_buf->size[i]; - display->width[i] = mm_video_buf->width[i]; - display->height[i] = mm_video_buf->height[i]; - display->stride_width[i] = mm_video_buf->stride_width[i]; - display->stride_height[i] = mm_video_buf->stride_height[i]; - display->native_video_size += display->plane_size[i]; - GST_LOG ("TBM bo[%d]:%p", i, display->bo[i]); - GST_LOG ("width[%d]:%d, height[%d]:%d", i, display->width[i], i, - display->height[i]); - GST_LOG ("stride_width[%d]:%d, stride_height[%d]:%d", i, - display->stride_width[i], i, display->stride_height[i]); - GST_LOG ("plane size[%d]:%d", i, display->plane_size[i]); - } -} - -static MMVideoBuffer * -gst_tizen_wl_sink_get_mm_video_buf (GstBuffer * buffer) -{ - GstMemory *mem; - GstMapInfo mem_info = GST_MAP_INFO_INIT; - MMVideoBuffer *mm_video_buf = NULL; - - g_return_val_if_fail (buffer != NULL, NULL); - FUNCTION; - - mem = gst_buffer_peek_memory (buffer, 1); - gst_memory_map (mem, &mem_info, GST_MAP_READ); - mm_video_buf = (MMVideoBuffer *) mem_info.data; - gst_memory_unmap (mem, &mem_info); - - if (mm_video_buf == NULL) { - GST_WARNING ("mm_video_buf of gstbuffer(@%p) is NULL.", buffer); - return NULL; - } - - if (mm_video_buf->type != MM_VIDEO_BUFFER_TYPE_TBM_BO) { - GST_ERROR ("Buffer type is not TBM"); - return NULL; - } - GST_DEBUG ("TBM bo: handle.bo[0]:%p, handle.bo[1]:%p, handle.bo[2]:%p", - mm_video_buf->handle.bo[0], mm_video_buf->handle.bo[1], - mm_video_buf->handle.bo[2]); - GST_DEBUG ("Number of TBM bo is %d", mm_video_buf->handle_num); - if (mm_video_buf->handle_num == 0) { - GST_ERROR ("Number of TBM bo is %d", mm_video_buf->handle_num); - return NULL; - } - GST_DEBUG ("Number of plane is %d", mm_video_buf->plane_num); - return mm_video_buf; -} - -static int -gst_tizen_wl_sink_get_mm_video_buf_info (GstTizenWlSink * sink, - GstBuffer * buffer) -{ - GstWlDisplay *display; - MMVideoBuffer *mm_video_buf = NULL; - - g_return_val_if_fail (sink != NULL, FALSE); - g_return_val_if_fail (buffer != NULL, FALSE); - - FUNCTION; - display = sink->display; - g_return_val_if_fail (sink->display != NULL, FALSE); - - /* get MMVideoBuffer from buffer */ - mm_video_buf = gst_tizen_wl_sink_get_mm_video_buf (buffer); - g_return_val_if_fail (mm_video_buf != NULL, FALSE); - - /* assign mm_video_buf info */ - display->native_video_size = 0; - display->flush_request = 0; - display->flush_request = mm_video_buf->flush_request; - GST_DEBUG ("flush_request value is %d", display->flush_request); -#ifdef USE_WL_FLUSH_BUFFER - if (gst_tizen_wl_sink_need_flush_buffer (sink)) { - /* Sometimes there isn't video data in MMVideoBuffer from buffer - when flush_request is true */ - if (mm_video_buf->flush_request && !mm_video_buf->size[0] - && sink->last_buffer) { - /* replace MMVideoBuffer from last buffer */ - mm_video_buf = gst_tizen_wl_sink_get_mm_video_buf (sink->last_buffer); - g_return_val_if_fail (mm_video_buf != NULL, FALSE); - } - if (!gst_tizen_wl_sink_copy_mm_video_buf_info_to_flush_buffer (display, - mm_video_buf)) { - GST_ERROR ("cat not copy mm_video_buf info to flush"); - return FALSE; - } - } else -#endif - /* normal routine */ - gst_tizen_wl_sink_add_mm_video_buf_info (display, mm_video_buf); - - return TRUE; -} - static void gst_tizen_wl_sink_render_flush_buffer (GstBaseSink * bsink) { @@ -1393,12 +1166,12 @@ gst_tizen_wl_sink_event (GstBaseSink * bsink, GstEvent * event) GST_LOG ("get GST_EVENT_CUSTOM_DOWNSTREAM EVENT: %s..state is %d", gst_structure_get_name (s), GST_STATE (sink)); - sink->got_costum_event = TRUE; - if (gst_tizen_wl_sink_is_gapless (sink)) { + sink->got_custum_event = TRUE; + if (gst_tizen_wl_sink_flush_event_avaliable (sink)) { gst_tizen_wl_sink_render_flush_buffer (bsink); - sink->got_costum_event = FALSE; + sink->got_custum_event = FALSE; } - sink->got_costum_event = FALSE; + sink->got_custum_event = FALSE; break; default: break; @@ -1558,9 +1331,7 @@ gst_tizen_wl_sink_change_state (GstElement * element, GstStateChange transition) if (sink->window) { if (!gst_wl_window_is_toplevel (sink->window)) { GstBaseSink *bsink = GST_BASE_SINK (element); - if (sink->USE_TBM && sink->display->is_native_format - && !sink->display->flush_buffer) { - /* To avoid duplicate request by App, check flush_buffer by flush_request of MMVideoBuffer */ + if (sink->USE_TBM && sink->display->is_native_format) { sink->request_camera_flush_buf = TRUE; gst_tizen_wl_sink_render_flush_buffer (bsink); sink->request_camera_flush_buf = FALSE; @@ -2015,7 +1786,7 @@ gst_tizen_wl_sink_has_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) gstwlbuffer = gst_buffer_get_wl_buffer (buffer); if (gstwlbuffer && gstwlbuffer->display == sink->display - && !gst_tizen_wl_sink_is_gapless (sink) + && !gst_tizen_wl_sink_flush_event_avaliable (sink) && !sink->request_camera_flush_buf) { /* gstbuffer has wlbuffer */ /* e.g) last_buffer, buffer is created by previous plugin or waylandsink with BufferPool */ @@ -2031,7 +1802,6 @@ static GstFlowReturn gst_tizen_wl_sink_no_create_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) { GstMemory *mem; - MMVideoBuffer *mm_video_buf = NULL; GstFlowReturn ret = GST_FLOW_OK; FUNCTION; g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR); @@ -2044,20 +1814,10 @@ gst_tizen_wl_sink_no_create_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer) GST_LOG ("buffer(%p) is created by waylandsink has a wl_buffer, " "writing directly", buffer); } else { - /* check mm_video_buf by log */ GST_LOG ("buffer(%p) is created by previous plugins with BufferPool has a wl_buffer, " "writing directly", buffer); GST_LOG ("previous plugins must manage buffer index well"); - /* check MMVideoBuffer */ - mm_video_buf = gst_tizen_wl_sink_get_mm_video_buf (buffer); - if (mm_video_buf != NULL) { - GST_LOG ("GstBuffer(%p) has MMVideoBuffer(%p)", buffer, mm_video_buf); - } else { - GST_ERROR ("GstBuffer(%p) has not MMVideoBuffer(%p)", buffer, - mm_video_buf); - return GST_FLOW_ERROR; - } } sink->to_render = buffer; @@ -2090,6 +1850,7 @@ gst_tizen_wl_sink_create_wlbuffer_with_wl_mem (GstTizenWlSink * sink, } } +/* in case of native format (SN12, ST12, SN21, SR32 and S420) */ static GstFlowReturn gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink * sink, GstBuffer * buffer) @@ -2107,15 +1868,25 @@ gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink * ("buffer(%p) is created by previous plugin with no BufferPool does not have a wl_buffer", buffer); GST_LOG ("Use native format with previous plugins TBM"); - /* in case of native format (SN12, ST12, SN21, SR32 and S420) */ - if (!gst_tizen_wl_sink_get_mm_video_buf_info (sink, buffer)) { - return GST_FLOW_ERROR; + + mem = gst_buffer_peek_memory (buffer, 0); + + if (gst_tizen_wl_sink_need_flush_buffer (sink)) { + /* create flush buffer */ + wbuf = gst_tizen_wl_construct_flush_wl_buffer (mem, sink->display); + if (G_UNLIKELY (!wbuf)) { + GST_ERROR ("could not create wl_buffer"); + return GST_FLOW_ERROR; + } + sink->flush_gstbuf = gst_buffer_new (); + GST_LOG ("To flush, create gstBuffer(%p) for flush", sink->flush_gstbuf); + gst_buffer_add_wl_buffer (sink->flush_gstbuf, wbuf, sink->display); + + return ret; } wlbuffer = gst_buffer_get_wl_buffer (buffer); - /* last_buffer from gaplasee have wlbuffer */ - if (G_UNLIKELY (!wlbuffer) || sink->display->flush_request) { - mem = gst_buffer_peek_memory (buffer, 0); + if (G_UNLIKELY (!wlbuffer)) { wbuf = gst_tizen_wl_shm_memory_construct_wl_buffer (mem, sink->display, &sink->video_info); @@ -2123,14 +1894,9 @@ gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink * GST_ERROR ("could not create wl_buffer"); return GST_FLOW_ERROR; } - if (sink->display->flush_request) { - sink->flush_gstbuf = gst_buffer_new (); - GST_LOG ("To flush, new gstBuffer(%p)", sink->flush_gstbuf); - gst_buffer_add_wl_buffer (sink->flush_gstbuf, wbuf, sink->display); - } else { - gst_buffer_add_wl_buffer (buffer, wbuf, sink->display); - } + gst_buffer_add_wl_buffer (buffer, wbuf, sink->display); } + return ret; } @@ -2349,7 +2115,7 @@ gst_tizen_wl_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) } /* drop buffers until we get a frame callback */ - if (sink->redraw_pending && !gst_tizen_wl_sink_is_gapless (sink)) + if (sink->redraw_pending && !gst_tizen_wl_sink_flush_event_avaliable (sink)) goto done; /* create wl_buffer */ diff --git a/tizenwlsink/src/gsttizenwlsink.h b/tizenwlsink/src/gsttizenwlsink.h index a4f9711..adc6e7b 100644 --- a/tizenwlsink/src/gsttizenwlsink.h +++ b/tizenwlsink/src/gsttizenwlsink.h @@ -91,7 +91,7 @@ struct _GstTizenWlSink gboolean signal_handoffs; gboolean request_camera_flush_buf; gboolean keep_camera_preview; - gboolean got_costum_event; + gboolean got_custum_event; gboolean visible; gboolean follow_parent_transform; gboolean USE_TBM; diff --git a/tizenwlsink/src/tizen-wlshmallocator.c b/tizenwlsink/src/tizen-wlshmallocator.c index de5e516..84b9ef2 100644 --- a/tizenwlsink/src/tizen-wlshmallocator.c +++ b/tizenwlsink/src/tizen-wlshmallocator.c @@ -40,6 +40,8 @@ GST_DEBUG_CATEGORY_EXTERN (gst_tizen_wl_debug); G_DEFINE_TYPE (GstTizenWlShmAllocator, gst_tizen_wl_shm_allocator, GST_TYPE_ALLOCATOR); +typedef struct _tbm_surface *tbm_surface_h; + gint gst_tizen_wl_fwrite_data (gchar * file, gpointer data, guint size) { @@ -82,64 +84,69 @@ gst_tizen_wl_tbm_dump_normal_raw_video (gpointer bo, guint size, } static void -gst_tizen_wl_tbm_dump_native_raw_video (GstWlDisplay * display, +gst_tizen_wl_tbm_dump_native_raw_video (GstMemory * mem, GstWlDisplay * display, guint dump_count) { gchar file_name[128]; gchar err_str[256]; FILE *fp; + tbm_surface_h src_tsurface; tbm_bo_handle virtual_addr; + int bo_size = 0; + int bo_num = 0; + tbm_bo src_bo = NULL; gchar *data; int i; + g_return_if_fail (display != NULL); + g_return_if_fail (mem != NULL); + /* check dump count */ if (dump_count > display->total_dump) { display->dump_video = FALSE; return; } - /* get virtual addr with bo and TBM_DEVICD_CPU */ - virtual_addr = tbm_bo_get_handle (display->bo[0], TBM_DEVICE_CPU); - if (!virtual_addr.ptr) { - strerror_r (errno, err_str, sizeof (err_str)); - GST_ERROR ("get tbm bo handle failed: %s(%d)", err_str, errno); - return; - } + /*get current surface */ + src_tsurface = (tbm_surface_h) gst_tizen_memory_get_surface (mem); + GST_LOG ("get tbm surface(%p)", src_tsurface); + + /* get number of bo */ + bo_num = tbm_surface_internal_get_num_bos (src_tsurface); + GST_LOG ("bo_num(%d)", bo_num); + + + /* set file name */ snprintf (file_name, sizeof (file_name), "/tmp/WLSINK_OUT_DUMP_%2.2d.dump", dump_count); fp = fopen (file_name, "wb"); if (fp == NULL) return; - data = (gchar *) virtual_addr.ptr; - /* Y */ - for (i = 0; i < display->height[0]; i++) { - fwrite (data, display->width[0], 1, fp); - data += display->stride_width[0]; - } + for (i = 0; i < bo_num; i++) { + /* get bo */ + src_bo = tbm_surface_internal_get_bo (src_tsurface, i); + + /* get bo size */ + bo_size = tbm_bo_size (src_bo); + GST_LOG ("tbm bo size: %d", bo_size); - if (display->bo[1] == NULL) { - /* sprd */ - data = (gchar *) virtual_addr.ptr + - (display->stride_width[0] * display->stride_height[0]); - GST_LOG ("UV: virtual_addr.ptr(%p)", data); - } else { - /* omx */ - virtual_addr = tbm_bo_get_handle (display->bo[1], TBM_DEVICE_CPU); + /* get virtual addr with bo and TBM_DEVICE_CPU */ + virtual_addr = tbm_bo_get_handle (src_bo, TBM_DEVICE_CPU); if (!virtual_addr.ptr) { strerror_r (errno, err_str, sizeof (err_str)); GST_ERROR ("get tbm bo handle failed: %s(%d)", err_str, errno); fclose (fp); return; } + data = (gchar *) virtual_addr.ptr; - } - /* UV */ - for (i = 0; i < display->height[1]; i++) { - fwrite (data, display->width[1], 1, fp); - data += display->stride_width[1]; + fwrite (data, bo_size, 1, fp); + + data += bo_size; + } fclose (fp); @@ -356,6 +363,99 @@ gst_is_tizen_wl_memory (GstMemory * mem) } struct wl_buffer * +gst_tizen_wl_construct_flush_wl_buffer (GstMemory * mem, GstWlDisplay * display) +{ + struct wl_buffer *wbuffer; + tbm_surface_info_s ts_info; + tbm_surface_h src_tsurface; + tbm_bo src_bo = NULL, dst_bo = NULL; + int bo_size = 0; + int bo_num = 0; + int i; + tbm_bo_handle src; + tbm_bo_handle dst; + gchar err_str[256]; + FUNCTION; + + g_return_val_if_fail (mem != NULL, NULL); + + /*get current surface */ + src_tsurface = (tbm_surface_h) gst_tizen_memory_get_surface (mem); + GST_LOG ("get tbm surface(%p)", src_tsurface); + + /* get number of bo */ + bo_num = tbm_surface_internal_get_num_bos (src_tsurface); + GST_LOG ("bo_num(%d)", bo_num); + + /* get surface info */ + tbm_surface_get_info (src_tsurface, &ts_info); + GST_LOG + ("set tbm_surface_info_s: width(%d) height(%d) format(%s) bpp(%d) num_planes(%d)", + ts_info.width, ts_info.height, + gst_wl_tbm_format_to_string (ts_info.format), ts_info.bpp, + ts_info.num_planes); + GST_LOG + ("set tbm_surface_info_s: planse[0].stride(%d) planes[1].stride(%d) planes[2].stride(%d) planes[0].offset(%d) planes[1].offset(%d) planes[2].offset(%d)", + ts_info.planes[0].stride, ts_info.planes[1].stride, + ts_info.planes[2].stride, ts_info.planes[0].offset, + ts_info.planes[1].offset, ts_info.planes[2].offset); + + /* create new surface for flushing */ + display->flush_tsurface = + tbm_surface_create (ts_info.width, ts_info.height, ts_info.format); + + /* copy video frame */ + for (i = 0; i < bo_num; i++) { + /* get bo */ + src_bo = tbm_surface_internal_get_bo (src_tsurface, i); + dst_bo = tbm_surface_internal_get_bo (display->flush_tsurface, i); + GST_LOG ("src_bo(%p) dst_bo(%p)", src_bo, dst_bo); + if (!src_bo || !dst_bo) { + strerror_r (errno, err_str, sizeof (err_str)); + GST_ERROR ("get tbm bo failed src(%p) dst(%p): %s(%d)", src_bo, dst_bo, + err_str, errno); + } + + /* get bo size */ + bo_size = tbm_bo_size (src_bo); + GST_LOG ("tbm bo size: %d", bo_size); + + /* bo map, we can use tbm_bo_map too. */ + src.ptr = dst.ptr = NULL; + src = tbm_bo_map (src_bo, TBM_DEVICE_CPU, TBM_OPTION_READ); + dst = + tbm_bo_map (dst_bo, TBM_DEVICE_CPU, TBM_OPTION_READ | TBM_OPTION_WRITE); + if (G_UNLIKELY ((!src.ptr || !dst.ptr))) { + strerror_r (errno, err_str, sizeof (err_str)); + GST_ERROR ("get tbm bo handle failed src(%p) dst(%p): %s(%d)", src.ptr, + dst.ptr, err_str, errno); + if (src.ptr) + tbm_bo_unmap (src_bo); + if (dst.ptr) + tbm_bo_unmap (dst_bo); + return NULL; + } + + /* copy */ + memcpy (dst.ptr, src.ptr, bo_size); + + /* bo unmap */ + tbm_bo_unmap (src_bo); + tbm_bo_unmap (dst_bo); + } + + wbuffer = + wayland_tbm_client_create_buffer (display->tbm_client, + display->flush_tsurface); + GST_LOG ("create wbuffer(%p)", wbuffer); + + display->buffer_width = ts_info.width; + display->buffer_height = ts_info.height; + + return wbuffer; +} + +struct wl_buffer * gst_tizen_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info) { @@ -368,64 +468,36 @@ gst_tizen_wl_shm_memory_construct_wl_buffer (GstMemory * mem, struct wl_buffer *wbuffer; FUNCTION; -#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT if (display->USE_TBM) { tbm_surface_info_s ts_info; - int offset[GST_VIDEO_MAX_PLANES]; + tbm_surface_h tsurface; if (display->is_native_format == TRUE) { - /* In case of native format, use MMVideoBuffer data instead of GstVideoInfo */ - if (display->dump_video) - gst_tizen_wl_tbm_dump_native_raw_video (display, display->dump_count++); - - width = display->width[0]; - height = display->height[0]; - format = gst_video_format_to_wl_tbm_format (GST_VIDEO_INFO_FORMAT (info)); - ts_info.width = width; - ts_info.height = height; - ts_info.format = format; - ts_info.bpp = tbm_surface_internal_get_bpp (ts_info.format); - ts_info.num_planes = tbm_surface_internal_get_num_planes (ts_info.format); + tsurface = (tbm_surface_h) gst_tizen_memory_get_surface (mem); + GST_LOG ("get tbm surface(%p)", tsurface); - for (i = 0; i < display->plane_num; i++) { - ts_info.planes[i].size = display->plane_size[i]; - ts_info.planes[i].stride = display->stride_width[i]; - offset[i] = display->stride_width[i] * display->stride_height[i]; - } + tbm_surface_get_info (tsurface, &ts_info); - if (display->tbm_bo_num == 1) { - ts_info.planes[0].offset = 0; - ts_info.planes[1].offset = offset[0]; - if (display->plane_num == 3) - ts_info.planes[2].offset = offset[0] + offset[1]; - } else if (display->tbm_bo_num == 2) { - ts_info.planes[0].offset = 0; - ts_info.planes[1].offset = 0; - if (display->plane_num == 3) - ts_info.planes[2].offset = offset[1]; - } else if (display->tbm_bo_num == 3) { - ts_info.planes[0].offset = 0; - ts_info.planes[1].offset = 0; - ts_info.planes[2].offset = 0; - } + if (display->dump_video) + gst_tizen_wl_tbm_dump_native_raw_video (mem, display, + display->dump_count++); GST_LOG - ("set tbm_surface_info_s: width(%d) height(%d) format(%s) bpp(%d) num_planes(%d)", - ts_info.width, ts_info.height, gst_wl_tbm_format_to_string (format), - ts_info.bpp, ts_info.num_planes); + ("tbm_surface_info_s: width(%d) height(%d) format(%s) bpp(%d) num_planes(%d)", + ts_info.width, ts_info.height, + gst_wl_tbm_format_to_string (ts_info.format), ts_info.bpp, + ts_info.num_planes); GST_LOG - ("set tbm_surface_info_s: planse[0].stride(%d) planes[1].stride(%d) planes[2].stride(%d) planes[0].offset(%d) planes[1].offset(%d) planes[2].offset(%d)", + ("tbm_surface_info_s: planse[0].stride(%d) planes[1].stride(%d) planes[2].stride(%d) planes[0].offset(%d) planes[1].offset(%d) planes[2].offset(%d)", ts_info.planes[0].stride, ts_info.planes[1].stride, ts_info.planes[2].stride, ts_info.planes[0].offset, ts_info.planes[1].offset, ts_info.planes[2].offset); - display->tsurface = - tbm_surface_internal_create_with_bos (&ts_info, - (tbm_bo *) display->bo, display->tbm_bo_num); - GST_LOG ("create tbm surface(%p)", display->tsurface); wbuffer = - wayland_tbm_client_create_buffer (display->tbm_client, - display->tsurface); + wayland_tbm_client_create_buffer (display->tbm_client, tsurface); + width = ts_info.width; + height = ts_info.height; + } else { width = GST_VIDEO_INFO_WIDTH (info); @@ -521,30 +593,6 @@ gst_tizen_wl_shm_memory_construct_wl_buffer (GstMemory * mem, display->buffer_height = height; GST_LOG ("buffer_width(%d) buffer_height(%d)", display->buffer_width, display->buffer_height); - return wbuffer; - -#else /* open source */ - width = GST_VIDEO_INFO_WIDTH (info); - height = GST_VIDEO_INFO_HEIGHT (info); - stride = GST_VIDEO_INFO_PLANE_STRIDE (info, 0); - size = GST_VIDEO_INFO_SIZE (info); - format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (info)); - g_return_val_if_fail (gst_is_wl_shm_memory (mem), NULL); - g_return_val_if_fail (size <= mem->size, NULL); - g_return_val_if_fail (shm_mem->fd != -1, NULL); - - GST_DEBUG_OBJECT (mem->allocator, "Creating wl_buffer of size %" - G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height, - stride, gst_wl_shm_format_to_string (format)); - - wl_pool = wl_shm_create_pool (display->shm, shm_mem->fd, mem->size); - wbuffer = wl_shm_pool_create_buffer (wl_pool, 0, width, height, stride, - format); - - close (shm_mem->fd); - shm_mem->fd = -1; - wl_shm_pool_destroy (wl_pool); return wbuffer; -#endif } diff --git a/tizenwlsink/src/tizen-wlshmallocator.h b/tizenwlsink/src/tizen-wlshmallocator.h index 3acbcc8..e7fb637 100644 --- a/tizenwlsink/src/tizen-wlshmallocator.h +++ b/tizenwlsink/src/tizen-wlshmallocator.h @@ -71,6 +71,8 @@ GstAllocator *gst_tizen_wl_shm_allocator_get (void); gboolean gst_is_tizen_wl_shm_memory (GstMemory * mem); struct wl_buffer *gst_tizen_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info); +struct wl_buffer *gst_tizen_wl_construct_flush_wl_buffer (GstMemory * mem, + GstWlDisplay * display); #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT gint gst_tizen_wl_fwrite_data (gchar * file, gpointer data, guint size); diff --git a/tizenwlsink/src/wlbuffer.c b/tizenwlsink/src/wlbuffer.c index af4de87..393784b 100644 --- a/tizenwlsink/src/wlbuffer.c +++ b/tizenwlsink/src/wlbuffer.c @@ -107,8 +107,6 @@ static void gst_wl_buffer_finalize (GObject * gobject) { GstWlBuffer *self = GST_WL_BUFFER (gobject); - int i; - FUNCTION; GST_TRACE_OBJECT (self, "finalize"); @@ -124,20 +122,10 @@ gst_wl_buffer_finalize (GObject * gobject) } #ifdef USE_WL_FLUSH_BUFFER if (self->display) { - if (self->is_flush_request) { - self->display->flush_tbm_bufmgr = NULL; - if (self->display->flush_buffer) { - for (i = 0; i < self->display->tbm_bo_num; i++) { - if (self->display->flush_buffer->bo[i]) { - GST_LOG ("flush buffer: tbm_bo_unref (bo@%p)", - self->display->flush_buffer->bo[i]); - tbm_bo_unref (self->display->flush_buffer->bo[i]); - self->display->flush_buffer->bo[i] = NULL; - } - } - g_free (self->display->flush_buffer); - self->display->flush_buffer = NULL; - } + if (self->display->flush_tsurface) { + GST_LOG ("tbm_surface_destroy (flush_tsurface_h@%p)", + self->display->flush_tsurface); + tbm_surface_destroy (self->display->flush_tsurface); } } #endif diff --git a/tizenwlsink/src/wldisplay.h b/tizenwlsink/src/wldisplay.h index dd7e7d4..79a5127 100644 --- a/tizenwlsink/src/wldisplay.h +++ b/tizenwlsink/src/wldisplay.h @@ -43,13 +43,6 @@ G_BEGIN_DECLS #define GST_WL_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_DISPLAY, GstWlDisplayClass)) #define FUNCTION GST_LOG ("") -#ifdef USE_WL_FLUSH_BUFFER -typedef struct -{ - void *bo[GST_VIDEO_MAX_PLANES]; -} GstWlFlushBuffer; -#endif - #define TBM_BO_NUM 20 struct _GstWlDisplay @@ -90,29 +83,15 @@ struct _GstWlDisplay tbm_bo tbm_bo[TBM_BO_NUM]; gint tbm_bo_idx; tbm_surface_h tsurface; + tbm_surface_h flush_tsurface; gboolean USE_TBM; - -#ifdef USE_WL_FLUSH_BUFFER - GstWlFlushBuffer *flush_buffer; - tbm_bufmgr flush_tbm_bufmgr; gint flush_request; -#endif gboolean dump_video; guint total_dump; guint dump_count; - gboolean is_native_format; /*SN12, ST12, SR32, S420 */ - gpointer bo[GST_VIDEO_MAX_PLANES]; - gint plane_size[GST_VIDEO_MAX_PLANES]; - gint stride_width[GST_VIDEO_MAX_PLANES]; - gint stride_height[GST_VIDEO_MAX_PLANES]; - gint width[GST_VIDEO_MAX_PLANES]; - gint height[GST_VIDEO_MAX_PLANES]; - gint native_video_size; guint wl_surface_id; gint buffer_width, buffer_height; - gint plane_num; - gint tbm_bo_num; #endif #if 1 -- 2.7.4 From 2ffadcad97617dc5a8e2305d2edadfa110529ab0 Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 5 Sep 2018 10:53:47 +0900 Subject: [PATCH 11/16] tizenwlsink: fix bug about setting flush_request Change-Id: I52eb3634796166d34923f2c8c7ab081e53d86914 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 17 +++++++++-------- tizenwlsink/src/gsttizenwlsink.h | 1 - tizenwlsink/src/wldisplay.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 4940300..5ba456e 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -606,7 +606,7 @@ gst_tizen_wl_sink_stop_video (GstTizenWlSink * sink) gst_wl_window_render (sink->window, NULL, NULL); } -static int +static gboolean gst_tizen_wl_sink_flush_event_avaliable (GstTizenWlSink * sink) { g_return_val_if_fail (sink != NULL, FALSE); @@ -620,17 +620,15 @@ gst_tizen_wl_sink_flush_event_avaliable (GstTizenWlSink * sink) return FALSE; } -static int +static gboolean gst_tizen_wl_sink_need_flush_buffer (GstTizenWlSink * sink) { g_return_val_if_fail (sink != NULL, FALSE); - g_return_val_if_fail (sink->display != NULL, FALSE); - if ((gst_tizen_wl_sink_flush_event_avaliable (sink)) - || sink->request_camera_flush_buf || sink->display->flush_request == 1) { - sink->display->flush_request = TRUE; + if (gst_tizen_wl_sink_flush_event_avaliable (sink) + || sink->request_camera_flush_buf) return TRUE; - } + return FALSE; } @@ -1861,6 +1859,7 @@ gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink * GstFlowReturn ret = GST_FLOW_OK; FUNCTION; g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (sink->display != NULL, GST_FLOW_ERROR); g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR); sink->flush_gstbuf = NULL; @@ -1871,7 +1870,9 @@ gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink * mem = gst_buffer_peek_memory (buffer, 0); - if (gst_tizen_wl_sink_need_flush_buffer (sink)) { + sink->display->flush_request = gst_tizen_wl_sink_need_flush_buffer (sink); + + if (sink->display->flush_request) { /* create flush buffer */ wbuf = gst_tizen_wl_construct_flush_wl_buffer (mem, sink->display); if (G_UNLIKELY (!wbuf)) { diff --git a/tizenwlsink/src/gsttizenwlsink.h b/tizenwlsink/src/gsttizenwlsink.h index adc6e7b..4761a9c 100644 --- a/tizenwlsink/src/gsttizenwlsink.h +++ b/tizenwlsink/src/gsttizenwlsink.h @@ -96,7 +96,6 @@ struct _GstTizenWlSink gboolean follow_parent_transform; gboolean USE_TBM; gboolean is_native_format; - gboolean flush_request; gboolean disable_overlay; guint total_dump; guint rotate_angle; diff --git a/tizenwlsink/src/wldisplay.h b/tizenwlsink/src/wldisplay.h index 79a5127..e6ea1e3 100644 --- a/tizenwlsink/src/wldisplay.h +++ b/tizenwlsink/src/wldisplay.h @@ -85,7 +85,7 @@ struct _GstWlDisplay tbm_surface_h tsurface; tbm_surface_h flush_tsurface; gboolean USE_TBM; - gint flush_request; + gboolean flush_request; gboolean dump_video; guint total_dump; guint dump_count; -- 2.7.4 From fe1a1c49a624684f46a8b55e3ffe472f99443b6f Mon Sep 17 00:00:00 2001 From: Hyunil Date: Wed, 12 Sep 2018 18:29:41 +0900 Subject: [PATCH 12/16] tizenwlsink: Exclude gst_query_add_allocation_meta() if use_tbm is set Change-Id: I3de400328f522126b44acd506a57e17eb43ab621 Signed-off-by: Hyunil --- tizenwlsink/src/gsttizenwlsink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index 5ba456e..2ffda56 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -1657,7 +1657,10 @@ gst_tizen_wl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) gst_query_add_allocation_pool (query, sink->pool, size, min_bufs, max_bufs); gst_query_add_allocation_param (query, gst_tizen_wl_shm_allocator_get (), NULL); - gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT + if (!sink->USE_TBM) +#endif + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); gst_structure_free (config); GST_WARNING ("set propose allocation"); -- 2.7.4 From 4bd1dce52e43159e89df32bee5f887cd55d6f03e Mon Sep 17 00:00:00 2001 From: Hyunil Date: Fri, 14 Sep 2018 18:37:35 +0900 Subject: [PATCH 13/16] tizenwlsink: fix typo Change-Id: I230e0a995ffd7aaa0c21cf53619d617f5bd090ac Signed-off-by: Hyunil --- tizenwlsink/src/wlwindow.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tizenwlsink/src/wlwindow.c b/tizenwlsink/src/wlwindow.c index 7fae499..9fa56c9 100644 --- a/tizenwlsink/src/wlwindow.c +++ b/tizenwlsink/src/wlwindow.c @@ -584,7 +584,7 @@ gst_wl_window_find_flip_transform (guint flip) } #endif -#if TIZEN_FEATURE_WLSINK_ENHANCEMENT +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT static void gst_wl_window_resize_tizen_video_viewport (GstWlWindow * window, gboolean commit) @@ -840,7 +840,7 @@ void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info) { -#if TIZEN_FEATURE_WLSINK_ENHANCEMENT +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT FUNCTION; /* check video buffer size for wl_surface_damage_buffer */ if (window->buffer_width != window->display->buffer_width @@ -899,7 +899,7 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, #endif } -#if TIZEN_FEATURE_WLSINK_ENHANCEMENT +#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT gboolean gst_wl_window_set_roi_area (GstWlWindow * window, gint x, gint y, gint w, gint h) -- 2.7.4 From 99c78b5e33c7ee8dd69d53113752cc1cf7f12a25 Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Mon, 1 Oct 2018 16:32:01 +0900 Subject: [PATCH 14/16] pdpushsrc: fix svace issue Change-Id: I13c966cc1dcfaa01fd8e8dce06bf6d8fbacc5f00 --- pdpushsrc/src/gstpdpushsrc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pdpushsrc/src/gstpdpushsrc.c b/pdpushsrc/src/gstpdpushsrc.c index 266ca18..54f4bf2 100644 --- a/pdpushsrc/src/gstpdpushsrc.c +++ b/pdpushsrc/src/gstpdpushsrc.c @@ -629,7 +629,9 @@ gst_pd_pushsrc_start (GstBaseSrc * basesrc) } else { src->seekable = TRUE; } - lseek (src->fd, 0, SEEK_SET); + + if (lseek (src->fd, 0, SEEK_SET) < 0) + goto seek_failed; } /* We can only really do seeking on regular files - for other file types, we @@ -681,12 +683,19 @@ was_directory: } was_socket: { - GST_ERROR_OBJECT (src, "Is a Socket"); + GST_ERROR_OBJECT (src, "Is a Socket"); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"\" is a socket."), (NULL)); close (src->fd); return FALSE; } +seek_failed: + { + GST_ERROR_OBJECT (src, "Seek failed..."); + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); + close (src->fd); + return FALSE; + } } /* unmap and close the file */ -- 2.7.4 From 6edbfaee9e26379d4c87adb29457325d88e31450 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Tue, 11 Sep 2018 19:55:24 +0900 Subject: [PATCH 15/16] [tizenipc] Change zero copy buffer handling [Version] 1.0.0-60 [Profile] Common [Issue Type] Update [Dependency module] N/A Change-Id: Ia58644a4d9ca0b34157a93841e1b90e4b98fd263 Signed-off-by: Jeongmo Yang --- Makefile.am | 0 configure.ac | 6 - packaging/gst-plugins-tizen.spec | 3 +- tizenipc/src/Makefile.am | 8 +- tizenipc/src/gsttizenipc.h | 62 +++++ tizenipc/src/gsttizenipcsink.c | 497 ++++++++++++++++++++++----------------- tizenipc/src/gsttizenipcsink.h | 41 +--- tizenipc/src/gsttizenipcsrc.c | 491 ++++++++++++++++++++++---------------- tizenipc/src/gsttizenipcsrc.h | 43 +--- 9 files changed, 659 insertions(+), 492 deletions(-) mode change 100755 => 100644 Makefile.am create mode 100644 tizenipc/src/gsttizenipc.h diff --git a/Makefile.am b/Makefile.am old mode 100755 new mode 100644 diff --git a/configure.ac b/configure.ac index fee158f..021fc8f 100644 --- a/configure.ac +++ b/configure.ac @@ -156,8 +156,6 @@ AC_SUBST(GST_VIDEO_CFLAGS) AC_SUBST(GST_VIDEO_LIBS) PKG_CHECK_MODULES(GST_ALLOCATORS, gstreamer-allocators-$GST_MAJORMINOR >= $GST_REQUIRED) - -dnl make _CFLAGS and _LIBS available AC_SUBST(GST_ALLOCATORS_CFLAGS) AC_SUBST(GST_ALLOCATORS_LIBS) @@ -177,10 +175,6 @@ PKG_CHECK_MODULES(MMCOMMON,mm-common) AC_SUBST(MMCOMMON_CFLAGS) AC_SUBST(MMCOMMON_LIBS) -PKG_CHECK_MODULES([GST_ALLOCATORS], [gstreamer-allocators-1.0]) -AC_SUBST(GST_ALLOCATORS_CFLAGS) -AC_SUBST(GST_ALLOCATORS_LIBS) - dnl belows are related to wfdtsdemux AG_GST_ARG_WITH_PACKAGE_NAME AG_GST_ARG_WITH_PACKAGE_ORIGIN diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index cbe1603..8349f9f 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -9,7 +9,7 @@ Name: gst-plugins-tizen Version: 1.0.0 Summary: GStreamer tizen plugins (common) -Release: 59 +Release: 60 Group: Multimedia/Framework Url: http://gstreamer.freedesktop.org/ License: LGPL-2.1+ @@ -18,6 +18,7 @@ Source0: %{name}-%{version}.tar.gz BuildRequires: pkgconfig(gstreamer-audio-1.0) BuildRequires: pkgconfig(gstreamer-video-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) +BuildRequires: pkgconfig(gstreamer-allocators-1.0) BuildRequires: pkgconfig(gstreamer-1.0) BuildRequires: pkgconfig(libexif) %if %{with x} diff --git a/tizenipc/src/Makefile.am b/tizenipc/src/Makefile.am index c0bbd25..bc88145 100644 --- a/tizenipc/src/Makefile.am +++ b/tizenipc/src/Makefile.am @@ -18,8 +18,8 @@ libgsttizenipcsink_la_SOURCES = gsttizenipcsink.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed -libgsttizenipcsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) -libgsttizenipcsink_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(TBM_LIBS) +libgsttizenipcsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_ALLOCATORS_CFLAGS) $(TBM_CFLAGS) +libgsttizenipcsink_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_ALLOCATORS_LIBS) $(TBM_LIBS) libgsttizenipcsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # sources used to compile this plug-in @@ -27,8 +27,8 @@ libgsttizenipcsrc_la_SOURCES = gsttizenipcsrc.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed -libgsttizenipcsrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) -libgsttizenipcsrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(TBM_LIBS) +libgsttizenipcsrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_ALLOCATORS_CFLAGS) $(TBM_CFLAGS) +libgsttizenipcsrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_ALLOCATORS_LIBS) $(TBM_LIBS) libgsttizenipcsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # headers we need but don't want installed diff --git a/tizenipc/src/gsttizenipc.h b/tizenipc/src/gsttizenipc.h new file mode 100644 index 0000000..1e56a18 --- /dev/null +++ b/tizenipc/src/gsttizenipc.h @@ -0,0 +1,62 @@ +/* + * GStreamer Tizen IPC + * + * Copyright (C) 2018 Jeongmo Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __GST_TIZEN_IPC_H__ +#define __GST_TIZEN_IPC_H__ + +#include + +G_BEGIN_DECLS + +#define IPC_BUFFER_MAX 30 +#define INIT_FD (-1) + +typedef struct _GstTizenipcMessage GstTizenipcMessage; + +typedef enum { + TIZEN_IPC_SHM_PATH = 0, + TIZEN_IPC_SHM_SIZE, + TIZEN_IPC_BUFFER_TYPE, + TIZEN_IPC_BUFFER_CAPS, + TIZEN_IPC_BUFFER_NEW, + TIZEN_IPC_BUFFER_RECEIVED, + TIZEN_IPC_BUFFER_RELEASE, + TIZEN_IPC_CLOSE_CLIENT +} TizenIPCID; + +typedef enum { + BUFFER_TYPE_NORMAL = 0, + BUFFER_TYPE_ZERO_COPY +} BufferType; + +struct _GstTizenipcMessage { + TizenIPCID id; + union { + BufferType type; + int size; + int tbm_key[TBM_SURF_PLANE_MAX]; + }; +}; + +G_END_DECLS + +#endif /* __GST_TIZEN_IPC_H__ */ + diff --git a/tizenipc/src/gsttizenipcsink.c b/tizenipc/src/gsttizenipcsink.c index 59de30e..3ec604d 100644 --- a/tizenipc/src/gsttizenipcsink.c +++ b/tizenipc/src/gsttizenipcsink.c @@ -33,10 +33,11 @@ #include #include #include +#include #include "gsttizenipcsink.h" #define DEFAULT_SOCKET_PATH "/tmp/tizenipc.0" -#define DEFAULT_SHM_PATH "/tizenipcshm" +#define DEFAULT_SHM_PATH "/tmp/tizenipcshm" #define DEFAULT_PERMISSIONS (S_IRUSR|S_IWUSR|S_IRGRP) #define DEFAULT_BACKLOG 5 #define CLIENT_RESPONSE_TIMEOUT_NORMAL (G_TIME_SPAN_SECOND) @@ -71,7 +72,8 @@ enum { }; - +static gboolean __init_socket(GstTizenipcSink *self); +static gboolean __init_shared_memory(GstTizenipcSink *self, guint shm_size); static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size); static gboolean _add_buffer_to_list(GstTizenipcSink *self, GstBuffer *buf, int *tbm_key); static gboolean _remove_buffer_from_list(GstTizenipcSink *self, int *tbm_key); @@ -96,23 +98,19 @@ static guint signals[LAST_SIGNAL] = {0, 0}; - -static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) +static gboolean __init_socket(GstTizenipcSink *self) { int i = 0; int flags = 0; struct sockaddr_un addr_un; struct sockaddr *address = NULL; socklen_t address_len = 0; - gchar shm_path[32] = {'\0',}; - if (self == NULL) { + if (!self) { GST_ERROR("NULL handle"); return FALSE; } - GST_INFO_OBJECT(self, "start - shared memory size %u", shm_size); - /* open socket */ self->socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); if (self->socket_fd < 0) { @@ -123,13 +121,13 @@ static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) flags = fcntl(self->socket_fd, F_GETFL, NULL); if (flags < 0) { GST_ERROR_OBJECT(self, "failed to fcntl F_GETFL"); - goto _FAILED; + goto _SOCKET_FAILED; } /* set non-block mode */ if (fcntl (self->socket_fd, F_SETFL, flags|O_NONBLOCK) < 0) { GST_ERROR_OBJECT(self, "failed to fcntl F_SETFL"); - goto _FAILED; + goto _SOCKET_FAILED; } memset(&addr_un, 0x0, sizeof(addr_un)); @@ -146,12 +144,12 @@ static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) while (bind(self->socket_fd, address, address_len) < 0) { if (errno != EADDRINUSE) { GST_ERROR_OBJECT(self, "failed to bind. errno %d", errno); - goto _FAILED; + goto _SOCKET_FAILED; } if (i > 256) { GST_ERROR_OBJECT(self, "no more free socket name"); - goto _FAILED; + goto _SOCKET_FAILED; } snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), "%s.%d", self->socket_path, i); @@ -168,21 +166,44 @@ static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) self->socket_path_result = g_strdup(addr_un.sun_path); if (self->socket_path_result == NULL) { GST_ERROR_OBJECT(self, "failed to copy string %s", addr_un.sun_path); - goto _FAILED; + goto _SOCKET_FAILED; } if (chmod(self->socket_path_result, self->permissions) < 0) { GST_ERROR_OBJECT(self, "failed to chmod %s - %d", addr_un.sun_path, self->permissions); - goto _FAILED; + goto _SOCKET_FAILED; } if (listen(self->socket_fd, DEFAULT_BACKLOG) < 0) { GST_ERROR_OBJECT(self, "failed to listen"); - goto _FAILED; + goto _SOCKET_FAILED; + } + + GST_INFO_OBJECT(self, "socket fd [%d]", self->socket_fd); + + return TRUE; + +_SOCKET_FAILED: + if (self->socket_fd > INIT_FD) { + shutdown(self->socket_fd, SHUT_RDWR); + close(self->socket_fd); + self->socket_fd = INIT_FD; + } + + return FALSE; +} + + +static gboolean __init_shared_memory(GstTizenipcSink *self, guint shm_size) +{ + int i = 0; + gchar shm_path[32] = {'\0',}; + + if (shm_size == 0) { + GST_INFO_OBJECT(self, "shm size is 0"); + return TRUE; } - /* create shared memory */ - i = 0; do { snprintf(shm_path, 32, "%s.%d", DEFAULT_SHM_PATH, i++); self->shm_fd = shm_open(shm_path, O_RDWR|O_CREAT|O_EXCL, self->permissions); @@ -190,7 +211,7 @@ static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) if (self->shm_fd < 0) { GST_ERROR_OBJECT(self, "failed to open shared memory [%s], errno [%d]", shm_path, errno); - goto _FAILED; + goto _SHARED_MEMORY_FAILED; } if (self->shm_path) { @@ -201,33 +222,66 @@ static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) self->shm_path = g_strdup(shm_path); if (self->shm_path == NULL) { GST_ERROR_OBJECT(self, "failed to copy shared memory path"); - goto _FAILED; + goto _SHARED_MEMORY_FAILED; } if (ftruncate(self->shm_fd, shm_size) < 0) { GST_ERROR_OBJECT(self, "failed to resize shm to %d", shm_size); - goto _FAILED; + goto _SHARED_MEMORY_FAILED; } self->shm_mapped_area = (gchar *)mmap(NULL, - shm_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - self->shm_fd, - 0); + shm_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + self->shm_fd, + 0); if (self->shm_mapped_area == MAP_FAILED) { GST_ERROR_OBJECT(self, "failed to mmap for shared memory"); - goto _FAILED; + goto _SHARED_MEMORY_FAILED; } self->shm_mapped_size = shm_size; + GST_INFO_OBJECT(self, "shared memory size [%d]", self->shm_mapped_size); + + return TRUE; + +_SHARED_MEMORY_FAILED: + if (self->shm_fd > INIT_FD) { + close(self->shm_fd); + self->shm_fd = INIT_FD; + } + + return FALSE; +} + + +static gboolean _prepare_tizenipc_sink(GstTizenipcSink *self, guint shm_size) +{ + if (self == NULL) { + GST_ERROR("NULL handle"); + return FALSE; + } + + GST_INFO_OBJECT(self, "start - socket path [%s], shared memory size [%u]", + self->socket_path, shm_size); + + /* socket */ + if (!__init_socket(self)) + return FALSE; + + /* shared memory */ + if (!__init_shared_memory(self, shm_size)) + goto _FAILED; + /* create gst poll and thread for poll */ self->poll = gst_poll_new(TRUE); if (self->poll == NULL) { GST_ERROR_OBJECT(self, "failed to create gst poll"); goto _FAILED; } + gst_poll_fd_init(&self->pollfd); self->pollfd.fd = self->socket_fd; gst_poll_add_fd(self->poll, &self->pollfd); @@ -254,14 +308,14 @@ _FAILED: self->poll = NULL; } - if (self->shm_fd > -1) { + if (self->shm_fd > INIT_FD) { close(self->shm_fd); - self->shm_fd = -1; + self->shm_fd = INIT_FD; } - if (self->socket_fd > -1) { + if (self->socket_fd > INIT_FD) { close(self->socket_fd); - self->socket_fd = -1; + self->socket_fd = INIT_FD; } return FALSE; @@ -272,7 +326,7 @@ static gboolean _add_buffer_to_list(GstTizenipcSink *self, GstBuffer *buf, int * { int i = 0; int j = 0; - GstTizenipcBuffer *sended_buffer = NULL; + GstTizenipcBuffer *buffer_list = NULL; if (self == NULL || buf == NULL || tbm_key == NULL) { GST_ERROR("NULL parameter %p, %p, %p", self, buf, tbm_key); @@ -281,23 +335,23 @@ static gboolean _add_buffer_to_list(GstTizenipcSink *self, GstBuffer *buf, int * g_mutex_lock(&self->buffer_lock); - sended_buffer = self->sended_buffer; + buffer_list = self->buffer_list; - for (i = 0 ; i < GST_TIZENIPC_BUFFER_MAX ; i++) { + for (i = 0 ; i < IPC_BUFFER_MAX ; i++) { /* find empty space */ - if (sended_buffer[i].gst_buf == NULL) { - self->sended_buffer_count++; + if (buffer_list[i].gst_buf == NULL) { + self->buffer_list_count++; GST_DEBUG_OBJECT(self, "insert buffer(key[0] %d) to index %d, count %d", - tbm_key[0], i, self->sended_buffer_count); + tbm_key[0], i, self->buffer_list_count); /* ref gst buffer and set tbm key */ gst_buffer_ref(buf); - sended_buffer[i].gst_buf = buf; + buffer_list[i].gst_buf = buf; - for (j = 0 ; j < MM_VIDEO_BUFFER_PLANE_MAX ; j++) { + for (j = 0 ; j < TBM_SURF_PLANE_MAX ; j++) { if (tbm_key[j] > 0) { - sended_buffer[i].tbm_key[j] = tbm_key[j]; + buffer_list[i].tbm_key[j] = tbm_key[j]; } else { break; } @@ -320,7 +374,7 @@ static gboolean _add_buffer_to_list(GstTizenipcSink *self, GstBuffer *buf, int * static gboolean _remove_buffer_from_list(GstTizenipcSink *self, int *tbm_key) { int i = 0; - GstTizenipcBuffer *sended_buffer = NULL; + GstTizenipcBuffer *buffer_list = NULL; if (self == NULL || tbm_key == NULL) { GST_ERROR("NULL parameter %p, %p", self, tbm_key); @@ -329,31 +383,31 @@ static gboolean _remove_buffer_from_list(GstTizenipcSink *self, int *tbm_key) g_mutex_lock(&self->buffer_lock); - sended_buffer = self->sended_buffer; + buffer_list = self->buffer_list; - for (i = 0 ; i < GST_TIZENIPC_BUFFER_MAX ; i++) { + for (i = 0 ; i < IPC_BUFFER_MAX ; i++) { /* find matched buffer info */ - if (sended_buffer[i].tbm_key[0] == tbm_key[0] && - sended_buffer[i].tbm_key[1] == tbm_key[1] && - sended_buffer[i].tbm_key[2] == tbm_key[2] && - sended_buffer[i].tbm_key[3] == tbm_key[3]) { + if (buffer_list[i].tbm_key[0] == tbm_key[0] && + buffer_list[i].tbm_key[1] == tbm_key[1] && + buffer_list[i].tbm_key[2] == tbm_key[2] && + buffer_list[i].tbm_key[3] == tbm_key[3]) { /* remove buffer info and unref gst buffer */ - self->sended_buffer_count--; + self->buffer_list_count--; GST_DEBUG_OBJECT(self, "gst buffer %p for key[0] %d, count %d", - sended_buffer[i].gst_buf, tbm_key[0], self->sended_buffer_count); + buffer_list[i].gst_buf, tbm_key[0], self->buffer_list_count); - if (sended_buffer[i].gst_buf) { - gst_buffer_unref(sended_buffer[i].gst_buf); - sended_buffer[i].gst_buf = NULL; + if (buffer_list[i].gst_buf) { + gst_buffer_unref(buffer_list[i].gst_buf); + buffer_list[i].gst_buf = NULL; } else { GST_WARNING_OBJECT(self, "no gst buffer for key[0] %d", tbm_key[0]); } - sended_buffer[i].tbm_key[0] = 0; - sended_buffer[i].tbm_key[1] = 0; - sended_buffer[i].tbm_key[2] = 0; - sended_buffer[i].tbm_key[3] = 0; + buffer_list[i].tbm_key[0] = 0; + buffer_list[i].tbm_key[1] = 0; + buffer_list[i].tbm_key[2] = 0; + buffer_list[i].tbm_key[3] = 0; g_cond_signal(&self->buffer_cond); g_mutex_unlock(&self->buffer_lock); @@ -383,20 +437,20 @@ static void gst_tizenipc_sink_init(GstTizenipcSink *self) g_mutex_init(&self->ipc_lock); g_cond_init(&self->ipc_cond); - self->socket_fd = -1; - self->client_fd = -1; - self->shm_fd = -1; + self->socket_fd = INIT_FD; + self->client_fd = INIT_FD; + self->shm_fd = INIT_FD; self->shm_mapped_area = MAP_FAILED; self->is_connected = FALSE; self->permissions = DEFAULT_PERMISSIONS; + self->socket_path = g_strdup(DEFAULT_SOCKET_PATH); - if (self->socket_path == NULL) { + if (self->socket_path == NULL) GST_ERROR_OBJECT(self, "failed to dup socket path [%s]", DEFAULT_SOCKET_PATH); - } - self->sended_buffer = g_new0(GstTizenipcBuffer, GST_TIZENIPC_BUFFER_MAX); - if (self->sended_buffer == NULL) { - GST_ERROR_OBJECT(self, "failed to alloc sended_buffer"); - } + + self->buffer_list = g_new0(GstTizenipcBuffer, IPC_BUFFER_MAX); + if (self->buffer_list == NULL) + GST_ERROR_OBJECT(self, "failed to alloc buffer_list"); return; } @@ -499,19 +553,19 @@ static void gst_tizenipc_sink_finalize(GObject *object) g_mutex_clear(&self->buffer_lock); g_cond_clear(&self->buffer_cond); - if (self->socket_path) { - g_free(self->socket_path); - self->socket_path = NULL; - } + g_free(self->socket_path); + self->socket_path = NULL; - if (self->socket_path_result) { - g_free(self->socket_path_result); - self->socket_path_result = NULL; - } + g_free(self->socket_path_result); + self->socket_path_result = NULL; - if (self->shm_path) { - g_free(self->shm_path); - self->shm_path = NULL; + g_free(self->shm_path); + self->shm_path = NULL; + + if (self->caps_string) { + GST_INFO_OBJECT(self, "release caps string [%s]", self->caps_string); + g_free(self->caps_string); + self->caps_string = NULL; } G_OBJECT_CLASS(parent_class)->finalize(object); @@ -543,10 +597,7 @@ static void gst_tizenipc_sink_set_property(GObject *object, guint prop_id, { gchar *temp_string = g_value_dup_string(value); if (temp_string) { - if (self->socket_path) { - g_free(self->socket_path); - self->socket_path = NULL; - } + g_free(self->socket_path); self->socket_path = temp_string; } else { GST_ERROR_OBJECT(object, "failed to copy string [%s]", g_value_get_string(value)); @@ -620,9 +671,9 @@ static gboolean gst_tizenipc_sink_start(GstBaseSink *bsink) /* check socket path and buffer list */ if (self->socket_path == NULL || - self->sended_buffer == NULL) { - GST_ERROR_OBJECT(self, "socket path[%p] or sended buffer [%p] is NULL", - self->socket_path, self->sended_buffer); + self->buffer_list == NULL) { + GST_ERROR_OBJECT(self, "socket path[%p] or buffer_list [%p] is NULL", + self->socket_path, self->buffer_list); return FALSE; } @@ -648,7 +699,24 @@ static gboolean gst_tizenipc_sink_stop(GstBaseSink *bsink) return FALSE; } - GST_INFO_OBJECT(self, "start"); + /* wait for buffer */ + g_mutex_lock(&self->buffer_lock); + + GST_INFO_OBJECT(self, "start - not returned buffer %d", self->buffer_list_count); + + while (self->buffer_list_count > 0) { + wait_end_time = g_get_monotonic_time () + BUFFER_WAIT_TIMEOUT; + if (!g_cond_wait_until(&self->buffer_cond, &self->buffer_lock, wait_end_time)) { + GST_WARNING_OBJECT(self, "wait timeout - current count %d", + self->buffer_list_count); + break; + } else { + GST_WARNING_OBJECT(self, "signal received - current count %d", + self->buffer_list_count); + } + } + + g_mutex_unlock(&self->buffer_lock); /* stop poll thread */ self->poll_thread_run = FALSE; @@ -665,23 +733,6 @@ static gboolean gst_tizenipc_sink_stop(GstBaseSink *bsink) GST_WARNING_OBJECT(self, "no poll thread"); } - /* wait for sended buffer */ - g_mutex_lock(&self->buffer_lock); - - while (self->sended_buffer_count > 0) { - wait_end_time = g_get_monotonic_time () + BUFFER_WAIT_TIMEOUT; - if (!g_cond_wait_until(&self->buffer_cond, &self->buffer_lock, wait_end_time)) { - GST_WARNING_OBJECT(self, "wait timeout - current count %d", - self->sended_buffer_count); - break; - } else { - GST_WARNING_OBJECT(self, "signal received - current count %d", - self->sended_buffer_count); - } - } - - g_mutex_unlock(&self->buffer_lock); - /* close client */ if (self->client_fd >= 0) { GST_INFO_OBJECT(self, "close client fd %d", self->client_fd); @@ -689,7 +740,7 @@ static gboolean gst_tizenipc_sink_stop(GstBaseSink *bsink) shutdown(self->client_fd, SHUT_RDWR); close(self->client_fd); g_signal_emit(self, signals[SIGNAL_CLIENT_DISCONNECTED], 0, self->client_fd); - self->client_fd = -1; + self->client_fd = INIT_FD; } else { GST_WARNING_OBJECT(self, "no client"); } @@ -703,7 +754,7 @@ static gboolean gst_tizenipc_sink_stop(GstBaseSink *bsink) } close(self->shm_fd); - self->shm_fd = -1; + self->shm_fd = INIT_FD; if (self->shm_path) { shm_unlink(self->shm_path); @@ -728,7 +779,7 @@ static gboolean gst_tizenipc_sink_stop(GstBaseSink *bsink) shutdown(self->socket_fd, SHUT_RDWR); close(self->socket_fd); - self->socket_fd = -1; + self->socket_fd = INIT_FD; } else { GST_WARNING_OBJECT(self, "socket is not opened"); } @@ -747,11 +798,9 @@ static GstFlowReturn gst_tizenipc_sink_render(GstBaseSink *bsink, GstBuffer *buf { GstTizenipcSink *self = NULL; GstTizenipcMessage msg = {0, }; - MMVideoBuffer *mm_buf = NULL; GstMemory *memory = NULL; GstMapInfo map_info = GST_MAP_INFO_INIT; gint64 wait_end_time = 0; - int tbm_key[MM_VIDEO_BUFFER_PLANE_MAX] = {0, }; int i = 0; if (bsink == NULL) { @@ -782,11 +831,16 @@ static GstFlowReturn gst_tizenipc_sink_render(GstBaseSink *bsink, GstBuffer *buf goto _SKIP_BUFFER; } + memory = gst_buffer_peek_memory(buf, 0); + if (!memory) { + GST_WARNING_OBJECT(self, "failed to peek memory 0 for %p", buf); + goto _SKIP_BUFFER; + } + if (self->is_normal_format) { - memory = gst_buffer_peek_memory(buf, 0); - if (memory == NULL) { - GST_WARNING_OBJECT(self, "failed to peek memory 0 for %p", buf); - goto _SKIP_BUFFER; + if (self->shm_mapped_area == MAP_FAILED) { + GST_ERROR_OBJECT(self, "no mapped area"); + return GST_FLOW_ERROR; } if (gst_memory_map(memory, &map_info, GST_MAP_READ) == FALSE) { @@ -806,62 +860,40 @@ static GstFlowReturn gst_tizenipc_sink_render(GstBaseSink *bsink, GstBuffer *buf msg.id = TIZEN_IPC_BUFFER_NEW; msg.size = map_info.size; } else { - /* get mm_buf from gst buffer */ - if (gst_buffer_n_memory(buf) <= 1) { - GST_WARNING_OBJECT(self, "invalid memory number %d", gst_buffer_n_memory(buf)); - goto _SKIP_BUFFER; - } + int num_bos = 0; + tbm_bo bo = NULL; - memory = gst_buffer_peek_memory(buf, 1); - if (memory == NULL) { - GST_WARNING_OBJECT(self, "failed to peek memory 1 for %p", buf); - goto _SKIP_BUFFER; - } + /* set command type */ + msg.id = TIZEN_IPC_BUFFER_NEW; - if (gst_memory_map(memory, &map_info, GST_MAP_READ) == FALSE) { - GST_WARNING_OBJECT(self, "failed to map memory %p", memory); - goto _SKIP_BUFFER; - } + /* get number of bo */ + num_bos = gst_tizen_memory_get_num_bos(memory); - mm_buf = (MMVideoBuffer *)map_info.data; + GST_LOG_OBJECT(self, "Tizen memory[%p] : number of bo %d", memory, num_bos); - gst_memory_unmap(memory, &map_info); + /* get bo and export to deliver to client process */ + for (i = 0 ; i < num_bos ; i++) { + bo = gst_tizen_memory_get_bos(memory, i); + if (!bo) { + GST_ERROR_OBJECT(self, "failed to get bo for index %d", i); + continue; + } - if (mm_buf == NULL) { - GST_WARNING_OBJECT(self, "NULL mm_buf"); - goto _SKIP_BUFFER; - } + msg.tbm_key[i] = tbm_bo_export(bo); - GST_LOG_OBJECT(self, "MMVideoBuffer info - %p, num handle %d", - mm_buf, mm_buf->handle_num); - - /* export bo to pass buffer to client process */ - for (i = 0 ; i < mm_buf->handle_num ; i++) { - if (mm_buf->handle.bo[i]) { - tbm_key[i] = tbm_bo_export(mm_buf->handle.bo[i]); - GST_LOG_OBJECT(self, "export tbm key[index:%d] %d", i, tbm_key[i]); - if (tbm_key[i] <= 0) { - GST_ERROR_OBJECT(self, "failed to export bo[%d] %p", i, mm_buf->handle.bo[i]); - goto _SKIP_BUFFER; - } - } else { - break; + GST_LOG_OBJECT(self, "export tbm key[index:%d] %d", i, msg.tbm_key[i]); + + if (msg.tbm_key[i] <= 0) { + GST_ERROR_OBJECT(self, "failed to export bo[%d] %p", i, bo); + goto _SKIP_BUFFER; } } /* keep and send buffer */ - if (_add_buffer_to_list(self, buf, tbm_key) == FALSE) { - GST_ERROR_OBJECT(self, "failed to add to list for buffer %p and key[0] %d", buf, tbm_key[0]); + if (_add_buffer_to_list(self, buf, msg.tbm_key) == FALSE) { + GST_ERROR_OBJECT(self, "failed to add to list for buffer %p and key[0] %d", buf, msg.tbm_key[0]); goto _SKIP_BUFFER; } - - /* set command type and size */ - msg.id = TIZEN_IPC_BUFFER_NEW; - msg.size = sizeof(MMVideoBuffer) + sizeof(tbm_key); - - /* copy zero copy info to shared memory */ - memcpy(self->shm_mapped_area, mm_buf, sizeof(MMVideoBuffer)); - memcpy(self->shm_mapped_area + sizeof(MMVideoBuffer), tbm_key, sizeof(tbm_key)); } /* send data */ @@ -894,7 +926,7 @@ static GstFlowReturn gst_tizenipc_sink_render(GstBaseSink *bsink, GstBuffer *buf _SKIP_BUFFER_AFTER_ADD_TO_LIST: if (!self->is_normal_format) - _remove_buffer_from_list(self, tbm_key); + _remove_buffer_from_list(self, msg.tbm_key); _SKIP_BUFFER: g_mutex_unlock(&self->ipc_lock); @@ -920,7 +952,7 @@ static gboolean gst_tizenipc_sink_event(GstBaseSink *bsink, GstEvent *event) switch (GST_EVENT_TYPE(event)) { case GST_EVENT_EOS: - /* wait for sended buffer */ + /* wait for buffer */ break; default: break; @@ -945,7 +977,6 @@ static gboolean gst_tizenipc_sink_unlock_stop(GstBaseSink *bsink) static gboolean gst_tizenipc_sink_set_caps(GstBaseSink *bsink, GstCaps *caps) { GstTizenipcSink *self = NULL; - GstStructure *structure = NULL; if (bsink == NULL) { GST_ERROR("NULL object"); @@ -960,49 +991,56 @@ static gboolean gst_tizenipc_sink_set_caps(GstBaseSink *bsink, GstCaps *caps) GST_INFO_OBJECT(self, "start - caps [%"GST_PTR_FORMAT"]", caps); - self->is_normal_format = TRUE; - - structure = gst_caps_get_structure(caps, 0); - if (structure == NULL) { - GST_ERROR_OBJECT(self, "failed to get structure from caps [%"GST_PTR_FORMAT"]", caps); + /* get GstVideoInfo */ + gst_video_info_init(&self->video_info); + if (!gst_video_info_from_caps(&self->video_info, caps)) { + GST_ERROR_OBJECT(bsink, "failed to get video info from caps[%p,%"GST_PTR_FORMAT"]", + caps, caps); return FALSE; } - if (!gst_structure_has_name(structure, "video/x-raw")) { - GST_ERROR_OBJECT(self, "not supported caps [%"GST_PTR_FORMAT"]", caps); + self->is_normal_format = TRUE; + self->format = GST_VIDEO_INFO_FORMAT(&self->video_info); + self->width = GST_VIDEO_INFO_WIDTH(&self->video_info); + self->height = GST_VIDEO_INFO_HEIGHT(&self->video_info); + + switch (self->format) { + case GST_VIDEO_FORMAT_SN12: + case GST_VIDEO_FORMAT_SN21: + case GST_VIDEO_FORMAT_S420: + case GST_VIDEO_FORMAT_ST12: + case GST_VIDEO_FORMAT_SR32: + case GST_VIDEO_FORMAT_STV0: + case GST_VIDEO_FORMAT_STV1: + self->shm_size = 0; + self->is_normal_format = FALSE; + break; + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + self->shm_size = (self->width * self->height * 3) >> 1; + break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + self->shm_size = (self->width * self->height) << 1; + break; + default: + GST_ERROR_OBJECT(self, "unsupported format [%d]", self->format); return FALSE; } - self->format_string = gst_structure_get_string(structure, "format"); - if (self->format_string == NULL) { - GST_ERROR_OBJECT(self, "failed to get format from caps [%"GST_PTR_FORMAT"]", caps); - return FALSE; - } + GST_INFO_OBJECT(self, "format %d, size %dx%d, shm size %d", + self->format, self->width, self->height, self->shm_size); - if (!gst_structure_get_int(structure, "width", &self->width) || - !gst_structure_get_int(structure, "height", &self->height)) { - GST_ERROR_OBJECT(self, "failed to get width, height from caps [%"GST_PTR_FORMAT"]", caps); - return FALSE; + if (self->caps_string) { + GST_INFO_OBJECT(self, "release caps string [%s]", self->caps_string); + g_free(self->caps_string); + self->caps_string = NULL; } - if (!strcmp(self->format_string, "SN12") || !strcmp(self->format_string, "SN21") || - !strcmp(self->format_string, "SYVY") || !strcmp(self->format_string, "SUYV") || - !strcmp(self->format_string, "S420")) { - self->shm_size = sizeof(MMVideoBuffer) + (sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX); - self->is_normal_format = FALSE; - } else if (!strcmp(self->format_string, "NV12") || !strcmp(self->format_string, "NV21") || - !strcmp(self->format_string, "I420") || !strcmp(self->format_string, "YV12")) { - self->shm_size = (self->width * self->height * 3) >> 1; - } else if (!strcmp(self->format_string, "YUYV") || !strcmp(self->format_string, "YUY2") || - !strcmp(self->format_string, "UYVY")) { - self->shm_size = (self->width * self->height) << 1; - } else { - GST_ERROR_OBJECT(self, "unsupported format [%s]", self->format_string); - return FALSE; - } + /* get caps string */ + self->caps_string = gst_caps_to_string(caps); - GST_INFO_OBJECT(self, "format %s, size %dx%d, shm size %d", - self->format_string, self->width, self->height, self->shm_size); + GST_INFO_OBJECT(self, "caps [%s]", self->caps_string); /* create socket and shared memory for sending buffer */ if (!_prepare_tizenipc_sink(self, self->shm_size)) { @@ -1093,50 +1131,73 @@ static gpointer _gst_poll_thread_func(gpointer data) GST_INFO_OBJECT(self, "client accpeted : fd %d", self->client_fd); - /* send shard memory size */ - msg.id = TIZEN_IPC_SHM_SIZE; - msg.size = self->shm_mapped_size; - if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { - GST_ERROR_OBJECT(self, "failed to send shard memory size"); - close(self->client_fd); - self->client_fd = -1; - g_mutex_unlock(&self->ipc_lock); - continue; + if (self->shm_mapped_size > 0) { + /* send shard memory size */ + msg.id = TIZEN_IPC_SHM_SIZE; + msg.size = self->shm_mapped_size; + if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { + GST_ERROR_OBJECT(self, "failed to send shard memory size"); + close(self->client_fd); + self->client_fd = INIT_FD; + g_mutex_unlock(&self->ipc_lock); + continue; + } + + /* send shard memory path */ + msg.id = TIZEN_IPC_SHM_PATH; + msg.size = strlen(self->shm_path) + 1; + if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { + GST_ERROR_OBJECT(self, "failed to send shard memory path 1"); + close(self->client_fd); + self->client_fd = INIT_FD; + g_mutex_unlock(&self->ipc_lock); + continue; + } + + if (send(self->client_fd, self->shm_path, msg.size, MSG_NOSIGNAL) != msg.size) { + GST_ERROR_OBJECT(self, "failed to send shard memory path 2"); + close(self->client_fd); + self->client_fd = INIT_FD; + g_mutex_unlock(&self->ipc_lock); + continue; + } + + GST_INFO_OBJECT(self, "send shm path done - %s", self->shm_path); } - /* send shard memory path */ - msg.id = TIZEN_IPC_SHM_PATH; - msg.size = strlen(self->shm_path) + 1; + /* send buffer type */ + msg.id = TIZEN_IPC_BUFFER_TYPE; + msg.type = self->is_normal_format ? BUFFER_TYPE_NORMAL : BUFFER_TYPE_ZERO_COPY; if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { - GST_ERROR_OBJECT(self, "failed to send shard memory path 1"); + GST_ERROR_OBJECT(self, "failed to send buffer type"); close(self->client_fd); - self->client_fd = -1; + self->client_fd = INIT_FD; g_mutex_unlock(&self->ipc_lock); continue; } - if (send(self->client_fd, self->shm_path, strlen(self->shm_path) + 1, MSG_NOSIGNAL) != (strlen(self->shm_path) + 1)) { - GST_ERROR_OBJECT(self, "failed to send shard memory path 2"); + GST_INFO_OBJECT(self, "send buffer type done - %d", msg.type); + + /* send caps string */ + msg.id = TIZEN_IPC_BUFFER_CAPS; + msg.size = strlen(self->caps_string) + 1; + if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { + GST_ERROR_OBJECT(self, "failed to send caps string 1"); close(self->client_fd); - self->client_fd = -1; + self->client_fd = INIT_FD; g_mutex_unlock(&self->ipc_lock); continue; } - GST_INFO_OBJECT(self, "send shm path done - %s", self->shm_path); - - /* send buffer type */ - msg.id = TIZEN_IPC_BUFFER_TYPE; - msg.type = self->is_normal_format ? BUFFER_TYPE_NORMAL : BUFFER_TYPE_ZERO_COPY; - if (send(self->client_fd, &msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL) != sizeof(GstTizenipcMessage)) { - GST_ERROR_OBJECT(self, "failed to send buffer type"); + if (send(self->client_fd, self->caps_string, msg.size, MSG_NOSIGNAL) != msg.size) { + GST_ERROR_OBJECT(self, "failed to send caps string 2"); close(self->client_fd); - self->client_fd = -1; + self->client_fd = INIT_FD; g_mutex_unlock(&self->ipc_lock); continue; } - GST_INFO_OBJECT(self, "send buffer type done - %d", msg.type); + GST_INFO_OBJECT(self, "send caps string done - %s", self->caps_string); gst_poll_fd_init(&self->client_pollfd); self->client_pollfd.fd = self->client_fd; @@ -1150,7 +1211,7 @@ static gpointer _gst_poll_thread_func(gpointer data) continue; } - if (self->client_fd > -1) { + if (self->client_fd > INIT_FD) { if (gst_poll_fd_has_closed(self->poll, &self->client_pollfd)) { GST_WARNING_OBJECT(self, "client is gone, closing"); goto close_client; @@ -1210,8 +1271,10 @@ static gpointer _gst_poll_thread_func(gpointer data) GST_INFO_OBJECT(self, "close client fd %d", self->client_fd); gst_poll_remove_fd(self->poll, &self->client_pollfd); + + shutdown(self->client_fd, SHUT_RDWR); close(self->client_fd); - self->client_fd = -1; + self->client_fd = INIT_FD; g_mutex_unlock(&self->ipc_lock); diff --git a/tizenipc/src/gsttizenipcsink.h b/tizenipc/src/gsttizenipcsink.h index cd329e0..46d6dd8 100644 --- a/tizenipc/src/gsttizenipcsink.h +++ b/tizenipc/src/gsttizenipcsink.h @@ -24,8 +24,9 @@ #include #include +#include #include -#include +#include "gsttizenipc.h" G_BEGIN_DECLS @@ -36,20 +37,19 @@ G_BEGIN_DECLS #define GST_IS_TIZENIPC_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_TIZENIPC_SINK)) #define GST_TIZENIPC_SINK_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS((inst), GST_TYPE_TIZENIPC_SINK, GstTizenipcSinkClass)) -#define GST_TIZENIPC_BUFFER_MAX 30 - typedef struct _GstTizenipcSink GstTizenipcSink; typedef struct _GstTizenipcSinkClass GstTizenipcSinkClass; typedef struct _GstTizenipcBuffer GstTizenipcBuffer; -typedef struct _GstTizenipcMessage GstTizenipcMessage; struct _GstTizenipcSink { GstBaseSink parent; - const gchar *format_string; + gchar *caps_string; + GstVideoFormat format; gint width; gint height; gboolean is_normal_format; + GstVideoInfo video_info; /* ipc */ int socket_fd; @@ -75,8 +75,8 @@ struct _GstTizenipcSink { guint permissions; /* buffer management */ - GstTizenipcBuffer *sended_buffer; - guint sended_buffer_count; + GstTizenipcBuffer *buffer_list; + guint buffer_list_count; GMutex buffer_lock; GCond buffer_cond; }; @@ -87,32 +87,7 @@ struct _GstTizenipcSinkClass { struct _GstTizenipcBuffer { GstBuffer *gst_buf; - guint tbm_key[MM_VIDEO_BUFFER_PLANE_MAX]; -}; - - -typedef enum { - TIZEN_IPC_SHM_PATH = 0, - TIZEN_IPC_SHM_SIZE, - TIZEN_IPC_BUFFER_TYPE, - TIZEN_IPC_BUFFER_NEW, - TIZEN_IPC_BUFFER_RECEIVED, - TIZEN_IPC_BUFFER_RELEASE, - TIZEN_IPC_CLOSE_CLIENT -} TizenIPCID; - -typedef enum { - BUFFER_TYPE_NORMAL = 0, - BUFFER_TYPE_ZERO_COPY -} BufferType; - -struct _GstTizenipcMessage { - TizenIPCID id; - union { - BufferType type; - int size; - int tbm_key[MM_VIDEO_BUFFER_PLANE_MAX]; - }; + guint tbm_key[TBM_SURF_PLANE_MAX]; }; GType diff --git a/tizenipc/src/gsttizenipcsrc.c b/tizenipc/src/gsttizenipcsrc.c index f10b428..a7a3f01 100644 --- a/tizenipc/src/gsttizenipcsrc.c +++ b/tizenipc/src/gsttizenipcsrc.c @@ -34,10 +34,11 @@ #include #include #include +#include #include "gsttizenipcsrc.h" #define DEFAULT_SOCKET_PATH "/tmp/tizenipc.0" -#define DEFAULT_SHM_PATH "/tizenipcshm" +#define DEFAULT_SHM_PATH "/tmp/tizenipcshm" #define DEFAULT_PERMISSIONS (S_IRUSR|S_IWUSR|S_IRGRP) #define DEFAULT_BACKLOG 5 #define BUFFER_WAIT_TIMEOUT (G_TIME_SPAN_MILLISECOND * 3000) @@ -68,6 +69,10 @@ enum { }; +static GstBuffer *_tizenipc_src_buffer_new(GstTizenipcSrc *self, GstTizenipcMessage *recv_msg); +static void _tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *buffer); +static gboolean _tizenipc_get_tbm_format(GstVideoFormat video_format, guint32 *tbm_format); + static void gst_tizenipc_src_finalize(GObject *object); static void gst_tizenipc_src_set_property(GObject *object, guint prop_id, @@ -76,14 +81,48 @@ static void gst_tizenipc_src_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static gboolean gst_tizenipc_src_start(GstBaseSrc *bsrc); static gboolean gst_tizenipc_src_stop(GstBaseSrc *bsrc); -static GstFlowReturn gst_tizenipc_src_create(GstPushSrc *psrc, GstBuffer **outbuf); static gboolean gst_tizenipc_src_unlock(GstBaseSrc *bsrc); static gboolean gst_tizenipc_src_unlock_stop(GstBaseSrc *bsrc); +static GstFlowReturn gst_tizenipc_src_create(GstPushSrc *psrc, GstBuffer **outbuf); static GstStateChangeReturn gst_tizenipc_src_change_state(GstElement *element, GstStateChange transition); -static void gst_tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *buffer); +static gboolean _tizenipc_get_tbm_format(GstVideoFormat video_format, guint32 *tbm_format) +{ + if (!tbm_format) { + GST_ERROR("NULL param"); + return FALSE; + } + + switch(video_format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_S420: + *tbm_format = TBM_FORMAT_YUV420; + break; + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_SN12: + *tbm_format = TBM_FORMAT_NV12; + break; + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_SN21: + *tbm_format = TBM_FORMAT_NV21; + break; + case GST_VIDEO_FORMAT_YUY2: + *tbm_format = TBM_FORMAT_YUYV; + break; + case GST_VIDEO_FORMAT_UYVY: + *tbm_format = TBM_FORMAT_UYVY; + break; + default: + GST_ERROR("unhandled format %d", video_format); + return FALSE; + } + + return TRUE; +} + + static gboolean _tizenipc_src_prepare_to_read(GstTizenipcSrc *self) { struct sockaddr_un addr_un; @@ -106,7 +145,7 @@ static gboolean _tizenipc_src_prepare_to_read(GstTizenipcSrc *self) return FALSE; } - GST_INFO_OBJECT(self, "start"); + GST_INFO_OBJECT(self, "start - socket path [%s]", self->socket_path); /* socket connection */ self->socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); @@ -121,7 +160,7 @@ static gboolean _tizenipc_src_prepare_to_read(GstTizenipcSrc *self) goto _PREPARE_FAILED; } - if (fcntl(self->socket_fd, F_SETFL, flags|FD_CLOEXEC) < 0) { + if (fcntl(self->socket_fd, F_SETFL, flags | FD_CLOEXEC) < 0) { GST_ERROR_OBJECT(self, "failed to fcntl F_SETFL FD_CLOEXEC for socket fd %d", self->socket_fd); goto _PREPARE_FAILED; } @@ -133,7 +172,7 @@ static gboolean _tizenipc_src_prepare_to_read(GstTizenipcSrc *self) address_len = sizeof(addr_un); if (connect(self->socket_fd, address, address_len) < 0) { - GST_ERROR_OBJECT(self, "failed to connect for socket fd %d", self->socket_fd); + GST_ERROR_OBJECT(self, "failed to connect for socket fd %d, errno %d", self->socket_fd, errno); goto _PREPARE_FAILED; } @@ -152,7 +191,7 @@ _PREPARE_FAILED: if (self->socket_fd >= 0) { shutdown(self->socket_fd, SHUT_RDWR); close(self->socket_fd); - self->socket_fd = -1; + self->socket_fd = INIT_FD; } if (self->socket_path) { @@ -209,21 +248,17 @@ static gboolean _tizenipc_src_stop_to_read(GstTizenipcSrc *self) shutdown(self->socket_fd, SHUT_RDWR); close(self->socket_fd); - self->socket_fd = -1; + self->socket_fd = INIT_FD; } - if (self->socket_path) { - unlink(self->socket_path); - } - - if (self->shm_mapped_area) { + if (self->shm_mapped_area != MAP_FAILED) { munmap(self->shm_mapped_area, self->shm_mapped_size); self->shm_mapped_area = MAP_FAILED; } if (self->shm_fd) { close(self->shm_fd); - self->shm_fd = -1; + self->shm_fd = INIT_FD; } GST_INFO_OBJECT(self, "done"); @@ -241,20 +276,24 @@ static void gst_tizenipc_src_init(GstTizenipcSrc *self) g_mutex_init(&self->buffer_lock); g_cond_init(&self->buffer_cond); - self->socket_fd = -1; - self->shm_fd = -1; + self->socket_fd = INIT_FD; + self->shm_fd = INIT_FD; self->shm_mapped_area = MAP_FAILED; self->bufmgr = tbm_bufmgr_init(-1); + self->socket_path = g_strdup(DEFAULT_SOCKET_PATH); - if (self->socket_path == NULL) { + if (self->socket_path == NULL) GST_ERROR_OBJECT(self, "failed to dup socket path [%s]", DEFAULT_SOCKET_PATH); - } + self->poll = gst_poll_new(TRUE); - if (self->poll == NULL) { + if (self->poll == NULL) GST_ERROR_OBJECT(self, "failed to get gst poll"); - } else { + else gst_poll_fd_init(&self->pollfd); - } + + self->allocator = gst_tizen_allocator_new(); + if (!self->allocator) + GST_ERROR_OBJECT(self, "tizen allocator new failed"); return; } @@ -340,15 +379,11 @@ static void gst_tizenipc_src_finalize(GObject *object) g_mutex_clear(&self->buffer_lock); g_cond_clear(&self->buffer_cond); - if (self->socket_path) { - g_free(self->socket_path); - self->socket_path = NULL; - } + g_free(self->socket_path); + self->socket_path = NULL; - if (self->shm_path) { - g_free(self->shm_path); - self->shm_path = NULL; - } + g_free(self->shm_path); + self->shm_path = NULL; if (self->poll) { gst_poll_free(self->poll); @@ -360,6 +395,12 @@ static void gst_tizenipc_src_finalize(GObject *object) self->bufmgr = NULL; } + if (self->caps_string) { + GST_INFO_OBJECT(self, "release caps string [%s]", self->caps_string); + g_free(self->caps_string); + self->caps_string = NULL; + } + GST_INFO_OBJECT(self, "done"); G_OBJECT_CLASS(parent_class)->finalize(object); @@ -393,11 +434,9 @@ static void gst_tizenipc_src_set_property(GObject *object, guint prop_id, temp_string = g_value_dup_string(value); if (temp_string) { - if (self->socket_path) { - g_free(self->socket_path); - self->socket_path = NULL; - } + g_free(self->socket_path); self->socket_path = temp_string; + GST_INFO_OBJECT(object, "socket path [%s]", self->socket_path); } else { GST_ERROR_OBJECT(object, "failed to copy string [%s]", g_value_get_string(value)); } @@ -510,11 +549,10 @@ static gboolean gst_tizenipc_src_stop(GstBaseSrc *bsrc) } -static void gst_tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *ipc_buf) +static void _tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *ipc_buf) { GstTizenipcSrc *self = NULL; GstTizenipcMessage send_msg = {0,}; - MMVideoBuffer *mm_buf = NULL; int i = 0; int send_len = 0; @@ -524,17 +562,15 @@ static void gst_tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *ipc_buf) } self = ipc_buf->self; - mm_buf = ipc_buf->mm_buf; - if (self == NULL) { GST_ERROR("NULL handle"); goto _BUFFER_FINALIZE_DONE; } /* send message to sink for current tbm key */ - if (self->socket_fd > -1) { + if (self->socket_fd > INIT_FD) { send_msg.id = TIZEN_IPC_BUFFER_RELEASE; - memcpy(send_msg.tbm_key, ipc_buf->tbm_key, sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX); + memcpy(send_msg.tbm_key, ipc_buf->tbm_key, sizeof(int) * TBM_SURF_PLANE_MAX); send_len = send(self->socket_fd, &send_msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL); if (send_len != sizeof(GstTizenipcMessage)) { GST_ERROR_OBJECT(self, "send failed : BUFFER_RELEASE key[0] %d", send_msg.tbm_key[0]); @@ -547,7 +583,7 @@ static void gst_tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *ipc_buf) g_mutex_lock(&self->buffer_lock); GST_DEBUG_OBJECT(self, "live buffer(tbm key[0] %d) count %d -> %d", - ipc_buf->tbm_key[0], self->live_buffer_count, self->live_buffer_count-1); + ipc_buf->tbm_key[0], self->live_buffer_count, self->live_buffer_count - 1); self->live_buffer_count--; g_cond_signal(&self->buffer_cond); @@ -558,18 +594,18 @@ static void gst_tizenipc_src_buffer_finalize(GstTizenipcSrcBuffer *ipc_buf) self = NULL; _BUFFER_FINALIZE_DONE: - if (mm_buf) { - for (i = 0 ; i < mm_buf->handle_num ; i++) { - if (mm_buf->handle.bo[i]) { - tbm_bo_unref(mm_buf->handle.bo[i]); - mm_buf->handle.bo[i] = NULL; - } else { - break; - } - } + if (ipc_buf->t_surface) { + tbm_surface_destroy(ipc_buf->t_surface); + ipc_buf->t_surface = NULL; + } - free(mm_buf); - mm_buf = NULL; + for (i = 0 ; ipc_buf->bos[i] ; i++) { + if (ipc_buf->bos[i]) { + tbm_bo_unref(ipc_buf->bos[i]); + ipc_buf->bos[i] = NULL; + } else { + break; + } } free(ipc_buf); @@ -579,17 +615,145 @@ _BUFFER_FINALIZE_DONE: } +static GstBuffer *_tizenipc_src_buffer_new(GstTizenipcSrc *self, GstTizenipcMessage *recv_msg) +{ + int i = 0; + int num_bos = 0; + void *normal_buffer_data = NULL; + + GstBuffer *buffer = NULL; + GstMemory *memory = NULL; + + GstTizenipcSrcBuffer *ipc_buf = NULL; + GstTizenipcMessage send_msg = {0,}; + + if (!self || !recv_msg) { + GST_ERROR_OBJECT(self, "NULL param %p %p", self, recv_msg); + return NULL; + } + + /* create empty buffer */ + buffer = gst_buffer_new(); + if (!buffer) { + GST_ERROR_OBJECT(self, "buffer failed"); + return NULL; + } + + /* get new buffer from sink */ + if (self->is_normal_format) { + if (self->shm_mapped_area == MAP_FAILED) { + GST_ERROR_OBJECT(self, "no mapped area"); + goto _BUFFER_NEW_FAILED; + } + /* non-zero-copy case */ + normal_buffer_data = (void *)malloc(recv_msg->size); + if (!normal_buffer_data) { + GST_ERROR_OBJECT(self, "normal buffer[%d] failed", recv_msg->size); + goto _BUFFER_NEW_FAILED; + } + + memcpy(normal_buffer_data, self->shm_mapped_area, recv_msg->size); + + /* create GstMemory */ + memory = gst_memory_new_wrapped(0, + normal_buffer_data, recv_msg->size, 0, + recv_msg->size, normal_buffer_data, free); + } else { + /* zero-copy case */ + ipc_buf = g_new0(GstTizenipcSrcBuffer, 1); + if (!ipc_buf) { + GST_ERROR_OBJECT(self, "GstTizenipcSrcBuffer alloc failed"); + goto _BUFFER_NEW_FAILED; + } + + ipc_buf->gst_buf = buffer; + ipc_buf->self = gst_object_ref(self); + + /* get tbm key from message */ + memcpy(send_msg.tbm_key, recv_msg->tbm_key, sizeof(int) * TBM_SURF_PLANE_MAX); + + /* import tbm bo */ + for (i = 0 ; i < TBM_SURF_PLANE_MAX && send_msg.tbm_key[i] > 0 ; i++) { + ipc_buf->bos[i] = tbm_bo_import(self->bufmgr, send_msg.tbm_key[i]); + if (ipc_buf->bos[i] == NULL) { + GST_ERROR_OBJECT(self, "bo import failed for key [%d]", send_msg.tbm_key[i]); + goto _BUFFER_NEW_FAILED; + } + + ipc_buf->tbm_key[i] = send_msg.tbm_key[i]; + + num_bos++; + } + + /* create tbm surface */ + ipc_buf->t_surface = tbm_surface_internal_create_with_bos(&self->ts_info, ipc_buf->bos, num_bos); + if (!ipc_buf->t_surface) { + GST_ERROR_OBJECT(self, "tbm surface create failed"); + goto _BUFFER_NEW_FAILED; + } + + /* create GstMemory */ + memory = gst_tizen_allocator_alloc_surface(self->allocator, + &self->video_info, + ipc_buf->t_surface, + (gpointer)ipc_buf, + (GDestroyNotify)_tizenipc_src_buffer_finalize); + + if (memory) { + g_mutex_lock(&self->buffer_lock); + self->live_buffer_count++; + GST_DEBUG_OBJECT(self, "gst buffer %p, live count %d", buffer, self->live_buffer_count); + g_mutex_unlock(&self->buffer_lock); + } + } + + if (!memory) { + GST_ERROR_OBJECT(self, "gst memory create failed"); + goto _BUFFER_NEW_FAILED; + } + + /* append memory */ + gst_buffer_append_memory(buffer, memory); + + GST_LOG_OBJECT(self, "new buffer %p", buffer); + + return buffer; + +_BUFFER_NEW_FAILED: + if (ipc_buf) { + for (i = 0 ; i < TBM_SURF_PLANE_MAX ; i++) { + if (ipc_buf->bos[i]) { + GST_WARNING_OBJECT(self, "release imported bo[%d] %p", i, ipc_buf->bos[i]); + tbm_bo_unref(ipc_buf->bos[i]); + ipc_buf->bos[i] = NULL; + } + } + + gst_object_unref(ipc_buf->self); + ipc_buf->self = NULL; + + g_free(ipc_buf); + ipc_buf = NULL; + } + + if (normal_buffer_data) { + free(normal_buffer_data); + normal_buffer_data = NULL; + } + + gst_buffer_unref(buffer); + buffer = NULL; + + return NULL; +} + + static GstFlowReturn gst_tizenipc_src_create(GstPushSrc *psrc, GstBuffer **outbuf) { GstTizenipcSrc *self = NULL; - GstTizenipcSrcBuffer *ipc_buf = NULL; GstTizenipcMessage recv_msg = {0,}; GstTizenipcMessage send_msg = {0,}; - MMVideoBuffer *mm_buf = NULL; GstBuffer *gst_buf = NULL; - GstMemory *gst_memory = NULL; - void *normal_buffer_data = NULL; - int i = 0; int recv_len = 0; int send_len = 0; @@ -650,54 +814,7 @@ again: /* handle message */ if (recv_msg.id == TIZEN_IPC_BUFFER_NEW) { - /* get new buffer from sink */ - if (self->shm_mapped_area == MAP_FAILED) { - GST_ERROR_OBJECT(self, "shared memory is not mapped"); - return GST_FLOW_ERROR; - } - - if (!self->is_normal_format) { - mm_buf = (MMVideoBuffer *)malloc(sizeof(MMVideoBuffer)); - if (mm_buf) { - memcpy(mm_buf, self->shm_mapped_area, sizeof(MMVideoBuffer)); - memcpy(send_msg.tbm_key, self->shm_mapped_area + sizeof(MMVideoBuffer), sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX); - - for (i = 0 ; i < MM_VIDEO_BUFFER_PLANE_MAX ; i++) { - if (send_msg.tbm_key[i] > 0) { - tbm_bo_handle bo_handle = {0, }; - - GST_LOG_OBJECT(self, "received tbm key[%d] %d", i, send_msg.tbm_key[i]); - - /* import bo from tbm key */ - mm_buf->handle.bo[i] = tbm_bo_import(self->bufmgr, send_msg.tbm_key[i]); - if (mm_buf->handle.bo[i] == NULL) { - GST_ERROR_OBJECT(self, "failed to import bo for tbm key %d", send_msg.tbm_key[i]); - break; - } - - /* get user address */ - bo_handle = tbm_bo_get_handle(mm_buf->handle.bo[i], TBM_DEVICE_CPU); - if (bo_handle.ptr == NULL) { - GST_ERROR_OBJECT(self, "failed to get user address for bo %p, key %d", - mm_buf->handle.bo[i], send_msg.tbm_key[i]); - break; - } - mm_buf->data[i] = bo_handle.ptr; - } else { - break; - } - } - } else { - GST_ERROR_OBJECT(self, "failed to alloc MMVideoBuffer"); - } - } else { - normal_buffer_data = (void *)malloc(recv_msg.size); - if (normal_buffer_data) { - memcpy(normal_buffer_data, self->shm_mapped_area, recv_msg.size); - } else { - GST_ERROR_OBJECT(self, "failed to alloc new buffer data - size %d", recv_msg.size); - } - } + gst_buf = _tizenipc_src_buffer_new(self, &recv_msg); /* send received message */ send_msg.id = TIZEN_IPC_BUFFER_RECEIVED; @@ -705,12 +822,10 @@ again: GST_OBJECT_LOCK(self); send_len = send(self->socket_fd, &send_msg, sizeof(GstTizenipcMessage), MSG_NOSIGNAL); + if (send_len != sizeof(GstTizenipcMessage)) + GST_ERROR_OBJECT(self, "failed to send RECEIVED message"); GST_OBJECT_UNLOCK(self); - - if (send_len != sizeof(GstTizenipcMessage)) { - GST_ERROR_OBJECT(self, "failed to send RECEIVED message"); - } } else if (recv_msg.id == TIZEN_IPC_SHM_PATH) { gchar shm_path[32] = {'\0',}; @@ -754,7 +869,7 @@ again: if (self->shm_mapped_area == MAP_FAILED) { GST_ERROR_OBJECT(self, "failed to mmap shared memory for fd %d", self->shm_fd); close(self->shm_fd); - self->shm_fd = -1; + self->shm_fd = INIT_FD; return GST_FLOW_ERROR; } @@ -771,113 +886,91 @@ again: self->is_normal_format = (recv_msg.type == BUFFER_TYPE_NORMAL) ? TRUE : FALSE; GST_INFO_OBJECT(self, "is normal format? %d", self->is_normal_format); goto again; - } else { - GST_WARNING_OBJECT(self, "unknown message : id %d", recv_msg.id); - goto again; - } - } + } else if (recv_msg.id == TIZEN_IPC_BUFFER_CAPS) { + int tbm_ret = 0; + guint32 tbm_format = 0; + GstCaps *caps = NULL; + tbm_surface_h t_surface = NULL; + + if (recv_msg.size <= 0) { + GST_ERROR_OBJECT(self, "invalid caps_string size %d", recv_msg.size); + return GST_FLOW_ERROR; + } - if (mm_buf == NULL && normal_buffer_data == NULL) { - GST_ERROR_OBJECT(self, "All buffers are NULL"); - return GST_FLOW_ERROR; - } + g_free(self->caps_string); + self->caps_string = NULL; - /* make gst buffer with mm_buf */ - gst_buf = gst_buffer_new(); - if (gst_buf == NULL) { - GST_ERROR_OBJECT(self, "failed to create gst buffer"); - goto _CREATE_FAILED; - } + self->caps_string = (gchar *)g_malloc((gsize)recv_msg.size); + if (!self->caps_string) { + GST_ERROR_OBJECT(self, "caps_string allocation failed"); + return GST_FLOW_ERROR; + } - /* default memory */ - if (mm_buf) { - gst_memory = gst_memory_new_wrapped(0, - mm_buf->data[0], mm_buf->size[0], 0, - mm_buf->size[0], NULL, NULL); - } else { - gst_memory = gst_memory_new_wrapped(0, - normal_buffer_data, recv_msg.size, 0, - recv_msg.size, normal_buffer_data, free); - } - if (gst_memory == NULL) { - GST_ERROR_OBJECT(self, "failed to create default gst memory"); - goto _CREATE_FAILED; - } - - gst_buffer_append_memory(gst_buf, gst_memory); - gst_memory = NULL; - - if (mm_buf) { - /* mm_buf memory */ - gst_memory = gst_memory_new_wrapped(0, - mm_buf, sizeof(MMVideoBuffer), 0, - sizeof(MMVideoBuffer), mm_buf, NULL); - if (gst_memory == NULL) { - GST_ERROR_OBJECT(self, "failed to create gst memory for mm_buf"); - goto _CREATE_FAILED; - } + /* get caps string */ + recv_len = recv(self->socket_fd, self->caps_string, recv_msg.size, 0); + if (recv_len != recv_msg.size) { + GST_ERROR_OBJECT(self, "failed to receive message from sink %d : %d", + recv_len, recv_msg.size); + return GST_FLOW_ERROR; + } - gst_buffer_append_memory(gst_buf, gst_memory); - gst_memory = NULL; + GST_INFO_OBJECT(self, "caps string from sink [%s]", self->caps_string); - /* ipc_buf memory */ - ipc_buf = (GstTizenipcSrcBuffer *)malloc(sizeof(GstTizenipcSrcBuffer)); - if (ipc_buf == NULL) { - GST_ERROR_OBJECT(self, "failed to create GstTizenipcsrcBuffer"); - goto _CREATE_FAILED; - } + /* get caps from string */ + caps = gst_caps_from_string(self->caps_string); + if (!caps) { + GST_ERROR_OBJECT(self, "failed to get caps from string"); + return GST_FLOW_ERROR; + } - ipc_buf->self = gst_object_ref(self); - ipc_buf->gst_buf = gst_buf; - ipc_buf->mm_buf = mm_buf; - memcpy(ipc_buf->tbm_key, send_msg.tbm_key, sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX); - - gst_memory = gst_memory_new_wrapped(0, - ipc_buf, sizeof(GstTizenipcSrcBuffer), 0, - sizeof(GstTizenipcSrcBuffer), ipc_buf, - (GDestroyNotify)gst_tizenipc_src_buffer_finalize); - if (gst_memory == NULL) { - GST_ERROR_OBJECT(self, "failed to create gst memory for ipc_buf"); - goto _CREATE_FAILED; - } + /* get video info from caps */ + if (!gst_video_info_from_caps(&self->video_info, caps)) { + GST_ERROR_OBJECT(self, "get video info failed (caps[%s])", self->caps_string); + return GST_FLOW_ERROR; + } - gst_buffer_append_memory(gst_buf, gst_memory); - gst_memory = NULL; + /* get tbm format */ + if (!_tizenipc_get_tbm_format(GST_VIDEO_INFO_FORMAT(&self->video_info), &tbm_format)) { + GST_ERROR_OBJECT(self, "get tbm format failed - video format %d", GST_VIDEO_INFO_FORMAT(&self->video_info)); + return GST_FLOW_ERROR; + } - g_mutex_lock(&self->buffer_lock); - self->live_buffer_count++; - GST_DEBUG_OBJECT(self, "gst buffer %p, live count %d", gst_buf, self->live_buffer_count); - g_mutex_unlock(&self->buffer_lock); - } else { - GST_DEBUG_OBJECT(self, "normal buffer create done - size %d", recv_msg.size); - } + /* get tbm surface info */ + t_surface = tbm_surface_create(GST_VIDEO_INFO_WIDTH(&self->video_info), + GST_VIDEO_INFO_HEIGHT(&self->video_info), tbm_format); + if (!t_surface) { + GST_ERROR_OBJECT(self, "tbm surface failed"); + return GST_FLOW_ERROR; + } - *outbuf = gst_buf; + memset(&self->ts_info, 0x0, sizeof(tbm_surface_info_s)); - return GST_FLOW_OK; + tbm_ret = tbm_surface_get_info(t_surface, &self->ts_info); -_CREATE_FAILED: - if (ipc_buf) { - free(ipc_buf); - ipc_buf = NULL; - } + tbm_surface_destroy(t_surface); + t_surface = NULL; - if (mm_buf) { - free(mm_buf); - mm_buf = NULL; - } + if (tbm_ret != TBM_SURFACE_ERROR_NONE) { + GST_ERROR_OBJECT(self, "tbm_surface_get_info failed. 0x%x", tbm_ret); + return GST_FLOW_ERROR; + } - if (gst_buf) { - gst_buffer_unref(gst_buf); - gst_buf = NULL; + GST_INFO_OBJECT(self, "video/tbm surface info done."); + goto again; + } else { + GST_WARNING_OBJECT(self, "unknown message : id %d", recv_msg.id); + goto again; + } } - if (normal_buffer_data) { - free(normal_buffer_data); - normal_buffer_data = NULL; + if (!gst_buf) { + GST_ERROR_OBJECT(self, "no buffer"); + return GST_FLOW_ERROR; } - return GST_FLOW_ERROR; + *outbuf = gst_buf; + + return GST_FLOW_OK; } diff --git a/tizenipc/src/gsttizenipcsrc.h b/tizenipc/src/gsttizenipcsrc.h index 80c976c..bdbfff2 100644 --- a/tizenipc/src/gsttizenipcsrc.h +++ b/tizenipc/src/gsttizenipcsrc.h @@ -25,8 +25,9 @@ #include #include #include -#include -#include +#include +#include +#include "gsttizenipc.h" G_BEGIN_DECLS @@ -37,17 +38,19 @@ G_BEGIN_DECLS #define GST_IS_TIZENIPC_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_TIZENIPC_SRC)) #define GST_TIZENIPC_SRC_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS((inst), GST_TYPE_TIZENIPC_SRC, GstTizenipcSrcClass)) -#define GST_TIZENIPC_BUFFER_MAX 30 - typedef struct _GstTizenipcSrc GstTizenipcSrc; typedef struct _GstTizenipcSrcClass GstTizenipcSrcClass; typedef struct _GstTizenipcSrcBuffer GstTizenipcSrcBuffer; -typedef struct _GstTizenipcMessage GstTizenipcMessage; struct _GstTizenipcSrc { GstPushSrc parent; + /* buffer */ gboolean is_normal_format; + gchar *caps_string; + GstAllocator *allocator; + GstVideoInfo video_info; + tbm_surface_info_s ts_info; /* ipc */ int socket_fd; @@ -75,34 +78,10 @@ struct _GstTizenipcSrcClass { struct _GstTizenipcSrcBuffer { GstBuffer *gst_buf; - MMVideoBuffer *mm_buf; - int tbm_key[MM_VIDEO_BUFFER_PLANE_MAX]; GstTizenipcSrc *self; -}; - - -typedef enum { - TIZEN_IPC_SHM_PATH = 0, - TIZEN_IPC_SHM_SIZE, - TIZEN_IPC_BUFFER_TYPE, - TIZEN_IPC_BUFFER_NEW, - TIZEN_IPC_BUFFER_RECEIVED, - TIZEN_IPC_BUFFER_RELEASE, - TIZEN_IPC_CLOSE_CLIENT -} TizenIPCID; - -typedef enum { - BUFFER_TYPE_NORMAL = 0, - BUFFER_TYPE_ZERO_COPY -} BufferType; - -struct _GstTizenipcMessage { - TizenIPCID id; - union { - BufferType type; - int size; - int tbm_key[MM_VIDEO_BUFFER_PLANE_MAX]; - }; + tbm_bo bos[TBM_SURF_PLANE_MAX]; + int tbm_key[TBM_SURF_PLANE_MAX]; + tbm_surface_h t_surface; }; GType -- 2.7.4 From 50411b891f4d0a19c4fc7a44680d631091e7e75a Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 4 Oct 2018 13:25:49 +0900 Subject: [PATCH 16/16] remove build warning Change-Id: Ia859e1074778e493e5bfa1b8680f33360430c5c2 --- tizenwlsink/src/tizen-wlshmallocator.c | 1 + video360/src/gstvideo360.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tizenwlsink/src/tizen-wlshmallocator.c b/tizenwlsink/src/tizen-wlshmallocator.c index 84b9ef2..ac6fce4 100644 --- a/tizenwlsink/src/tizen-wlshmallocator.c +++ b/tizenwlsink/src/tizen-wlshmallocator.c @@ -25,6 +25,7 @@ #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT #include "tizen-wlvideoformat.h" #include +#include #endif #include #include diff --git a/video360/src/gstvideo360.c b/video360/src/gstvideo360.c index 3151c71..dea5920 100644 --- a/video360/src/gstvideo360.c +++ b/video360/src/gstvideo360.c @@ -877,7 +877,7 @@ gst_video360_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf) gst_memory_map (in_mem, &in_info, GST_MAP_READ); } - out_info.data = (tbm_surface_h) surface; + out_info.data = (guint8 *) surface; #else out_mem = gst_buffer_peek_memory (out_buf, 0); gst_memory_map (in_mem, &in_info, GST_MAP_READ); -- 2.7.4