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