2022-01-04 14:20:41 +00:00
|
|
|
/* GStreamer Wayland Library
|
2016-09-22 09:10:47 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2016 STMicroelectronics SA
|
|
|
|
* Copyright (C) 2016 Fabien Dessenne <fabien.dessenne@st.com>
|
2022-01-04 14:20:41 +00:00
|
|
|
* Copyright (C) 2022 Collabora Ltd.
|
2016-09-22 09:10:47 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free
|
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2022-01-04 14:20:41 +00:00
|
|
|
#include "gstwllinuxdmabuf.h"
|
2016-09-22 09:10:47 +00:00
|
|
|
|
2022-01-04 14:20:41 +00:00
|
|
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
2016-09-22 09:10:47 +00:00
|
|
|
|
2022-01-04 14:20:41 +00:00
|
|
|
GST_DEBUG_CATEGORY (gst_wl_dmabuf_debug);
|
|
|
|
#define GST_CAT_DEFAULT gst_wl_dmabuf_debug
|
|
|
|
|
|
|
|
void
|
|
|
|
gst_wl_linux_dmabuf_init_once (void)
|
|
|
|
{
|
|
|
|
static gsize _init = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&_init)) {
|
|
|
|
GST_DEBUG_CATEGORY_INIT (gst_wl_dmabuf_debug, "wl_dmabuf", 0,
|
|
|
|
"wl_dmabuf library");
|
|
|
|
|
|
|
|
g_once_init_leave (&_init, 1);
|
|
|
|
}
|
|
|
|
}
|
2016-09-22 09:10:47 +00:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GMutex lock;
|
|
|
|
GCond cond;
|
|
|
|
struct wl_buffer *wbuf;
|
|
|
|
} ConstructBufferData;
|
|
|
|
|
|
|
|
static void
|
|
|
|
create_succeeded (void *data, struct zwp_linux_buffer_params_v1 *params,
|
|
|
|
struct wl_buffer *new_buffer)
|
|
|
|
{
|
|
|
|
ConstructBufferData *d = data;
|
|
|
|
|
|
|
|
g_mutex_lock (&d->lock);
|
|
|
|
d->wbuf = new_buffer;
|
|
|
|
zwp_linux_buffer_params_v1_destroy (params);
|
|
|
|
g_cond_signal (&d->cond);
|
|
|
|
g_mutex_unlock (&d->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
create_failed (void *data, struct zwp_linux_buffer_params_v1 *params)
|
|
|
|
{
|
|
|
|
ConstructBufferData *d = data;
|
|
|
|
|
|
|
|
g_mutex_lock (&d->lock);
|
|
|
|
d->wbuf = NULL;
|
|
|
|
zwp_linux_buffer_params_v1_destroy (params);
|
|
|
|
g_cond_signal (&d->cond);
|
|
|
|
g_mutex_unlock (&d->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct zwp_linux_buffer_params_v1_listener params_listener = {
|
|
|
|
create_succeeded,
|
|
|
|
create_failed
|
|
|
|
};
|
|
|
|
|
|
|
|
struct wl_buffer *
|
|
|
|
gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
2023-07-25 03:37:02 +00:00
|
|
|
GstWlDisplay * display, const GstVideoInfo * info, guint64 modifier)
|
2016-09-22 09:10:47 +00:00
|
|
|
{
|
|
|
|
GstMemory *mem;
|
2017-03-13 10:46:47 +00:00
|
|
|
int format;
|
|
|
|
guint i, width, height;
|
2023-02-17 02:12:08 +00:00
|
|
|
const gsize *offsets = info->offset;
|
|
|
|
const gint *strides = info->stride;
|
|
|
|
GstVideoMeta *vmeta;
|
2017-03-13 10:46:47 +00:00
|
|
|
guint nplanes, flags = 0;
|
2016-09-22 09:10:47 +00:00
|
|
|
struct zwp_linux_buffer_params_v1 *params;
|
|
|
|
gint64 timeout;
|
|
|
|
ConstructBufferData data;
|
|
|
|
|
2016-09-29 20:30:33 +00:00
|
|
|
g_return_val_if_fail (gst_wl_display_check_format_for_dmabuf (display,
|
2023-07-25 03:37:02 +00:00
|
|
|
GST_VIDEO_INFO_FORMAT (info), modifier), NULL);
|
2016-09-29 20:30:33 +00:00
|
|
|
|
2016-09-22 09:10:47 +00:00
|
|
|
mem = gst_buffer_peek_memory (buf, 0);
|
|
|
|
format = gst_video_format_to_wl_dmabuf_format (GST_VIDEO_INFO_FORMAT (info));
|
|
|
|
|
|
|
|
g_cond_init (&data.cond);
|
|
|
|
g_mutex_init (&data.lock);
|
|
|
|
g_mutex_lock (&data.lock);
|
|
|
|
|
|
|
|
width = GST_VIDEO_INFO_WIDTH (info);
|
|
|
|
height = GST_VIDEO_INFO_HEIGHT (info);
|
|
|
|
nplanes = GST_VIDEO_INFO_N_PLANES (info);
|
|
|
|
|
2023-02-17 02:12:08 +00:00
|
|
|
vmeta = gst_buffer_get_video_meta (buf);
|
|
|
|
if (vmeta) {
|
|
|
|
offsets = vmeta->offset;
|
|
|
|
strides = vmeta->stride;
|
|
|
|
}
|
|
|
|
|
2023-07-25 03:37:02 +00:00
|
|
|
const gchar *format_string =
|
|
|
|
gst_wl_dmabuf_format_to_string (format, modifier);
|
|
|
|
GST_DEBUG_OBJECT (display,
|
|
|
|
"Creating wl_buffer from DMABuf of size %" G_GSSIZE_FORMAT
|
|
|
|
" (%d x %d), format %s", info->size, width, height, format_string);
|
2016-09-29 20:30:33 +00:00
|
|
|
|
2016-09-22 09:10:47 +00:00
|
|
|
/* Creation and configuration of planes */
|
2022-01-04 14:20:41 +00:00
|
|
|
params = zwp_linux_dmabuf_v1_create_params (gst_wl_display_get_dmabuf_v1
|
|
|
|
(display));
|
2016-09-22 09:10:47 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nplanes; i++) {
|
2017-03-13 10:46:47 +00:00
|
|
|
guint offset, stride, mem_idx, length;
|
|
|
|
gsize skip;
|
|
|
|
|
2023-02-17 02:12:08 +00:00
|
|
|
offset = offsets[i];
|
|
|
|
stride = strides[i];
|
2017-03-13 10:46:47 +00:00
|
|
|
if (gst_buffer_find_memory (buf, offset, 1, &mem_idx, &length, &skip)) {
|
|
|
|
GstMemory *m = gst_buffer_peek_memory (buf, mem_idx);
|
|
|
|
gint fd = gst_dmabuf_memory_get_fd (m);
|
|
|
|
zwp_linux_buffer_params_v1_add (params, fd, i, m->offset + skip,
|
2023-07-25 03:37:02 +00:00
|
|
|
stride, modifier >> 32, modifier & G_GUINT64_CONSTANT (0x0ffffffff));
|
2017-03-13 10:46:47 +00:00
|
|
|
} else {
|
|
|
|
GST_ERROR_OBJECT (mem->allocator, "memory does not seem to contain "
|
|
|
|
"enough data for the specified format");
|
|
|
|
zwp_linux_buffer_params_v1_destroy (params);
|
|
|
|
data.wbuf = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
2016-09-22 09:10:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
|
|
|
|
GST_DEBUG_OBJECT (mem->allocator, "interlaced buffer");
|
|
|
|
flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED;
|
|
|
|
|
|
|
|
if (!GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_TFF)) {
|
|
|
|
GST_DEBUG_OBJECT (mem->allocator, "with bottom field first");
|
|
|
|
flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Request buffer creation */
|
|
|
|
zwp_linux_buffer_params_v1_add_listener (params, ¶ms_listener, &data);
|
|
|
|
zwp_linux_buffer_params_v1_create (params, width, height, format, flags);
|
|
|
|
|
|
|
|
/* Wait for the request answer */
|
2022-01-04 14:20:41 +00:00
|
|
|
wl_display_flush (gst_wl_display_get_display (display));
|
2016-09-22 09:10:47 +00:00
|
|
|
data.wbuf = (gpointer) 0x1;
|
|
|
|
timeout = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
|
|
|
|
while (data.wbuf == (gpointer) 0x1) {
|
|
|
|
if (!g_cond_wait_until (&data.cond, &data.lock, timeout)) {
|
|
|
|
GST_ERROR_OBJECT (mem->allocator, "zwp_linux_buffer_params_v1 time out");
|
|
|
|
zwp_linux_buffer_params_v1_destroy (params);
|
|
|
|
data.wbuf = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-13 10:46:47 +00:00
|
|
|
out:
|
2016-09-22 09:10:47 +00:00
|
|
|
if (!data.wbuf) {
|
|
|
|
GST_ERROR_OBJECT (mem->allocator, "can't create linux-dmabuf buffer");
|
|
|
|
} else {
|
|
|
|
GST_DEBUG_OBJECT (mem->allocator, "created linux_dmabuf wl_buffer (%p):"
|
2023-02-17 14:42:42 +00:00
|
|
|
"%dx%d, fmt=%" GST_FOURCC_FORMAT ", %d planes",
|
|
|
|
data.wbuf, width, height, GST_FOURCC_ARGS (format), nplanes);
|
2016-09-22 09:10:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_mutex_unlock (&data.lock);
|
|
|
|
g_mutex_clear (&data.lock);
|
|
|
|
g_cond_clear (&data.cond);
|
|
|
|
|
|
|
|
return data.wbuf;
|
|
|
|
}
|