1From c3dce1eaba3d7e75c288319cc8ce41b5c7735393 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Tue, 24 May 2022 16:16:33 +0800 4Subject: [PATCH 12/14] glupload: Support NV12_10LE40 and NV12|NV12_10LE40|NV16 5 (AFBC) 6 7Tested on RK356x with: 8export GST_MPP_VIDEODEC_DEFAULT_ARM_AFBC=1 9gst-play-1.0 video.mp4 --videosink=glimagesink 10 11Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 12--- 13 gst-libs/gst/gl/egl/gsteglimage.c | 49 ++++++++++++++++++++++++++----- 14 gst-libs/gst/gl/egl/gsteglimage.h | 44 +++++++++++++++++++++++++++ 15 gst-libs/gst/gl/gstglmemory.h | 2 +- 16 gst-libs/gst/gl/gstglupload.c | 15 +++++++++- 17 gst-libs/gst/gl/meson.build | 5 +++- 18 5 files changed, 105 insertions(+), 10 deletions(-) 19 20diff --git a/gst-libs/gst/gl/egl/gsteglimage.c b/gst-libs/gst/gl/egl/gsteglimage.c 21index 8c05328..57f261e 100644 22--- a/gst-libs/gst/gl/egl/gsteglimage.c 23+++ b/gst-libs/gst/gl/egl/gsteglimage.c 24@@ -701,6 +701,19 @@ _drm_direct_fourcc_from_info (const GstVideoInfo * info) 25 26 GST_DEBUG ("Getting DRM fourcc for %s", gst_video_format_to_string (format)); 27 28+ if (GST_VIDEO_INFO_IS_AFBC (info)) { 29+ /* Mali uses these formats instead */ 30+ if (format == GST_VIDEO_FORMAT_NV12) 31+ return DRM_FORMAT_YUV420_8BIT; 32+ else if (format == GST_VIDEO_FORMAT_NV12_10LE40) 33+ return DRM_FORMAT_YUV420_10BIT; 34+ else if (format == GST_VIDEO_FORMAT_NV16) 35+ return DRM_FORMAT_YUYV; 36+ 37+ GST_INFO ("unsupported format for AFBC"); 38+ return -1; 39+ } 40+ 41 switch (format) { 42 case GST_VIDEO_FORMAT_YUY2: 43 return DRM_FORMAT_YUYV; 44@@ -784,6 +797,9 @@ _drm_direct_fourcc_from_info (const GstVideoInfo * info) 45 case GST_VIDEO_FORMAT_xBGR: 46 return DRM_FORMAT_RGBX8888; 47 48+ case GST_VIDEO_FORMAT_NV12_10LE40: 49+ return DRM_FORMAT_NV15; 50+ 51 default: 52 GST_INFO ("Unsupported format for direct DMABuf."); 53 return -1; 54@@ -939,10 +955,12 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 55 { 56 57 EGLImageKHR img; 58+ GstVideoFormat format = GST_VIDEO_INFO_FORMAT (in_info); 59 guint n_planes = GST_VIDEO_INFO_N_PLANES (in_info); 60 gint fourcc; 61 gint i; 62 gboolean with_modifiers; 63+ guint64 modifier = DRM_FORMAT_MOD_LINEAR; 64 65 /* Explanation of array length: 66 * - 6 plane independent values are at the start (width, height, format FourCC) 67@@ -952,6 +970,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 68 */ 69 guintptr attribs[41]; /* 6 + 10 * 3 + 4 + 1 */ 70 gint atti = 0; 71+ gfloat stride_scale = 1.0f; 72 73 if (!gst_egl_image_check_dmabuf_direct (context, in_info, target)) 74 return NULL; 75@@ -960,6 +979,22 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 76 with_modifiers = gst_gl_context_check_feature (context, 77 "EGL_EXT_image_dma_buf_import_modifiers"); 78 79+ if (GST_VIDEO_INFO_IS_AFBC (in_info)) { 80+ if (!with_modifiers) 81+ return NULL; 82+ 83+ /* Mali uses these formats instead */ 84+ if (format == GST_VIDEO_FORMAT_NV12) 85+ stride_scale = 1.5; 86+ else if (format == GST_VIDEO_FORMAT_NV12_10LE40) 87+ stride_scale = 1.5; 88+ else if (format == GST_VIDEO_FORMAT_NV16) 89+ stride_scale = 2; 90+ 91+ modifier = DRM_AFBC_MODIFIER; 92+ n_planes = 1; 93+ } 94+ 95 /* EGL DMABuf importation supports a maximum of 3 planes */ 96 if (G_UNLIKELY (n_planes > 3)) 97 return NULL; 98@@ -978,12 +1013,12 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 99 attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; 100 attribs[atti++] = offset[0]; 101 attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; 102- attribs[atti++] = get_egl_stride (in_info, 0); 103+ attribs[atti++] = get_egl_stride (in_info, 0) * stride_scale; 104 if (with_modifiers) { 105 attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; 106- attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; 107+ attribs[atti++] = modifier & 0xffffffff; 108 attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; 109- attribs[atti++] = (DRM_FORMAT_MOD_LINEAR >> 32) & 0xffffffff; 110+ attribs[atti++] = (modifier >> 32) & 0xffffffff; 111 } 112 } 113 114@@ -997,9 +1032,9 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 115 attribs[atti++] = get_egl_stride (in_info, 1); 116 if (with_modifiers) { 117 attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; 118- attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; 119+ attribs[atti++] = modifier & 0xffffffff; 120 attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; 121- attribs[atti++] = (DRM_FORMAT_MOD_LINEAR >> 32) & 0xffffffff; 122+ attribs[atti++] = (modifier >> 32) & 0xffffffff; 123 } 124 } 125 126@@ -1013,9 +1048,9 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, 127 attribs[atti++] = get_egl_stride (in_info, 2); 128 if (with_modifiers) { 129 attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; 130- attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; 131+ attribs[atti++] = modifier & 0xffffffff; 132 attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT; 133- attribs[atti++] = (DRM_FORMAT_MOD_LINEAR >> 32) & 0xffffffff; 134+ attribs[atti++] = (modifier >> 32) & 0xffffffff; 135 } 136 } 137 138diff --git a/gst-libs/gst/gl/egl/gsteglimage.h b/gst-libs/gst/gl/egl/gsteglimage.h 139index f90fa82..e6fc1df 100644 140--- a/gst-libs/gst/gl/egl/gsteglimage.h 141+++ b/gst-libs/gst/gl/egl/gsteglimage.h 142@@ -26,8 +26,52 @@ 143 #include <gst/gl/gstgl_fwd.h> 144 #include <gst/gl/gstglformat.h> 145 146+#include <libdrm/drm_fourcc.h> 147+ 148 G_BEGIN_DECLS 149 150+#ifndef DRM_FORMAT_NV15 151+#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') 152+#endif 153+ 154+#ifndef DRM_FORMAT_YUV420_8BIT 155+#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8') 156+#endif 157+ 158+#ifndef DRM_FORMAT_YUV420_10BIT 159+#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0') 160+#endif 161+ 162+#ifndef DRM_FORMAT_MOD_VENDOR_ARM 163+#define DRM_FORMAT_MOD_VENDOR_ARM 0x08 164+#endif 165+ 166+#ifndef DRM_FORMAT_MOD_ARM_AFBC 167+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, __afbc_mode) 168+#endif 169+ 170+#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 171+#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL) 172+#endif 173+ 174+#ifndef AFBC_FORMAT_MOD_SPARSE 175+#define AFBC_FORMAT_MOD_SPARSE (((__u64)1) << 6) 176+#endif 177+ 178+#define DRM_AFBC_MODIFIER \ 179+ (DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_SPARSE) | \ 180+ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)) 181+ 182+#ifndef GST_VIDEO_FLAG_ARM_AFBC 183+#define GST_VIDEO_FLAG_ARM_AFBC (1UL << 31) 184+#define GST_VIDEO_INFO_SET_AFBC(i) \ 185+ GST_VIDEO_INFO_FLAG_SET (i, GST_VIDEO_FLAG_ARM_AFBC) 186+#define GST_VIDEO_INFO_UNSET_AFBC(i) \ 187+ GST_VIDEO_INFO_FLAG_UNSET (i, GST_VIDEO_FLAG_ARM_AFBC) 188+#define GST_VIDEO_INFO_IS_AFBC(i) \ 189+ GST_VIDEO_INFO_FLAG_IS_SET (i, GST_VIDEO_FLAG_ARM_AFBC) 190+#endif 191+ 192 GST_GL_API GType gst_egl_image_get_type (void); 193 194 #define GST_TYPE_EGL_IMAGE (gst_egl_image_get_type()) 195diff --git a/gst-libs/gst/gl/gstglmemory.h b/gst-libs/gst/gl/gstglmemory.h 196index 5000759..3c4e268 100644 197--- a/gst-libs/gst/gl/gstglmemory.h 198+++ b/gst-libs/gst/gl/gstglmemory.h 199@@ -64,7 +64,7 @@ GType gst_gl_memory_allocator_get_type(void); 200 #define GST_GL_MEMORY_VIDEO_FORMATS_STR \ 201 "{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, GBRA, GBR, RGBP, BGRP, RGB, BGR, RGB16, BGR16, " \ 202 "AYUV, VUYA, Y410, I420, YV12, NV12, NV21, NV16, NV61, YUY2, UYVY, Y210, Y41B, " \ 203- "Y42B, Y444, GRAY8, GRAY16_LE, GRAY16_BE, ARGB64, A420, AV12, NV12_16L32S, NV12_4L4" \ 204+ "Y42B, Y444, GRAY8, GRAY16_LE, GRAY16_BE, ARGB64, A420, AV12, NV12_10LE40, NV12_16L32S, NV12_4L4" \ 205 GST_GL_MEMORY_VIDEO_EXT_FORMATS "}" 206 207 /** 208diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c 209index 39be33a..a5297f2 100644 210--- a/gst-libs/gst/gl/gstglupload.c 211+++ b/gst-libs/gst/gl/gstglupload.c 212@@ -507,7 +507,8 @@ static GstStaticCaps _dma_buf_upload_caps = 213 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES 214 (GST_CAPS_FEATURE_MEMORY_DMABUF, 215 GST_GL_MEMORY_VIDEO_FORMATS_STR) ";" 216- GST_VIDEO_CAPS_MAKE (GST_GL_MEMORY_VIDEO_FORMATS_STR)); 217+ GST_VIDEO_CAPS_MAKE (GST_GL_MEMORY_VIDEO_FORMATS_STR) ";" 218+ GST_VIDEO_CAPS_MAKE ("{NV12, NV12_10LE40}") ", arm-afbc = (int) 1"); 219 220 static gpointer 221 _dma_buf_upload_new (GstGLUpload * upload) 222@@ -2444,6 +2445,9 @@ static gboolean 223 _gst_gl_upload_set_caps_unlocked (GstGLUpload * upload, GstCaps * in_caps, 224 GstCaps * out_caps) 225 { 226+ GstStructure *s; 227+ gint value; 228+ 229 g_return_val_if_fail (upload != NULL, FALSE); 230 g_return_val_if_fail (gst_caps_is_fixed (in_caps), FALSE); 231 232@@ -2458,6 +2462,15 @@ _gst_gl_upload_set_caps_unlocked (GstGLUpload * upload, GstCaps * in_caps, 233 gst_video_info_from_caps (&upload->priv->in_info, in_caps); 234 gst_video_info_from_caps (&upload->priv->out_info, out_caps); 235 236+ /* parse AFBC from caps */ 237+ s = gst_caps_get_structure (in_caps, 0); 238+ if (gst_structure_get_int (s, "arm-afbc", &value)) { 239+ if (value) 240+ GST_VIDEO_INFO_SET_AFBC (&upload->priv->in_info); 241+ else 242+ GST_VIDEO_INFO_UNSET_AFBC (&upload->priv->in_info); 243+ } 244+ 245 upload->priv->method = NULL; 246 upload->priv->method_impl = NULL; 247 upload->priv->method_i = 0; 248diff --git a/gst-libs/gst/gl/meson.build b/gst-libs/gst/gl/meson.build 249index 1080b5d..ee1f646 100644 250--- a/gst-libs/gst/gl/meson.build 251+++ b/gst-libs/gst/gl/meson.build 252@@ -1050,6 +1050,8 @@ if build_gstgl 253 # case-insensitive FS would include gst-libs/gl/egl/egl.h as EGL/egl.h. 254 common_args += '-I@0@'.format(meson.current_build_dir()) 255 256+ libdrm_dep = dependency('libdrm') 257+ 258 gstgl = library('gstgl-' + api_version, 259 gl_sources, gl_egl_sources, gl_x11_sources, gl_wayland_sources, gl_priv_sources, gl_enumtypes_c, gl_enumtypes_h, 260 c_args : common_args, 261@@ -1061,7 +1063,8 @@ if build_gstgl 262 darwin_versions : osxversion, 263 install : true, 264 dependencies : [gst_base_dep, video_dep, allocators_dep, gmodule_dep, 265- gl_lib_deps, gl_platform_deps, gl_winsys_deps, gl_misc_deps], 266+ gl_lib_deps, gl_platform_deps, gl_winsys_deps, gl_misc_deps, 267+ libdrm_dep], 268 # don't confuse EGL/egl.h with gst-libs/gl/egl/egl.h on case-insensitive file systems 269 implicit_include_directories : false) 270 271-- 2722.20.1 273 274