#include "gstwaylandsink.h"
#ifdef GST_WLSINK_ENHANCEMENT
#include <mm_types.h>
+#include "tizen-wlvideoformat.h"
#endif
#include "wlvideoformat.h"
#include "wlbuffer.h"
#include <stdlib.h>
#include <string.h>
-//#define DUMP_BUFFER
#ifdef GST_WLSINK_ENHANCEMENT
#define GST_TYPE_WAYLANDSINK_DISPLAY_GEOMETRY_METHOD (gst_waylandsink_display_geometry_method_get_type())
#define GST_TYPE_WAYLANDSINK_ROTATE_ANGLE (gst_waylandsink_rotate_angle_get_type())
static void
gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
{
- FUNCTION;
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSinkClass *gstbasesink_class;
+ FUNCTION;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
#ifdef GST_WLSINK_ENHANCEMENT
static void
-update_last_buffer_geometry (GstWaylandSink * sink)
+gst_wayland_sink_update_last_buffer_geometry (GstWaylandSink * sink)
{
+ GstWlBuffer *wlbuffer;
FUNCTION;
+ g_return_if_fail (sink != NULL);
- GstWlBuffer *wlbuffer;
wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer);
wlbuffer->used_by_compositor = FALSE;
to call gst_wl_buffer_finalize(), we need to decrease buffer ref count */
gst_buffer_unref (wlbuffer->gstbuffer);
}
+#ifdef USE_WL_FLUSH_BUFFER
+static int
+gst_wayland_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);
+
+ flush_buffer = (GstWlFlushBuffer *)malloc(sizeof(GstWlFlushBuffer));
+ if (!flush_buffer){
+ GST_ERROR ("GstWlFlushBuffer alloc faile");
+ return FALSE;
+ }
+ memset (flush_buffer, 0x0, sizeof(GstWlFlushBuffer));
+
+ display->flush_tbm_bufmgr = wayland_tbm_client_get_bufmgr (display->tbm_client);
+ g_return_if_fail (display->flush_tbm_bufmgr != NULL);
+
+ for (i=0; i<NV_BUF_PLANE_NUM; i++){
+ if (mm_video_buf->handle.bo[i] != NULL){
+ tbm_bo_handle src;
+ tbm_bo_handle dst;
+
+ /* 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 (!bo) {
+ GST_ERROR ("alloc tbm bo(size:%d) failed: %s", bo_size, strerror(errno));
+ return FALSE;
+ }
+ GST_INFO ("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_get_handle (mm_video_buf->handle.bo[i], TBM_DEVICE_CPU);
+ dst = tbm_bo_get_handle (bo, TBM_DEVICE_CPU);
+ if (!src.ptr || !dst.ptr) {
+ GST_ERROR ("get tbm bo handle failed src(%p) dst(%p): %s", src.ptr, dst.ptr, strerror (errno));
+ tbm_bo_unref (mm_video_buf->handle.bo[i]);
+ tbm_bo_unref (bo);
+ 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_wayland_sink_copy_mm_video_buf_info_to_flush (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;
+
+ ret = gst_wayland_sink_make_flush_buffer(display, mm_video_buf);
+ if (ret){
+ int i;
+ for (i = 0; i < NV_BUF_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->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];
+ }
+ }
+ return ret;
+}
+#endif
+
+static void
+gst_wayland_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;
+
+ for (i = 0; i < NV_BUF_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->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];
+ }
+}
+
+static int
+gst_wayland_sink_get_mm_video_buf_info(GstWlDisplay * display, GstBuffer * buffer)
+{
+ GstMemory *mem;
+ GstMapInfo mem_info = GST_MAP_INFO_INIT;
+ MMVideoBuffer *mm_video_buf = NULL;
+
+ g_return_val_if_fail (display != NULL, FALSE);
+ g_return_val_if_fail (buffer != NULL, FALSE);
+
+ 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 is NULL. Skip rendering");
+ return FALSE;
+ }
+ /* assign mm_video_buf info */
+ if (mm_video_buf->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
+ GST_DEBUG ("TBM bo %p %p %p", mm_video_buf->handle.bo[0],
+ mm_video_buf->handle.bo[1], mm_video_buf->handle.bo[2]);
+ display->native_video_size = 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 (display->flush_request) {
+ if(!gst_wayland_sink_copy_mm_video_buf_info_to_flush(display, mm_video_buf)){
+ GST_ERROR("cat not copy mm_video_buf info to flush");
+ return FALSE;
+ }
+ } else
+#endif
+ /* normal routine */
+ gst_wayland_sink_add_mm_video_buf_info(display, mm_video_buf);
+ } else {
+ GST_ERROR ("Buffer type is not TBM");
+ return FALSE;
+ }
+ return TRUE;
+}
+
#endif
static void
gst_wayland_sink_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (object);
+ FUNCTION;
switch (prop_id) {
case PROP_DISPLAY:
gst_wayland_sink_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (object);
+ FUNCTION;
g_mutex_lock (&sink->render_lock);
switch (prop_id) {
}
if (sink->video_info_changed && sink->window
&& GST_STATE (sink) == GST_STATE_PAUSED) {
- update_last_buffer_geometry (sink);
+ gst_wayland_sink_update_last_buffer_geometry (sink);
}
g_mutex_unlock (&sink->render_lock);
static void
gst_wayland_sink_finalize (GObject * object)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (object);
-
+ FUNCTION;
GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
if (sink->last_buffer)
gst_wayland_sink_set_display_from_context (GstWaylandSink * sink,
GstContext * context)
{
- FUNCTION;
struct wl_display *display;
GError *error = NULL;
+ FUNCTION;
display = gst_wayland_display_handle_context_get_handle (context);
sink->display = gst_wl_display_new_existing (display, FALSE, &error);
static gboolean
gst_wayland_sink_find_display (GstWaylandSink * sink)
{
- FUNCTION;
GstQuery *query;
GstMessage *msg;
GstContext *context = NULL;
GError *error = NULL;
gboolean ret = TRUE;
+ FUNCTION;
g_mutex_lock (&sink->display_lock);
static GstStateChangeReturn
gst_wayland_sink_change_state (GstElement * element, GstStateChange transition)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (element);
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ FUNCTION;
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
g_clear_object (&sink->window);
} else {
/* remove buffer from surface, show nothing */
+#ifdef USE_WL_FLUSH_BUFFER
+ sink->display->flush_request = 0;
+#endif
gst_wl_window_render (sink->window, NULL, NULL);
}
}
static void
gst_wayland_sink_set_context (GstElement * element, GstContext * context)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (element);
+ FUNCTION;
if (gst_context_has_context_type (context,
GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE)) {
static GstCaps *
gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
{
- FUNCTION;
GstWaylandSink *sink;
GstCaps *caps;
+ FUNCTION;
sink = GST_WAYLAND_SINK (bsink);
static gboolean
gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
- FUNCTION;
GstWaylandSink *sink;
GstBufferPool *newpool;
GstVideoInfo info;
GArray *formats;
gint i;
GstStructure *structure;
+ GstWlShmAllocator *self = NULL;
+
+ FUNCTION;
sink = GST_WAYLAND_SINK (bsink);
sink->video_info_changed = TRUE;
} else {
sink->display->is_native_format = FALSE;
- GstWlShmAllocator *self =
- GST_WL_SHM_ALLOCATOR (gst_wl_shm_allocator_get ());
+ self = GST_WL_SHM_ALLOCATOR (gst_wl_shm_allocator_get ());
self->display = sink->display;
/* create a new pool for the new configuration */
newpool = gst_video_buffer_pool_new ();
}
} else { /* USE SHM */
- GstWlShmAllocator *self =
- GST_WL_SHM_ALLOCATOR (gst_wl_shm_allocator_get ());
+ self = GST_WL_SHM_ALLOCATOR (gst_wl_shm_allocator_get ());
self->display = sink->display;
/* create a new pool for the new configuration */
static gboolean
gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
GstStructure *config;
guint size, min_bufs, max_bufs;
#ifdef GST_WLSINK_ENHANCEMENT
gboolean need_pool;
GstCaps *caps;
+ FUNCTION;
+
if (sink->USE_TBM) {
if (sink->display->is_native_format == TRUE)
return TRUE;
static void
frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time)
{
- FUNCTION;
GstWaylandSink *sink = data;
+ FUNCTION;
GST_LOG ("frame_redraw_cb");
static void
render_last_buffer (GstWaylandSink * sink)
{
- FUNCTION;
GstWlBuffer *wlbuffer;
const GstVideoInfo *info = NULL;
struct wl_surface *surface;
struct wl_callback *callback;
+ FUNCTION;
wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer);
surface = gst_wl_window_get_wl_surface (sink->window);
static GstFlowReturn
gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
GstBuffer *to_render;
GstWlBuffer *wlbuffer;
GstFlowReturn ret = GST_FLOW_OK;
+ FUNCTION;
g_mutex_lock (&sink->render_lock);
if (sink->USE_TBM && sink->display->is_native_format) {
/* in case of SN12 or ST12 */
- GstMemory *mem;
- struct wl_buffer *wbuf = NULL;
- 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 (!gst_wayland_sink_get_mm_video_buf_info(sink->display, buffer))
+ return GST_FLOW_ERROR;
+
wlbuffer = gst_buffer_get_wl_buffer (buffer);
if (G_UNLIKELY (!wlbuffer)) {
wbuf =
&sink->video_info);
if (G_UNLIKELY (!wbuf))
goto no_wl_buffer;
-
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
gst_wayland_sink_set_wl_window_wl_surface_id (GstVideoOverlay * overlay,
guintptr wl_surface_id)
{
- FUNCTION;
-
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
+ FUNCTION;
g_return_if_fail (sink != NULL);
if (sink->window != NULL) {
g_mutex_lock (&sink->render_lock);
g_clear_object (&sink->window);
- GST_INFO ("wl_surface_id %d %p", (int) wl_surface_id, wl_surface_id);
+ GST_INFO ("wl_surface_id %d %p", (int) wl_surface_id, (guintptr)wl_surface_id);
if (wl_surface_id) {
if (G_LIKELY (gst_wayland_sink_find_display (sink))) {
static void
gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
{
- FUNCTION;
-
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
struct wl_surface *surface = (struct wl_surface *) handle;
+ FUNCTION;
g_return_if_fail (sink != NULL);
gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
gint x, gint y, gint w, gint h)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
+ FUNCTION;
g_return_if_fail (sink != NULL);
static void
gst_wayland_sink_expose (GstVideoOverlay * overlay)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
+ FUNCTION;
g_return_if_fail (sink != NULL);
static void
gst_wayland_sink_begin_geometry_change (GstWaylandVideo * video)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (video);
+ FUNCTION;
g_return_if_fail (sink != NULL);
g_mutex_lock (&sink->render_lock);
static void
gst_wayland_sink_end_geometry_change (GstWaylandVideo * video)
{
- FUNCTION;
GstWaylandSink *sink = GST_WAYLAND_SINK (video);
+ FUNCTION;
g_return_if_fail (sink != NULL);
g_mutex_lock (&sink->render_lock);
*/
#include "wlbuffer.h"
+#define NV_BUF_PLANE_NUM 2 /*SN12 or ST12 has 2 plane */
GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
static void
gst_wl_buffer_dispose (GObject * gobject)
{
- FUNCTION;
GstWlBuffer *self = GST_WL_BUFFER (gobject);
+ FUNCTION;
GST_TRACE_OBJECT (self, "dispose");
static void
gst_wl_buffer_finalize (GObject * gobject)
{
- FUNCTION;
GstWlBuffer *self = GST_WL_BUFFER (gobject);
+ int i;
+
+ FUNCTION;
GST_TRACE_OBJECT (self, "finalize");
#ifdef GST_WLSINK_ENHANCEMENT
if (self->wlbuffer)
wl_buffer_destroy (self->wlbuffer);
+#ifdef USE_WL_FLUSH_BUFFER
+ if (self->display->flush_request) {
+ if (self->display->flush_tbm_bufmgr)
+ self->display->flush_tbm_bufmgr = NULL;
+ for (i = 0; i < NV_BUF_PLANE_NUM; i++) {
+ if (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;
+ }
+#endif
+
G_OBJECT_CLASS (gst_wl_buffer_parent_class)->finalize (gobject);
}
static void
gst_wl_buffer_class_init (GstWlBufferClass * klass)
{
- FUNCTION;
GObjectClass *object_class = (GObjectClass *) klass;
-
+ FUNCTION;
object_class->dispose = gst_wl_buffer_dispose;
object_class->finalize = gst_wl_buffer_finalize;
}
static void
buffer_release (void *data, struct wl_buffer *wl_buffer)
{
- FUNCTION;
GstWlBuffer *self = data;
+ FUNCTION;
GST_LOG_OBJECT (self, "wl_buffer(%p)::release (GstBuffer: %p)", wl_buffer,
self->gstbuffer);
self->used_by_compositor = FALSE;
+#ifdef USE_WL_FLUSH_BUFFER
/* unref should be last, because it may end up destroying the GstWlBuffer */
+ if (!self->display->flush_request) {
+ /*in case of flush_request, gstbuffer ref-count has already decreased. */
+ gst_buffer_unref (self->gstbuffer);
+ } else {
+ /*we blocked below code at gstbuffer_disposed() */
+ /* unref(GstWlBuffer), now gst_wl_buffer_dispose() will be called by below code */
+ g_object_unref (self);
+ }
+#else
gst_buffer_unref (self->gstbuffer);
-
+#endif
}
static const struct wl_buffer_listener buffer_listener = {
/* this will normally destroy the GstWlBuffer, unless the display is
* finalizing and it has taken an additional reference to it */
- g_object_unref (self);
+#ifdef USE_WL_FLUSH_BUFFER
+ /* in case of normal routine, gstbuffer_disposed() is called by buffer_release()
+ but in case of flush_request, this func() is called when basesink unref gstbuffer.
+ buffer_release() is not called if we do 'g_object_unref (self)' */
+ if (!self->display->flush_request)
+#endif
+ g_object_unref (self);
}
GstWlBuffer *
gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
GstWlDisplay * display)
{
- FUNCTION;
GstWlBuffer *self;
+ FUNCTION;
self = g_object_new (GST_TYPE_WL_BUFFER, NULL);
self->gstbuffer = gstbuffer;
#ifdef GST_WLSINK_ENHANCEMENT //need to contribute to upstream !!
wl_proxy_set_queue ((struct wl_proxy *) self->wlbuffer, self->display->queue);
#endif
-
gst_mini_object_set_qdata ((GstMiniObject *) gstbuffer,
gst_wl_buffer_qdata_quark (), self, (GDestroyNotify) gstbuffer_disposed);
GST_INFO ("GstWlBuffer (%p)", self);
/* Add a reference to the buffer. This represents the fact that
* the compositor is using the buffer and it should not return
* back to the pool and be re-used until the compositor releases it. */
- gst_buffer_ref (self->gstbuffer);
+#ifdef USE_WL_FLUSH_BUFFER
+ /* in case of flush_request, we need to copy info and unref gstbuffer
+ so, we need not to increase ref count. */
+ if (!self->display->flush_request)
+#endif
+ gst_buffer_ref (self->gstbuffer);
self->used_by_compositor = TRUE;
}
handle_tizen_video_format (void *data, struct tizen_video *tizen_video,
uint32_t format)
{
- FUNCTION;
GstWlDisplay *self = data;
+ FUNCTION;
g_return_if_fail (self != NULL);
static void
gst_wl_display_class_init (GstWlDisplayClass * klass)
{
- FUNCTION;
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ FUNCTION;
gobject_class->finalize = gst_wl_display_finalize;
}
static void
gst_wl_display_finalize (GObject * gobject)
{
- FUNCTION;
GstWlDisplay *self = GST_WL_DISPLAY (gobject);
+ FUNCTION;
gst_poll_set_flushing (self->wl_fd_poll, TRUE);
g_thread_join (self->thread);
static void
sync_callback (void *data, struct wl_callback *callback, uint32_t serial)
{
- FUNCTION;
gboolean *done = data;
*done = TRUE;
}
static gint
gst_wl_display_roundtrip (GstWlDisplay * self)
{
- FUNCTION;
struct wl_callback *callback;
gint ret = 0;
gboolean done = FALSE;
+ FUNCTION;
g_return_val_if_fail (self != NULL, -1);
registry_handle_global (void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
{
- FUNCTION;
GstWlDisplay *self = data;
+ FUNCTION;
if (g_strcmp0 (interface, "wl_compositor") == 0) {
self->compositor = wl_registry_bind (registry, id, &wl_compositor_interface,
static gpointer
gst_wl_display_thread_run (gpointer data)
{
- FUNCTION;
GstWlDisplay *self = data;
GstPollFD pollfd = GST_POLL_FD_INIT;
+ FUNCTION;
pollfd.fd = wl_display_get_fd (self->display);
gst_poll_add_fd (self->wl_fd_poll, &pollfd);
GstWlDisplay *
gst_wl_display_new (const gchar * name, GError ** error)
{
- FUNCTION;
struct wl_display *display;
+ FUNCTION;
display = wl_display_connect (name);
gst_wl_display_new_existing (struct wl_display * display,
gboolean take_ownership, GError ** error)
{
- FUNCTION;
GstWlDisplay *self;
GError *err = NULL;
gint i;
+ FUNCTION;
g_return_val_if_fail (display != NULL, NULL);
#include <wayland-tbm-client.h>
#include <tizen-extension-client-protocol.h>
#define NV_BUF_PLANE_NUM 2 /*SN12 or ST12 has 2 plane */
+#define USE_WL_FLUSH_BUFFER
#endif
G_BEGIN_DECLS
typedef struct _GstWlDisplay GstWlDisplay;
typedef struct _GstWlDisplayClass GstWlDisplayClass;
+#ifdef USE_WL_FLUSH_BUFFER
+typedef struct {
+ void *bo[NV_BUF_PLANE_NUM];
+}GstWlFlushBuffer;
+#endif
+
#define TBM_BO_NUM 20
struct _GstWlDisplay
tbm_surface_h tsurface;
gboolean USE_TBM;
+#ifdef USE_WL_FLUSH_BUFFER
+ GstWlFlushBuffer *flush_buffer;
+ tbm_bufmgr flush_tbm_bufmgr;
+ int flush_request;
+#endif
+
gboolean is_native_format; /*SN12, ST12 */
void *bo[NV_BUF_PLANE_NUM];
int plane_size[NV_BUF_PLANE_NUM];
#include "wlshmallocator.h"
#include "wlvideoformat.h"
-
+#ifdef GST_WLSINK_ENHANCEMENT
+#include "tizen-wlvideoformat.h"
+#include <tbm_surface_internal.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
-//#define DUMP_BUFFER
+
#ifdef DUMP_BUFFER
int dump_cnt = 0;
int _write_rawdata (const char *file, const void *data, unsigned int size);
gst_wl_shm_allocator_alloc (GstAllocator * allocator, gsize size,
GstAllocationParams * params)
{
- FUNCTION;
GstWlShmAllocator *self = GST_WL_SHM_ALLOCATOR (allocator);
char filename[1024];
static int init = 0;
int idx;
gpointer data;
GstWlShmMemory *mem;
+ FUNCTION;
#ifdef GST_WLSINK_ENHANCEMENT
if (self->display->USE_TBM) {
static void
gst_wl_shm_allocator_free (GstAllocator * allocator, GstMemory * memory)
{
- FUNCTION;
GstWlShmMemory *shm_mem = (GstWlShmMemory *) memory;
+ FUNCTION;
if (shm_mem->fd != -1)
close (shm_mem->fd);
static void
gst_wl_shm_allocator_class_init (GstWlShmAllocatorClass * klass)
{
- FUNCTION;
GstAllocatorClass *alloc_class = (GstAllocatorClass *) klass;
+ FUNCTION;
alloc_class->alloc = GST_DEBUG_FUNCPTR (gst_wl_shm_allocator_alloc);
alloc_class->free = GST_DEBUG_FUNCPTR (gst_wl_shm_allocator_free);
gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
const GstVideoInfo * info)
{
- FUNCTION;
GstWlShmMemory *shm_mem = (GstWlShmMemory *) mem;
gint width, height, stride;
gsize size;
enum wl_shm_format format;
struct wl_shm_pool *wl_pool;
struct wl_buffer *wbuffer;
+ FUNCTION;
#ifdef GST_WLSINK_ENHANCEMENT
if (display->USE_TBM) {
- tbm_bo_handle virtual_addr;
tbm_surface_info_s ts_info;
int num_bo;
+#ifdef DUMP_BUFFER
+ tbm_bo_handle virtual_addr;
void *data;
-
+#endif
if (display->is_native_format == TRUE) {
width = GST_VIDEO_INFO_WIDTH (info);
height = GST_VIDEO_INFO_HEIGHT (info);
}
}
#endif
- GST_DEBUG ("TBM bo %p %p %p", display->bo[0], display->bo[1], 0);
+ GST_DEBUG ("TBM bo %p %p %p", display->bo[0], display->bo[1], display->bo[2]);
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);
GST_DEBUG
- ("ts_info.width(%d) height(%d) format(%d) 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);
+ ("ts_info.width(%d) height(%d) bpp(%d) num_planes(%d)",
+ ts_info.width, ts_info.height, ts_info.bpp, ts_info.num_planes);
ts_info.planes[0].stride = display->stride_width[0];
ts_info.planes[1].stride = display->stride_width[1];
num_bo = (display->bo[1]) ? 2 : 1;
GST_INFO ("num_bo(%d)", num_bo);
display->tsurface =
- tbm_surface_internal_create_with_bos (&ts_info, display->bo, num_bo);
+ tbm_surface_internal_create_with_bos (&ts_info, (tbm_bo *)display->bo, num_bo);
GST_INFO ("display->tsurface(%p)", display->tsurface);
GST_INFO ("tbm_client(%p),tsurface(%p)", display->tbm_client,
display->tsurface);
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_tbm_format_to_string (format));
+ G_GSSIZE_FORMAT " (%d x %d, stride %d)", size, width,
+ height, stride);
#ifdef DUMP_BUFFER
virtual_addr = tbm_bo_get_handle (shm_mem->tbm_bo_ptr, TBM_DEVICE_CPU);
int ret;
char file_name[128];
GST_INFO ("DUMP %d ", dump_cnt);
-// if (dump_cnt < 60) {
sprintf (file_name, "/home/owner/WLSINK_OUT_DUMP_%2.2d.dump", dump_cnt++);
ret = _write_rawdata (file_name, virtual_addr.ptr, size);
if (ret) {
GST_ERROR ("_write_rawdata() failed");
}
-// }
#endif
ts_info.width = width;
ts_info.height = height;
GST_INFO ("tbm_bo (%p)", shm_mem->tbm_bo_ptr);
display->tsurface =
- tbm_surface_internal_create_with_bos (&ts_info, &shm_mem->tbm_bo_ptr,
+ tbm_surface_internal_create_with_bos (&ts_info, (tbm_bo *)&shm_mem->tbm_bo_ptr,
1);
wbuffer =
wayland_tbm_client_create_buffer (display->tbm_client,
enum wl_shm_format
gst_video_format_to_wl_shm_format (GstVideoFormat format)
{
- FUNCTION;
guint i;
+ FUNCTION;
for (i = 0; i < G_N_ELEMENTS (formats); i++)
if (formats[i].gst_format == format)
GstVideoFormat
gst_wl_shm_format_to_video_format (enum wl_shm_format wl_format)
{
- FUNCTION;
guint i;
+ FUNCTION;
for (i = 0; i < G_N_ELEMENTS (formats); i++)
if (formats[i].wl_format == wl_format)
#include "wlshmallocator.h"
#include "wlbuffer.h"
-#define SWAP(a, b) { (a) ^= (b) ^= (a) ^= (b); }
-
GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
static void
gst_wl_window_class_init (GstWlWindowClass * klass)
{
- FUNCTION;
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ FUNCTION;
gobject_class->finalize = gst_wl_window_finalize;
}
static void
gst_wl_window_finalize (GObject * gobject)
{
- FUNCTION;
GstWlWindow *self = GST_WL_WINDOW (gobject);
+ FUNCTION;
#ifdef GST_WLSINK_ENHANCEMENT
if (self->video_object)
gst_wl_window_new_internal (GstWlDisplay * display)
#endif
{
- FUNCTION;
GstWlWindow *window;
GstVideoInfo info;
+#ifndef GST_WLSINK_ENHANCEMENT
GstBuffer *buf;
GstMapInfo mapinfo;
struct wl_buffer *wlbuf;
GstWlBuffer *gwlbuf;
+#endif
struct wl_region *region;
+ FUNCTION;
window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
window->display = g_object_ref (display);
GstWlWindow *
gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info)
{
- FUNCTION;
GstWlWindow *window;
gint width;
+ FUNCTION;
/* not create shell_surface here for enlightenment */
#ifdef GST_WLSINK_ENHANCEMENT
gst_wl_window_new_in_surface (GstWlDisplay * display,
struct wl_surface * parent)
{
- FUNCTION;
GstWlWindow *window;
+ FUNCTION;
display->use_parent_wl_surface = TRUE;
#ifdef GST_WLSINK_ENHANCEMENT
static void
gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
{
- FUNCTION;
GstVideoRectangle src = { 0, };
GstVideoRectangle res;
-
- /* center the video_subsurface inside area_subsurface */
- src.w = window->video_width;
- src.h = window->video_height;
#ifdef GST_WLSINK_ENHANCEMENT // need to change ifndef to ifdef
-
GstVideoRectangle src_origin = { 0, 0, 0, 0 };
GstVideoRectangle src_input = { 0, 0, 0, 0 };
GstVideoRectangle dst = { 0, 0, 0, 0 };
-
- gint rotate = 0;
+ int temp = 0;
gint transform = WL_OUTPUT_TRANSFORM_NORMAL;
+#endif
+ FUNCTION;
+ /* center the video_subsurface inside area_subsurface */
+ src.w = window->video_width;
+ src.h = window->video_height;
+
+#ifdef GST_WLSINK_ENHANCEMENT // need to change ifndef to ifdef
src.x = src.y = 0;
src_input.w = src_origin.w = window->video_width;
src_input.h = src_origin.h = window->video_height;
GST_INFO ("wl_viewport_set_destination(%d,%d)", res.w, res.h);
/*need to swap */
- if (transform % 2 == 1) /*1, 3, 5, 7 */
- SWAP (src_input.w, src_input.h);
-
+ if (transform % 2 == 1){ /*1, 3, 5, 7 */
+ temp = src_input.w;
+ src_input.w = src_input.h;
+ src_input.h = temp;
+ }
wl_viewport_set_source (window->video_viewport,
wl_fixed_from_int (src_input.x), wl_fixed_from_int (src_input.y),
wl_fixed_from_int (src_input.w), wl_fixed_from_int (src_input.h));