1From 741bffa21b7f8cb0b71ccf6584a444ca80a31b5d 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