Added TI patches, generated from commit 04f9d72 of the following tree:
[ubuntu-omap:gst-plugins-bad1-0.git] / debian / patches / 0031-01-12-drm-add-GstDRMBufferPool.patch
1 From da0084313ab33a69c8be89d46b5ceb449f37888b Mon Sep 17 00:00:00 2001
2 From: Rob Clark <rob@ti.com>
3 Date: Tue, 12 Jun 2012 09:41:31 -0500
4 Subject: [PATCH 031/100] [01/12] drm: add GstDRMBufferPool
5
6 A re-usable bufferpool for elements which are using DRM buffers.
7
8 TODO: remove omap dependencies.. not sure how to handle allocation
9 since that part still needs a driver specific ioctl, but for the
10 rest we could probably add some gst drm helpers and use that instead
11 of libdrm_omap.
12 ---
13  gst-libs/gst/drm/Makefile.am        |   33 ++++
14  gst-libs/gst/drm/drmbufferpool.h    |  120 ++++++++++++++
15  gst-libs/gst/drm/gstdrmbufferpool.c |  306 +++++++++++++++++++++++++++++++++++
16  gst-libs/gst/drm/gstdrmbufferpool.h |   56 +++++++
17  4 files changed, 515 insertions(+)
18  create mode 100644 gst-libs/gst/drm/Makefile.am
19  create mode 100644 gst-libs/gst/drm/drmbufferpool.h
20  create mode 100644 gst-libs/gst/drm/gstdrmbufferpool.c
21  create mode 100644 gst-libs/gst/drm/gstdrmbufferpool.h
22
23 diff --git a/gst-libs/gst/drm/Makefile.am b/gst-libs/gst/drm/Makefile.am
24 new file mode 100644
25 index 0000000..c5f11c1
26 --- /dev/null
27 +++ b/gst-libs/gst/drm/Makefile.am
28 @@ -0,0 +1,33 @@
29 +
30 +lib_LTLIBRARIES = libgstdrm-@GST_MAJORMINOR@.la
31 +
32 +CLEANFILES = $(BUILT_SOURCES)
33 +
34 +libgstdrm_@GST_MAJORMINOR@_la_SOURCES = \
35 +       gstdrmbufferpool.c
36 +
37 +libgstdrm_@GST_MAJORMINOR@includedir = \
38 +       $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/drm
39 +
40 +libgstdrm_@GST_MAJORMINOR@include_HEADERS = \
41 +       gstdrmbufferpool.h
42 +
43 +libgstdrm_@GST_MAJORMINOR@_la_CFLAGS = \
44 +       $(DRM_CFLAGS) \
45 +       $(GST_PLUGINS_BAD_CFLAGS) \
46 +       $(GST_PLUGINS_BASE_CFLAGS) \
47 +       -DGST_USE_UNSTABLE_API \
48 +       $(GST_CFLAGS)
49 +
50 +libgstdrm_@GST_MAJORMINOR@_la_LIBADD = \
51 +       $(DRM_LIBS) \
52 +       $(GST_PLUGINS_BASE_LIBS) \
53 +       $(GST_BASE_LIBS) \
54 +       $(GST_LIBS)
55 +
56 +libgstdrm_@GST_MAJORMINOR@_la_LDFLAGS = \
57 +       $(DRM_LDFLAGS) \
58 +       $(GST_LIB_LDFLAGS) \
59 +       $(GST_ALL_LDFLAGS) \
60 +       $(GST_LT_LDFLAGS)
61 +
62 diff --git a/gst-libs/gst/drm/drmbufferpool.h b/gst-libs/gst/drm/drmbufferpool.h
63 new file mode 100644
64 index 0000000..a5bf842
65 --- /dev/null
66 +++ b/gst-libs/gst/drm/drmbufferpool.h
67 @@ -0,0 +1,120 @@
68 +/*
69 + * GStreamer
70 + *
71 + * Copyright (C) 2012 Texas Instruments 
72 + * Copyright (C) 2012 Collabora Ltd
73 + *
74 + * Authors:
75 + *  Alessandro Decina <alessandro.decina@collabora.co.uk>
76 + *  Rob Clark <rob.clark@linaro.org>
77 + *
78 + * This library is free software; you can redistribute it and/or
79 + * modify it under the terms of the GNU Lesser General Public
80 + * License as published by the Free Software Foundation
81 + * version 2.1 of the License.
82 + *
83 + * This library is distributed in the hope that it will be useful,
84 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
85 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
86 + * Lesser General Public License for more details.
87 + *
88 + * You should have received a copy of the GNU Lesser General Public
89 + * License along with this library; if not, write to the Free Software
90 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
91 + */
92 +
93 +#ifndef __DRMBUFFERPOOL_H__
94 +#define __DRMBUFFERPOOL_H__
95 +
96 +/*
97 + * private header for gstdrmbufferpool
98 + */
99 +
100 +#include <string.h>
101 +#include <stdint.h>
102 +#include <errno.h>
103 +#include <string.h>
104 +
105 +#include <gst/gst.h>
106 +#include <gst/dmabuf/dmabuf.h>
107 +
108 +/* TODO replace dependency on libdrm_omap w/ libdrm.. the only thing
109 + * missing is way to allocate buffers, but this should probably be
110 + * done via libdrm?
111 + */
112 +#include <omap_drm.h>
113 +#include <omap_drmif.h>
114 +
115 +G_BEGIN_DECLS
116 +
117 +/*
118 + * GstDRMBuffer:
119 + */
120 +
121 +#define GST_TYPE_DRM_BUFFER (gst_drm_buffer_get_type())
122 +#define GST_IS_DRM_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DRM_BUFFER))
123 +#define GST_DRM_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DRM_BUFFER, GstDRMBuffer))
124 +
125 +typedef struct _GstDRMBuffer GstDRMBuffer;
126 +typedef struct _GstDRMBufferClass GstDRMBufferClass;
127 +
128 +/* forward declaration */
129 +struct _GstDRMBufferPool;
130 +
131 +struct _GstDRMBuffer {
132 +  GstBuffer parent;
133 +
134 +  struct omap_bo *bo;
135 +
136 +  struct _GstDRMBufferPool *pool; /* buffer-pool that this buffer belongs to */
137 +  GstDRMBuffer *next;             /* next in freelist, if not in use */
138 +  gboolean remove_from_pool;
139 +};
140 +
141 +struct _GstDRMBufferClass {
142 +  GstBufferClass klass;
143 +};
144 +
145 +GType gst_drm_buffer_get_type (void);
146 +GstDRMBuffer * gst_drm_buffer_new (struct _GstDRMBufferPool * pool);
147 +void gst_drm_buffer_set_pool (GstDRMBuffer * self, struct _GstDRMBufferPool * pool);
148 +
149 +/*
150 + * GstDRMBufferPool:
151 + */
152 +
153 +/* TODO do we want GstDRMBufferPool to be subclassed.. if so, move this
154 + * back to public header.. for now I'm just keeping the implementation
155 + * entirely opaque
156 + */
157 +struct _GstDRMBufferPool
158 +{
159 +  GstMiniObject parent;
160 +
161 +  int fd;
162 +  struct omap_device *dev;
163 +
164 +  /* output (padded) size including any codec padding: */
165 +  gint width, height;
166 +
167 +  gboolean         strided;  /* 2d buffers? */
168 +  GstCaps         *caps;
169 +  GMutex          *lock;
170 +  gboolean         running;  /* with lock */
171 +  GstElement      *element;  /* the element that owns us.. */
172 +  GstDRMBuffer    *head; /* list of available buffers */
173 +  GstDRMBuffer    *tail;
174 +  guint size;
175 +};
176 +
177 +struct _GstDRMBufferPoolClass
178 +{
179 +  GstMiniObjectClass klass;
180 +};
181 +
182 +gboolean gst_drm_buffer_pool_put (GstDRMBufferPool * self, GstDRMBuffer * buf);
183 +
184 +
185 +G_END_DECLS
186 +
187 +#endif /* __DRMBUFFERPOOL_H__ */
188 diff --git a/gst-libs/gst/drm/gstdrmbufferpool.c b/gst-libs/gst/drm/gstdrmbufferpool.c
189 new file mode 100644
190 index 0000000..58fbb11
191 --- /dev/null
192 +++ b/gst-libs/gst/drm/gstdrmbufferpool.c
193 @@ -0,0 +1,306 @@
194 +/*
195 + * GStreamer
196 + *
197 + * Copyright (C) 2012 Texas Instruments
198 + * Copyright (C) 2012 Collabora Ltd
199 + *
200 + * Authors:
201 + *  Alessandro Decina <alessandro.decina@collabora.co.uk>
202 + *  Rob Clark <rob.clark@linaro.org>
203 + *
204 + * This library is free software; you can redistribute it and/or
205 + * modify it under the terms of the GNU Lesser General Public
206 + * License as published by the Free Software Foundation
207 + * version 2.1 of the License.
208 + *
209 + * This library is distributed in the hope that it will be useful,
210 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
211 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
212 + * Lesser General Public License for more details.
213 + *
214 + * You should have received a copy of the GNU Lesser General Public
215 + * License along with this library; if not, write to the Free Software
216 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
217 + */
218 +
219 +#ifdef HAVE_CONFIG_H
220 +#include "config.h"
221 +#endif
222 +
223 +#include "gstdrmbufferpool.h"
224 +#include "drmbufferpool.h"
225 +
226 +/*
227 + * GstDRMBufferPool:
228 + */
229 +
230 +typedef GstDRMBufferPool GstDRMDRMBufferPool;
231 +typedef GstDRMBufferPoolClass GstDRMDRMBufferPoolClass;
232 +
233 +G_DEFINE_TYPE (GstDRMDRMBufferPool, gst_drm_buffer_pool,
234 +    GST_TYPE_MINI_OBJECT);
235 +
236 +GstDRMBufferPool *
237 +gst_drm_buffer_pool_new (GstElement * element,
238 +    int fd, GstCaps * caps, guint size)
239 +{
240 +  GstDRMBufferPool *self = (GstDRMBufferPool *)
241 +      gst_mini_object_new (GST_TYPE_DRM_BUFFER_POOL);
242 +
243 +  self->element = gst_object_ref (element);
244 +  self->fd   = fd;
245 +  self->dev  = omap_device_new (fd);
246 +  self->caps = NULL;
247 +  gst_drm_buffer_pool_set_caps (self, caps);
248 +  self->size = size;
249 +  self->head = NULL;
250 +  self->tail = NULL;
251 +  self->lock = g_mutex_new ();
252 +  self->running = TRUE;
253 +
254 +  return self;
255 +}
256 +
257 +/** get size of individual buffers within the bufferpool */
258 +guint
259 +gst_drm_buffer_pool_size (GstDRMBufferPool * self)
260 +{
261 +  return self->size;
262 +}
263 +
264 +void
265 +gst_drm_buffer_pool_set_caps (GstDRMBufferPool * self, GstCaps * caps)
266 +{
267 +  gst_caps_replace (&self->caps, caps);
268 +  if (caps) {
269 +    GstStructure *s = gst_caps_get_structure (caps, 0);
270 +
271 +    self->strided =
272 +        !strcmp (gst_structure_get_name (s), "video/x-raw-yuv-strided");
273 +
274 +    gst_structure_get_int (s, "width", &self->width);
275 +    gst_structure_get_int (s, "height", &self->height);
276 +  } else {
277 +    self->width = 0;
278 +    self->height = 0;
279 +    self->strided = FALSE;
280 +  }
281 +}
282 +
283 +gboolean
284 +gst_drm_buffer_pool_check_caps (GstDRMBufferPool * self,
285 +    GstCaps * caps)
286 +{
287 +  return gst_caps_is_equal (self->caps, caps);
288 +}
289 +
290 +/** destroy existing bufferpool */
291 +void
292 +gst_drm_buffer_pool_destroy (GstDRMBufferPool * self)
293 +{
294 +  g_return_if_fail (self);
295 +
296 +  GST_DRM_BUFFER_POOL_LOCK (self);
297 +  self->running = FALSE;
298 +
299 +  GST_DEBUG_OBJECT (self->element, "destroy pool");
300 +
301 +  /* free all buffers on the freelist */
302 +  while (self->head) {
303 +    GstDRMBuffer *buf = self->head;
304 +    self->head = buf->next;
305 +    buf->next = NULL;
306 +    GST_DEBUG_OBJECT (self, "unreffing %p from freelist", buf);
307 +    GST_DRM_BUFFER_POOL_UNLOCK (self);
308 +    gst_buffer_unref (GST_BUFFER (buf));
309 +    GST_DRM_BUFFER_POOL_LOCK (self);
310 +  }
311 +  self->tail = NULL;
312 +  GST_DRM_BUFFER_POOL_UNLOCK (self);
313 +  gst_mini_object_unref (GST_MINI_OBJECT (self));
314 +}
315 +
316 +#if 0
317 +static void
318 +dump_list (GstDRMBufferPool * pool, GstDRMBuffer * buf)
319 +{
320 +  GST_ERROR_OBJECT (pool->element, "LIST");
321 +  while (buf) {
322 +    GST_ERROR_OBJECT (pool->element, "BUF: %p", buf);
323 +    buf = buf->next;
324 +  }
325 +}
326 +#endif
327 +
328 +/** get buffer from bufferpool, allocate new buffer if needed */
329 +GstBuffer *
330 +gst_drm_buffer_pool_get (GstDRMBufferPool * self, gboolean force_alloc)
331 +{
332 +  GstDRMBuffer *buf = NULL;
333 +
334 +  g_return_val_if_fail (self, NULL);
335 +
336 +  GST_DRM_BUFFER_POOL_LOCK (self);
337 +  if (self->running) {
338 +    /* re-use a buffer off the freelist if any are available
339 +     */
340 +    if (!force_alloc && self->head) {
341 +//      dump_list (self, self->head);
342 +      buf = self->head;
343 +      self->head = buf->next;
344 +      if (self->head == NULL)
345 +        self->tail = NULL;
346 +    } else {
347 +      buf = gst_drm_buffer_new (self);
348 +    }
349 +    if (self->caps)
350 +      gst_buffer_set_caps (GST_BUFFER (buf), self->caps);
351 +  }
352 +  GST_DRM_BUFFER_POOL_UNLOCK (self);
353 +
354 +  GST_LOG_OBJECT (self->element, "returning buf %p", buf);
355 +
356 +  return GST_BUFFER (buf);
357 +}
358 +
359 +gboolean
360 +gst_drm_buffer_pool_put (GstDRMBufferPool * self, GstDRMBuffer * buf)
361 +{
362 +  gboolean reuse = FALSE;
363 +
364 +  if (buf->remove_from_pool)
365 +    return FALSE;
366 +
367 +  GST_DRM_BUFFER_POOL_LOCK (self);
368 +  if (self->running) {
369 +    reuse = TRUE;
370 +
371 +    GST_LOG_OBJECT (self->element, "reviving buffer %p", buf);
372 +    gst_buffer_ref (GST_BUFFER (buf));
373 +
374 +    buf->next = NULL;
375 +    if (self->tail)
376 +      self->tail->next = buf;
377 +    self->tail = buf;
378 +    if (self->head == NULL)
379 +      self->head = self->tail;
380 +    buf->remove_from_pool = FALSE;
381 +  } else {
382 +    GST_INFO_OBJECT (self->element, "the pool is shutting down");
383 +    buf->remove_from_pool = TRUE;
384 +  }
385 +  GST_DRM_BUFFER_POOL_UNLOCK (self);
386 +
387 +  return reuse;
388 +}
389 +
390 +static void
391 +gst_drm_buffer_pool_finalize (GstDRMBufferPool * self)
392 +{
393 +  g_mutex_free (self->lock);
394 +  if (self->caps)
395 +    gst_caps_unref (self->caps);
396 +  gst_object_unref (self->element);
397 +  GST_MINI_OBJECT_CLASS (gst_drm_buffer_pool_parent_class)->finalize
398 +      (GST_MINI_OBJECT (self));
399 +}
400 +
401 +static void
402 +gst_drm_buffer_pool_class_init (GstDRMBufferPoolClass * klass)
403 +{
404 +  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (klass);
405 +
406 +  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
407 +      GST_DEBUG_FUNCPTR (gst_drm_buffer_pool_finalize);
408 +}
409 +
410 +static void
411 +gst_drm_buffer_pool_init (GstDRMBufferPool * self)
412 +{
413 +}
414 +
415 +/*
416 + * GstDRMBuffer:
417 + */
418 +
419 +
420 +typedef GstDRMBuffer GstDRMDRMBuffer;
421 +typedef GstDRMBufferClass GstDRMDRMBufferClass;
422 +
423 +G_DEFINE_TYPE (GstDRMDRMBuffer, gst_drm_buffer, GST_TYPE_BUFFER);
424 +
425 +GstDRMBuffer *
426 +gst_drm_buffer_new (GstDRMBufferPool * pool)
427 +{
428 +  GstDRMBuffer *self = (GstDRMBuffer *)
429 +      gst_mini_object_new (GST_TYPE_DRM_BUFFER);
430 +
431 +  /* TODO: if allocation could be handled via libkms then this
432 +   * bufferpool implementation could be completely generic..
433 +   * otherwise we might want some support for various different
434 +   * drm drivers here:
435 +   */
436 +  self->bo = omap_bo_new (pool->dev, pool->size, OMAP_BO_WC);
437 +
438 +  GST_BUFFER_DATA (self) = omap_bo_map (self->bo);
439 +  GST_BUFFER_SIZE (self) = pool->size;
440 +
441 +  /* attach dmabuf handle to buffer so that elements from other
442 +   * plugins can access for zero copy hw accel:
443 +   */
444 +  gst_buffer_set_dma_buf (GST_BUFFER (self),
445 +      gst_dma_buf_new (omap_bo_dmabuf (self->bo)));
446 +
447 +  gst_drm_buffer_set_pool (self, pool);
448 +
449 +  return self;
450 +}
451 +
452 +void
453 +gst_drm_buffer_set_pool (GstDRMBuffer * self, GstDRMBufferPool * pool)
454 +{
455 +
456 +  GST_LOG_OBJECT (pool->element, "creating buffer %p in pool %p", self, pool);
457 +
458 +  self->pool = (GstDRMBufferPool *)
459 +      gst_mini_object_ref (GST_MINI_OBJECT (pool));
460 +  self->remove_from_pool = FALSE;
461 +
462 +  if (pool->caps)
463 +    gst_buffer_set_caps (GST_BUFFER (self), pool->caps);
464 +}
465 +
466 +static void
467 +gst_drm_buffer_finalize (GstDRMBuffer * self)
468 +{
469 +  GstDRMBufferPool *pool = self->pool;
470 +  gboolean resuscitated = FALSE;
471 +
472 +  GST_LOG_OBJECT (pool->element, "finalizing buffer %p", self);
473 +
474 +  resuscitated = gst_drm_buffer_pool_put (pool, self);
475 +  if (resuscitated)
476 +    return;
477 +
478 +  GST_BUFFER_DATA (self) = NULL;
479 +  omap_bo_del (self->bo);
480 +
481 +  gst_mini_object_unref (GST_MINI_OBJECT (pool));
482 +
483 +  GST_MINI_OBJECT_CLASS (gst_drm_buffer_parent_class)->finalize
484 +      (GST_MINI_OBJECT (self));
485 +}
486 +
487 +static void
488 +gst_drm_buffer_class_init (GstDRMBufferClass * klass)
489 +{
490 +  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (klass);
491 +
492 +  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
493 +      GST_DEBUG_FUNCPTR (gst_drm_buffer_finalize);
494 +}
495 +
496 +static void
497 +gst_drm_buffer_init (GstDRMBuffer * buffer)
498 +{
499 +}
500 diff --git a/gst-libs/gst/drm/gstdrmbufferpool.h b/gst-libs/gst/drm/gstdrmbufferpool.h
501 new file mode 100644
502 index 0000000..b7d09ed
503 --- /dev/null
504 +++ b/gst-libs/gst/drm/gstdrmbufferpool.h
505 @@ -0,0 +1,56 @@
506 +/*
507 + * GStreamer
508 + *
509 + * Copyright (C) 2012 Texas Instruments
510 + * Copyright (C) 2012 Collabora Ltd
511 + *
512 + * Authors:
513 + *  Alessandro Decina <alessandro.decina@collabora.co.uk>
514 + *  Rob Clark <rob.clark@linaro.org>
515 + *
516 + * This library is free software; you can redistribute it and/or
517 + * modify it under the terms of the GNU Lesser General Public
518 + * License as published by the Free Software Foundation
519 + * version 2.1 of the License.
520 + *
521 + * This library is distributed in the hope that it will be useful,
522 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
523 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
524 + * Lesser General Public License for more details.
525 + *
526 + * You should have received a copy of the GNU Lesser General Public
527 + * License along with this library; if not, write to the Free Software
528 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
529 + */
530 +
531 +#ifndef __GSTDRMBUFFERPOOL_H__
532 +#define __GSTDRMBUFFERPOOL_H__
533 +
534 +#include <gst/gst.h>
535 +
536 +G_BEGIN_DECLS
537 +
538 +#define GST_TYPE_DRM_BUFFER_POOL (gst_drm_buffer_pool_get_type())
539 +#define GST_IS_DRM_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DRM_BUFFER_POOL))
540 +#define GST_DRM_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DRM_BUFFER_POOL, GstDRMBufferPool))
541 +
542 +#define GST_DRM_BUFFER_POOL_LOCK(self)     g_mutex_lock ((self)->lock)
543 +#define GST_DRM_BUFFER_POOL_UNLOCK(self)   g_mutex_unlock ((self)->lock)
544 +
545 +typedef struct _GstDRMBufferPool GstDRMBufferPool;
546 +typedef struct _GstDRMBufferPoolClass GstDRMBufferPoolClass;
547 +
548 +GType gst_drm_buffer_pool_get_type (void);
549 +GstDRMBufferPool * gst_drm_buffer_pool_new (GstElement * element,
550 +    int fd, GstCaps * caps, guint size);
551 +void gst_drm_buffer_pool_destroy (GstDRMBufferPool * self);
552 +guint gst_drm_buffer_pool_size (GstDRMBufferPool * self);
553 +void gst_drm_buffer_pool_set_caps (GstDRMBufferPool * self, GstCaps * caps);
554 +gboolean gst_drm_buffer_pool_check_caps (GstDRMBufferPool * self,
555 +    GstCaps * caps);
556 +GstBuffer * gst_drm_buffer_pool_get (GstDRMBufferPool * self,
557 +    gboolean force_alloc);
558 +
559 +G_END_DECLS
560 +
561 +#endif /* __GSTDRMBUFFERPOOL_H__ */
562 -- 
563 1.7.9.5
564