From 65b8b6444f541ceb12c57b995656e3db011c5721 Mon Sep 17 00:00:00 2001 From: Hyunil Park Date: Fri, 26 Jun 2015 12:47:21 +0900 Subject: [PATCH] 1. Wayalndsink : 1. Add Zero copy logic for H/W codec 2. Add MMVideoBuffer Type 2. remove Cairo buildrequire. Change-Id: Ib7ddaed67f34feb6d7952369d96d6c77d19e4e3a Signed-off-by: Hyunil Park --- configure.ac | 3 + ext/wayland/Makefile.am | 2 +- ext/wayland/gstwaylandsink.c | 139 ++++++++++++++++++- ext/wayland/gstwaylandsink.h | 4 +- ext/wayland/tizen-wlvideoformat.h | 10 +- ext/wayland/waylandpool.c | 276 ++++++++++++++++++++++++-------------- ext/wayland/waylandpool.h | 9 +- ext/wayland/wldisplay.c | 22 ++- ext/wayland/wldisplay.h | 15 ++- ext/wayland/wlvideoformat.h | 8 +- ext/wayland/wlwindow.c | 3 +- packaging/gst-plugins-bad.spec | 5 +- 12 files changed, 370 insertions(+), 126 deletions(-) diff --git a/configure.ac b/configure.ac index dc5c74a..4b692bc 100644 --- a/configure.ac +++ b/configure.ac @@ -2009,6 +2009,9 @@ PKG_CHECK_MODULES(TBM, libtbm) AC_SUBST(TBM_CFLAGS) AC_SUBST(TBM_LIBS) +PKG_CHECK_MODULES(MMCOMMON, mm-common) +AC_SUBST(MMCOMMON_CFLAGS) + dnl **** WebP **** translit(dnm, m, l) AM_CONDITIONAL(USE_WEBP, true) AG_GST_CHECK_FEATURE(WEBP, [WebP], webp , [ diff --git a/ext/wayland/Makefile.am b/ext/wayland/Makefile.am index 268f0bd..39dc1bd 100644 --- a/ext/wayland/Makefile.am +++ b/ext/wayland/Makefile.am @@ -12,7 +12,7 @@ libgstwaylandsink_la_SOURCES = \ protocol/tizen-bufferpoolprotocol.c libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ - $(WAYLAND_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS) $(DRM_CFLAGS) $(TBM_CFLAGS) + $(WAYLAND_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS) $(DRM_CFLAGS) $(TBM_CFLAGS) $(MMCOMMON_CFLAGS) libgstwaylandsink_la_LIBADD = \ $(GST_PLUGINS_BASE_LIBS) \ -lgstvideo-$(GST_API_VERSION) \ diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index 36c66ff..b0d98ef 100755 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -43,6 +43,7 @@ #include "gstwaylandsink.h" #ifdef GST_WLSINK_ENHANCEMENT +#include #include "tizen-wlvideoformat.h" #else #include "wlvideoformat.h" @@ -75,6 +76,9 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, " "RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, " +#ifdef GST_WLSINK_ENHANCEMENT + "SN12, ST12, " +#endif "YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }")) ); @@ -505,6 +509,9 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) /* extract info from caps */ if (!gst_video_info_from_caps (&info, caps)) goto invalid_format; +#ifdef GST_WLSINK_ENHANCEMENT + sink->caps = gst_caps_copy (caps); +#endif format = gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT (&info)); if ((gint) format == -1) @@ -520,6 +527,32 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (i >= formats->len) goto unsupported_format; +#ifdef GST_WLSINK_ENHANCEMENT + if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_SN12 || + GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ST12) { + sink->display->is_special_format = TRUE; + } else { + sink->display->is_special_format = FALSE; + + /* create a new pool for the new configuration */ + newpool = gst_wayland_buffer_pool_new (sink->display); + if (!newpool) + goto pool_failed; + + structure = gst_buffer_pool_get_config (newpool); + gst_buffer_pool_config_set_params (structure, caps, info.size, 2, 0); + gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms); + if (!gst_buffer_pool_set_config (newpool, structure)) + goto config_failed; + + gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); + gst_object_unref (newpool); + + } + /* store the video info */ + sink->video_info = info; + sink->video_info_changed = TRUE; +#else /* create a new pool for the new configuration */ newpool = gst_wayland_buffer_pool_new (sink->display); if (!newpool) @@ -537,7 +570,7 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); gst_object_unref (newpool); - +#endif return TRUE; invalid_format: @@ -577,6 +610,9 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) guint size; gboolean need_pool; + if (sink->display->is_special_format == TRUE) + return TRUE; + gst_query_parse_allocation (query, &caps, &need_pool); if (caps == NULL) @@ -692,6 +728,8 @@ render_last_buffer (GstWaylandSink * sink) * releases it. The release is handled internally in the pool */ gst_wayland_compositor_acquire_buffer (meta->pool, sink->last_buffer); + GST_DEBUG ("wl_surface_attach wl_buffer %p", meta->wbuffer); + wl_surface_attach (surface, meta->wbuffer, 0, 0); wl_surface_damage (surface, 0, 0, sink->window->surface_width, sink->window->surface_height); @@ -710,6 +748,12 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstWlMeta *meta; GstFlowReturn ret = GST_FLOW_OK; +#ifdef GST_WLSINK_ENHANCEMENT + GstBufferPool *newpool; + GstStructure *structure; + static GstAllocationParams params = { 0, 0, 0, 15, }; +#endif + g_mutex_lock (&sink->render_lock); GST_LOG_OBJECT (sink, "render buffer %p", buffer); @@ -766,6 +810,96 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstMapInfo src; GST_LOG_OBJECT (sink, "buffer %p not from our pool, copying", buffer); +#ifdef GST_WLSINK_ENHANCEMENT + if (sink->display->is_special_format == TRUE) { + /*in case of SN12 or ST12 video format */ + GstMemory *mem; + GstMapInfo mem_info = GST_MAP_INFO_INIT; + MMVideoBuffer *mm_video_buf = NULL; + + 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_OBJECT (sink, "mm_video_buf is NULL. Skip rendering"); + return ret; + } + /* assign mm_video_buf info */ + if (mm_video_buf->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { + GST_DEBUG_OBJECT (sink, "TBM bo %p %p %p", mm_video_buf->handle.bo[0], + mm_video_buf->handle.bo[1], mm_video_buf->handle.bo[2]); + + sink->display->native_video_size = 0; + + for (int i = 0; i < NV_BUF_PLANE_NUM; i++) { + if (mm_video_buf->handle.bo[i] != NULL) { + sink->display->bo[i] = mm_video_buf->handle.bo[i]; + } else { + sink->display->bo[i] = 0; + } + sink->display->plane_size[i] = mm_video_buf->size[i]; + sink->display->stride_width[i] = mm_video_buf->stride_width[i]; + sink->display->stride_height[i] = mm_video_buf->stride_height[i]; + sink->display->native_video_size += sink->display->plane_size[i]; + } + } else { + GST_ERROR_OBJECT (sink, "Buffer type is not TBM"); + return ret; + } + + if (!sink->pool) { + + /* create a new pool for the new configuration */ + newpool = gst_wayland_buffer_pool_new (sink->display); + if (!newpool) { + GST_DEBUG_OBJECT (sink, "Failed to create new pool"); + return FALSE; + } + structure = gst_buffer_pool_get_config (newpool); + gst_buffer_pool_config_set_params (structure, sink->caps, + sink->video_info.size, 2, 0); + gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms); + if (!gst_buffer_pool_set_config (newpool, structure)) { + GST_DEBUG_OBJECT (bsink, "failed setting config"); + gst_object_unref (newpool); + return FALSE; + } + + gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); + gst_object_unref (newpool); + + } + + if (!gst_buffer_pool_set_active (sink->pool, TRUE)) + goto activate_failed; + + ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL); + if (ret != GST_FLOW_OK) + goto no_buffer; + + + + } else { + /*in case of normal video format and pool is not our pool */ + + if (!sink->pool) + goto no_pool; + + if (!gst_buffer_pool_set_active (sink->pool, TRUE)) + goto activate_failed; + + ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL); + if (ret != GST_FLOW_OK) + goto no_buffer; + + gst_buffer_map (buffer, &src, GST_MAP_READ); + gst_buffer_fill (to_render, 0, src.data, src.size); + gst_buffer_unmap (buffer, &src); + } + +#else if (!sink->pool) goto no_pool; @@ -779,6 +913,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) gst_buffer_map (buffer, &src, GST_MAP_READ); gst_buffer_fill (to_render, 0, src.data, src.size); gst_buffer_unmap (buffer, &src); +#endif } gst_buffer_replace (&sink->last_buffer, to_render); @@ -865,7 +1000,7 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle) "display handle from your application with GstContext")); } else { sink->window = gst_wl_window_new_in_surface (sink->display, surface); - GST_ERROR ("sink->window %p", sink->window); + GST_DEBUG ("sink->window %p", sink->window); } } else { GST_ERROR_OBJECT (sink, "Failed to find display handle, " diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 6604a38..2c37f0b 100755 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -64,7 +64,9 @@ struct _GstWaylandSink GstVideoInfo video_info; gchar *display_name; - +#ifdef GST_WLSINK_ENHANCEMENT + GstCaps *caps; +#endif gboolean redraw_pending; GMutex render_lock; GstBuffer *last_buffer; diff --git a/ext/wayland/tizen-wlvideoformat.h b/ext/wayland/tizen-wlvideoformat.h index ab259e1..f6fc11b 100755 --- a/ext/wayland/tizen-wlvideoformat.h +++ b/ext/wayland/tizen-wlvideoformat.h @@ -31,11 +31,13 @@ #include "protocol/tizen-bufferpoolprotocol.h" G_BEGIN_DECLS + enum tizen_buffer_pool_format +gst_video_format_to_wayland_format (GstVideoFormat format); +GstVideoFormat gst_wayland_format_to_video_format (enum tizen_buffer_pool_format + wl_format); -enum tizen_buffer_pool_format gst_video_format_to_wayland_format (GstVideoFormat format); -GstVideoFormat gst_wayland_format_to_video_format (enum tizen_buffer_pool_format wl_format); - -const gchar *gst_wayland_format_to_string (enum tizen_buffer_pool_format wl_format); +const gchar *gst_wayland_format_to_string (enum tizen_buffer_pool_format + wl_format); G_END_DECLS #endif diff --git a/ext/wayland/waylandpool.c b/ext/wayland/waylandpool.c index b89551c..76496a6 100755 --- a/ext/wayland/waylandpool.c +++ b/ext/wayland/waylandpool.c @@ -34,6 +34,13 @@ #include #include #include +#ifdef GST_WLSINK_ENHANCEMENT +#define DUMP_BUFFER +#ifdef DUMP_BUFFER +int dump_cnt = 0; +int _write_rawdata (const char *file, const void *data, unsigned int size); +#endif +#endif GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug); #define GST_CAT_DEFAULT gstwayland_debug @@ -87,6 +94,7 @@ static GstFlowReturn gst_wayland_buffer_pool_alloc (GstBufferPool * pool, #ifdef GST_WLSINK_ENHANCEMENT /*tizen buffer pool*/ +static void gst_wayland_tizen_buffer_pool_finalize (GObject * object); static gboolean gst_wayland_tizen_buffer_pool_start (GstBufferPool * pool); static gboolean gst_wayland_tizen_buffer_pool_stop (GstBufferPool * pool); static GstFlowReturn gst_wayland_tizen_buffer_pool_alloc (GstBufferPool * pool, @@ -106,14 +114,14 @@ gst_wayland_buffer_pool_class_init (GstWaylandBufferPoolClass * klass) GObjectClass *gobject_class = (GObjectClass *) klass; GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass; - gobject_class->finalize = gst_wayland_buffer_pool_finalize; - gstbufferpool_class->set_config = gst_wayland_buffer_pool_set_config; #ifdef GST_WLSINK_ENHANCEMENT + gobject_class->finalize = gst_wayland_tizen_buffer_pool_finalize; gstbufferpool_class->start = gst_wayland_tizen_buffer_pool_start; gstbufferpool_class->stop = gst_wayland_tizen_buffer_pool_stop; gstbufferpool_class->alloc_buffer = gst_wayland_tizen_buffer_pool_alloc; #else + gobject_class->finalize = gst_wayland_buffer_pool_finalize; gstbufferpool_class->start = gst_wayland_buffer_pool_start; gstbufferpool_class->stop = gst_wayland_buffer_pool_stop; gstbufferpool_class->alloc_buffer = gst_wayland_buffer_pool_alloc; @@ -205,6 +213,8 @@ unref_used_buffers (gpointer key, gpointer value, gpointer data) GstWlMeta *meta = gst_buffer_get_wl_meta (buffer); GList **to_unref = data; + g_return_if_fail (meta != NULL); + if (meta->used_by_compositor) { meta->used_by_compositor = FALSE; *to_unref = g_list_prepend (*to_unref, buffer); @@ -430,78 +440,52 @@ gst_wayland_buffer_pool_new (GstWlDisplay * display) } #ifdef GST_WLSINK_ENHANCEMENT -static void -tizen_buffer_release (void *data, struct wl_buffer *wl_buffer) -{ - FUNCTION_ENTER (); - GstWaylandBufferPool *self = data; - GstBuffer *buffer; - GstWlMeta *meta; - - g_mutex_lock (&self->buffers_map_mutex); - buffer = g_hash_table_lookup (self->buffers_map, wl_buffer); - - GST_LOG_OBJECT (self, "wl_buffer::release (GstBuffer: %p)", buffer); - - if (buffer) { - meta = gst_buffer_get_wl_meta (buffer); - if (meta->used_by_compositor) { - meta->used_by_compositor = FALSE; - /* unlock before unref because stop() may be called from here */ - g_mutex_unlock (&self->buffers_map_mutex); - gst_buffer_unref (buffer); - return; - } - } - g_mutex_unlock (&self->buffers_map_mutex); -} - -static const struct wl_buffer_listener tizen_buffer_listener = { - tizen_buffer_release -}; - - -gboolean +static gboolean gst_wayland_tizen_buffer_pool_start (GstBufferPool * pool) { FUNCTION_ENTER (); GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool); - GST_DEBUG_OBJECT (self, "Initializing wayland buffer pool"); + GST_DEBUG_OBJECT (self, "Initializing tizen buffer pool"); tbm_bo_handle vitual_addr; guint size = 0; - size = GST_VIDEO_INFO_SIZE (&self->info) * 15; - - self->display->tbm_bufmgr = tbm_bufmgr_init (self->display->drm_fd); - g_return_if_fail (self->display->tbm_bufmgr != NULL); - - self->display->tbm_bo = - tbm_bo_alloc (self->display->tbm_bufmgr, size, TBM_BO_DEFAULT); - if (!self->display->tbm_bo) { - GST_ERROR_OBJECT (pool, "alloc tbm bo(size:%d) failed: %s", size, - strerror (errno)); - tbm_bufmgr_deinit (self->display->tbm_bufmgr); - self->display->tbm_bufmgr = NULL; - return FALSE; - } + if (self->display->is_special_format == TRUE) { + /*in case of SN12 or ST12 video format */ + size = self->display->native_video_size * 15; + vitual_addr.ptr = NULL; + + } else { + /*in case of normal video format */ + size = GST_VIDEO_INFO_SIZE (&self->info) * 15; + + self->display->tbm_bufmgr = tbm_bufmgr_init (self->display->drm_fd); + g_return_if_fail (self->display->tbm_bufmgr != NULL); + + self->display->tbm_bo = + tbm_bo_alloc (self->display->tbm_bufmgr, size, TBM_BO_DEFAULT); + if (!self->display->tbm_bo) { + GST_ERROR_OBJECT (pool, "alloc tbm bo(size:%d) failed: %s", size, + strerror (errno)); + tbm_bufmgr_deinit (self->display->tbm_bufmgr); + self->display->tbm_bufmgr = NULL; + return FALSE; + } - vitual_addr = tbm_bo_get_handle (self->display->tbm_bo, TBM_DEVICE_CPU); - if (!vitual_addr.ptr) { - GST_ERROR_OBJECT (pool, "get tbm bo handle failed: %s", strerror (errno)); - tbm_bo_unref (self->display->tbm_bo); - tbm_bufmgr_deinit (self->display->tbm_bufmgr); - self->display->tbm_bo = NULL; - self->display->tbm_bufmgr = NULL; - return FALSE; + vitual_addr = tbm_bo_get_handle (self->display->tbm_bo, TBM_DEVICE_CPU); + if (!vitual_addr.ptr) { + GST_ERROR_OBJECT (pool, "get tbm bo handle failed: %s", strerror (errno)); + tbm_bo_unref (self->display->tbm_bo); + tbm_bufmgr_deinit (self->display->tbm_bufmgr); + self->display->tbm_bo = NULL; + self->display->tbm_bufmgr = NULL; + return FALSE; + } } - if (vitual_addr.ptr) - memset (vitual_addr.ptr, 0x0, size); - self->data = vitual_addr.ptr; self->size = size; self->used = 0; @@ -509,23 +493,15 @@ gst_wayland_tizen_buffer_pool_start (GstBufferPool * pool) return GST_BUFFER_POOL_CLASS (parent_class)->start (pool); } -gboolean +static gboolean gst_wayland_tizen_buffer_pool_stop (GstBufferPool * pool) { FUNCTION_ENTER (); GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool); - GST_DEBUG_OBJECT (self, "Stopping wayland buffer pool"); - - if (self->display->tbm_bo) - tbm_bo_unref (self->display->tbm_bo); - if (self->display->tbm_bufmgr) - tbm_bufmgr_deinit (self->display->tbm_bufmgr); - self->display->tbm_bo = NULL; - self->display->tbm_bufmgr = NULL; + GST_DEBUG_OBJECT (self, "Stopping tizen buffer pool"); - self->wl_pool = NULL; self->size = 0; self->used = 0; @@ -538,7 +514,7 @@ gst_wayland_tizen_buffer_pool_stop (GstBufferPool * pool) return GST_BUFFER_POOL_CLASS (parent_class)->stop (pool); } -GstFlowReturn +static GstFlowReturn gst_wayland_tizen_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { @@ -546,54 +522,120 @@ gst_wayland_tizen_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool); - gint width, height, stride; + gint width, height; gsize size; enum tizen_buffer_pool_format format; - gint offset; + gint data_offset; void *data; GstWlMeta *meta; + tbm_bo_handle vitual_addr; - width = GST_VIDEO_INFO_WIDTH (&self->info); - height = GST_VIDEO_INFO_HEIGHT (&self->info); - stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0); - size = GST_VIDEO_INFO_SIZE (&self->info); - format = - gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT (&self->info)); + if (self->display->is_special_format == TRUE) { + /*in case of SN12 or ST12 video format */ + unsigned int name[NV_BUF_PLANE_NUM]; + unsigned int offset[NV_BUF_PLANE_NUM] = { 0, }; + unsigned int stride[NV_BUF_PLANE_NUM] = { 0, }; + width = GST_VIDEO_INFO_WIDTH (&self->info); + height = GST_VIDEO_INFO_HEIGHT (&self->info); + size = self->display->native_video_size; - GST_DEBUG_OBJECT (self, "Allocating buffer of size %" G_GSSIZE_FORMAT - " (%d x %d, stride %d), format %s", size, width, height, stride, - gst_wayland_format_to_string (format)); - /* try to reserve another memory block from the shm pool */ - if (self->used + size > self->size) - goto no_buffer; + format = + gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT + (&self->info)); - offset = self->used; - self->used += size; - data = ((gchar *) self->data) + offset; + vitual_addr = tbm_bo_get_handle (self->display->bo[0], TBM_DEVICE_CPU); + if (!vitual_addr.ptr) { + GST_ERROR_OBJECT (pool, "get tbm bo handle failed: %s", strerror (errno)); + return FALSE; + } + self->data = vitual_addr.ptr; + data = ((gchar *) self->data); +#ifdef DUMP_BUFFER + int ret; + char file_name[128]; + if (dump_cnt < 10) { + sprintf (file_name, "/root/WLSINK_OUT_DUMP_%2.2d.dump", dump_cnt++); + ret = _write_rawdata (file_name, vitual_addr.ptr,size); + if (ret) { + GST_ERROR_OBJECT (pool, "_write_rawdata() failed"); + } + } +#endif + /* create buffer and its metadata object */ + *buffer = gst_buffer_new (); + meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL); + meta->pool = self; + GST_DEBUG ("TBM bo %p %p %p", self->display->bo[0], + self->display->bo[1], 0); + for (int i = 0; i < NV_BUF_PLANE_NUM; i++) { + if (self->display->bo[i] != NULL) { + name[i] = tbm_bo_export (self->display->bo[i]); + offset[i] = 0; + } else { + name[i] = 0; + if (i > 0) { + offset[i] = offset[i - 1] + self->display->plane_size[i - 1]; + } + } + stride[i] = self->display->stride_width[i]; + } - /* create buffer and its metadata object */ - *buffer = gst_buffer_new (); - meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL); - meta->pool = self; + meta->wbuffer = + tizen_buffer_pool_create_planar_buffer (self->display-> + tizen_buffer_pool, width, height, format, name[0], offset[0], stride[0], + name[1], offset[1], stride[1], 0, 0, 0); + meta->used_by_compositor = FALSE; - meta->wbuffer = - tizen_buffer_pool_create_buffer (self->display->tizen_buffer_pool, - tbm_bo_export (self->display->tbm_bo), width, height, stride, format); - meta->used_by_compositor = FALSE; + GST_DEBUG ("tizen_buffer_pool_create_planar_buffer create wl_buffer %p", + meta->wbuffer); + } else { + int stride; + + /*in case of normal video format */ + width = GST_VIDEO_INFO_WIDTH (&self->info); + height = GST_VIDEO_INFO_HEIGHT (&self->info); + stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0); + size = GST_VIDEO_INFO_SIZE (&self->info); + format = + gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT + (&self->info)); + + GST_DEBUG_OBJECT (self, "Allocating buffer of size %" G_GSSIZE_FORMAT + " (%d x %d, stride %d), format %s", size, width, height, stride, + gst_wayland_format_to_string (format)); + + /* try to reserve another memory block from the shm pool */ + if (self->used + size > self->size) + goto no_buffer; + + data_offset = self->used; + self->used += size; + + data = ((gchar *) self->data) + data_offset; + + /* create buffer and its metadata object */ + *buffer = gst_buffer_new (); + meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL); + meta->pool = self; + + meta->wbuffer = + tizen_buffer_pool_create_buffer (self->display->tizen_buffer_pool, + tbm_bo_export (self->display->tbm_bo), width, height, stride, format); + meta->used_by_compositor = FALSE; + } /* configure listening to wl_buffer.release */ g_mutex_lock (&self->buffers_map_mutex); g_hash_table_insert (self->buffers_map, meta->wbuffer, *buffer); g_mutex_unlock (&self->buffers_map_mutex); - wl_buffer_add_listener (meta->wbuffer, &tizen_buffer_listener, self); + wl_buffer_add_listener (meta->wbuffer, &buffer_listener, self); /* add the allocated memory on the GstBuffer */ gst_buffer_append_memory (*buffer, gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data, size, 0, size, NULL, NULL)); - return GST_FLOW_OK; /* ERROR */ @@ -603,4 +645,42 @@ no_buffer: return GST_FLOW_ERROR; } } + +static void +gst_wayland_tizen_buffer_pool_finalize (GObject * object) +{ + FUNCTION_ENTER (); + + GstWaylandBufferPool *pool = GST_WAYLAND_BUFFER_POOL_CAST (object); + + if (pool->display->tizen_buffer_pool) { + gst_wayland_tizen_buffer_pool_stop (GST_BUFFER_POOL (pool)); + } else { + /*already stop*/ + return; + } + g_mutex_clear (&pool->buffers_map_mutex); + g_hash_table_unref (pool->buffers_map); + + g_object_unref (pool->display); + + G_OBJECT_CLASS (gst_wayland_buffer_pool_parent_class)->finalize (object); +} + +#endif +#ifdef DUMP_BUFFER +int +_write_rawdata (const char *file, const void *data, unsigned int size) +{ + FILE *fp; + + fp = fopen (file, "wb"); + if (fp == NULL) + return -1; + + fwrite ((char *) data, sizeof (char), size, fp); + fclose (fp); + + return 0; +} #endif diff --git a/ext/wayland/waylandpool.h b/ext/wayland/waylandpool.h index acd06f8..ef198f8 100755 --- a/ext/wayland/waylandpool.h +++ b/ext/wayland/waylandpool.h @@ -31,18 +31,15 @@ #endif G_BEGIN_DECLS - #define GST_TYPE_WAYLAND_BUFFER_POOL (gst_wayland_buffer_pool_get_type()) #define GST_IS_WAYLAND_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WAYLAND_BUFFER_POOL)) #define GST_WAYLAND_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WAYLAND_BUFFER_POOL, GstWaylandBufferPool)) #define GST_WAYLAND_BUFFER_POOL_CAST(obj) ((GstWaylandBufferPool*)(obj)) - #if 1 #define FUNCTION_ENTER() GST_INFO("") #else #define FUNCTION_ENTER() #endif - typedef struct _GstWaylandBufferPool GstWaylandBufferPool; typedef struct _GstWaylandBufferPoolClass GstWaylandBufferPoolClass; @@ -52,12 +49,13 @@ typedef struct _GstWlMeta GstWlMeta; GType gst_wl_meta_api_get_type (void); #define GST_WL_META_API_TYPE (gst_wl_meta_api_get_type()) -const GstMetaInfo * gst_wl_meta_get_info (void); +const GstMetaInfo *gst_wl_meta_get_info (void); #define GST_WL_META_INFO (gst_wl_meta_get_info()) #define gst_buffer_get_wl_meta(b) ((GstWlMeta*)gst_buffer_get_meta((b),GST_WL_META_API_TYPE)) -struct _GstWlMeta { +struct _GstWlMeta +{ GstMeta meta; GstWaylandBufferPool *pool; @@ -99,5 +97,4 @@ void gst_wayland_compositor_acquire_buffer (GstWaylandBufferPool * self, void gst_wayland_compositor_release_all_buffers (GstWaylandBufferPool * self); G_END_DECLS - #endif /*__GST_WAYLAND_BUFFER_POOL_H__*/ diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c index a3057c9..35b1f0a 100755 --- a/ext/wayland/wldisplay.c +++ b/ext/wayland/wldisplay.c @@ -150,10 +150,25 @@ gst_wl_display_finalize (GObject * gobject) if (self->thread) g_thread_join (self->thread); +#ifdef GST_WLSINK_ENHANCEMENT + if (self->is_special_format == FALSE) { /*need to remove */ + /*in case of normal video format */ + if (self->tbm_bo) + tbm_bo_unref (self->tbm_bo); + if (self->tbm_bufmgr) + tbm_bufmgr_deinit (self->tbm_bufmgr); + self->tbm_bo = NULL; + self->tbm_bufmgr = NULL; + } +#endif + g_array_unref (self->formats); gst_poll_free (self->wl_fd_poll); + +#ifndef GST_WLSINK_ENHANCEMENT if (self->shm) wl_shm_destroy (self->shm); +#endif if (self->shell) wl_shell_destroy (self->shell); @@ -177,8 +192,10 @@ gst_wl_display_finalize (GObject * gobject) #ifdef GST_WLSINK_ENHANCEMENT if (self->tizen_subsurface) tizen_subsurface_destroy (self->tizen_subsurface); - if (self->tizen_buffer_pool) + if (self->tizen_buffer_pool) { tizen_buffer_pool_destroy (self->tizen_buffer_pool); + self->tizen_buffer_pool = NULL; + } if (self->device_name) free (self->device_name); if (self->drm_fd >= 0) @@ -274,7 +291,8 @@ registry_handle_global (void *data, struct wl_registry *registry, self->name = id; self->drm_fd = -1; - tizen_buffer_pool_add_listener (self->tizen_buffer_pool, &tz_buffer_pool_listener, self); + tizen_buffer_pool_add_listener (self->tizen_buffer_pool, + &tz_buffer_pool_listener, self); /* make sure all tizen_buffer_pool's events are handled */ wl_display_roundtrip (self->display); diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h index 9b8d669..72625cd 100755 --- a/ext/wayland/wldisplay.h +++ b/ext/wayland/wldisplay.h @@ -28,6 +28,7 @@ #include #include "protocol/tizen-subsurfaceprotocol.h" #include "protocol/tizen-bufferpoolprotocol.h" +#define NV_BUF_PLANE_NUM 2 /*SN12 or ST12 has 2 plane */ #endif G_BEGIN_DECLS #define GST_TYPE_WL_DISPLAY (gst_wl_display_get_type ()) @@ -67,21 +68,25 @@ struct _GstWlDisplay GstPoll *wl_fd_poll; #ifdef GST_WLSINK_ENHANCEMENT - /*video output layer*/ + /*video output layer */ struct tizen_subsurface *tizen_subsurface; - /*zero copy*/ + /*tizen buffer pool */ struct tizen_buffer_pool *tizen_buffer_pool; uint32_t name; int has_capability; - - /* drm for zero copy */ char *device_name; int drm_fd; int authenticated; - /* tbm for zero copy*/ tbm_bufmgr tbm_bufmgr; tbm_bo tbm_bo; + + gboolean is_special_format; /*SN12, ST12 */ + void *bo[NV_BUF_PLANE_NUM]; + int plane_size[NV_BUF_PLANE_NUM]; + int stride_width[NV_BUF_PLANE_NUM]; + int stride_height[NV_BUF_PLANE_NUM]; + int native_video_size; #endif }; diff --git a/ext/wayland/wlvideoformat.h b/ext/wayland/wlvideoformat.h index b0aba5b..c03525b 100755 --- a/ext/wayland/wlvideoformat.h +++ b/ext/wayland/wlvideoformat.h @@ -30,13 +30,13 @@ #ifndef GST_WLSINK_ENHANCEMENT G_BEGIN_DECLS - -enum wl_shm_format gst_video_format_to_wayland_format (GstVideoFormat format); -GstVideoFormat gst_wayland_format_to_video_format (enum wl_shm_format wl_format); + enum wl_shm_format gst_video_format_to_wayland_format (GstVideoFormat + format); +GstVideoFormat gst_wayland_format_to_video_format (enum wl_shm_format + wl_format); const gchar *gst_wayland_format_to_string (enum wl_shm_format wl_format); G_END_DECLS - #endif #endif diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index dab8786..fe23a63 100755 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -176,7 +176,8 @@ gst_wl_window_new_in_surface (GstWlDisplay * display, wl_subsurface_set_desync (window->subsurface); #ifdef GST_WLSINK_ENHANCEMENT if (display->tizen_subsurface) - tizen_subsurface_place_below_parent (display->tizen_subsurface, window->subsurface); + tizen_subsurface_place_below_parent (display->tizen_subsurface, + window->subsurface); wl_surface_commit (parent); #endif diff --git a/packaging/gst-plugins-bad.spec b/packaging/gst-plugins-bad.spec index 250578e..7b38890 100644 --- a/packaging/gst-plugins-bad.spec +++ b/packaging/gst-plugins-bad.spec @@ -4,7 +4,7 @@ Name: gst-plugins-bad Version: 1.4.1 -Release: 3 +Release: 4 Summary: GStreamer Streaming-Media Framework Plug-Ins License: GPL-2.0+ and LGPL-2.1+ Group: Multimedia/Framework @@ -21,7 +21,7 @@ BuildRequires: gst-plugins-base-devel >= 1.0.0 BuildRequires: pkgconfig(orc-0.4) >= 0.4.11 BuildRequires: python BuildRequires: xsltproc -BuildRequires: pkgconfig(cairo) +#BuildRequires: pkgconfig(cairo) BuildRequires: pkgconfig(libusb-1.0) BuildRequires: pkgconfig(gudev-1.0) BuildRequires: pkgconfig(gio-2.0) >= 2.25.0 @@ -33,6 +33,7 @@ BuildRequires: pkgconfig(openssl) >= 0.9.5 BuildRequires: pkgconfig(sndfile) >= 1.0.16 BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(mm-common) %if %{with wayland} BuildRequires: pkgconfig(wayland-client) >= 1.0.0 %endif -- 2.7.4