waylandsink : modify code about create wlbuffer 48/122148/4
authorHyunil <hyunil46.park@samsung.com>
Thu, 30 Mar 2017 09:01:54 +0000 (18:01 +0900)
committerHyunil <hyunil46.park@samsung.com>
Tue, 4 Apr 2017 04:26:52 +0000 (13:26 +0900)
Change-Id: Ie7dbee267f00efd95d3578abf62e229b0ddf8e73
Signed-off-by: Hyunil <hyunil46.park@samsung.com>
ext/wayland/gstwaylandsink.c
ext/wayland/gstwaylandsink.h
ext/wayland/wlbuffer.c
ext/wayland/wlshmallocator.c
ext/wayland/wlshmallocator.h

index c334780..3a6861e 100755 (executable)
@@ -1828,6 +1828,7 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
   GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
   GstStructure *config;
   guint size, min_bufs, max_bufs;
+
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
   gboolean need_pool;
   GstCaps *caps;
@@ -1835,7 +1836,7 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
 
   if (sink->USE_TBM) {
     if (sink->display->is_native_format == TRUE)
-      return TRUE;
+      return FALSE;
 
     gst_query_parse_allocation (query, &caps, &need_pool);
 
@@ -1968,43 +1969,288 @@ render_last_buffer (GstWaylandSink * sink)
   gst_wl_window_render (sink->window, wlbuffer, info);
 }
 
