1*4882a593SmuzhiyunFrom 11b559342c5bed99b46652b68e35bfea171d1a86 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Fri, 12 Nov 2021 11:14:37 +0800 4*4882a593SmuzhiyunSubject: [PATCH 26/41] waylandsink: Support NV12_10LE40 and 5*4882a593Smuzhiyun NV12|NV12_10LE40|NV16 (AFBC) 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunTested on RK356x with: 8*4882a593Smuzhiyunexport GST_MPP_VIDEODEC_DEFAULT_ARM_AFBC=1 9*4882a593Smuzhiyungst-play-1.0 video.mp4 --videosink=waylandsink 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 12*4882a593Smuzhiyun--- 13*4882a593Smuzhiyun ext/wayland/gstwaylandsink.c | 86 ++++++++++++++++++++++++- 14*4882a593Smuzhiyun gst-libs/gst/wayland/gstwldisplay.c | 37 ++++++++++- 15*4882a593Smuzhiyun gst-libs/gst/wayland/gstwldisplay.h | 6 ++ 16*4882a593Smuzhiyun gst-libs/gst/wayland/gstwllinuxdmabuf.c | 26 +++++++- 17*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlvideoformat.c | 1 + 18*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlvideoformat.h | 44 +++++++++++++ 19*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.c | 50 +++++++++++--- 20*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.h | 4 ++ 21*4882a593Smuzhiyun 8 files changed, 243 insertions(+), 11 deletions(-) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 24*4882a593Smuzhiyunindex 5e142e9..b26b7ee 100644 25*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.c 26*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.c 27*4882a593Smuzhiyun@@ -74,7 +74,7 @@ GST_DEBUG_CATEGORY (gstwayland_debug); 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define WL_VIDEO_FORMATS \ 30*4882a593Smuzhiyun "{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, " \ 31*4882a593Smuzhiyun- "RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, " \ 32*4882a593Smuzhiyun+ "RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, NV12_10LE40, " \ 33*4882a593Smuzhiyun "YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }" 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", 36*4882a593Smuzhiyun@@ -647,6 +647,53 @@ gst_wayland_sink_event (GstBaseSink * bsink, GstEvent * event) 37*4882a593Smuzhiyun return ret; 38*4882a593Smuzhiyun } 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun+static GstCaps * 41*4882a593Smuzhiyun+gst_wayland_sink_fixup_caps (GstWaylandSink * self, GstCaps * caps) 42*4882a593Smuzhiyun+{ 43*4882a593Smuzhiyun+ GstCaps *tmp_caps = NULL; 44*4882a593Smuzhiyun+ 45*4882a593Smuzhiyun+ /* HACK: Allow nv12-10le40 and arm-afbc in main caps */ 46*4882a593Smuzhiyun+ 47*4882a593Smuzhiyun+ if (gst_wl_display_support_nv12_10le40 (self->display)) { 48*4882a593Smuzhiyun+ tmp_caps = gst_caps_from_string ( 49*4882a593Smuzhiyun+ GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, 50*4882a593Smuzhiyun+ "NV12_10LE40")); 51*4882a593Smuzhiyun+ 52*4882a593Smuzhiyun+ /* NV15(AFBC) */ 53*4882a593Smuzhiyun+ if (gst_wl_display_support_afbc (self->display)) { 54*4882a593Smuzhiyun+ gst_caps_ref (tmp_caps); 55*4882a593Smuzhiyun+ gst_caps_append (caps, tmp_caps); 56*4882a593Smuzhiyun+ 57*4882a593Smuzhiyun+ gst_caps_set_simple (tmp_caps, "arm-afbc", G_TYPE_INT, 1, NULL); 58*4882a593Smuzhiyun+ } 59*4882a593Smuzhiyun+ 60*4882a593Smuzhiyun+ gst_caps_append (caps, tmp_caps); 61*4882a593Smuzhiyun+ } 62*4882a593Smuzhiyun+ 63*4882a593Smuzhiyun+ /* NV12|NV16 (AFBC) */ 64*4882a593Smuzhiyun+ if (gst_wl_display_support_afbc (self->display)) { 65*4882a593Smuzhiyun+ if (gst_wl_display_check_format_for_dmabuf (self->display, 66*4882a593Smuzhiyun+ GST_VIDEO_FORMAT_NV12)) { 67*4882a593Smuzhiyun+ tmp_caps = gst_caps_from_string ( 68*4882a593Smuzhiyun+ GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, 69*4882a593Smuzhiyun+ "NV12")); 70*4882a593Smuzhiyun+ gst_caps_set_simple (tmp_caps, "arm-afbc", G_TYPE_INT, 1, NULL); 71*4882a593Smuzhiyun+ gst_caps_append (caps, tmp_caps); 72*4882a593Smuzhiyun+ } 73*4882a593Smuzhiyun+ 74*4882a593Smuzhiyun+ if (gst_wl_display_check_format_for_dmabuf (self->display, 75*4882a593Smuzhiyun+ GST_VIDEO_FORMAT_NV16)) { 76*4882a593Smuzhiyun+ tmp_caps = gst_caps_from_string ( 77*4882a593Smuzhiyun+ GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, 78*4882a593Smuzhiyun+ "NV16")); 79*4882a593Smuzhiyun+ gst_caps_set_simple (tmp_caps, "arm-afbc", G_TYPE_INT, 1, NULL); 80*4882a593Smuzhiyun+ gst_caps_append (caps, tmp_caps); 81*4882a593Smuzhiyun+ } 82*4882a593Smuzhiyun+ } 83*4882a593Smuzhiyun+ 84*4882a593Smuzhiyun+ return caps; 85*4882a593Smuzhiyun+} 86*4882a593Smuzhiyun+ 87*4882a593Smuzhiyun static GstCaps * 88*4882a593Smuzhiyun gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) 89*4882a593Smuzhiyun { 90*4882a593Smuzhiyun@@ -699,6 +746,8 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) 91*4882a593Smuzhiyun gst_structure_take_value (gst_caps_get_structure (caps, 1), "format", 92*4882a593Smuzhiyun &dmabuf_list); 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun+ caps = gst_wayland_sink_fixup_caps (self, caps); 95*4882a593Smuzhiyun+ 96*4882a593Smuzhiyun GST_DEBUG_OBJECT (self, "display caps: %" GST_PTR_FORMAT, caps); 97*4882a593Smuzhiyun } 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun@@ -746,6 +795,8 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) 100*4882a593Smuzhiyun GstWaylandSink *self = GST_WAYLAND_SINK (bsink);; 101*4882a593Smuzhiyun gboolean use_dmabuf; 102*4882a593Smuzhiyun GstVideoFormat format; 103*4882a593Smuzhiyun+ GstStructure *s; 104*4882a593Smuzhiyun+ gint value; 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun GST_DEBUG_OBJECT (self, "set caps %" GST_PTR_FORMAT, caps); 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun@@ -753,6 +804,15 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) 109*4882a593Smuzhiyun if (!gst_video_info_from_caps (&self->video_info, caps)) 110*4882a593Smuzhiyun goto invalid_format; 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun+ /* parse AFBC from caps */ 113*4882a593Smuzhiyun+ s = gst_caps_get_structure (caps, 0); 114*4882a593Smuzhiyun+ if (gst_structure_get_int (s, "arm-afbc", &value)) { 115*4882a593Smuzhiyun+ if (value) 116*4882a593Smuzhiyun+ GST_VIDEO_INFO_SET_AFBC (&self->video_info); 117*4882a593Smuzhiyun+ else 118*4882a593Smuzhiyun+ GST_VIDEO_INFO_UNSET_AFBC (&self->video_info); 119*4882a593Smuzhiyun+ } 120*4882a593Smuzhiyun+ 121*4882a593Smuzhiyun format = GST_VIDEO_INFO_FORMAT (&self->video_info); 122*4882a593Smuzhiyun self->video_info_changed = TRUE; 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun@@ -798,9 +858,17 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) 125*4882a593Smuzhiyun GstBufferPool *pool = NULL; 126*4882a593Smuzhiyun gboolean need_pool; 127*4882a593Smuzhiyun GstAllocator *alloc; 128*4882a593Smuzhiyun+ GstStructure *s; 129*4882a593Smuzhiyun+ gint value; 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun gst_query_parse_allocation (query, &caps, &need_pool); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun+ s = gst_caps_get_structure (caps, 0); 134*4882a593Smuzhiyun+ if (gst_structure_get_int (s, "arm-afbc", &value) && value) { 135*4882a593Smuzhiyun+ GST_DEBUG_OBJECT (self, "no allocation for AFBC"); 136*4882a593Smuzhiyun+ return FALSE; 137*4882a593Smuzhiyun+ } 138*4882a593Smuzhiyun+ 139*4882a593Smuzhiyun if (need_pool) 140*4882a593Smuzhiyun pool = gst_wayland_create_pool (self, caps); 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun@@ -811,6 +879,7 @@ gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) 143*4882a593Smuzhiyun alloc = gst_wl_shm_allocator_get (); 144*4882a593Smuzhiyun gst_query_add_allocation_param (query, alloc, NULL); 145*4882a593Smuzhiyun gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); 146*4882a593Smuzhiyun+ gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); 147*4882a593Smuzhiyun g_object_unref (alloc); 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun return TRUE; 150*4882a593Smuzhiyun@@ -884,6 +953,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 151*4882a593Smuzhiyun GstWaylandSink *self = GST_WAYLAND_SINK (vsink); 152*4882a593Smuzhiyun GstBuffer *to_render; 153*4882a593Smuzhiyun GstWlBuffer *wlbuffer; 154*4882a593Smuzhiyun+ GstVideoCropMeta *crop; 155*4882a593Smuzhiyun GstVideoMeta *vmeta; 156*4882a593Smuzhiyun GstVideoFormat format; 157*4882a593Smuzhiyun GstVideoInfo old_vinfo; 158*4882a593Smuzhiyun@@ -923,6 +993,11 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 159*4882a593Smuzhiyun } 160*4882a593Smuzhiyun } 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun+ crop = gst_buffer_get_video_crop_meta (buffer); 163*4882a593Smuzhiyun+ if (crop) 164*4882a593Smuzhiyun+ gst_wl_window_ensure_crop (self->window, crop->x, crop->y, 165*4882a593Smuzhiyun+ crop->width, crop->height); 166*4882a593Smuzhiyun+ 167*4882a593Smuzhiyun /* drop buffers until we get a frame callback */ 168*4882a593Smuzhiyun if (self->redraw_pending) { 169*4882a593Smuzhiyun GST_LOG_OBJECT (self, "buffer %" GST_PTR_FORMAT " dropped (redraw pending)", 170*4882a593Smuzhiyun@@ -977,6 +1052,9 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 171*4882a593Smuzhiyun &self->video_info); 172*4882a593Smuzhiyun } 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun+ if (!wbuf && GST_VIDEO_INFO_IS_AFBC (&self->video_info)) 175*4882a593Smuzhiyun+ goto no_afbc; 176*4882a593Smuzhiyun+ 177*4882a593Smuzhiyun if (!wbuf && gst_wl_display_check_format_for_shm (self->display, format)) { 178*4882a593Smuzhiyun if (gst_buffer_n_memory (buffer) == 1 && gst_is_fd_memory (mem)) 179*4882a593Smuzhiyun wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, self->display, 180*4882a593Smuzhiyun@@ -1107,6 +1185,12 @@ no_wl_buffer: 181*4882a593Smuzhiyun ret = GST_FLOW_ERROR; 182*4882a593Smuzhiyun goto done; 183*4882a593Smuzhiyun } 184*4882a593Smuzhiyun+no_afbc: 185*4882a593Smuzhiyun+ { 186*4882a593Smuzhiyun+ GST_ERROR_OBJECT (self, "could not import AFBC"); 187*4882a593Smuzhiyun+ ret = GST_FLOW_ERROR; 188*4882a593Smuzhiyun+ goto done; 189*4882a593Smuzhiyun+ } 190*4882a593Smuzhiyun activate_failed: 191*4882a593Smuzhiyun { 192*4882a593Smuzhiyun GST_ERROR_OBJECT (self, "failed to activate bufferpool."); 193*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwldisplay.c b/gst-libs/gst/wayland/gstwldisplay.c 194*4882a593Smuzhiyunindex 71a5dde..3e11211 100644 195*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwldisplay.c 196*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwldisplay.c 197*4882a593Smuzhiyun@@ -61,6 +61,9 @@ typedef struct _GstWlDisplayPrivate 198*4882a593Smuzhiyun GMutex buffers_mutex; 199*4882a593Smuzhiyun GHashTable *buffers; 200*4882a593Smuzhiyun gboolean shutting_down; 201*4882a593Smuzhiyun+ 202*4882a593Smuzhiyun+ gboolean support_afbc; 203*4882a593Smuzhiyun+ gboolean support_nv12_10le40; 204*4882a593Smuzhiyun } GstWlDisplayPrivate; 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun G_DEFINE_TYPE_WITH_CODE (GstWlDisplay, gst_wl_display, G_TYPE_OBJECT, 207*4882a593Smuzhiyun@@ -69,6 +72,20 @@ G_DEFINE_TYPE_WITH_CODE (GstWlDisplay, gst_wl_display, G_TYPE_OBJECT, 208*4882a593Smuzhiyun "wldisplay", 0, "wldisplay library"); 209*4882a593Smuzhiyun ); 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun+gboolean 212*4882a593Smuzhiyun+gst_wl_display_support_afbc (GstWlDisplay * self) 213*4882a593Smuzhiyun+{ 214*4882a593Smuzhiyun+ GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self); 215*4882a593Smuzhiyun+ return priv->support_afbc; 216*4882a593Smuzhiyun+} 217*4882a593Smuzhiyun+ 218*4882a593Smuzhiyun+gboolean 219*4882a593Smuzhiyun+gst_wl_display_support_nv12_10le40 (GstWlDisplay * self) 220*4882a593Smuzhiyun+{ 221*4882a593Smuzhiyun+ GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self); 222*4882a593Smuzhiyun+ return priv->support_nv12_10le40; 223*4882a593Smuzhiyun+} 224*4882a593Smuzhiyun+ 225*4882a593Smuzhiyun static void gst_wl_display_finalize (GObject * gobject); 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun static void 228*4882a593Smuzhiyun@@ -187,10 +204,28 @@ dmabuf_format (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN) 231*4882a593Smuzhiyun g_array_append_val (priv->dmabuf_formats, format); 232*4882a593Smuzhiyun+ 233*4882a593Smuzhiyun+ if (format == DRM_FORMAT_NV15) 234*4882a593Smuzhiyun+ priv->support_nv12_10le40 = TRUE; 235*4882a593Smuzhiyun+} 236*4882a593Smuzhiyun+ 237*4882a593Smuzhiyun+static void 238*4882a593Smuzhiyun+dmabuf_modifier (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, 239*4882a593Smuzhiyun+ uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo) 240*4882a593Smuzhiyun+{ 241*4882a593Smuzhiyun+ GstWlDisplay *self = data; 242*4882a593Smuzhiyun+ GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self); 243*4882a593Smuzhiyun+ uint64_t modifier = ((uint64_t) modifier_hi << 32) | modifier_lo; 244*4882a593Smuzhiyun+ 245*4882a593Smuzhiyun+ if (modifier == DRM_AFBC_MODIFIER) 246*4882a593Smuzhiyun+ priv->support_afbc = TRUE; 247*4882a593Smuzhiyun+ 248*4882a593Smuzhiyun+ dmabuf_format (data, zwp_linux_dmabuf, format); 249*4882a593Smuzhiyun } 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { 252*4882a593Smuzhiyun dmabuf_format, 253*4882a593Smuzhiyun+ dmabuf_modifier, 254*4882a593Smuzhiyun }; 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun gboolean 257*4882a593Smuzhiyun@@ -277,7 +312,7 @@ registry_handle_global (void *data, struct wl_registry *registry, 258*4882a593Smuzhiyun wl_registry_bind (registry, id, &wp_viewporter_interface, 1); 259*4882a593Smuzhiyun } else if (g_strcmp0 (interface, "zwp_linux_dmabuf_v1") == 0) { 260*4882a593Smuzhiyun priv->dmabuf = 261*4882a593Smuzhiyun- wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 2); 262*4882a593Smuzhiyun+ wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 3); 263*4882a593Smuzhiyun zwp_linux_dmabuf_v1_add_listener (priv->dmabuf, &dmabuf_listener, self); 264*4882a593Smuzhiyun } 265*4882a593Smuzhiyun } 266*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwldisplay.h b/gst-libs/gst/wayland/gstwldisplay.h 267*4882a593Smuzhiyunindex eb07e4f..c130b79 100644 268*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwldisplay.h 269*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwldisplay.h 270*4882a593Smuzhiyun@@ -35,6 +35,12 @@ struct _GstWlDisplay 271*4882a593Smuzhiyun GObject parent_instance; 272*4882a593Smuzhiyun }; 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun+GST_WL_API 275*4882a593Smuzhiyun+gboolean gst_wl_display_support_afbc (GstWlDisplay * self); 276*4882a593Smuzhiyun+ 277*4882a593Smuzhiyun+GST_WL_API 278*4882a593Smuzhiyun+gboolean gst_wl_display_support_nv12_10le40 (GstWlDisplay * self); 279*4882a593Smuzhiyun+ 280*4882a593Smuzhiyun GST_WL_API 281*4882a593Smuzhiyun GstWlDisplay *gst_wl_display_new (const gchar * name, GError ** error); 282*4882a593Smuzhiyun 283*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwllinuxdmabuf.c b/gst-libs/gst/wayland/gstwllinuxdmabuf.c 284*4882a593Smuzhiyunindex 2d5bb6b..65b6d8f 100644 285*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwllinuxdmabuf.c 286*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwllinuxdmabuf.c 287*4882a593Smuzhiyun@@ -57,8 +57,10 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf, 288*4882a593Smuzhiyun int format; 289*4882a593Smuzhiyun guint i, width, height; 290*4882a593Smuzhiyun guint nplanes, flags = 0; 291*4882a593Smuzhiyun+ gfloat stride_scale = 1.0f; 292*4882a593Smuzhiyun struct zwp_linux_buffer_params_v1 *params; 293*4882a593Smuzhiyun ConstructBufferData data; 294*4882a593Smuzhiyun+ guint64 modifier = GST_VIDEO_INFO_IS_AFBC (info) ? DRM_AFBC_MODIFIER : 0; 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun g_return_val_if_fail (gst_wl_display_check_format_for_dmabuf (display, 297*4882a593Smuzhiyun GST_VIDEO_INFO_FORMAT (info)), NULL); 298*4882a593Smuzhiyun@@ -74,6 +76,27 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf, 299*4882a593Smuzhiyun G_GSSIZE_FORMAT " (%d x %d), format %s", info->size, width, height, 300*4882a593Smuzhiyun gst_wl_dmabuf_format_to_string (format)); 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun+ if (GST_VIDEO_INFO_IS_AFBC (info)) { 303*4882a593Smuzhiyun+ /* Mali uses these formats instead */ 304*4882a593Smuzhiyun+ if (format == DRM_FORMAT_NV12) { 305*4882a593Smuzhiyun+ format = DRM_FORMAT_YUV420_8BIT; 306*4882a593Smuzhiyun+ nplanes = 1; 307*4882a593Smuzhiyun+ stride_scale = 1.5; 308*4882a593Smuzhiyun+ } else if (format == DRM_FORMAT_NV15) { 309*4882a593Smuzhiyun+ format = DRM_FORMAT_YUV420_10BIT; 310*4882a593Smuzhiyun+ nplanes = 1; 311*4882a593Smuzhiyun+ stride_scale = 1.5; 312*4882a593Smuzhiyun+ } else if (format == DRM_FORMAT_NV16) { 313*4882a593Smuzhiyun+ format = DRM_FORMAT_YUYV; 314*4882a593Smuzhiyun+ nplanes = 1; 315*4882a593Smuzhiyun+ stride_scale = 2; 316*4882a593Smuzhiyun+ } else { 317*4882a593Smuzhiyun+ GST_ERROR_OBJECT (mem->allocator, "unsupported format for AFBC"); 318*4882a593Smuzhiyun+ data.wbuf = NULL; 319*4882a593Smuzhiyun+ goto out; 320*4882a593Smuzhiyun+ } 321*4882a593Smuzhiyun+ } 322*4882a593Smuzhiyun+ 323*4882a593Smuzhiyun /* Creation and configuration of planes */ 324*4882a593Smuzhiyun params = zwp_linux_dmabuf_v1_create_params (gst_wl_display_get_dmabuf_v1 325*4882a593Smuzhiyun (display)); 326*4882a593Smuzhiyun@@ -84,11 +107,12 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf, 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun offset = GST_VIDEO_INFO_PLANE_OFFSET (info, i); 329*4882a593Smuzhiyun stride = GST_VIDEO_INFO_PLANE_STRIDE (info, i); 330*4882a593Smuzhiyun+ stride *= stride_scale; 331*4882a593Smuzhiyun if (gst_buffer_find_memory (buf, offset, 1, &mem_idx, &length, &skip)) { 332*4882a593Smuzhiyun GstMemory *m = gst_buffer_peek_memory (buf, mem_idx); 333*4882a593Smuzhiyun gint fd = gst_dmabuf_memory_get_fd (m); 334*4882a593Smuzhiyun zwp_linux_buffer_params_v1_add (params, fd, i, m->offset + skip, 335*4882a593Smuzhiyun- stride, 0, 0); 336*4882a593Smuzhiyun+ stride, modifier >> 32, modifier & 0xFFFFFFFF); 337*4882a593Smuzhiyun } else { 338*4882a593Smuzhiyun GST_ERROR_OBJECT (mem->allocator, "memory does not seem to contain " 339*4882a593Smuzhiyun "enough data for the specified format"); 340*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlvideoformat.c b/gst-libs/gst/wayland/gstwlvideoformat.c 341*4882a593Smuzhiyunindex 44a9536..003daa6 100644 342*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlvideoformat.c 343*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlvideoformat.c 344*4882a593Smuzhiyun@@ -71,6 +71,7 @@ static const wl_VideoFormat wl_formats[] = { 345*4882a593Smuzhiyun {WL_SHM_FORMAT_UYVY, DRM_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY}, 346*4882a593Smuzhiyun {WL_SHM_FORMAT_AYUV, DRM_FORMAT_AYUV, GST_VIDEO_FORMAT_AYUV}, 347*4882a593Smuzhiyun {WL_SHM_FORMAT_NV12, DRM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12}, 348*4882a593Smuzhiyun+ {-1, DRM_FORMAT_NV15, GST_VIDEO_FORMAT_NV12_10LE40}, 349*4882a593Smuzhiyun {WL_SHM_FORMAT_NV21, DRM_FORMAT_NV21, GST_VIDEO_FORMAT_NV21}, 350*4882a593Smuzhiyun {WL_SHM_FORMAT_NV16, DRM_FORMAT_NV16, GST_VIDEO_FORMAT_NV16}, 351*4882a593Smuzhiyun {WL_SHM_FORMAT_NV61, DRM_FORMAT_NV61, GST_VIDEO_FORMAT_NV61}, 352*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlvideoformat.h b/gst-libs/gst/wayland/gstwlvideoformat.h 353*4882a593Smuzhiyunindex bc36a08..abf579c 100644 354*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlvideoformat.h 355*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlvideoformat.h 356*4882a593Smuzhiyun@@ -27,8 +27,52 @@ 357*4882a593Smuzhiyun 358*4882a593Smuzhiyun #include <gst/video/video.h> 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun+#include <drm_fourcc.h> 361*4882a593Smuzhiyun+ 362*4882a593Smuzhiyun G_BEGIN_DECLS 363*4882a593Smuzhiyun 364*4882a593Smuzhiyun+#ifndef DRM_FORMAT_NV15 365*4882a593Smuzhiyun+#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') 366*4882a593Smuzhiyun+#endif 367*4882a593Smuzhiyun+ 368*4882a593Smuzhiyun+#ifndef DRM_FORMAT_YUV420_8BIT 369*4882a593Smuzhiyun+#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8') 370*4882a593Smuzhiyun+#endif 371*4882a593Smuzhiyun+ 372*4882a593Smuzhiyun+#ifndef DRM_FORMAT_YUV420_10BIT 373*4882a593Smuzhiyun+#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0') 374*4882a593Smuzhiyun+#endif 375*4882a593Smuzhiyun+ 376*4882a593Smuzhiyun+#ifndef DRM_FORMAT_MOD_VENDOR_ARM 377*4882a593Smuzhiyun+#define DRM_FORMAT_MOD_VENDOR_ARM 0x08 378*4882a593Smuzhiyun+#endif 379*4882a593Smuzhiyun+ 380*4882a593Smuzhiyun+#ifndef DRM_FORMAT_MOD_ARM_AFBC 381*4882a593Smuzhiyun+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, __afbc_mode) 382*4882a593Smuzhiyun+#endif 383*4882a593Smuzhiyun+ 384*4882a593Smuzhiyun+#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 385*4882a593Smuzhiyun+#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL) 386*4882a593Smuzhiyun+#endif 387*4882a593Smuzhiyun+ 388*4882a593Smuzhiyun+#ifndef AFBC_FORMAT_MOD_SPARSE 389*4882a593Smuzhiyun+#define AFBC_FORMAT_MOD_SPARSE (((__u64)1) << 6) 390*4882a593Smuzhiyun+#endif 391*4882a593Smuzhiyun+ 392*4882a593Smuzhiyun+#define DRM_AFBC_MODIFIER \ 393*4882a593Smuzhiyun+ (DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_SPARSE) | \ 394*4882a593Smuzhiyun+ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16)) 395*4882a593Smuzhiyun+ 396*4882a593Smuzhiyun+#ifndef GST_VIDEO_FLAG_ARM_AFBC 397*4882a593Smuzhiyun+#define GST_VIDEO_FLAG_ARM_AFBC (1UL << 31) 398*4882a593Smuzhiyun+#define GST_VIDEO_INFO_SET_AFBC(i) \ 399*4882a593Smuzhiyun+ GST_VIDEO_INFO_FLAG_SET (i, GST_VIDEO_FLAG_ARM_AFBC) 400*4882a593Smuzhiyun+#define GST_VIDEO_INFO_UNSET_AFBC(i) \ 401*4882a593Smuzhiyun+ GST_VIDEO_INFO_FLAG_UNSET (i, GST_VIDEO_FLAG_ARM_AFBC) 402*4882a593Smuzhiyun+#define GST_VIDEO_INFO_IS_AFBC(i) \ 403*4882a593Smuzhiyun+ GST_VIDEO_INFO_FLAG_IS_SET (i, GST_VIDEO_FLAG_ARM_AFBC) 404*4882a593Smuzhiyun+#endif 405*4882a593Smuzhiyun+ 406*4882a593Smuzhiyun GST_WL_API 407*4882a593Smuzhiyun void gst_wl_videoformat_init_once (void); 408*4882a593Smuzhiyun 409*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.c b/gst-libs/gst/wayland/gstwlwindow.c 410*4882a593Smuzhiyunindex 7dc0da5..df60a67 100644 411*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.c 412*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.c 413*4882a593Smuzhiyun@@ -66,6 +66,9 @@ typedef struct _GstWlWindowPrivate 414*4882a593Smuzhiyun /* the size of the video in the buffers */ 415*4882a593Smuzhiyun gint video_width, video_height; 416*4882a593Smuzhiyun 417*4882a593Smuzhiyun+ gint crop_x, crop_y, crop_w, crop_h; 418*4882a593Smuzhiyun+ gboolean crop_dirty; 419*4882a593Smuzhiyun+ 420*4882a593Smuzhiyun enum wl_output_transform buffer_transform; 421*4882a593Smuzhiyun 422*4882a593Smuzhiyun /* when this is not set both the area_surface and the video_surface are not 423*4882a593Smuzhiyun@@ -255,6 +258,29 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock) 424*4882a593Smuzhiyun return self; 425*4882a593Smuzhiyun } 426*4882a593Smuzhiyun 427*4882a593Smuzhiyun+void 428*4882a593Smuzhiyun+gst_wl_window_ensure_crop (GstWlWindow * self, gint x, gint y, gint w, gint h) 429*4882a593Smuzhiyun+{ 430*4882a593Smuzhiyun+ GstWlWindowPrivate *priv; 431*4882a593Smuzhiyun+ 432*4882a593Smuzhiyun+ if (!self) 433*4882a593Smuzhiyun+ return; 434*4882a593Smuzhiyun+ 435*4882a593Smuzhiyun+ priv = gst_wl_window_get_instance_private (self); 436*4882a593Smuzhiyun+ 437*4882a593Smuzhiyun+ if (priv->crop_x == x && priv->crop_y == y && 438*4882a593Smuzhiyun+ priv->crop_w == w && priv->crop_h == h) 439*4882a593Smuzhiyun+ return; 440*4882a593Smuzhiyun+ 441*4882a593Smuzhiyun+ priv->crop_x = x; 442*4882a593Smuzhiyun+ priv->crop_y = y; 443*4882a593Smuzhiyun+ priv->crop_w = w; 444*4882a593Smuzhiyun+ priv->crop_h = h; 445*4882a593Smuzhiyun+ priv->crop_dirty = TRUE; 446*4882a593Smuzhiyun+ 447*4882a593Smuzhiyun+ GST_LOG_OBJECT (self, "crop %dx%d-%dx%d", x, y, w, h); 448*4882a593Smuzhiyun+} 449*4882a593Smuzhiyun+ 450*4882a593Smuzhiyun void 451*4882a593Smuzhiyun gst_wl_window_ensure_fill_mode (GstWlWindow * self, 452*4882a593Smuzhiyun GstWlWindowFillMode fill_mode) 453*4882a593Smuzhiyun@@ -523,6 +549,14 @@ gst_wl_window_resize_video_surface (GstWlWindow * self, gboolean commit) 454*4882a593Smuzhiyun dst.w = priv->render_rectangle.w; 455*4882a593Smuzhiyun dst.h = priv->render_rectangle.h; 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun+ if (priv->crop_w && priv->crop_h) { 458*4882a593Smuzhiyun+ src.x = priv->crop_x; 459*4882a593Smuzhiyun+ src.y = priv->crop_y; 460*4882a593Smuzhiyun+ src.w = priv->crop_w; 461*4882a593Smuzhiyun+ src.h = priv->crop_h; 462*4882a593Smuzhiyun+ } 463*4882a593Smuzhiyun+ priv->crop_dirty = FALSE; 464*4882a593Smuzhiyun+ 465*4882a593Smuzhiyun /* center the video_subsurface inside area_subsurface */ 466*4882a593Smuzhiyun if (priv->video_viewport) { 467*4882a593Smuzhiyun if (priv->fill_mode == GST_WL_WINDOW_STRETCH) { 468*4882a593Smuzhiyun@@ -537,22 +571,21 @@ gst_wl_window_resize_video_surface (GstWlWindow * self, gboolean commit) 469*4882a593Smuzhiyun 470*4882a593Smuzhiyun if (src_ratio < dst_ratio) { 471*4882a593Smuzhiyun int h = src.w / dst_ratio; 472*4882a593Smuzhiyun- src.y = (src.h - h) / 2; 473*4882a593Smuzhiyun+ src.y += (src.h - h) / 2; 474*4882a593Smuzhiyun src.h = h; 475*4882a593Smuzhiyun } else if (src_ratio > dst_ratio) { 476*4882a593Smuzhiyun int w = src.h * dst_ratio; 477*4882a593Smuzhiyun- src.x = (src.w - w) / 2; 478*4882a593Smuzhiyun+ src.x += (src.w - w) / 2; 479*4882a593Smuzhiyun src.w = w; 480*4882a593Smuzhiyun } 481*4882a593Smuzhiyun 482*4882a593Smuzhiyun- wp_viewport_set_source (priv->video_viewport, 483*4882a593Smuzhiyun- wl_fixed_from_int (src.x), wl_fixed_from_int (src.y), 484*4882a593Smuzhiyun- wl_fixed_from_int (src.w), wl_fixed_from_int (src.h)); 485*4882a593Smuzhiyun- 486*4882a593Smuzhiyun res = dst; 487*4882a593Smuzhiyun } 488*4882a593Smuzhiyun 489*4882a593Smuzhiyun wp_viewport_set_destination (priv->video_viewport, res.w, res.h); 490*4882a593Smuzhiyun+ wp_viewport_set_source (priv->video_viewport, 491*4882a593Smuzhiyun+ wl_fixed_from_int (src.x), wl_fixed_from_int (src.y), 492*4882a593Smuzhiyun+ wl_fixed_from_int (src.w), wl_fixed_from_int (src.h)); 493*4882a593Smuzhiyun } else { 494*4882a593Smuzhiyun gst_video_center_rect (&src, &dst, &res, FALSE); 495*4882a593Smuzhiyun } 496*4882a593Smuzhiyun@@ -597,13 +630,14 @@ gst_wl_window_render (GstWlWindow * self, GstWlBuffer * buffer, 497*4882a593Smuzhiyun GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self); 498*4882a593Smuzhiyun 499*4882a593Smuzhiyun if (G_UNLIKELY (info)) { 500*4882a593Smuzhiyun- priv->video_width = 501*4882a593Smuzhiyun- gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); 502*4882a593Smuzhiyun+ priv->video_width = info->width; 503*4882a593Smuzhiyun priv->video_height = info->height; 504*4882a593Smuzhiyun 505*4882a593Smuzhiyun wl_subsurface_set_sync (priv->video_subsurface); 506*4882a593Smuzhiyun gst_wl_window_resize_video_surface (self, FALSE); 507*4882a593Smuzhiyun gst_wl_window_set_opaque (self, info); 508*4882a593Smuzhiyun+ } else if (priv->crop_dirty) { 509*4882a593Smuzhiyun+ gst_wl_window_resize_video_surface (self, FALSE); 510*4882a593Smuzhiyun } 511*4882a593Smuzhiyun 512*4882a593Smuzhiyun if (G_LIKELY (buffer)) { 513*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.h b/gst-libs/gst/wayland/gstwlwindow.h 514*4882a593Smuzhiyunindex 1571ece..8f02f00 100644 515*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.h 516*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.h 517*4882a593Smuzhiyun@@ -47,6 +47,10 @@ struct _GstWlWindow 518*4882a593Smuzhiyun GObject parent_instance; 519*4882a593Smuzhiyun }; 520*4882a593Smuzhiyun 521*4882a593Smuzhiyun+GST_WL_API 522*4882a593Smuzhiyun+void gst_wl_window_ensure_crop (GstWlWindow * self, 523*4882a593Smuzhiyun+ gint x, gint y, gint w, gint h); 524*4882a593Smuzhiyun+ 525*4882a593Smuzhiyun GST_WL_API 526*4882a593Smuzhiyun void gst_wl_window_ensure_fill_mode (GstWlWindow * self, 527*4882a593Smuzhiyun GstWlWindowFillMode fill_mode); 528*4882a593Smuzhiyun-- 529*4882a593Smuzhiyun2.20.1 530*4882a593Smuzhiyun 531