|
| 1 | +From 9d3c603b237d6da9977b8ab0a6afe5e1aaa210c7 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Sandeep Sheriker M < [email protected]> |
| 3 | +Date: Tue, 26 Mar 2019 15:44:02 -0700 |
| 4 | +Subject: [PATCH] Add support to gem handle |
| 5 | + |
| 6 | +Signed-off-by: Sandeep Sheriker M < [email protected]> |
| 7 | +--- |
| 8 | + sys/kms/gstkmsallocator.c | 20 ++++++++++++++---- |
| 9 | + sys/kms/gstkmsallocator.h | 6 +++++- |
| 10 | + sys/kms/gstkmssink.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- |
| 11 | + sys/kms/gstkmssink.h | 6 ++++++ |
| 12 | + 4 files changed, 78 insertions(+), 7 deletions(-) |
| 13 | + |
| 14 | +diff --git a/sys/kms/gstkmsallocator.c b/sys/kms/gstkmsallocator.c |
| 15 | +index 17e851d..a4ae20f 100644 |
| 16 | +--- a/sys/kms/gstkmsallocator.c |
| 17 | ++++ b/sys/kms/gstkmsallocator.c |
| 18 | +@@ -1,10 +1,12 @@ |
| 19 | + /* GStreamer |
| 20 | + * |
| 21 | + * Copyright (C) 2016 Igalia |
| 22 | ++ * Copyright (C) Microchip Technology Inc. |
| 23 | + * |
| 24 | + * Authors: |
| 25 | + * Víctor Manuel Jáquez Leal < [email protected]> |
| 26 | + * Javier Martin < [email protected]> |
| 27 | ++ * Sandeep Sheriker M <[email protected]> |
| 28 | + * |
| 29 | + * This library is free software; you can redistribute it and/or |
| 30 | + * modify it under the terms of the GNU Library General Public |
| 31 | +@@ -42,6 +44,7 @@ |
| 32 | + |
| 33 | + #include "gstkmsallocator.h" |
| 34 | + #include "gstkmsutils.h" |
| 35 | ++#include "gstkmssink.h" |
| 36 | + |
| 37 | + #ifndef DRM_RDWR |
| 38 | + #define DRM_RDWR O_RDWR |
| 39 | +@@ -111,6 +114,7 @@ gst_kms_allocator_memory_reset (GstKMSAllocator * allocator, GstKMSMemory * mem) |
| 40 | + if (!check_fd (allocator)) |
| 41 | + return; |
| 42 | + |
| 43 | ++ if (allocator->kmssink->Ismaster) { |
| 44 | + if (mem->fb_id) { |
| 45 | + GST_DEBUG_OBJECT (allocator, "removing fb id %d", mem->fb_id); |
| 46 | + drmModeRmFB (allocator->priv->fd, mem->fb_id); |
| 47 | +@@ -136,6 +140,7 @@ gst_kms_allocator_memory_reset (GstKMSAllocator * allocator, GstKMSMemory * mem) |
| 48 | + |
| 49 | + g_free (mem->bo); |
| 50 | + mem->bo = NULL; |
| 51 | ++ } |
| 52 | + } |
| 53 | + |
| 54 | + /* Copied from gst_v4l2_object_extrapolate_stride() */ |
| 55 | +@@ -181,7 +186,7 @@ gst_kms_allocator_memory_create (GstKMSAllocator * allocator, |
| 56 | + kmsmem->bo = g_malloc0 (sizeof (*kmsmem->bo)); |
| 57 | + if (!kmsmem->bo) |
| 58 | + return FALSE; |
| 59 | +- |
| 60 | ++ if (allocator->kmssink->Ismaster) { |
| 61 | + fmt = gst_drm_format_from_video (GST_VIDEO_INFO_FORMAT (vinfo)); |
| 62 | + arg.bpp = gst_drm_bpp_from_drm (fmt); |
| 63 | + arg.width = GST_VIDEO_INFO_WIDTH (vinfo); |
| 64 | +@@ -232,6 +237,9 @@ done: |
| 65 | + " but we require at least %" G_GSIZE_FORMAT " to hold a frame", |
| 66 | + kmsmem->bo->size, GST_VIDEO_INFO_SIZE (vinfo)); |
| 67 | + return FALSE; |
| 68 | ++ } else { |
| 69 | ++ kmsmem->bo->handle = allocator->kmssink->gemhandle; |
| 70 | ++ kmsmem->bo->size = allocator->kmssink->gemsize; |
| 71 | + } |
| 72 | + |
| 73 | + return TRUE; |
| 74 | +@@ -422,12 +430,15 @@ gst_kms_allocator_init (GstKMSAllocator * allocator) |
| 75 | + } |
| 76 | + |
| 77 | + GstAllocator * |
| 78 | +-gst_kms_allocator_new (int fd) |
| 79 | ++gst_kms_allocator_new (GstKMSSink * self) |
| 80 | + { |
| 81 | + GstAllocator *alloc; |
| 82 | + |
| 83 | + alloc = g_object_new (GST_TYPE_KMS_ALLOCATOR, "name", |
| 84 | +- "KMSMemory::allocator", "drm-fd", fd, NULL); |
| 85 | ++ "KMSMemory::allocator", "drm-fd", self->fd, NULL); |
| 86 | ++ |
| 87 | ++ alloc->kmssink = self; |
| 88 | ++ |
| 89 | + gst_object_ref_sink (alloc); |
| 90 | + |
| 91 | + return alloc; |
| 92 | +@@ -464,7 +475,7 @@ gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem, |
| 93 | + |
| 94 | + GST_DEBUG_OBJECT (alloc, "bo handles: %d, %d, %d, %d", bo_handles[0], |
| 95 | + bo_handles[1], bo_handles[2], bo_handles[3]); |
| 96 | +- |
| 97 | ++ if (alloc->kmssink->Ismaster) { |
| 98 | + ret = drmModeAddFB2 (alloc->priv->fd, w, h, fmt, bo_handles, pitches, |
| 99 | + offsets, &kmsmem->fb_id, 0); |
| 100 | + if (ret) { |
| 101 | +@@ -472,6 +483,7 @@ gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem, |
| 102 | + strerror (-ret), ret); |
| 103 | + return FALSE; |
| 104 | + } |
| 105 | ++ } |
| 106 | + |
| 107 | + return TRUE; |
| 108 | + } |
| 109 | +diff --git a/sys/kms/gstkmsallocator.h b/sys/kms/gstkmsallocator.h |
| 110 | +index 9d00126..bcf277a 100644 |
| 111 | +--- a/sys/kms/gstkmsallocator.h |
| 112 | ++++ b/sys/kms/gstkmsallocator.h |
| 113 | +@@ -1,10 +1,12 @@ |
| 114 | + /* GStreamer |
| 115 | + * |
| 116 | + * Copyright (C) 2016 Igalia |
| 117 | ++ * Copyright (C) Microchip Technology Inc. |
| 118 | + * |
| 119 | + * Authors: |
| 120 | + * Víctor Manuel Jáquez Leal < [email protected]> |
| 121 | + * Javier Martin < [email protected]> |
| 122 | ++ * Sandeep Sheriker M <[email protected]> |
| 123 | + * |
| 124 | + * This library is free software; you can redistribute it and/or |
| 125 | + * modify it under the terms of the GNU Library General Public |
| 126 | +@@ -28,6 +30,7 @@ |
| 127 | + |
| 128 | + #include <gst/gst.h> |
| 129 | + #include <gst/video/video.h> |
| 130 | ++#include "gstkmssink.h" |
| 131 | + |
| 132 | + G_BEGIN_DECLS |
| 133 | + |
| 134 | +@@ -63,6 +66,7 @@ struct _GstKMSMemory |
| 135 | + struct _GstKMSAllocator |
| 136 | + { |
| 137 | + GstAllocator parent; |
| 138 | ++ GstKMSSink *kmssink; |
| 139 | + GstKMSAllocatorPrivate *priv; |
| 140 | + }; |
| 141 | + |
| 142 | +@@ -75,7 +79,7 @@ GType gst_kms_allocator_get_type (void) G_GNUC_CONST; |
| 143 | + gboolean gst_is_kms_memory (GstMemory *mem); |
| 144 | + guint32 gst_kms_memory_get_fb_id (GstMemory *mem); |
| 145 | + |
| 146 | +-GstAllocator* gst_kms_allocator_new (gint fd); |
| 147 | ++GstAllocator *gst_kms_allocator_new (GstKMSSink * self); |
| 148 | + |
| 149 | + GstMemory* gst_kms_allocator_bo_alloc (GstAllocator *allocator, |
| 150 | + GstVideoInfo *vinfo); |
| 151 | +diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c |
| 152 | +index 1331883..2d3ad27 100644 |
| 153 | +--- a/sys/kms/gstkmssink.c |
| 154 | ++++ b/sys/kms/gstkmssink.c |
| 155 | +@@ -1,10 +1,13 @@ |
| 156 | + /* GStreamer |
| 157 | + * |
| 158 | + * Copyright (C) 2016 Igalia |
| 159 | ++ * Copyright (C) Microchip Technology Inc. |
| 160 | + * |
| 161 | + * Authors: |
| 162 | + * Víctor Manuel Jáquez Leal < [email protected]> |
| 163 | + * Javier Martin < [email protected]> |
| 164 | ++ * Sandeep Sheriker M |
| 165 | + |
| 166 | + * |
| 167 | + * This library is free software; you can redistribute it and/or |
| 168 | + * modify it under the terms of the GNU Library General Public |
| 169 | +@@ -23,6 +26,12 @@ |
| 170 | + * |
| 171 | + */ |
| 172 | + |
| 173 | ++/* |
| 174 | ++ * kmsink is customized for Microchip(Atmel AT91) SAMA5D4 to |
| 175 | ++ * implement as a DRM client using GEM handle and render video |
| 176 | ++ * frames directly on planes of a DRM/KMS device using zerocopy. |
| 177 | ++ */ |
| 178 | ++ |
| 179 | + /** |
| 180 | + * SECTION:element-kmssink |
| 181 | + * @title: kmssink |
| 182 | +@@ -88,6 +97,7 @@ enum |
| 183 | + PROP_CAN_SCALE, |
| 184 | + PROP_DISPLAY_WIDTH, |
| 185 | + PROP_DISPLAY_HEIGHT, |
| 186 | ++ PROP_GEM_NAME, |
| 187 | + PROP_N |
| 188 | + }; |
| 189 | + |
| 190 | +@@ -584,6 +594,7 @@ gst_kms_sink_start (GstBaseSink * bsink) |
| 191 | + drmModePlane *plane; |
| 192 | + gboolean universal_planes; |
| 193 | + gboolean ret; |
| 194 | ++ struct drm_gem_open gemobj; |
| 195 | + |
| 196 | + self = GST_KMS_SINK (bsink); |
| 197 | + universal_planes = FALSE; |
| 198 | +@@ -605,6 +616,26 @@ gst_kms_sink_start (GstBaseSink * bsink) |
| 199 | + if (!get_drm_caps (self)) |
| 200 | + goto bail; |
| 201 | + |
| 202 | ++ |
| 203 | ++ GST_INFO_OBJECT (self, "GEM Name: %d\n", self->gemname); |
| 204 | ++ if (self->gemname > 0) { |
| 205 | ++ |
| 206 | ++ memset (&gemobj, 0, sizeof (gemobj)); |
| 207 | ++ gemobj.name = self->gemname; |
| 208 | ++ ret = drmIoctl (self->fd, DRM_IOCTL_GEM_OPEN, &gemobj); |
| 209 | ++ if (ret < 0) { |
| 210 | ++ GST_ERROR_OBJECT (self, "could not flink %d", ret); |
| 211 | ++ goto bail; |
| 212 | ++ } |
| 213 | ++ self->gemhandle = gemobj.handle; |
| 214 | ++ self->gemsize = gemobj.size; |
| 215 | ++ GST_INFO_OBJECT (self, "GEM handle: %d\n", gemobj.handle); |
| 216 | ++ GST_INFO_OBJECT (self, "GEM Size: %lld\n", gemobj.size); |
| 217 | ++ self->Ismaster = FALSE; |
| 218 | ++ self->can_scale = FALSE; |
| 219 | ++ } else { |
| 220 | ++ |
| 221 | ++ self->can_scale = TRUE; |
| 222 | + res = drmModeGetResources (self->fd); |
| 223 | + if (!res) |
| 224 | + goto resources_failed; |
| 225 | +@@ -673,7 +704,7 @@ retry_find_plane: |
| 226 | + |
| 227 | + GST_INFO_OBJECT (self, "display size: pixels = %dx%d / millimeters = %dx%d", |
| 228 | + self->hdisplay, self->vdisplay, self->mm_width, self->mm_height); |
| 229 | +- |
| 230 | ++ } |
| 231 | + self->pollfd.fd = self->fd; |
| 232 | + gst_poll_add_fd (self->poll, &self->pollfd); |
| 233 | + gst_poll_fd_ctl_read (self->poll, &self->pollfd, TRUE); |
| 234 | +@@ -874,7 +905,7 @@ ensure_kms_allocator (GstKMSSink * self) |
| 235 | + { |
| 236 | + if (self->allocator) |
| 237 | + return; |
| 238 | +- self->allocator = gst_kms_allocator_new (self->fd); |
| 239 | ++ self->allocator = gst_kms_allocator_new (self); |
| 240 | + } |
| 241 | + |
| 242 | + static GstBufferPool * |
| 243 | +@@ -1417,6 +1448,8 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) |
| 244 | + |
| 245 | + if (!buffer) |
| 246 | + return GST_FLOW_ERROR; |
| 247 | ++ |
| 248 | ++ if (self->Ismaster) { |
| 249 | + fb_id = gst_kms_memory_get_fb_id (gst_buffer_peek_memory (buffer, 0)); |
| 250 | + if (fb_id == 0) |
| 251 | + goto buffer_invalid; |
| 252 | +@@ -1428,6 +1461,7 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) |
| 253 | + self->buffer_id = fb_id; |
| 254 | + goto sync_frame; |
| 255 | + } |
| 256 | ++ } |
| 257 | + |
| 258 | + if ((crop = gst_buffer_get_video_crop_meta (buffer))) { |
| 259 | + GstVideoInfo vinfo = self->vinfo; |
| 260 | +@@ -1483,6 +1517,7 @@ retry_set_plane: |
| 261 | + "drmModeSetPlane at (%i,%i) %ix%i sourcing at (%i,%i) %ix%i", |
| 262 | + result.x, result.y, result.w, result.h, src.x, src.y, src.w, src.h); |
| 263 | + |
| 264 | ++ if (self->Ismaster) { |
| 265 | + ret = drmModeSetPlane (self->fd, self->plane_id, self->crtc_id, fb_id, 0, |
| 266 | + result.x, result.y, result.w, result.h, |
| 267 | + /* source/cropping coordinates are given in Q16 */ |
| 268 | +@@ -1494,6 +1529,7 @@ retry_set_plane: |
| 269 | + } |
| 270 | + goto set_plane_failed; |
| 271 | + } |
| 272 | ++ } |
| 273 | + |
| 274 | + sync_frame: |
| 275 | + /* Wait for the previous frame to complete redraw */ |
| 276 | +@@ -1609,6 +1645,9 @@ gst_kms_sink_set_property (GObject * object, guint prop_id, |
| 277 | + case PROP_CAN_SCALE: |
| 278 | + sink->can_scale = g_value_get_boolean (value); |
| 279 | + break; |
| 280 | ++ case PROP_GEM_NAME: |
| 281 | ++ sink->gemname = g_value_get_int (value); |
| 282 | ++ break; |
| 283 | + default: |
| 284 | + if (!gst_video_overlay_set_property (object, PROP_N, prop_id, value)) |
| 285 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| 286 | +@@ -1640,6 +1679,8 @@ gst_kms_sink_get_property (GObject * object, guint prop_id, |
| 287 | + case PROP_FORCE_MODESETTING: |
| 288 | + g_value_set_boolean (value, sink->modesetting_enabled); |
| 289 | + break; |
| 290 | ++ case PROP_GEM_NAME: |
| 291 | ++ g_value_set_int (value, sink->gemname); |
| 292 | + case PROP_CAN_SCALE: |
| 293 | + g_value_set_boolean (value, sink->can_scale); |
| 294 | + break; |
| 295 | +@@ -1678,6 +1719,9 @@ gst_kms_sink_init (GstKMSSink * sink) |
| 296 | + sink->fd = -1; |
| 297 | + sink->conn_id = -1; |
| 298 | + sink->plane_id = -1; |
| 299 | ++ sink->gemhandle = 0; |
| 300 | ++ sink->gemsize = 0; |
| 301 | ++ sink->Ismaster = TRUE; |
| 302 | + sink->can_scale = TRUE; |
| 303 | + gst_poll_fd_init (&sink->pollfd); |
| 304 | + sink->poll = gst_poll_new (TRUE); |
| 305 | +@@ -1775,6 +1819,11 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass) |
| 306 | + "When enabled, the sink try to configure the display mode", FALSE, |
| 307 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); |
| 308 | + |
| 309 | ++ g_properties[PROP_GEM_NAME] = g_param_spec_int ("gem-name", "gem-name", |
| 310 | ++ "when gem name is set, kmssink will function as drm client" |
| 311 | ++ "and communicate with drm master using gem name", -1, G_MAXINT32, -1, |
| 312 | ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT); |
| 313 | ++ |
| 314 | + /** |
| 315 | + * kmssink:can-scale: |
| 316 | + * |
| 317 | +diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h |
| 318 | +index a80699c..69c3240 100644 |
| 319 | +--- a/sys/kms/gstkmssink.h |
| 320 | ++++ b/sys/kms/gstkmssink.h |
| 321 | +@@ -1,10 +1,12 @@ |
| 322 | + /* GStreamer |
| 323 | + * |
| 324 | + * Copyright (C) 2016 Igalia |
| 325 | ++ * Copyright (C) Microchip Technology Inc. |
| 326 | + * |
| 327 | + * Authors: |
| 328 | + * Víctor Manuel Jáquez Leal < [email protected]> |
| 329 | + * Javier Martin < [email protected]> |
| 330 | ++ * Sandeep Sheriker M <[email protected]> |
| 331 | + * |
| 332 | + * This library is free software; you can redistribute it and/or |
| 333 | + * modify it under the terms of the GNU Library General Public |
| 334 | +@@ -81,6 +83,10 @@ struct _GstKMSSink { |
| 335 | + GstPoll *poll; |
| 336 | + GstPollFD pollfd; |
| 337 | + |
| 338 | ++ gint32 gemname; |
| 339 | ++ guint32 gemsize, gemhandle; |
| 340 | ++ gboolean Ismaster; |
| 341 | ++ |
| 342 | + /* render video rectangle */ |
| 343 | + GstVideoRectangle render_rect; |
| 344 | + |
| 345 | +-- |
| 346 | +2.7.4 |
| 347 | + |
0 commit comments