+
+static gboolean
+gst_wayland_sink_has_wlbuffer (GstWaylandSink * sink, GstBuffer * buffer)
+{
+  GstWlBuffer *gstwlbuffer;
+  FUNCTION;
+  g_return_val_if_fail (sink != NULL, FALSE);
+  g_return_val_if_fail (buffer != NULL, FALSE);
+
+  gstwlbuffer = gst_buffer_get_wl_buffer (buffer);
+  if (gstwlbuffer && gstwlbuffer->display == sink->display
+      && !gst_wayland_sink_is_gapless (sink)
+      && !sink->request_camera_flush_buf) {
+    /* gstbuffer has wlbuffer */
+    /* e.g) last_buffer, buffer is created by previous plugin or waylandsink with BufferPool */
+    GST_LOG ("buffer(%p) has GstWlBuffer(%p):wlbuffer(%p)", buffer, gstwlbuffer,
+        gstwlbuffer->wlbuffer);
+    return TRUE;
+  }
+  GST_LOG ("buffer(%p) has not wlbuffer", buffer);
+  return FALSE;
+}
+
+static void
+gst_wayland_sink_no_create_wlbuffer (GstWaylandSink * sink, GstBuffer * buffer)
+{
+  GstMemory *mem;
+  FUNCTION;
+  g_return_if_fail (sink != NULL);
+  g_return_if_fail (buffer != NULL);
+
+  /* the last_buffer for flushing has wlbuffer or
+     buffer is created by previous plugins or waylandsink has wlbuffer */
+  mem = gst_buffer_peek_memory (buffer, 0);
+  if (gst_is_wl_memory (mem)) {
+    GST_LOG ("buffer(%p) is created by waylandsink has a wl_buffer, "
+        "writing directly", buffer);
+  } else {
+    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");
+  }
+
+  sink->to_render = buffer;
+
+  if (sink->dump_video && !sink->display->is_native_format)
+    gst_wayland_sink_dump_raw_video (sink, sink->to_render,
+        sink->display->dump_count++, sink->total_dump);
+}
+
+static void
+gst_wayland_sink_create_wlbuffer_with_wl_mem (GstWaylandSink * sink,
+    GstBuffer * buffer)
+{
+  GstMemory *mem;
+  struct wl_buffer *wbuf = NULL;
+  FUNCTION;
+  g_return_if_fail (sink != NULL);
+  g_return_if_fail (buffer != NULL);
+
+  GST_LOG ("gstbuffer(%p) is created by wayland has not wlbuffer", buffer);
+  mem = gst_buffer_peek_memory (buffer, 0);
+  wbuf =
+      gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
+      &sink->video_info);
+  if (wbuf) {
+    gst_buffer_add_wl_buffer (buffer, wbuf, sink->display);
+    sink->to_render = buffer;
+  }
+}
+
+static GstFlowReturn
+gst_wayland_sink_create_wlbuffer_with_previous_plugin_tbm (GstWaylandSink *
+    sink, GstBuffer * buffer)
+{
+  GstMemory *mem;
+  GstWlBuffer *wlbuffer;
+  struct wl_buffer *wbuf = NULL;
+  GstFlowReturn ret = GST_FLOW_OK;
+  FUNCTION;
+  g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR);
+  g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
+  sink->flush_gstbuf = NULL;
+
+  GST_LOG
+      ("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, SR32 and S420) */
+  if (!gst_wayland_sink_get_mm_video_buf_info (sink, buffer)) {
+    return GST_FLOW_ERROR;
+  }
+
+  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);
+    wbuf =
+        gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
+        &sink->video_info);
+    if (G_UNLIKELY (!wbuf)) {
+      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);
+    }
+  }
+  return ret;
+}
+
+static GstFlowReturn
+    gst_wayland_sink_copy_input_gstbuffer_to_wl_gstbuffer_with_wl_mem
+    (GstWaylandSink * sink, GstBuffer * buffer)
+{
+  GstWlBuffer *wlbuffer;
+  GstMemory *mem;
+  GstWlShmMemory *shm_mem;
+  GstMapInfo src;
+  struct wl_buffer *wbuf = NULL;
+  GstFlowReturn ret = GST_FLOW_OK;
+  FUNCTION;
+  g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR);
+  g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
+
+  GST_LOG ("Use normal format with wayland TBM or SHM");
+  /* sink->pool always exists (created in set_caps), but it may not
+   * be active if upstream is not using it */
+  if (!gst_buffer_pool_is_active (sink->pool) &&
+      !gst_buffer_pool_set_active (sink->pool, TRUE)) {
+    GST_ERROR ("failed to activate bufferpool.");
+    return GST_FLOW_ERROR;
+  }
+
+  ret = gst_buffer_pool_acquire_buffer (sink->pool, &sink->to_render, NULL);
+  if (ret != GST_FLOW_OK) {
+    GST_WARNING ("could not create buffer");
+    return ret;
+  }
+  /* the first time we acquire a buffer,
+   * we need to attach a wl_buffer on it */
+  wlbuffer = gst_buffer_get_wl_buffer (buffer);
+  if (G_UNLIKELY (!wlbuffer)) {
+    mem = gst_buffer_peek_memory (sink->to_render, 0);
+    shm_mem = (GstWlShmMemory *) mem;
+    GST_LOG ("to_render(%p), shm_mem->fd(%d)", sink->to_render, shm_mem->fd);
+    wbuf =
+        gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
+        &sink->video_info);
+    if (G_UNLIKELY (!wbuf)) {
+      GST_ERROR ("could not create wl_buffer out of wl memory");
+      return GST_FLOW_ERROR;
+    }
+    wlbuffer = gst_buffer_add_wl_buffer (sink->to_render, wbuf, sink->display);
+  }
+
+  gst_buffer_map (buffer, &src, GST_MAP_READ);
+  gst_buffer_fill (sink->to_render, 0, src.data, src.size);
+  gst_buffer_unmap (buffer, &src);
+
+  return ret;
+}
+
+static GstFlowReturn
+gst_wayland_sink_create_wlbuffer (GstWaylandSink * sink, GstBuffer * buffer)
+{
+  GstMemory *mem;
+  GstFlowReturn ret = GST_FLOW_OK;
+  FUNCTION;
+  g_return_val_if_fail (sink != NULL, GST_FLOW_ERROR);
+  g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
+
+  sink->to_render = NULL;
+
+  if (gst_wayland_sink_has_wlbuffer (sink, buffer)) {
+    gst_wayland_sink_no_create_wlbuffer (sink, buffer);
+  } else {
+    mem = gst_buffer_peek_memory (buffer, 0);
+    if (gst_is_wl_memory (mem)) {
+      /* SHM or TBM */
+      gst_wayland_sink_create_wlbuffer_with_wl_mem (sink, buffer);
+    } else {
+      /* gstbuffer is not wl memory */
+      if (sink->USE_TBM && sink->display->is_native_format) {
+        /* Use tbm of buffer directly */
+        ret =
+            gst_wayland_sink_create_wlbuffer_with_previous_plugin_tbm (sink,
+            buffer);
+      } else {
+        /* Copy virtual addr to wayland SHM or TBM */
+        ret =
+            gst_wayland_sink_copy_input_gstbuffer_to_wl_gstbuffer_with_wl_mem
+            (sink, buffer);
+      }
+    }
+  }
+  return ret;
+}
+
+static void
+gst_wayland_sink_buffer_replace (GstWaylandSink * sink, GstBuffer * buffer)
+{
+  FUNCTION;
+  g_return_if_fail (sink != NULL);
+
+  if (sink->USE_TBM && sink->display->is_native_format) {
+    if (sink->flush_gstbuf && sink->display->flush_request) {
+      GST_LOG_OBJECT (sink, "replace last_buffer:(%p)->(%p)", sink->last_buffer,
+          sink->flush_gstbuf);
+      /* increase ref count of sink->fflush_gstbuf, decrease  ref count of sink->last_buffer */
+      gst_buffer_replace (&sink->last_buffer, sink->flush_gstbuf);
+      GST_LOG_OBJECT (sink, "after gst_buffer_replace buffer %p, ref_count(%d)",
+          sink->flush_gstbuf, GST_OBJECT_REFCOUNT_VALUE (sink->flush_gstbuf));
+      /* decrease  ref count of flush_buffer */
+      gst_buffer_unref (sink->flush_gstbuf);
+    } else {
+      /* normal case */
+      GST_LOG_OBJECT (sink, "replace last_buffer:(%p)->(%p)", sink->last_buffer,
+          buffer);
+      /* increase ref count of buffer decrease  ref count of sink->last_buffer */
+      gst_buffer_replace (&sink->last_buffer, buffer);
+      GST_LOG_OBJECT (sink, "after gst_buffer_replace buffer %p, ref_count(%d)",
+          buffer, GST_OBJECT_REFCOUNT_VALUE (buffer));
+    }
+  } else {
+    gst_buffer_replace (&sink->last_buffer, sink->to_render);
+    GST_LOG_OBJECT (sink, "after gst_buffer_replace buffer %p, ref_count(%d)",
+        sink->to_render, GST_OBJECT_REFCOUNT_VALUE (sink->to_render));
+  }
+}
+
+static void
+gst_wayland_sink_get_window (GstWaylandSink * sink)
+{
+  g_return_if_fail (sink != NULL);
+  FUNCTION;
+
+  /* ask for window handle. Unlock render_lock while doing that because
+   * set_window_handle & friends will lock it in this context */
+  g_mutex_unlock (&sink->render_lock);
+  gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
+  g_mutex_lock (&sink->render_lock);
+
+  if (!sink->window) {
+    /* if we were not provided a window, create one ourselves */
+    sink->window =
+        gst_wl_window_new_toplevel (sink->display, &sink->video_info);
+  }
+  gst_wayland_sink_update_window_geometry (sink);
+}
+
 static GstFlowReturn
 gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 {
+#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
+
   GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
-  GstBuffer *to_render;
-  GstBuffer *flush_gstbuf = NULL;
-  GstWlBuffer *wlbuffer;
   GstFlowReturn ret = GST_FLOW_OK;
   FUNCTION;
 
   g_mutex_lock (&sink->render_lock);
 
-  GST_LOG_OBJECT (sink, "render gstbuffer %p, ref_count(%d)", buffer,
+  GST_LOG_OBJECT (sink, "input gstbuffer %p, ref_count(%d)", buffer,
       GST_OBJECT_REFCOUNT_VALUE (buffer));
 
+  /* check overlay */
   if (gst_wayland_sink_is_disabled_overlay (sink)) {
     GST_LOG ("set disable_overlay, so skip");
     goto done;
   }
 
+  /* check window */
   if (G_UNLIKELY (!sink->window)) {
-    /* ask for window handle. Unlock render_lock while doing that because
-     * set_window_handle & friends will lock it in this context */
-    g_mutex_unlock (&sink->render_lock);
-    gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
-    g_mutex_lock (&sink->render_lock);
-
-    if (!sink->window) {
-      /* if we were not provided a window, create one ourselves */
-      sink->window =
-          gst_wl_window_new_toplevel (sink->display, &sink->video_info);
-    }
-#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
-    gst_wayland_sink_update_window_geometry (sink);
-#endif
+    gst_wayland_sink_get_window (sink);
   }
 
+  /* fakesink function for media stream callback case */
   if (sink->signal_handoffs) {
     GST_LOG ("g_signal_emit: hand-off ");
     g_signal_emit (sink, gst_waylandsink_signals[SIGNAL_HANDOFF], 0, buffer,
@@ -2017,193 +2263,65 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
       && !gst_wayland_sink_is_gapless (sink))
     goto done;
 
-#ifndef TIZEN_FEATURE_WLSINK_ENHANCEMENT        /* for tizen view_port, we don't know window size */
-  /* make sure that the application has called set_render_rectangle() */
-  if (G_UNLIKELY (sink->window->render_rectangle.w == 0))
-    goto no_window_size;
-#endif
-#ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
+  /* create wl_buffer */
+  ret = gst_wayland_sink_create_wlbuffer (sink, buffer);
+  if (ret != GST_FLOW_OK)
+    goto done;
 
-  wlbuffer = gst_buffer_get_wl_buffer (buffer);
-  if (G_LIKELY (wlbuffer && wlbuffer->display == sink->display)
-      && !(gst_wayland_sink_is_gapless (sink))
-      && !sink->request_camera_flush_buf) {
-    GST_LOG_OBJECT (sink, "buffer %p has a wl_buffer from our display, " "writing directly", buffer);   //buffer is from our  pool and have wl_buffer
-    GST_LOG ("wl_buffer (%p)", wlbuffer->wlbuffer);
-    to_render = buffer;
+  /* drop double rendering */
+  if ((G_UNLIKELY (buffer == sink->last_buffer)
+          && !(sink->display->flush_request))) {
+    GST_LOG_OBJECT (sink, "Buffer already being rendered");
+    goto done;
+  }
 
-    if (sink->dump_video)
-      gst_wayland_sink_dump_raw_video (sink, to_render,
-          sink->display->dump_count++, sink->total_dump);
+  /* replace last_buffer */
+  gst_wayland_sink_buffer_replace (sink, buffer);
 
+  /* rendering */
+  if (sink->visible) {
+    render_last_buffer (sink);
   } else {
-    GstMemory *mem;
-    struct wl_buffer *wbuf = NULL;
-
-    GST_LOG_OBJECT (sink, "buffer %p does not have a wl_buffer from our " "display, creating it", buffer);      //buffer is from our pool but have not wl_buffer
-    mem = gst_buffer_peek_memory (buffer, 0);
-    if (gst_is_wl_shm_memory (mem)) {
-      FUNCTION;
-      wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
-          &sink->video_info);
-      if (wbuf) {
-        gst_buffer_add_wl_buffer (buffer, wbuf, sink->display); //careat GstWlBuffer and add  gstbuffer, wlbuffer, display and etc
-        to_render = buffer;
-      }
-    } else {                    //buffer is not from our pool and have not wl_buffer
-      GstMapInfo src;
-      /* we don't know how to create a wl_buffer directly from the provided
-       * memory, so we have to copy the data to a memory that we know how
-       * to handle... */
-
-      GST_LOG_OBJECT (sink, "buffer %p is not from our pool", buffer);
-      GST_LOG_OBJECT (sink, "buffer %p cannot have a wl_buffer, " "copying",
-          buffer);
-
-      if (sink->USE_TBM && sink->display->is_native_format) {
-        /* in case of SN12 or ST12 */
-        if (!gst_wayland_sink_get_mm_video_buf_info (sink, buffer)) {
-          ret = GST_FLOW_ERROR;
-          goto done;
-        }
-
-        wlbuffer = gst_buffer_get_wl_buffer (buffer);
-        /* last_buffer from gaplasee have wlbuffer */
-        if (G_UNLIKELY (!wlbuffer) || sink->display->flush_request) {
-          wbuf =
-              gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
-              &sink->video_info);
-          if (G_UNLIKELY (!wbuf))
-            goto no_wl_buffer;
-          if (sink->display->flush_request) {
-            flush_gstbuf = gst_buffer_new ();
-            GST_LOG ("To flush, new gstBuffer(%p)", flush_gstbuf);
-            gst_buffer_add_wl_buffer (flush_gstbuf, wbuf, sink->display);
-
-          } else {
-            gst_buffer_add_wl_buffer (buffer, wbuf, sink->display);
-          }
-        }
-      } else if (sink->USE_TBM && !sink->display->is_native_format) {
-
-        /* sink->pool always exists (created in set_caps), but it may not
-         * be active if upstream is not using it */
-        if (!gst_buffer_pool_is_active (sink->pool)
-            && !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;
-
-        //GstMemory *mem;
-        //mem = gst_buffer_peek_memory (to_render, 0);
-        //if (gst_is_wl_shm_memory (mem)) {
-        GST_LOG ("to_render buffer is our buffer");
-        //}
-        /* the first time we acquire a buffer,
-         * we need to attach a wl_buffer on it */
-        wlbuffer = gst_buffer_get_wl_buffer (buffer);
-        if (G_UNLIKELY (!wlbuffer)) {
-          mem = gst_buffer_peek_memory (to_render, 0);
-          wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
-              &sink->video_info);
-          if (G_UNLIKELY (!wbuf))
-            goto no_wl_buffer;
-
-          wlbuffer = gst_buffer_add_wl_buffer (to_render, wbuf, sink->display);
-        }
-
-        gst_buffer_map (buffer, &src, GST_MAP_READ);
-        gst_buffer_fill (to_render, 0, src.data, src.size);
-        gst_buffer_unmap (buffer, &src);
-      } else {                  /* USE SHM */
-        /* sink->pool always exists (created in set_caps), but it may not
-         * be active if upstream is not using it */
-        if (!gst_buffer_pool_is_active (sink->pool) &&
-            !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;
-        /* the first time we acquire a buffer,
-         * we need to attach a wl_buffer on it */
-        wlbuffer = gst_buffer_get_wl_buffer (buffer);
-        if (G_UNLIKELY (!wlbuffer)) {
-          mem = gst_buffer_peek_memory (to_render, 0);
-          wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
-              &sink->video_info);
-          if (G_UNLIKELY (!wbuf))
-            goto no_wl_buffer;
-
-          gst_buffer_add_wl_buffer (to_render, wbuf, sink->display);
-
-        }
-
-        gst_buffer_map (buffer, &src, GST_MAP_READ);
-        gst_buffer_fill (to_render, 0, src.data, src.size);
-        gst_buffer_unmap (buffer, &src);
-      }
-    }
+    GST_LOG ("skip rendering");
   }
 
-  if (sink->USE_TBM && sink->display->is_native_format) {
-    if ((G_UNLIKELY (buffer == sink->last_buffer)
-            && !(sink->display->flush_request))) {
-      GST_LOG_OBJECT (sink, "Buffer already being rendered");
-      goto done;
-    }
+  if (sink->to_render) {
+    if (buffer != sink->to_render)
+      gst_buffer_unref (sink->to_render);
+  }
 
-    if (flush_gstbuf && sink->display->flush_request) {
+  goto done;
 
-      GST_LOG_OBJECT (sink, "replace last_buffer: (%p) -> (%p)",
-          sink->last_buffer, flush_gstbuf);
-      /*  increase ref count of flush_gstbuf
-         decrease  ref count of sink->last_buffer */
-      gst_buffer_replace (&sink->last_buffer, flush_gstbuf);
-      GST_LOG_OBJECT (sink, "after gst_buffer_replace buffer %p, ref_count(%d)",
-          flush_gstbuf, GST_OBJECT_REFCOUNT_VALUE (flush_gstbuf));
-      /* decrease  ref count of flush_buffer */
-      gst_buffer_unref (flush_gstbuf);
+#else /* open source */
 
-    } else {                    //normal case
+  GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
+  GstBuffer *to_render = NULL;
+  GstFlowReturn ret = GST_FLOW_OK;
 
-      GST_LOG_OBJECT (sink, "replace last_buffer: (%p) -> (%p)",
-          sink->last_buffer, buffer);
-      /*  increase ref count of buffer
-         decrease  ref count of sink->last_buffer */
-      gst_buffer_replace (&sink->last_buffer, buffer);
-      GST_LOG_OBJECT (sink, "after gst_buffer_replace buffer %p, ref_count(%d)",
-          buffer, GST_OBJECT_REFCOUNT_VALUE (buffer));
-    }
-    if (sink->visible) {
-      render_last_buffer (sink);
-    } else {
-      GST_LOG ("skip rendering");
-    }
-    goto done;
+  g_mutex_lock (&sink->render_lock);
 
-  } else {                      /* USE SHM or normal format */
-    /* drop double rendering */
-    if (G_UNLIKELY (buffer == sink->last_buffer)) {
-      GST_LOG_OBJECT (sink, "Buffer already being rendered");
-      goto done;
-    }
-    gst_buffer_replace (&sink->last_buffer, to_render);
+  if (G_UNLIKELY (!sink->window)) {
+    /* ask for window handle. Unlock render_lock while doing that because
+     * set_window_handle & friends will lock it in this context */
+    g_mutex_unlock (&sink->render_lock);
+    gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
+    g_mutex_lock (&sink->render_lock);
 
-    if (sink->visible) {
-      render_last_buffer (sink);
-    } else {
-      GST_LOG ("skip rendering");
+    if (!sink->window) {
+      /* if we were not provided a window, create one ourselves */
+      sink->window =
+          gst_wl_window_new_toplevel (sink->display, &sink->video_info);
     }
+  }
 
-    if (buffer != to_render)
-      gst_buffer_unref (to_render);
-
+  /* drop buffers until we get a frame callback */
+  if (g_atomic_int_get (&sink->redraw_pending) == TRUE
+      && !gst_wayland_sink_is_gapless (sink))
     goto done;
-  }
 
-#else /* open source */
+  /* make sure that the application has called set_render_rectangle() */
+  if (G_UNLIKELY (sink->window->render_rectangle.w == 0))
+    goto no_window_size;
 
   wlbuffer = gst_buffer_get_wl_buffer (buffer);
 
@@ -2222,7 +2340,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
         "buffer %p does not have a wl_buffer from our " "display, creating it",
         buffer);
     mem = gst_buffer_peek_memory (buffer, 0);
-    if (gst_is_wl_shm_memory (mem)) {
+    if (gst_is_wl_shm_memory (mem)) {   /* is wayland memory */
       FUNCTION;
       wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
           &sink->video_info);
@@ -2293,7 +2411,6 @@ no_window_size:
     ret = GST_FLOW_ERROR;
     goto done;
   }
-#endif
 no_buffer:
   {
     GST_WARNING_OBJECT (sink, "could not create buffer");
@@ -2311,6 +2428,7 @@ activate_failed:
     ret = GST_FLOW_ERROR;
     goto done;
   }
+#endif
 done:
   {
     g_mutex_unlock (&sink->render_lock);
index 1864329..58c1e11 100644 (file)
@@ -80,8 +80,9 @@ struct _GstWaylandSink
   gboolean redraw_pending;
   GMutex render_lock;
   GstBuffer *last_buffer;
-
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
+  GstBuffer *to_render;
+  GstBuffer *flush_gstbuf;
   /* Framerate numerator and denominator */
   gint fps_n;
   gint fps_d;
index 11e0e53..9ba1815 100644 (file)
@@ -253,6 +253,8 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT //need to contribute to upstream !!
   wl_proxy_set_queue ((struct wl_proxy *) self->wlbuffer, self->display->queue);
 #endif
+  /* called gstbuffer_disposed when the gstbuffer is disposed,
+     or the same gstbuffer is being overwritten by below api */
   gst_mini_object_set_qdata ((GstMiniObject *) gstbuffer,
       gst_wl_buffer_qdata_quark (), self, (GDestroyNotify) gstbuffer_disposed);
   GST_LOG ("GstWlBuffer (%p)", self);
index e6a8bd4..f1cbc45 100644 (file)
@@ -128,6 +128,7 @@ gst_wl_tbm_dump_native_raw_video (GstWlDisplay * display, guint dump_count)
     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;
@@ -279,7 +280,7 @@ gst_wl_shm_allocator_free (GstAllocator * allocator, GstMemory * memory)
 {
   GstWlShmMemory *shm_mem = (GstWlShmMemory *) memory;
   FUNCTION;
-
+  GST_LOG ("shm_mem->fd(%d)", shm_mem->fd);
   if (shm_mem->fd != -1)
     close (shm_mem->fd);
   munmap (shm_mem->data, memory->maxsize);
@@ -342,6 +343,13 @@ gst_is_wl_shm_memory (GstMemory * mem)
   return gst_memory_is_type (mem, GST_ALLOCATOR_WL_SHM);
 }
 
+gboolean
+gst_is_wl_memory (GstMemory * mem)
+{
+  FUNCTION;
+  return gst_memory_is_type (mem, GST_ALLOCATOR_WL_SHM);
+}
+
 struct wl_buffer *
 gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
     const GstVideoInfo * info)
@@ -405,7 +413,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
       size = GST_VIDEO_INFO_SIZE (info);
 
       format = gst_video_format_to_wl_tbm_format (GST_VIDEO_INFO_FORMAT (info));
-      g_return_val_if_fail (gst_is_wl_shm_memory (mem), NULL);
+      g_return_val_if_fail (gst_is_wl_memory (mem), NULL);
       g_return_val_if_fail (size <= mem->size, NULL);
       g_return_val_if_fail (shm_mem->fd != -1, NULL);
 
@@ -448,7 +456,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
     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 (gst_is_wl_memory (mem), NULL);
     g_return_val_if_fail (size <= mem->size, NULL);
     g_return_val_if_fail (shm_mem->fd != -1, NULL);
 
@@ -460,8 +468,6 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
     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);
   }
   display->buffer_width = width;
index 3dd9dfa..c06b182 100644 (file)
@@ -74,6 +74,7 @@ struct wl_buffer *gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem,
 
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
 gint gst_wl_fwrite_data (gchar * file, gpointer data, guint size);
+gboolean gst_is_wl_memory (GstMemory * mem);
 #endif
 G_END_DECLS
 #endif /* __GST_WL_SHM_ALLOCATOR_H__ */