struct wl_buffer * gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info) { 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; 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; }
static GstCaps * gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) { GstWaylandSink *sink; GstCaps *caps; sink = GST_WAYLAND_SINK (bsink); caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); g_mutex_lock (&sink->display_lock); if (sink->display) { GValue list = G_VALUE_INIT; GValue value = G_VALUE_INIT; GArray *formats; gint i; enum wl_shm_format fmt; g_value_init (&list, GST_TYPE_LIST); g_value_init (&value, G_TYPE_STRING); formats = sink->display->shm_formats; for (i = 0; i < formats->len; i++) { fmt = g_array_index (formats, uint32_t, i); g_value_set_string (&value, gst_wl_shm_format_to_string (fmt)); gst_value_list_append_value (&list, &value); } caps = gst_caps_make_writable (caps); gst_structure_set_value (gst_caps_get_structure (caps, 0), "format", &list); GST_DEBUG_OBJECT (sink, "display caps: %" GST_PTR_FORMAT, caps); } g_mutex_unlock (&sink->display_lock); if (filter) { GstCaps *intersection; intersection = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); caps = intersection; } return caps; }
struct wl_buffer * gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info) { gint width, height, stride; gsize offset, size, memsize, maxsize; enum wl_shm_format format; struct wl_shm_pool *wl_pool; struct wl_buffer *wbuffer; if (!gst_wl_shm_validate_video_info (info)) { GST_DEBUG_OBJECT (display, "Unsupported strides and offsets."); return NULL; } 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)); memsize = gst_memory_get_sizes (mem, &offset, &maxsize); offset += GST_VIDEO_INFO_PLANE_OFFSET (info, 0); g_return_val_if_fail (gst_is_fd_memory (mem), NULL); g_return_val_if_fail (size <= memsize, NULL); g_return_val_if_fail (gst_wl_display_check_format_for_shm (display, GST_VIDEO_INFO_FORMAT (info)), NULL); GST_DEBUG_OBJECT (display, "Creating wl_buffer from SHM 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, gst_fd_memory_get_fd (mem), memsize); wbuffer = wl_shm_pool_create_buffer (wl_pool, offset, width, height, stride, format); wl_shm_pool_destroy (wl_pool); return wbuffer; }
static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstWaylandSink *sink; GstBufferPool *newpool; GstVideoInfo info; enum wl_shm_format format; GArray *formats; gint i; GstStructure *structure; sink = GST_WAYLAND_SINK (bsink); GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); /* extract info from caps */ if (!gst_video_info_from_caps (&info, caps)) goto invalid_format; format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (&info)); if ((gint) format == -1) goto invalid_format; /* verify we support the requested format */ formats = sink->display->shm_formats; for (i = 0; i < formats->len; i++) { if (g_array_index (formats, uint32_t, i) == format) break; } if (i >= formats->len) goto unsupported_format; /* create a new pool for the new configuration */ newpool = gst_video_buffer_pool_new (); 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, gst_wl_shm_allocator_get (), NULL); if (!gst_buffer_pool_set_config (newpool, structure)) goto config_failed; /* store the video info */ sink->video_info = info; sink->video_info_changed = TRUE; gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); gst_object_unref (newpool); return TRUE; invalid_format: { GST_DEBUG_OBJECT (sink, "Could not locate image format from caps %" GST_PTR_FORMAT, caps); return FALSE; } unsupported_format: { GST_DEBUG_OBJECT (sink, "Format %s is not available on the display", gst_wl_shm_format_to_string (format)); return FALSE; } pool_failed: { GST_DEBUG_OBJECT (sink, "Failed to create new pool"); return FALSE; } config_failed: { GST_DEBUG_OBJECT (bsink, "failed setting config"); gst_object_unref (newpool); return FALSE; } }