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