1From 7f63060162edc2aee11f727acf5c764b24f3587a Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Wed, 3 Jul 2019 19:54:36 +0800
4Subject: [PATCH 07/14] HACK: xvimagesink: Support dma buffer rendering
5
6Send dma buffer to xv port when it supports dma port attributes.
7
8Change-Id: I69d94ffb700eb95af83799cdd5cde476d2930f92
9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10---
11 sys/xvimage/meson.build   |   4 +-
12 sys/xvimage/xvcontext.c   |  71 +++++++++-
13 sys/xvimage/xvcontext.h   |  20 +++
14 sys/xvimage/xvimagesink.c | 270 ++++++++++++++++++++++++++++++++++++--
15 sys/xvimage/xvimagesink.h |  10 ++
16 5 files changed, 361 insertions(+), 14 deletions(-)
17
18diff --git a/sys/xvimage/meson.build b/sys/xvimage/meson.build
19index ce84ed0..2873c9b 100644
20--- a/sys/xvimage/meson.build
21+++ b/sys/xvimage/meson.build
22@@ -12,6 +12,8 @@ if cc.has_argument ('-Wno-deprecated-declarations')
23   no_warn_args += '-Wno-deprecated-declarations'
24 endif
25
26+libdrm_dep = dependency('libdrm')
27+
28 xvideo_dep = dependency('xv', required : get_option('xvideo'))
29
30 if xvideo_dep.found()
31@@ -19,7 +21,7 @@ if xvideo_dep.found()
32     xvimage_sources,
33     c_args : gst_plugins_base_args + no_warn_args,
34     include_directories: [configinc, libsinc],
35-    dependencies : [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep, xvideo_dep, xi_dep, libm],
36+    dependencies : [video_dep, gst_base_dep, gst_dep, x11_dep, xshm_dep, xvideo_dep, xi_dep, libdrm_dep, libm, allocators_dep],
37     install : true,
38     install_dir : plugins_install_dir,
39   )
40diff --git a/sys/xvimage/xvcontext.c b/sys/xvimage/xvcontext.c
41index 75bebd9..975c3a9 100644
42--- a/sys/xvimage/xvcontext.c
43+++ b/sys/xvimage/xvcontext.c
44@@ -105,7 +105,7 @@ gst_lookup_xv_port_from_adaptor (GstXvContext * context,
45    the port via XvGrabPort */
46 static GstCaps *
47 gst_xvcontext_get_xv_support (GstXvContext * context,
48-    const GstXvContextConfig * config, GError ** error)
49+    GstXvContextConfig * config, GError ** error)
50 {
51   gint i;
52   XvAdaptorInfo *adaptors;
53@@ -158,9 +158,11 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
54   if (!context->xv_port_id)
55     goto no_ports;
56
57+  config->dma_client_id = context->xv_port_id;
58+
59   /* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */
60   {
61-    int count, todo = 4;
62+    int count, todo = 7;
63     XvAttribute *const attr = XvQueryPortAttributes (context->disp,
64         context->xv_port_id, &count);
65     static const char autopaint[] = "XV_AUTOPAINT_COLORKEY";
66@@ -168,6 +170,9 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
67     static const char colorkey[] = "XV_COLORKEY";
68     static const char iturbt709[] = "XV_ITURBT_709";
69     static const char *xv_colorspace = "XV_COLORSPACE";
70+    static const char dma_client_id[] = XV_DMA_CLIENT_PROP;
71+    static const char dma_drm_fourcc[] = XV_DMA_DRM_FOURCC_PROP;
72+    static const char dma_drm_afbc[] = XV_DMA_DRM_AFBC_PROP;
73
74     GST_DEBUG ("Checking %d Xv port attributes", count);
75
76@@ -176,6 +181,7 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
77     context->have_colorkey = FALSE;
78     context->have_iturbt709 = FALSE;
79     context->have_xvcolorspace = FALSE;
80+    context->have_dma_client = FALSE;
81
82     for (i = 0; ((i < count) && todo); i++) {
83       GST_DEBUG ("Got attribute %s", attr[i].name);
84@@ -247,6 +253,19 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
85       } else if (!strcmp (attr[i].name, xv_colorspace)) {
86         context->have_xvcolorspace = TRUE;
87         todo--;
88+      } else if (!strcmp (attr[i].name, dma_client_id)) {
89+        const Atom atom = XInternAtom (context->disp, dma_client_id, False);
90+
91+        XvSetPortAttribute (context->disp, context->xv_port_id, atom,
92+            config->dma_client_id);
93+        todo--;
94+        context->have_dma_client = TRUE;
95+      } else if (!strcmp (attr[i].name, dma_drm_fourcc)) {
96+        todo--;
97+        context->have_dma_drm_fourcc = TRUE;
98+      } else if (!strcmp (attr[i].name, dma_drm_afbc)) {
99+        todo--;
100+        context->have_dma_drm_afbc = TRUE;
101       }
102     }
103
104@@ -361,6 +380,50 @@ gst_xvcontext_get_xv_support (GstXvContext * context,
105   if (gst_caps_is_empty (caps))
106     goto no_caps;
107
108+  if (context->have_dma_drm_afbc) {
109+    GstCaps *format_caps;
110+
111+    format_caps = gst_caps_new_simple ("video/x-raw",
112+        "format", G_TYPE_STRING, "NV12",
113+        "width", GST_TYPE_INT_RANGE, 1, max_w,
114+        "height", GST_TYPE_INT_RANGE, 1, max_h,
115+        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
116+    gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
117+    gst_caps_append (caps, format_caps);
118+  }
119+
120+  if (context->have_dma_drm_fourcc) {
121+    GstCaps *format_caps;
122+
123+    format_caps = gst_caps_new_simple ("video/x-raw",
124+        "format", G_TYPE_STRING, "NV16",
125+        "width", GST_TYPE_INT_RANGE, 1, max_w,
126+        "height", GST_TYPE_INT_RANGE, 1, max_h,
127+        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
128+    if (context->have_dma_drm_afbc) {
129+      gst_caps_ref (format_caps);
130+      gst_caps_append (caps, format_caps);
131+
132+      gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
133+    }
134+    gst_caps_append (caps, format_caps);
135+
136+    format_caps = gst_caps_new_simple ("video/x-raw",
137+        "format", G_TYPE_STRING, "NV12_10LE40",
138+        "width", GST_TYPE_INT_RANGE, 1, max_w,
139+        "height", GST_TYPE_INT_RANGE, 1, max_h,
140+        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
141+    if (context->have_dma_drm_afbc) {
142+      gst_caps_ref (format_caps);
143+      gst_caps_append (caps, format_caps);
144+
145+      gst_caps_set_simple (format_caps, "arm-afbc", G_TYPE_INT, 1, NULL);
146+    }
147+    gst_caps_append (caps, format_caps);
148+  }
149+
150+  GST_DEBUG ("Final caps caps: %" GST_PTR_FORMAT, caps);
151+
152   return caps;
153
154   /* ERRORS */
155@@ -920,6 +983,10 @@ gst_xvcontext_get_format_from_info (GstXvContext * context,
156 {
157   GList *list = NULL;
158
159+  /* HACK: Use NV12 format for fake formats */
160+  if (context->drm_fourcc != -1)
161+    return DRM_FORMAT_NV12;
162+
163   list = context->formats_list;
164
165   while (list) {
166diff --git a/sys/xvimage/xvcontext.h b/sys/xvimage/xvcontext.h
167index ea5424d..e515fcc 100644
168--- a/sys/xvimage/xvcontext.h
169+++ b/sys/xvimage/xvcontext.h
170@@ -42,6 +42,19 @@
171
172 #include <gst/video/video.h>
173
174+#include <libdrm/drm_fourcc.h>
175+
176+#define XV_DMA_CLIENT_PROP      "XV_DMA_CLIENT_ID"
177+#define XV_DMA_VER_STRIDE_PROP  "XV_DMA_VER_STRIDE"
178+#define XV_DMA_HOR_STRIDE_PROP  "XV_DMA_HOR_STRIDE"
179+#define XV_DMA_DRM_FOURCC_PROP  "XV_DMA_DRM_FOURCC"
180+#define XV_DMA_DRM_AFBC_PROP  "XV_DMA_DRM_AFBC"
181+#define XV_DMA_CLIENT_PATH      "/tmp/.xv_dma_client"
182+
183+#ifndef DRM_FORMAT_NV12_10
184+#define DRM_FORMAT_NV12_10 fourcc_code('N', 'A', '1', '2')
185+#endif
186+
187 G_BEGIN_DECLS
188
189 typedef struct _GstXvContextConfig GstXvContextConfig;
190@@ -70,6 +83,8 @@ struct _GstXvContextConfig
191   gint hue;
192   gint saturation;
193   gboolean cb_changed;
194+
195+  guint dma_client_id;
196 };
197
198 /**
199@@ -167,6 +182,11 @@ struct _GstXvContext
200   gboolean have_double_buffer;
201   gboolean have_iturbt709;
202   gboolean have_xvcolorspace;
203+  gboolean have_dma_client;
204+  gboolean have_dma_drm_fourcc;
205+  gboolean have_dma_drm_afbc;
206+
207+  guint32 drm_fourcc;
208
209   GList *formats_list;
210
211diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
212index e9fcb6c..44c98a9 100644
213--- a/sys/xvimage/xvimagesink.c
214+++ b/sys/xvimage/xvimagesink.c
215@@ -121,6 +121,7 @@
216 #include <gst/video/colorbalance.h>
217 /* Helper functions */
218 #include <gst/video/gstvideometa.h>
219+#include <gst/allocators/gstdmabuf.h>
220
221 /* Object header */
222 #include "xvimagesink.h"
223@@ -137,6 +138,11 @@
224 #include <X11/extensions/XInput2.h>
225 #endif
226
227+#include <stdio.h>
228+#include <unistd.h>
229+#include <sys/socket.h>
230+#include <sys/un.h>
231+
232 GST_DEBUG_CATEGORY_EXTERN (gst_debug_xv_context);
233 GST_DEBUG_CATEGORY_EXTERN (gst_debug_xv_image_pool);
234 GST_DEBUG_CATEGORY (gst_debug_xv_image_sink);
235@@ -235,6 +241,173 @@ GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (xvimagesink, "xvimagesink",
236 /*                                                               */
237 /* ============================================================= */
238
239+static void
240+gst_xv_image_sink_check_dma_client (GstXvImageSink * xvimagesink)
241+{
242+  GstXvContext *context = xvimagesink->context;
243+  Atom prop_atom;
244+  int xv_value = 0;
245+
246+  if (!context->have_dma_client)
247+    return;
248+
249+  g_mutex_lock (&context->lock);
250+  prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
251+  if (prop_atom != None) {
252+    XvGetPortAttribute (context->disp, context->xv_port_id,
253+        prop_atom, &xv_value);
254+  }
255+  g_mutex_unlock (&context->lock);
256+
257+  context->have_dma_client = xv_value > 0;
258+}
259+
260+static void
261+gst_xv_image_sink_flush_dma_client (GstXvImageSink * xvimagesink)
262+{
263+  GstXvContext *context = xvimagesink->context;
264+  Atom prop_atom;
265+  int xv_value;
266+
267+  if (!context->have_dma_client)
268+    return;
269+
270+  g_mutex_lock (&context->lock);
271+  prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
272+  if (prop_atom != None) {
273+    XvSetPortAttribute (context->disp, context->xv_port_id,
274+        prop_atom, xvimagesink->config.dma_client_id);
275+    XvGetPortAttribute (context->disp, context->xv_port_id,
276+        prop_atom, &xv_value);
277+  }
278+  g_mutex_unlock (&context->lock);
279+}
280+
281+static void
282+gst_xv_image_sink_disable_dma_client (GstXvImageSink * xvimagesink)
283+{
284+  GstXvContext *context = xvimagesink->context;
285+  Atom prop_atom;
286+
287+  if (!context->have_dma_client)
288+    return;
289+
290+  g_mutex_lock (&context->lock);
291+  prop_atom = XInternAtom (context->disp, XV_DMA_CLIENT_PROP, True);
292+  if (prop_atom != None) {
293+    XvSetPortAttribute (context->disp, context->xv_port_id, prop_atom, 0);
294+  }
295+  g_mutex_unlock (&context->lock);
296+
297+  context->have_dma_client = FALSE;
298+}
299+
300+static gboolean
301+gst_xv_image_sink_send_dma_params (GstXvImageSink * xvimagesink,
302+    gint hor_stride, gint ver_stride, gboolean afbc)
303+{
304+  GstXvContext *context = xvimagesink->context;
305+  Atom prop_atom;
306+  gboolean error = FALSE;
307+
308+  if (!context->have_dma_client)
309+    return FALSE;
310+
311+  g_mutex_lock (&context->lock);
312+  prop_atom = XInternAtom (context->disp, XV_DMA_HOR_STRIDE_PROP, True);
313+  if (prop_atom != None) {
314+    XvSetPortAttribute (context->disp, context->xv_port_id,
315+        prop_atom, hor_stride);
316+  } else {
317+    error = TRUE;
318+  }
319+  prop_atom = XInternAtom (context->disp, XV_DMA_VER_STRIDE_PROP, True);
320+  if (prop_atom != None) {
321+    XvSetPortAttribute (context->disp, context->xv_port_id,
322+        prop_atom, ver_stride);
323+  } else {
324+    error = TRUE;
325+  }
326+  prop_atom = XInternAtom (context->disp, XV_DMA_DRM_FOURCC_PROP, True);
327+  if (prop_atom != None) {
328+    XvSetPortAttribute (context->disp, context->xv_port_id,
329+        prop_atom, context->drm_fourcc);
330+  }
331+  prop_atom = XInternAtom (context->disp, XV_DMA_DRM_AFBC_PROP, True);
332+  if (prop_atom != None) {
333+    XvSetPortAttribute (context->disp, context->xv_port_id, prop_atom, afbc);
334+  }
335+  g_mutex_unlock (&context->lock);
336+
337+  if (error == TRUE) {
338+    gst_xv_image_sink_disable_dma_client (xvimagesink);
339+    return FALSE;
340+  }
341+
342+  return TRUE;
343+}
344+
345+static gboolean
346+gst_xv_image_sink_send_dma_fd (GstXvImageSink * xvimagesink, gint dma_fd)
347+{
348+  GstXvContext *context = xvimagesink->context;
349+  struct sockaddr_un addr;
350+  struct iovec iov;
351+  struct msghdr msg;
352+  struct cmsghdr *header;
353+  gchar buf[CMSG_SPACE (sizeof (int))];
354+  gint socket_fd;
355+
356+  if (!context->have_dma_client)
357+    return FALSE;
358+
359+  gst_xv_image_sink_flush_dma_client (xvimagesink);
360+
361+  socket_fd = socket (PF_UNIX, SOCK_DGRAM, 0);
362+  if (socket_fd < 0)
363+    goto failed;
364+
365+  addr.sun_family = AF_LOCAL;
366+  snprintf (addr.sun_path, sizeof (addr.sun_path),
367+      XV_DMA_CLIENT_PATH ".%d", xvimagesink->config.dma_client_id);
368+  addr.sun_path[sizeof (addr.sun_path) - 1] = '\0';
369+
370+  if (connect (socket_fd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
371+    goto failed;
372+
373+  iov.iov_base = buf;
374+  iov.iov_len = 1;
375+
376+  msg.msg_iov = &iov;
377+  msg.msg_iovlen = 1;
378+  msg.msg_control = buf;
379+  msg.msg_controllen = sizeof (buf);
380+  msg.msg_name = NULL;
381+  msg.msg_namelen = 0;
382+
383+  header = CMSG_FIRSTHDR (&msg);
384+  header->cmsg_level = SOL_SOCKET;
385+  header->cmsg_type = SCM_RIGHTS;
386+
387+  header->cmsg_len = CMSG_LEN (sizeof (int));
388+  *((int *) CMSG_DATA (header)) = dma_fd;
389+  sendmsg (socket_fd, &msg, 0);
390+
391+  /* Send am empty msg at the end */
392+  header->cmsg_len = CMSG_LEN (0);
393+  sendmsg (socket_fd, &msg, 0);
394+
395+  close (socket_fd);
396+  return TRUE;
397+
398+failed:
399+  gst_xv_image_sink_disable_dma_client (xvimagesink);
400+
401+  if (socket_fd >= 0)
402+    close (socket_fd);
403+
404+  return FALSE;
405+}
406
407 /* This function puts a GstXvImage on a GstXvImageSink's window. Returns FALSE
408  * if no window was available  */
409@@ -322,6 +495,13 @@ gst_xv_image_sink_xvimage_put (GstXvImageSink * xvimagesink,
410     memcpy (&result, &xwindow->render_rect, sizeof (GstVideoRectangle));
411   }
412
413+  if (gst_buffer_n_memory (xvimage) > 1) {
414+    GstMemory *dma_mem = gst_buffer_peek_memory (xvimage, 1);
415+    gint dma_fd = gst_dmabuf_memory_get_fd (dma_mem);
416+    if (dma_fd >= 0)
417+      gst_xv_image_sink_send_dma_fd (xvimagesink, dma_fd);
418+  }
419+
420   gst_xvimage_memory_render (mem, &src, xwindow, &result, draw_border);
421
422   g_mutex_unlock (&xvimagesink->flow_lock);
423@@ -844,6 +1024,27 @@ config_failed:
424   }
425 }
426
427+static gboolean
428+gst_xv_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
429+{
430+  GstStructure *s;
431+  gint value;
432+
433+  if (!gst_video_info_from_caps (info, caps))
434+    return FALSE;
435+
436+  /* parse AFBC from caps */
437+  s = gst_caps_get_structure (caps, 0);
438+  if (gst_structure_get_int (s, "arm-afbc", &value)) {
439+    if (value)
440+      GST_VIDEO_INFO_SET_AFBC (info);
441+    else
442+      GST_VIDEO_INFO_UNSET_AFBC (info);
443+  }
444+
445+  return TRUE;
446+}
447+
448 static gboolean
449 gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
450 {
451@@ -866,7 +1067,7 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
452   if (!gst_caps_can_intersect (context->caps, caps))
453     goto incompatible_caps;
454
455-  if (!gst_video_info_from_caps (&info, caps))
456+  if (!gst_xv_video_info_from_caps (&info, caps))
457     goto invalid_format;
458
459   xvimagesink->fps_n = info.fps_n;
460@@ -976,6 +1177,20 @@ gst_xv_image_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
461     gst_object_unref (oldpool);
462   }
463
464+  context->drm_fourcc = -1;
465+
466+  if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_NV12_10LE40) {
467+    if (!context->have_dma_drm_fourcc)
468+      return FALSE;
469+
470+    context->drm_fourcc = DRM_FORMAT_NV12_10;
471+  } else if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_NV16) {
472+    if (!context->have_dma_drm_fourcc)
473+      return FALSE;
474+
475+    context->drm_fourcc = DRM_FORMAT_NV16;
476+  }
477+
478   return TRUE;
479
480   /* ERRORS */
481@@ -1128,6 +1343,47 @@ gst_xv_image_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
482     if (res != GST_FLOW_OK)
483       goto no_buffer;
484
485+    if ((crop_meta = gst_buffer_get_video_crop_meta (buf))) {
486+      GstVideoCropMeta *dmeta = gst_buffer_add_video_crop_meta (to_put);
487+
488+      dmeta->x = crop_meta->x;
489+      dmeta->y = crop_meta->y;
490+      dmeta->width = crop_meta->width;
491+      dmeta->height = crop_meta->height;
492+    }
493+
494+    mem = gst_buffer_peek_memory (buf, 0);
495+    gst_xv_image_sink_check_dma_client (xvimagesink);
496+    if (gst_is_dmabuf_memory (mem) && xvimagesink->context->have_dma_client) {
497+      GstVideoMeta *vmeta = gst_buffer_get_video_meta (buf);
498+      gint hor_stride, ver_stride;
499+
500+      /* If this buffer is dmabuf and the xserver supports dma_client, we will
501+         send the dmabuf fd directly */
502+      GST_LOG_OBJECT (xvimagesink, "buffer %p is dmabuf, will send dmabuf fd",
503+          buf);
504+
505+      /* Stash the dmabuf in index 1 */
506+      gst_buffer_insert_memory (to_put, 1, gst_buffer_get_memory (buf, 0));
507+
508+      /* Try to send dmabuf params */
509+      if (vmeta) {
510+        hor_stride = vmeta->stride[0];
511+        ver_stride = vmeta->height;
512+
513+        if (vmeta->n_planes > 1)
514+          ver_stride = vmeta->offset[1] / hor_stride;
515+      } else {
516+        hor_stride = xvimagesink->info.width;
517+        ver_stride = xvimagesink->info.height;
518+      }
519+
520+      if (gst_xv_image_sink_send_dma_params (xvimagesink,
521+              hor_stride, ver_stride,
522+              GST_VIDEO_INFO_IS_AFBC (&xvimagesink->info)))
523+        goto put_image;
524+    }
525+
526     GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
527         "slow copy buffer %p into bufferpool buffer %p", buf, to_put);
528
529@@ -1143,17 +1399,9 @@ gst_xv_image_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
530
531     gst_video_frame_unmap (&dest);
532     gst_video_frame_unmap (&src);
533-
534-    if ((crop_meta = gst_buffer_get_video_crop_meta (buf))) {
535-      GstVideoCropMeta *dmeta = gst_buffer_add_video_crop_meta (to_put);
536-
537-      dmeta->x = crop_meta->x;
538-      dmeta->y = crop_meta->y;
539-      dmeta->width = crop_meta->width;
540-      dmeta->height = crop_meta->height;
541-    }
542   }
543
544+put_image:
545   if (!gst_xv_image_sink_xvimage_put (xvimagesink, to_put))
546     goto no_window;
547
548@@ -1242,7 +1490,7 @@ gst_xv_image_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
549   if (caps == NULL)
550     goto no_caps;
551
552-  if (!gst_video_info_from_caps (&info, caps))
553+  if (!gst_xv_video_info_from_caps (&info, caps))
554     goto invalid_caps;
555
556   /* the normal size of a frame */
557diff --git a/sys/xvimage/xvimagesink.h b/sys/xvimage/xvimagesink.h
558index 6f5ffa1..35a3081 100644
559--- a/sys/xvimage/xvimagesink.h
560+++ b/sys/xvimage/xvimagesink.h
561@@ -25,6 +25,16 @@
562 /* Helper functions */
563 #include <gst/video/video.h>
564
565+#ifndef GST_VIDEO_FLAG_ARM_AFBC
566+#define GST_VIDEO_FLAG_ARM_AFBC (1UL << 31)
567+#define GST_VIDEO_INFO_SET_AFBC(i) \
568+  GST_VIDEO_INFO_FLAG_SET (i, GST_VIDEO_FLAG_ARM_AFBC)
569+#define GST_VIDEO_INFO_UNSET_AFBC(i) \
570+  GST_VIDEO_INFO_FLAG_UNSET (i, GST_VIDEO_FLAG_ARM_AFBC)
571+#define GST_VIDEO_INFO_IS_AFBC(i) \
572+  GST_VIDEO_INFO_FLAG_IS_SET (i, GST_VIDEO_FLAG_ARM_AFBC)
573+#endif
574+
575 G_BEGIN_DECLS
576 #define GST_TYPE_XV_IMAGE_SINK \
577   (gst_xv_image_sink_get_type())
578--
5792.20.1
580
581