From 094fec0f3717ec330426a1c004d6350239926f2d Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Wed, 3 Jul 2019 19:54:36 +0800
|
Subject: [PATCH 07/13] HACK: xvimagesink: Support dma buffer rendering
|
|
Send dma buffer to xv port when it supports dma port attributes.
|
|
Change-Id: I69d94ffb700eb95af83799cdd5cde476d2930f92
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
sys/xvimage/meson.build | 4 +-
|
sys/xvimage/xvcontext.c | 71 +++++++++-
|
sys/xvimage/xvcontext.h | 20 +++
|
sys/xvimage/xvimagesink.c | 270 ++++++++++++++++++++++++++++++++++++--
|
sys/xvimage/xvimagesink.h | 10 ++
|
5 files changed, 361 insertions(+), 14 deletions(-)
|
|
diff --git a/sys/xvimage/meson.build b/sys/xvimage/meson.build
|
index f1aaecf1a..9b21c6046 100644
|
--- a/sys/xvimage/meson.build
|
+++ b/sys/xvimage/meson.build
|
@@ -12,6 +12,8 @@ if cc.has_argument ('-Wno-deprecated-declarations')
|
no_warn_args += '-Wno-deprecated-declarations'
|
endif
|
|
+libdrm_dep = dependency('libdrm')
|
+
|
xvideo_dep = dependency('xv', required : get_option('xvideo'))
|
|
if xvideo_dep.found()
|
@@ -19,7 +21,7 @@ if xvideo_dep.found()
|
xvimage_sources,
|
c_args : gst_plugins_base_args + no_warn_args,
|
include_directories: [configinc, libsinc],
|
- dependencies : glib_deps + [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep, xvideo_dep, libm],
|
+ dependencies : glib_deps + [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep, xvideo_dep, libdrm_dep, libm, allocators_dep],
|
install : true,
|
install_dir : plugins_install_dir,
|
)
|
diff --git a/sys/xvimage/xvcontext.c b/sys/xvimage/xvcontext.c
|
index 56dee97e0..839fb71aa 100644
|
--- a/sys/xvimage/xvcontext.c
|
+++ b/sys/xvimage/xvcontext.c
|
@@ -97,7 +97,7 @@ gst_lookup_xv_port_from_adaptor (GstXvContext * context,
|
the port via XvGrabPort */
|
static GstCaps *
|
gst_xvcontext_get_xv_support (GstXvContext * context,
|
- const GstXvContextConfig * config, GError ** error)
|
+ GstXvContextConfig * config, GError ** error)
|
{
|
gint i;
|
XvAdaptorInfo *adaptors;
|
@@ -150,9 +150,11 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
|
if (!context->xv_port_id)
|
goto no_ports;
|
|
+ config->dma_client_id = context->xv_port_id;
|
+
|
/* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */
|
{
|
- int count, todo = 4;
|
+ int count, todo = 7;
|
XvAttribute *const attr = XvQueryPortAttributes (context->disp,
|
context->xv_port_id, &count);
|
static const char autopaint[] = "XV_AUTOPAINT_COLORKEY";
|
@@ -160,6 +162,9 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
|
static const char colorkey[] = "XV_COLORKEY";
|
static const char iturbt709[] = "XV_ITURBT_709";
|
static const char *xv_colorspace = "XV_COLORSPACE";
|
+ static const char dma_client_id[] = XV_DMA_CLIENT_PROP;
|
+ static const char dma_drm_fourcc[] = XV_DMA_DRM_FOURCC_PROP;
|
+ static const char dma_drm_afbc[] = XV_DMA_DRM_AFBC_PROP;
|
|
GST_DEBUG ("Checking %d Xv port attributes", count);
|
|
@@ -168,6 +173,7 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
|
context->have_colorkey = FALSE;
|
context->have_iturbt709 = FALSE;
|
context->have_xvcolorspace = FALSE;
|
+ context->have_dma_client = FALSE;
|
|
for (i = 0; ((i < count) && todo); i++) {
|
GST_DEBUG ("Got attribute %s", attr[i].name);
|
@@ -239,6 +245,19 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
|
} else if (!strcmp (attr[i].name, xv_colorspace)) {
|
context->have_xvcolorspace = TRUE;
|
todo--;
|
+ } else if (!strcmp (attr[i].name, dma_client_id)) {
|
+ const Atom atom = XInternAtom (context->disp, dma_client_id, False);
|
+
|
+ XvSetPortAttribute (context->disp, context->xv_port_id, atom,
|
+ config->dma_client_id);
|
+ todo--;
|
+ context->have_dma_client = TRUE;
|
+ } else if (!strcmp (attr[i].name, dma_drm_fourcc)) {
|
+ todo--;
|
+ context->have_dma_drm_fourcc = TRUE;
|
+ } else if (!strcmp (attr[i].name, dma_drm_afbc)) {
|
+ todo--;
|
+ context->have_dma_drm_afbc = TRUE;
|
}
|
}
|
|
@@ -353,6 +372,50 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
|
if (gst_caps_is_empty (caps))
|
goto no_caps;
|
|
+ if (context->have_dma_drm_afbc) {
|
+ GstCaps *format_caps;
|
+
|
+ format_caps = gst_caps_new_simple ("video/x-raw",
|
+ "format", G_TYPE_STRING, "NV12",
|
+ "width", GST_TYPE_INT_RANGE, 1, max_w,
|
+ "height", GST_TYPE_INT_RANGE, 1, max_h,
|
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
+ gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
|
+ gst_caps_append (caps, format_caps);
|
+ }
|
+
|
+ if (context->have_dma_drm_fourcc) {
|
+ GstCaps *format_caps;
|
+
|
+ format_caps = gst_caps_new_simple ("video/x-raw",
|
+ "format", G_TYPE_STRING, "NV16",
|
+ "width", GST_TYPE_INT_RANGE, 1, max_w,
|
+ "height", GST_TYPE_INT_RANGE, 1, max_h,
|
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
+ if (context->have_dma_drm_afbc) {
|
+ gst_caps_ref (format_caps);
|
+ gst_caps_append (caps, format_caps);
|
+
|
+ gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
|
+ }
|
+ gst_caps_append (caps, format_caps);
|
+
|
+ format_caps = gst_caps_new_simple ("video/x-raw",
|
+ "format", G_TYPE_STRING, "NV12_10LE40",
|
+ "width", GST_TYPE_INT_RANGE, 1, max_w,
|
+ "height", GST_TYPE_INT_RANGE, 1, max_h,
|
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
+ if (context->have_dma_drm_afbc) {
|
+ gst_caps_ref (format_caps);
|
+ gst_caps_append (caps, format_caps);
|
+
|
+ gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
|
+ }
|
+ gst_caps_append (caps, format_caps);
|
+ }
|
+
|
+ GST_DEBUG ("Final caps caps: %" GST_PTR_FORMAT, caps);
|
+
|
return caps;
|
|
/* ERRORS */
|
@@ -891,6 +954,10 @@ gst_xvcontext_get_format_from_info (GstXvContext * context,
|
{
|
GList *list = NULL;
|
|
+ /* HACK: Use NV12 format for fake formats */
|
+ if (context->drm_fourcc != -1)
|
+ return DRM_FORMAT_NV12;
|
+
|
list = context->formats_list;
|
|
while (list) {
|
diff --git a/sys/xvimage/xvcontext.h b/sys/xvimage/xvcontext.h
|
index 701b527fa..607f6f934 100644
|
--- a/sys/xvimage/xvcontext.h
|
+++ b/sys/xvimage/xvcontext.h
|
@@ -42,6 +42,19 @@
|
|
#include <gst/video/video.h>
|
|
+#include <libdrm/drm_fourcc.h>
|
+
|
+#define XV_DMA_CLIENT_PROP "XV_DMA_CLIENT_ID"
|
+#define XV_DMA_VER_STRIDE_PROP "XV_DMA_VER_STRIDE"
|
+#define XV_DMA_HOR_STRIDE_PROP "XV_DMA_HOR_STRIDE"
|
+#define XV_DMA_DRM_FOURCC_PROP "XV_DMA_DRM_FOURCC"
|
+#define XV_DMA_DRM_AFBC_PROP "XV_DMA_DRM_AFBC"
|
+#define XV_DMA_CLIENT_PATH "/tmp/.xv_dma_client"
|
+
|
+#ifndef DRM_FORMAT_NV12_10
|
+#define DRM_FORMAT_NV12_10 fourcc_code('N', 'A', '1', '2')
|
+#endif
|
+
|
G_BEGIN_DECLS
|
|
typedef struct _GstXvContextConfig GstXvContextConfig;
|
@@ -69,6 +82,8 @@ struct _GstXvContextConfig
|
gint hue;
|
gint saturation;
|
gboolean cb_changed;
|
+
|
+ guint dma_client_id;
|
};
|
|
/**
|
@@ -161,6 +176,11 @@ struct _GstXvContext
|
gboolean have_double_buffer;
|
gboolean have_iturbt709;
|
gboolean have_xvcolorspace;
|
+ gboolean have_dma_client;
|
+ gboolean have_dma_drm_fourcc;
|
+ gboolean have_dma_drm_afbc;
|
+
|
+ guint32 drm_fourcc;
|
|
GList *formats_list;
|
|
diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
|
index 993d3f773..00f995a8e 100644
|
--- a/sys/xvimage/xvimagesink.c
|
+++ b/sys/xvimage/xvimagesink.c
|
@@ -121,6 +121,7 @@
|
#include <gst/video/colorbalance.h>
|
/* Helper functions */
|
#include <gst/video/gstvideometa.h>
|
+#include <gst/allocators/gstdmabuf.h>
|
|
/* Object header */
|
#include "xvimagesink.h"
|
@@ -132,6 +133,11 @@
|
/* for XkbKeycodeToKeysym */
|
#include <X11/XKBlib.h>
|
|
+#include <stdio.h>
|
+#include <unistd.h>
|
+#include <sys/socket.h>
|
+#include <sys/un.h>
|
+
|
GST_DEBUG_CATEGORY_EXTERN (gst_debug_xv_context);
|
GST_DEBUG_CATEGORY_EXTERN (gst_debug_xv_image_pool);
|
GST_DEBUG_CATEGORY (gst_debug_xv_image_sink);
|
@@ -230,6 +236,173 @@ GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (xvimagesink, "xvimagesink",
|
/* */
|
/* ============================================================= */
|
|
+static void
|
+gst_xv_image_sink_check_dma_client (GstXvImageSink * xvimagesink)
|
+{
|
+ GstXvContext *context = xvimagesink->context;
|
+ Atom prop_atom;
|
+ int xv_value = 0;
|
+
|
+ if (!context->have_dma_client)
|
+ return;
|
+
|
+ g_mutex_lock (&context->lock);
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvGetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, &xv_value);
|
+ }
|
+ g_mutex_unlock (&context->lock);
|
+
|
+ context->have_dma_client = xv_value > 0;
|
+}
|
+
|
+static void
|
+gst_xv_image_sink_flush_dma_client (GstXvImageSink * xvimagesink)
|
+{
|
+ GstXvContext *context = xvimagesink->context;
|
+ Atom prop_atom;
|
+ int xv_value;
|
+
|
+ if (!context->have_dma_client)
|
+ return;
|
+
|
+ g_mutex_lock (&context->lock);
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, xvimagesink->config.dma_client_id);
|
+ XvGetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, &xv_value);
|
+ }
|
+ g_mutex_unlock (&context->lock);
|
+}
|
+
|
+static void
|
+gst_xv_image_sink_disable_dma_client (GstXvImageSink * xvimagesink)
|
+{
|
+ GstXvContext *context = xvimagesink->context;
|
+ Atom prop_atom;
|
+
|
+ if (!context->have_dma_client)
|
+ return;
|
+
|
+ g_mutex_lock (&context->lock);
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id, prop_atom, 0);
|
+ }
|
+ g_mutex_unlock (&context->lock);
|
+
|
+ context->have_dma_client = FALSE;
|
+}
|
+
|
+static gboolean
|
+gst_xv_image_sink_send_dma_params (GstXvImageSink * xvimagesink,
|
+ gint hor_stride, gint ver_stride, gboolean afbc)
|
+{
|
+ GstXvContext *context = xvimagesink->context;
|
+ Atom prop_atom;
|
+ gboolean error = FALSE;
|
+
|
+ if (!context->have_dma_client)
|
+ return FALSE;
|
+
|
+ g_mutex_lock (&context->lock);
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_HOR_STRIDE_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, hor_stride);
|
+ } else {
|
+ error = TRUE;
|
+ }
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_VER_STRIDE_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, ver_stride);
|
+ } else {
|
+ error = TRUE;
|
+ }
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_DRM_FOURCC_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id,
|
+ prop_atom, context->drm_fourcc);
|
+ }
|
+ prop_atom = XInternAtom (context->disp, XV_DMA_DRM_AFBC_PROP, True);
|
+ if (prop_atom != None) {
|
+ XvSetPortAttribute (context->disp, context->xv_port_id, prop_atom, afbc);
|
+ }
|
+ g_mutex_unlock (&context->lock);
|
+
|
+ if (error == TRUE) {
|
+ gst_xv_image_sink_disable_dma_client (xvimagesink);
|
+ return FALSE;
|
+ }
|
+
|
+ return TRUE;
|
+}
|
+
|
+static gboolean
|
+gst_xv_image_sink_send_dma_fd (GstXvImageSink * xvimagesink, gint dma_fd)
|
+{
|
+ GstXvContext *context = xvimagesink->context;
|
+ struct sockaddr_un addr;
|
+ struct iovec iov;
|
+ struct msghdr msg;
|
+ struct cmsghdr *header;
|
+ gchar buf[CMSG_SPACE (sizeof (int))];
|
+ gint socket_fd;
|
+
|
+ if (!context->have_dma_client)
|
+ return FALSE;
|
+
|
+ gst_xv_image_sink_flush_dma_client (xvimagesink);
|
+
|
+ socket_fd = socket (PF_UNIX, SOCK_DGRAM, 0);
|
+ if (socket_fd < 0)
|
+ goto failed;
|
+
|
+ addr.sun_family = AF_LOCAL;
|
+ snprintf (addr.sun_path, sizeof (addr.sun_path),
|
+ XV_DMA_CLIENT_PATH ".%d", xvimagesink->config.dma_client_id);
|
+ addr.sun_path[sizeof (addr.sun_path) - 1] = '\0';
|
+
|
+ if (connect (socket_fd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
|
+ goto failed;
|
+
|
+ iov.iov_base = buf;
|
+ iov.iov_len = 1;
|
+
|
+ msg.msg_iov = &iov;
|
+ msg.msg_iovlen = 1;
|
+ msg.msg_control = buf;
|
+ msg.msg_controllen = sizeof (buf);
|
+ msg.msg_name = NULL;
|
+ msg.msg_namelen = 0;
|
+
|
+ header = CMSG_FIRSTHDR (&msg);
|
+ header->cmsg_level = SOL_SOCKET;
|
+ header->cmsg_type = SCM_RIGHTS;
|
+
|
+ header->cmsg_len = CMSG_LEN (sizeof (int));
|
+ *((int *) CMSG_DATA (header)) = dma_fd;
|
+ sendmsg (socket_fd, &msg, 0);
|
+
|
+ /* Send am empty msg at the end */
|
+ header->cmsg_len = CMSG_LEN (0);
|
+ sendmsg (socket_fd, &msg, 0);
|
+
|
+ close (socket_fd);
|
+ return TRUE;
|
+
|
+failed:
|
+ gst_xv_image_sink_disable_dma_client (xvimagesink);
|
+
|
+ if (socket_fd >= 0)
|
+ close (socket_fd);
|
+
|
+ return FALSE;
|
+}
|
|
/* This function puts a GstXvImage on a GstXvImageSink's window. Returns FALSE
|
* if no window was available */
|
@@ -317,6 +490,13 @@ gst_xv_image_sink_xvimage_put (GstXvImageSink * xvimagesink,
|
memcpy (&result, &xwindow->render_rect, sizeof (GstVideoRectangle));
|
}
|
|
+ if (gst_buffer_n_memory (xvimage) > 1) {
|
+ GstMemory *dma_mem = gst_buffer_peek_memory (xvimage, 1);
|
+ gint dma_fd = gst_dmabuf_memory_get_fd (dma_mem);
|
+ if (dma_fd >= 0)
|
+ gst_xv_image_sink_send_dma_fd (xvimagesink, dma_fd);
|
+ }
|
+
|
gst_xvimage_memory_render (mem, &src, xwindow, &result, draw_border);
|
|
g_mutex_unlock (&xvimagesink->flow_lock);
|
@@ -699,6 +879,27 @@ config_failed:
|
}
|
}
|
|
+static gboolean
|
+gst_xv_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
|
+{
|
+ GstStructure *s;
|
+ gint value;
|
+
|
+ if (!gst_video_info_from_caps (info, caps))
|
+ return FALSE;
|
+
|
+ /* parse AFBC from caps */
|
+ s = gst_caps_get_structure (caps, 0);
|
+ if (gst_structure_get_int (s, "arm-afbc", &value)) {
|
+ if (value)
|
+ GST_VIDEO_INFO_SET_AFBC (info);
|
+ else
|
+ GST_VIDEO_INFO_UNSET_AFBC (info);
|
+ }
|
+
|
+ return TRUE;
|
+}
|
+
|
static gboolean
|
gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
{
|
@@ -721,7 +922,7 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
if (!gst_caps_can_intersect (context->caps, caps))
|
goto incompatible_caps;
|
|
- if (!gst_video_info_from_caps (&info, caps))
|
+ if (!gst_xv_video_info_from_caps (&info, caps))
|
goto invalid_format;
|
|
xvimagesink->fps_n = info.fps_n;
|
@@ -831,6 +1032,20 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
gst_object_unref (oldpool);
|
}
|
|
+ context->drm_fourcc = -1;
|
+
|
+ if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_NV12_10LE40) {
|
+ if (!context->have_dma_drm_fourcc)
|
+ return FALSE;
|
+
|
+ context->drm_fourcc = DRM_FORMAT_NV12_10;
|
+ } else if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_NV16) {
|
+ if (!context->have_dma_drm_fourcc)
|
+ return FALSE;
|
+
|
+ context->drm_fourcc = DRM_FORMAT_NV16;
|
+ }
|
+
|
return TRUE;
|
|
/* ERRORS */
|
@@ -983,6 +1198,47 @@ gst_xv_image_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
if (res != GST_FLOW_OK)
|
goto no_buffer;
|
|
+ if ((crop_meta = gst_buffer_get_video_crop_meta (buf))) {
|
+ GstVideoCropMeta *dmeta = gst_buffer_add_video_crop_meta (to_put);
|
+
|
+ dmeta->x = crop_meta->x;
|
+ dmeta->y = crop_meta->y;
|
+ dmeta->width = crop_meta->width;
|
+ dmeta->height = crop_meta->height;
|
+ }
|
+
|
+ mem = gst_buffer_peek_memory (buf, 0);
|
+ gst_xv_image_sink_check_dma_client (xvimagesink);
|
+ if (gst_is_dmabuf_memory (mem) && xvimagesink->context->have_dma_client) {
|
+ GstVideoMeta *vmeta = gst_buffer_get_video_meta (buf);
|
+ gint hor_stride, ver_stride;
|
+
|
+ /* If this buffer is dmabuf and the xserver supports dma_client, we will
|
+ send the dmabuf fd directly */
|
+ GST_LOG_OBJECT (xvimagesink, "buffer %p is dmabuf, will send dmabuf fd",
|
+ buf);
|
+
|
+ /* Stash the dmabuf in index 1 */
|
+ gst_buffer_insert_memory (to_put, 1, gst_buffer_get_memory (buf, 0));
|
+
|
+ /* Try to send dmabuf params */
|
+ if (vmeta) {
|
+ hor_stride = vmeta->stride[0];
|
+ ver_stride = vmeta->height;
|
+
|
+ if (vmeta->n_planes > 1)
|
+ ver_stride = vmeta->offset[1] / hor_stride;
|
+ } else {
|
+ hor_stride = xvimagesink->info.width;
|
+ ver_stride = xvimagesink->info.height;
|
+ }
|
+
|
+ if (gst_xv_image_sink_send_dma_params (xvimagesink,
|
+ hor_stride, ver_stride,
|
+ GST_VIDEO_INFO_IS_AFBC (&xvimagesink->info)))
|
+ goto put_image;
|
+ }
|
+
|
GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
|
"slow copy buffer %p into bufferpool buffer %p", buf, to_put);
|
|
@@ -998,17 +1254,9 @@ gst_xv_image_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
|
gst_video_frame_unmap (&dest);
|
gst_video_frame_unmap (&src);
|
-
|
- if ((crop_meta = gst_buffer_get_video_crop_meta (buf))) {
|
- GstVideoCropMeta *dmeta = gst_buffer_add_video_crop_meta (to_put);
|
-
|
- dmeta->x = crop_meta->x;
|
- dmeta->y = crop_meta->y;
|
- dmeta->width = crop_meta->width;
|
- dmeta->height = crop_meta->height;
|
- }
|
}
|
|
+put_image:
|
if (!gst_xv_image_sink_xvimage_put (xvimagesink, to_put))
|
goto no_window;
|
|
@@ -1097,7 +1345,7 @@ gst_xv_image_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
if (caps == NULL)
|
goto no_caps;
|
|
- if (!gst_video_info_from_caps (&info, caps))
|
+ if (!gst_xv_video_info_from_caps (&info, caps))
|
goto invalid_caps;
|
|
/* the normal size of a frame */
|
diff --git a/sys/xvimage/xvimagesink.h b/sys/xvimage/xvimagesink.h
|
index 6f5ffa156..35a3081e9 100644
|
--- a/sys/xvimage/xvimagesink.h
|
+++ b/sys/xvimage/xvimagesink.h
|
@@ -25,6 +25,16 @@
|
/* Helper functions */
|
#include <gst/video/video.h>
|
|
+#ifndef GST_VIDEO_FLAG_ARM_AFBC
|
+#define GST_VIDEO_FLAG_ARM_AFBC (1UL << 31)
|
+#define GST_VIDEO_INFO_SET_AFBC(i) \
|
+ GST_VIDEO_INFO_FLAG_SET (i, GST_VIDEO_FLAG_ARM_AFBC)
|
+#define GST_VIDEO_INFO_UNSET_AFBC(i) \
|
+ GST_VIDEO_INFO_FLAG_UNSET (i, GST_VIDEO_FLAG_ARM_AFBC)
|
+#define GST_VIDEO_INFO_IS_AFBC(i) \
|
+ GST_VIDEO_INFO_FLAG_IS_SET (i, GST_VIDEO_FLAG_ARM_AFBC)
|
+#endif
|
+
|
G_BEGIN_DECLS
|
#define GST_TYPE_XV_IMAGE_SINK \
|
(gst_xv_image_sink_get_type())
|
--
|
2.20.1
|