waylandsink: Port to vmeta and GstVideoFrame

This add support for non-standard strides to be used. Note that
some extra work is needed for multi-plane format which may have
a different GstMemory object per plane. This is not currently a
problem since SHM interface is limited to 1 memory.
This commit is contained in:
Nicolas Dufresne 2016-09-19 12:11:59 -04:00
parent 74a7baa533
commit 3378b1a259

View file

@ -624,12 +624,25 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
"writing directly", buffer); "writing directly", buffer);
to_render = buffer; to_render = buffer;
} else { } else {
GstVideoMeta *vmeta;
GstMemory *mem; GstMemory *mem;
struct wl_buffer *wbuf = NULL; struct wl_buffer *wbuf = NULL;
/* update video info from video meta */
vmeta = gst_buffer_get_video_meta (buffer);
if (vmeta) {
gint i;
for (i = 0; i < vmeta->n_planes; i++) {
sink->video_info.offset[i] = vmeta->offset[i];
sink->video_info.stride[i] = vmeta->stride[i];
}
}
GST_LOG_OBJECT (sink, "buffer %p does not have a wl_buffer from our " GST_LOG_OBJECT (sink, "buffer %p does not have a wl_buffer from our "
"display, creating it", buffer); "display, creating it", buffer);
/* FIXME check all memory when introducing DMA-Buf */
mem = gst_buffer_peek_memory (buffer, 0); mem = gst_buffer_peek_memory (buffer, 0);
if (gst_is_wl_shm_memory (mem)) { if (gst_is_wl_shm_memory (mem)) {
@ -641,7 +654,9 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
gst_buffer_add_wl_buffer (buffer, wbuf, sink->display); gst_buffer_add_wl_buffer (buffer, wbuf, sink->display);
to_render = buffer; to_render = buffer;
} else { } else {
GstMapInfo src; GstVideoFrame src, dst;
GstVideoInfo src_info = sink->video_info;
/* we don't know how to create a wl_buffer directly from the provided /* 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 * memory, so we have to copy the data to a memory that we know how
* to handle... */ * to handle... */
@ -672,9 +687,19 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
gst_buffer_add_wl_buffer (to_render, wbuf, sink->display); gst_buffer_add_wl_buffer (to_render, wbuf, sink->display);
} }
gst_buffer_map (buffer, &src, GST_MAP_READ); if (!gst_video_frame_map (&dst, &sink->video_info, to_render,
gst_buffer_fill (to_render, 0, src.data, src.size); GST_MAP_WRITE))
gst_buffer_unmap (buffer, &src); goto dst_map_failed;
if (!gst_video_frame_map (&src, &src_info, buffer, GST_MAP_READ)) {
gst_video_frame_unmap (&dst);
goto src_map_failed;
}
gst_video_frame_copy (&dst, &src);
gst_video_frame_unmap (&src);
gst_video_frame_unmap (&dst);
} }
} }
@ -716,6 +741,20 @@ activate_failed:
ret = GST_FLOW_ERROR; ret = GST_FLOW_ERROR;
goto done; goto done;
} }
src_map_failed:
{
GST_ELEMENT_ERROR (sink, RESOURCE, READ,
("Video memory can not be read from userspace."), (NULL));
ret = GST_FLOW_ERROR;
goto done;
}
dst_map_failed:
{
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
("Video memory can not be written from userspace."), (NULL));
ret = GST_FLOW_ERROR;
goto done;
}
done: done:
{ {
g_mutex_unlock (&sink->render_lock); g_mutex_unlock (&sink->render_lock);