summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gstducati.c10
-rw-r--r--src/gstducatibufferpool.c397
-rw-r--r--src/gstducatibufferpool.h85
-rw-r--r--src/gstducatih264dec.c3
-rw-r--r--src/gstducatimpeg2dec.c3
-rw-r--r--src/gstducatimpeg4dec.c3
-rw-r--r--src/gstducatirvdec.c5
-rw-r--r--src/gstducativc1dec.c5
-rw-r--r--src/gstducatividdec.c358
-rw-r--r--src/gstducatividdec.h4
-rw-r--r--src/gstducatividenc.h4
11 files changed, 488 insertions, 389 deletions
diff --git a/src/gstducati.c b/src/gstducati.c
index a6274d0..d5f57a2 100644
--- a/src/gstducati.c
+++ b/src/gstducati.c
@@ -42,7 +42,7 @@ plugin_init (GstPlugin * plugin)
/* TODO .. find some way to reasonably detect if the corresponding
* codecs are actually available..
*/
- return gst_element_register (plugin, "ducatih264dec", GST_RANK_PRIMARY,
+ return gst_element_register (plugin, "ducatih264dec", GST_RANK_PRIMARY + 1,
GST_TYPE_DUCATIH264DEC)
&& gst_element_register (plugin, "ducatimpeg4dec", GST_RANK_PRIMARY,
GST_TYPE_DUCATIMPEG4DEC)
@@ -56,10 +56,10 @@ plugin_init (GstPlugin * plugin)
GST_TYPE_DUCATIVP7DEC)
&& gst_element_register (plugin, "ducatirvdec", GST_RANK_PRIMARY,
GST_TYPE_DUCATIRVDEC)
- && gst_element_register (plugin, "ducatih264enc", GST_RANK_PRIMARY,
- GST_TYPE_DUCATIH264ENC)
- && gst_element_register (plugin, "ducatimpeg4enc", GST_RANK_PRIMARY,
- GST_TYPE_DUCATIMPEG4ENC);
+ /* && gst_element_register (plugin, "ducatih264enc", GST_RANK_PRIMARY, */
+ /* GST_TYPE_DUCATIH264ENC) */
+ /* && gst_element_register (plugin, "ducatimpeg4enc", GST_RANK_PRIMARY, */
+ /* GST_TYPE_DUCATIMPEG4ENC) */ ;
}
void *
diff --git a/src/gstducatibufferpool.c b/src/gstducatibufferpool.c
index fc5c379..55f0409 100644
--- a/src/gstducatibufferpool.c
+++ b/src/gstducatibufferpool.c
@@ -20,236 +20,287 @@
#include "gstducatibufferpool.h"
/*
- * GstDucatiBuffer
+ * GSTTITilerMeta
*/
-static GstBufferClass *buffer_parent_class;
+static void gst_ti_tiler_meta_free (GstTITilerMeta * meta, GstBuffer * buf);
-/* Get the original buffer, or whatever is the best output buffer.
- * Consumes the input reference, produces the output reference
- */
-GstBuffer *
-gst_ducati_buffer_get (GstDucatiBuffer * self)
+/* TI TILER Metadata */
+const GstMetaInfo *
+gst_ti_tiler_meta_get_info (void)
{
- if (self->orig) {
- // TODO copy to orig buffer.. if needed.
- gst_buffer_unref (self->orig);
- self->orig = NULL;
+ static const GstMetaInfo *ti_tiler_meta_info = NULL;
+
+ if (ti_tiler_meta_info == NULL) {
+ ti_tiler_meta_info = gst_meta_register ("GstTITilerMeta", "GstTITilerMeta",
+ sizeof (GstTITilerMeta),
+ (GstMetaInitFunction) NULL,
+ (GstMetaFreeFunction) gst_ti_tiler_meta_free,
+ (GstMetaCopyFunction) NULL, (GstMetaTransformFunction) NULL);
}
- return GST_BUFFER (self);
+ return ti_tiler_meta_info;
+
}
-static GstDucatiBuffer *
-gst_ducati_buffer_new (GstDucatiBufferPool * pool)
+static void
+my_tiler_free_func (gpointer data)
{
- GstDucatiBuffer *self = (GstDucatiBuffer *)
- gst_mini_object_new (GST_TYPE_DUCATIBUFFER);
- guint sz;
+ GST_DEBUG ("Calling MemMgr_Free on %p", data);
+ MemMgr_Free (data);
+}
- GST_LOG_OBJECT (pool->element, "creating buffer %p in pool %p", self, pool);
+static GstTITilerMeta *
+gst_buffer_add_ti_tiler_meta (GstBuffer * buffer, GstTITilerBufferPool * pool)
+{
+ GstTITilerMeta *meta;
+ guint8 *tilerdata;
+ GstMemory *memory;
+ gsize size;
+ guint stride;
+
+ meta =
+ (GstTITilerMeta *) gst_buffer_add_meta (buffer, GST_TI_TILER_META_INFO,
+ NULL);
+
+ /* FIXME : We are only doing 2D alloc */
+ GST_DEBUG_OBJECT (pool, "Adding new GstTITilerMeta on buffer %p", buffer);
+
+ stride = pool->alloc2d ? 4096 : pool->padded_width;
+
+ size = (stride * ALIGN2 (pool->padded_height, 1) * 3) / 2;
+
+ /* Fill fields */
+ meta->allocated = TRUE;
+
+ meta->nblocks = pool->alloc2d ? 2 : 1;
+ memset (meta->block, 0, sizeof (MemAllocBlock) * meta->nblocks);
+
+ if (meta->nblocks == 2) {
+ meta->block[0].pixelFormat = PIXEL_FMT_8BIT;
+ meta->block[0].dim.area.width = pool->padded_width;
+ meta->block[0].dim.area.height = ALIGN2 (pool->padded_height, 1);
+ meta->block[0].stride = stride;
+ meta->block[1].pixelFormat = PIXEL_FMT_16BIT;
+ meta->block[1].dim.area.width = pool->padded_width;
+ meta->block[1].dim.area.height = ALIGN2 (pool->padded_height, 1) / 2;
+ meta->block[1].stride = stride;
+ } else {
+ meta->block[0].pixelFormat = PIXEL_FMT_PAGE;
+ meta->block[0].dim.len = size;
+ }
- self->pool = (GstDucatiBufferPool *)
- gst_mini_object_ref (GST_MINI_OBJECT (pool));
+ /* allocate data */
+ tilerdata = MemMgr_Alloc (meta->block, meta->nblocks);
- GST_BUFFER_DATA (self) =
- gst_ducati_alloc_2d (pool->padded_width, pool->padded_height, &sz);
- GST_BUFFER_SIZE (self) = sz;
+ if (G_UNLIKELY (tilerdata == NULL))
+ goto alloc_failed;
- gst_buffer_set_caps (GST_BUFFER (self), pool->caps);
+ GST_DEBUG ("MemMgr_Alloc() returned %p", tilerdata);
- return self;
-}
+ /* Physical addresses */
+ meta->y_paddr = TilerMem_VirtToPhys (tilerdata);
+ meta->uv_paddr =
+ TilerMem_VirtToPhys (tilerdata + ALIGN2 (pool->padded_height,
+ 1) * stride);
-static void
-gst_ducati_buffer_finalize (GstDucatiBuffer * self)
-{
- GstDucatiBufferPool *pool = self->pool;
- gboolean resuscitated = FALSE;
+ GST_DEBUG ("y_paddr:%p , uv_paddr:%p", meta->y_paddr, meta->uv_paddr);
- GST_LOG_OBJECT (pool->element, "finalizing buffer %p", self);
+ meta->y_type = gst_ducati_get_mem_type (meta->y_paddr);
+ meta->uv_type = gst_ducati_get_mem_type (meta->uv_paddr);
- GST_DUCATI_BUFFER_POOL_LOCK (pool);
- if (pool->running) {
- resuscitated = TRUE;
+ /* Set the memory on the buffer */
+ memory =
+ gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, tilerdata,
+ my_tiler_free_func, size, 0, size);
+ gst_buffer_take_memory (buffer, -1, memory);
- GST_LOG_OBJECT (pool->element, "reviving buffer %p", self);
- gst_buffer_ref (GST_BUFFER (self));
+ return meta;
- /* insert self into freelist */
- self->next = pool->freelist;
- pool->freelist = self;
- } else {
- GST_LOG_OBJECT (pool->element, "the pool is shutting down");
- }
- GST_DUCATI_BUFFER_POOL_UNLOCK (pool);
-
- if (!resuscitated) {
- GST_LOG_OBJECT (pool->element,
- "buffer %p (data %p, len %u) not recovered, freeing",
- self, GST_BUFFER_DATA (self), GST_BUFFER_SIZE (self));
- MemMgr_Free ((void *) GST_BUFFER_DATA (self));
- GST_BUFFER_DATA (self) = NULL;
- gst_mini_object_unref (GST_MINI_OBJECT (pool));
- GST_MINI_OBJECT_CLASS (buffer_parent_class)->finalize (GST_MINI_OBJECT
- (self));
+alloc_failed:
+ {
+ GST_WARNING_OBJECT (pool, "Failed to allocate TILER memory");
+ return NULL;
}
}
static void
-gst_ducati_buffer_class_init (gpointer g_class, gpointer class_data)
-{
- GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
- buffer_parent_class = g_type_class_peek_parent (g_class);
-
- mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
- GST_DEBUG_FUNCPTR (gst_ducati_buffer_finalize);
-}
-
-GType
-gst_ducati_buffer_get_type (void)
+gst_ti_tiler_meta_free (GstTITilerMeta * meta, GstBuffer * buf)
{
- static GType type;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof (GstBufferClass),
- .class_init = gst_ducati_buffer_class_init,
- .instance_size = sizeof (GstDucatiBuffer),
- };
- type = g_type_register_static (GST_TYPE_BUFFER,
- "GstDucatiBuffer", &info, 0);
- }
- return type;
+ GST_DEBUG ("Freeing TITilerMeta on buffer %p", buf);
+ /* if (meta->allocated) { */
+ /* MemMgr_Free (meta->block[0].ptr); */
+ /* } else { */
+ /* MemMgr_UnMap (meta->block[0].ptr); */
+ /* } */
}
/*
- * GstDucatiBufferPool
+ * GstTITilerBufferPool
*/
-#define gst_ducati_buffer_pool_parent_class parent_class
-G_DEFINE_TYPE (GstDucatiBufferPool, gst_ducati_buffer_pool,
+#define gst_ti_tiler_buffer_pool_parent_class parent_class
+G_DEFINE_TYPE (GstTITilerBufferPool, gst_ti_tiler_buffer_pool,
GST_TYPE_BUFFER_POOL);
-/** create new bufferpool */
-GstDucatiBufferPool *
-gst_ducati_buffer_pool_new (GstElement * element, GstCaps * caps, guint size)
+static void
+gst_ti_tiler_buffer_pool_init (GstTITilerBufferPool * pool)
{
- GstDucatiBufferPool *self = (GstDucatiBufferPool *)
- gst_mini_object_new (GST_TYPE_DUCATIBUFFERPOOL);
- self->element = gst_object_ref (element);
- if (caps) {
- GstStructure *s = gst_caps_get_structure (caps, 0);
+}
- self->caps = gst_caps_ref (caps);
- gst_structure_get_int (s, "width", &self->padded_width);
- gst_structure_get_int (s, "height", &self->padded_height);
- } else {
- self->padded_width = 0;
- self->padded_height = 0;
- self->caps = NULL;
- }
- self->size = size;
- self->freelist = NULL;
- self->lock = g_mutex_new ();
- self->running = TRUE;
+
+GstBufferPool *
+gst_ti_tiler_buffer_pool_new (gboolean alloc2d)
+{
+ GstBufferPool *self;
+ GstTITilerBufferPool *tipool;
+
+ self = g_object_new (GST_TYPE_TI_TILER_BUFFER_POOL, NULL);
+ tipool = GST_TI_TILER_BUFFER_POOL (self);
+
+ tipool->alloc2d = alloc2d;
+
+ GST_ERROR_OBJECT (self, "Created new TI Tiler buffer pool %p (alloc2d:%d)",
+ self, tipool->alloc2d);
return self;
}
-/** destroy existing bufferpool */
-void
-gst_ducati_buffer_pool_destroy (GstDucatiBufferPool * self)
+static GstFlowReturn
+gst_ti_tiler_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
+ GstBufferPoolParams * params)
{
- g_return_if_fail (self);
+ GstTITilerBufferPool *tipool = GST_TI_TILER_BUFFER_POOL (pool);
+ GstBuffer *outbuf;
+ GstTITilerMeta *meta;
+ GstVideoInfo *info;
+ guint stride;
- GST_DUCATI_BUFFER_POOL_LOCK (self);
- self->running = FALSE;
- GST_DUCATI_BUFFER_POOL_UNLOCK (self);
+ info = &tipool->info;
- GST_DEBUG_OBJECT (self->element, "destroy pool");
+ outbuf = gst_buffer_new ();
- /* free all buffers on the freelist */
- while (self->freelist) {
- GstDucatiBuffer *buf = self->freelist;
- self->freelist = buf->next;
- gst_buffer_unref (GST_BUFFER (buf));
+ /* Add Tiler meta (will allocate memory) */
+ meta = gst_buffer_add_ti_tiler_meta (outbuf, tipool);
+ if (meta == NULL) {
+ gst_buffer_unref (outbuf);
+ goto no_buffer;
}
- gst_mini_object_unref (GST_MINI_OBJECT (self));
-}
+ /* Add metavideo */
+ if (tipool->alloc2d) {
+ gsize offset[GST_VIDEO_MAX_PLANES];
+ gint strides[GST_VIDEO_MAX_PLANES];
-/** get buffer from bufferpool, allocate new buffer if needed */
-GstDucatiBuffer *
-gst_ducati_buffer_pool_get (GstDucatiBufferPool * self, GstBuffer * orig)
-{
- GstDucatiBuffer *buf = NULL;
-
- g_return_val_if_fail (self, NULL);
-
- GST_DUCATI_BUFFER_POOL_LOCK (self);
- if (self->running) {
- /* re-use a buffer off the freelist if any are available
- */
- if (self->freelist) {
- buf = self->freelist;
- self->freelist = buf->next;
- } else {
- buf = gst_ducati_buffer_new (self);
- }
- buf->orig = orig;
- }
- GST_DUCATI_BUFFER_POOL_UNLOCK (self);
+ GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
+
+ stride = tipool->alloc2d ? 4096 : tipool->padded_width;
- if (buf && orig) {
- GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (orig);
- GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (orig);
+ /* these are just the defaults for now */
+ offset[0] = 0;
+ offset[1] = ALIGN2 (tipool->padded_height, 1) * stride;
+ offset[2] = offset[1] + 1;
+ strides[0] = strides[1] = strides[2] = stride;
+
+ gst_buffer_add_video_meta_full (outbuf, 0, GST_VIDEO_INFO_FORMAT (info),
+ tipool->padded_width, tipool->padded_height, 2, offset, strides);
}
+ *buffer = outbuf;
+
+ return GST_FLOW_OK;
- return buf;
+ /* ERROR */
+no_buffer:
+ {
+ GST_WARNING_OBJECT (pool, "can't create image");
+ return GST_FLOW_ERROR;
+ }
}
static void
-gst_ducati_buffer_pool_finalize (GstDucatiBufferPool * self)
+gst_ti_tiler_buffer_pool_finalize (GObject * object)
{
- g_mutex_free (self->lock);
- if (self->caps)
- gst_caps_unref (self->caps);
- gst_object_unref (self->element);
- GST_MINI_OBJECT_CLASS (bufferpool_parent_class)->finalize (GST_MINI_OBJECT
- (self));
+ GstTITilerBufferPool *pool = (GstTITilerBufferPool *) (object);
+
+ GST_LOG_OBJECT (pool, "finalize TITiler buffer pool %p", pool);
+
+ if (pool->caps)
+ gst_caps_unref (pool->caps);
+
+ G_OBJECT_CLASS (gst_ti_tiler_buffer_pool_parent_class)->finalize (object);
}
-static void
-gst_ducati_buffer_pool_class_init (gpointer g_class, gpointer class_data)
+static const gchar **
+gst_ti_tiler_buffer_pool_get_options (GstBufferPool * pool)
{
- GObjectClass *gobject_class = (GObjectClass *) klass;
- GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
-
- gobject_class->finalize = gst_ducati_buffer_pool_finalize;
+ static const gchar *options[] = {
+ GST_BUFFER_POOL_OPTION_VIDEO_META,
+ NULL
+ };
-#if 0
- gstbufferpool_class->get_options = ducati_buffer_pool_get_options;
- gstbufferpool_class->set_config = ducati_buffer_pool_set_config;
- gstbufferpool_class->alloc_buffer = ducati_buffer_pool_alloc;
- gstbufferpool_class->free_buffer = ducati_buffer_pool_free;
-#endif
+ return options;
}
-GType
-gst_ducati_buffer_pool_get_type (void)
+static gboolean
+gst_ti_tiler_buffer_pool_set_config (GstBufferPool * bufferpool,
+ GstStructure * config)
{
- static GType type;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof (GstMiniObjectClass),
- .class_init = gst_ducati_buffer_pool_class_init,
- .instance_size = sizeof (GstDucatiBufferPool),
- };
- type = g_type_register_static (GST_TYPE_MINI_OBJECT,
- "GstDucatiBufferPool", &info, 0);
+ GstTITilerBufferPool *pool = GST_TI_TILER_BUFFER_POOL (bufferpool);
+ GstVideoInfo info;
+ const GstCaps *caps;
+
+ if (!gst_buffer_pool_config_get (config, &caps, NULL, NULL, NULL, NULL, NULL))
+ goto wrong_config;
+
+ if (caps == NULL)
+ goto no_caps;
+
+ /* now parse the caps from the config */
+ if (!gst_video_info_from_caps (&info, caps))
+ goto wrong_caps;
+
+ GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height,
+ caps);
+
+ if (pool->caps)
+ gst_caps_unref (pool->caps);
+ pool->caps = gst_caps_copy (caps);
+ pool->info = info;
+
+ /* Remember width/height */
+ pool->padded_width = GST_VIDEO_INFO_WIDTH (&info);
+ pool->padded_height = GST_VIDEO_INFO_HEIGHT (&info);
+
+ return GST_BUFFER_POOL_CLASS (parent_class)->set_config (bufferpool, config);
+
+ /* ERRORS */
+wrong_config:
+ {
+ GST_WARNING_OBJECT (pool, "invalid config");
+ return FALSE;
+ }
+no_caps:
+ {
+ GST_WARNING_OBJECT (pool, "no caps in config");
+ return FALSE;
}
- return type;
+wrong_caps:
+ {
+ GST_WARNING_OBJECT (pool,
+ "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+}
+
+static void
+gst_ti_tiler_buffer_pool_class_init (GstTITilerBufferPoolClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+ gobject_class->finalize = gst_ti_tiler_buffer_pool_finalize;
+
+ gstbufferpool_class->get_options = gst_ti_tiler_buffer_pool_get_options;
+ gstbufferpool_class->set_config = gst_ti_tiler_buffer_pool_set_config;
+ gstbufferpool_class->alloc_buffer = gst_ti_tiler_buffer_pool_alloc;
}
diff --git a/src/gstducatibufferpool.h b/src/gstducatibufferpool.h
index 3d0875b..64b3522 100644
--- a/src/gstducatibufferpool.h
+++ b/src/gstducatibufferpool.h
@@ -21,61 +21,72 @@
#define __GSTDUCATIBUFFERPOOL_H__
#include "gstducati.h"
+#include <gst/video/video.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
G_BEGIN_DECLS
+typedef struct _GstTITilerMeta GstTITilerMeta;
-GType gst_ducati_buffer_get_type (void);
-#define GST_TYPE_DUCATIBUFFER (gst_ducati_buffer_get_type())
-#define GST_IS_DUCATIBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DUCATIBUFFER))
-#define GST_DUCATIBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DUCATIBUFFER, GstDucatiBuffer))
+typedef struct _GstTITilerBufferPool GstTITilerBufferPool;
+typedef struct _GstTITilerBufferPoolClass GstTITilerBufferPoolClass;
+typedef struct _GstTITilerBufferPoolPrivate GstTITilerBufferPoolPrivate;
-GType gst_ducati_buffer_pool_get_type (void);
-#define GST_TYPE_DUCATI_BUFFER_POOL (gst_ducati_buffer_pool_get_type())
-#define GST_IS_DUCATI_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DUCATI_BUFFER_POOL))
-#define GST_DUCATI_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DUCATI_BUFFER_POOL, GstDucatiBufferPool))
-#define GST_DUCATI_BUFFER_POOL_CAST(obj) ((GstXvImageBufferPool*)(obj))
+const GstMetaInfo * gst_ti_tiler_meta_get_info (void);
+#define GST_TI_TILER_META_INFO (gst_ti_tiler_meta_get_info())
-typedef struct _GstDucatiBufferPool GstDucatiBufferPool;
-typedef struct _GstDucatiBufferPoolClass GstDucatiBufferPoolClass;
-typedef struct _GstDucatiBuffer GstDucatiBuffer;
+#define gst_buffer_get_ti_tiler_meta(b) ((GstTITilerMeta*)gst_buffer_get_meta((b),GST_TI_TILER_META_INFO))
-struct _GstDucatiBufferPool
+struct _GstTITilerMeta
{
- GstBufferPool bufferpool;
+ GstMeta meta;
- /* output (padded) size including any codec padding: */
- gint padded_width, padded_height;
+ /* Allocation blocks */
+ guint nblocks;
+ MemAllocBlock block[2];
- GstCaps *caps;
- GMutex *lock;
- gboolean running; /* with lock */
- GstElement *element; /* the element that owns us.. */
- GstDucatiBuffer *freelist; /* list of available buffers */
- guint size;
-};
+ /* Physical adresses */
+ SSPtr y_paddr;
+ SSPtr uv_paddr;
-struct _GstDucatiBufferPoolClass
-{
- GstBufferPoolClass parent_class;
+ /* Memory type */
+ XDAS_Int16 y_type, uv_type;
+
+ /* TRUE if memory was allocated via MemMgr_Alloc or
+ * FALSE if via Memmgr_Map
+ */
+ gboolean allocated;
};
-GstDucatiBufferPool * gst_ducati_buffer_pool_new (GstElement * element, GstCaps * caps, guint size);
-void gst_ducati_buffer_pool_destroy (GstDucatiBufferPool * pool);
-GstDucatiBuffer * gst_ducati_buffer_pool_get (GstDucatiBufferPool * self, GstBuffer * orig);
+/* Buffer pool implementation */
+#define GST_TYPE_TI_TILER_BUFFER_POOL (gst_ti_tiler_buffer_pool_get_type())
+#define GST_IS_TI_TILER_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TI_TILER_BUFFER_POOL))
+#define GST_TI_TILER_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TI_TILER_BUFFER_POOL, GstTITilerBufferPool))
+#define GST_TI_TILER_BUFFER_POOL_CAST(obj) ((GstTITilerBufferPool*)(obj))
+
+struct _GstTITilerBufferPool
+{
+ GstBufferPool bufferpool;
-#define GST_DUCATI_BUFFER_POOL_LOCK(self) g_mutex_lock ((self)->lock)
-#define GST_DUCATI_BUFFER_POOL_UNLOCK(self) g_mutex_unlock ((self)->lock)
+ gboolean alloc2d;
-struct _GstDucatiBuffer {
- GstBuffer parent;
+ GstCaps *caps;
+ GstVideoInfo info;
+ GstVideoAlignment align;
+ guint padded_width;
+ guint padded_height;
+ gboolean add_metavideo;
+};
- GstDucatiBufferPool *pool; /* buffer-pool that this buffer belongs to */
- GstBuffer *orig; /* original buffer, if we need to copy output */
- GstDucatiBuffer *next; /* next in freelist, if not in use */
+struct _GstTITilerBufferPoolClass
+{
+ GstBufferPoolClass parent_class;
};
-GstBuffer * gst_ducati_buffer_get (GstDucatiBuffer * self);
+GType gst_ti_tiler_buffer_pool_get_type (void);
+
+GstBufferPool * gst_ti_tiler_buffer_pool_new (gboolean alloc2d);
G_END_DECLS
diff --git a/src/gstducatih264dec.c b/src/gstducatih264dec.c
index beeaf9c..66e6ea5 100644
--- a/src/gstducatih264dec.c
+++ b/src/gstducatih264dec.c
@@ -71,8 +71,7 @@ static gboolean
gst_ducati_h264dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret =
- GST_DUCATIVIDDEC_GET_CLASS (parent_class)->allocate_params (self,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
sizeof (IH264VDEC_Params), sizeof (IH264VDEC_DynamicParams),
sizeof (IH264VDEC_Status), sizeof (IH264VDEC_InArgs),
sizeof (IH264VDEC_OutArgs));
diff --git a/src/gstducatimpeg2dec.c b/src/gstducatimpeg2dec.c
index 74dee8c..29a50db 100644
--- a/src/gstducatimpeg2dec.c
+++ b/src/gstducatimpeg2dec.c
@@ -66,8 +66,7 @@ static gboolean
gst_ducati_mpeg2dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret =
- GST_DUCATIVIDDEC_GET_CLASS (parent_class)->allocate_params (self,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
sizeof (IVIDDEC3_Params), sizeof (IVIDDEC3_DynamicParams),
sizeof (IVIDDEC3_Status), sizeof (IVIDDEC3_InArgs),
sizeof (IVIDDEC3_OutArgs));
diff --git a/src/gstducatimpeg4dec.c b/src/gstducatimpeg4dec.c
index 99abd88..c810f67 100644
--- a/src/gstducatimpeg4dec.c
+++ b/src/gstducatimpeg4dec.c
@@ -77,8 +77,7 @@ static gboolean
gst_ducati_mpeg4dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret =
- GST_DUCATIVIDDEC_GET_CLASS (parent_class)->allocate_params (self,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
sizeof (VIDDEC3_Params), sizeof (VIDDEC3_DynamicParams),
sizeof (VIDDEC3_Status), sizeof (VIDDEC3_InArgs),
sizeof (VIDDEC3_OutArgs));
diff --git a/src/gstducatirvdec.c b/src/gstducatirvdec.c
index a2195da..49a7818 100644
--- a/src/gstducatirvdec.c
+++ b/src/gstducatirvdec.c
@@ -61,7 +61,7 @@ gst_ducati_rvdec_parse_caps (GstDucatiVidDec * vdec, GstStructure * s)
{
GstDucatiRVDec *self = GST_DUCATIRVDEC (vdec);
- if (GST_DUCATIVIDDEC_GET_CLASS (parent_class)->parse_caps (vdec, s)) {
+ if (GST_DUCATIVIDDEC_CLASS (parent_class)->parse_caps (vdec, s)) {
gboolean ret = gst_structure_get_int (s, "rmversion", &self->rmversion);
if (ret) {
IrealVDEC_Params *params = (IrealVDEC_Params *) vdec->params;
@@ -97,8 +97,7 @@ static gboolean
gst_ducati_rvdec_allocate_params (GstDucatiVidDec * vdec, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret =
- GST_DUCATIVIDDEC_GET_CLASS (parent_class)->allocate_params (vdec,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (vdec,
sizeof (IrealVDEC_Params), sizeof (IrealVDEC_DynamicParams),
sizeof (IrealVDEC_Status), sizeof (IrealVDEC_InArgs),
sizeof (IrealVDEC_OutArgs));
diff --git a/src/gstducativc1dec.c b/src/gstducativc1dec.c
index f25cc31..c3c7984 100644
--- a/src/gstducativc1dec.c
+++ b/src/gstducativc1dec.c
@@ -61,7 +61,7 @@ gst_ducati_vc1dec_parse_caps (GstDucatiVidDec * vdec, GstStructure * s)
GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
gboolean ret = FALSE;
- if (GST_DUCATIVIDDEC_GET_CLASS (parent_class)->parse_caps (vdec, s)) {
+ if (GST_DUCATIVIDDEC_CLASS (parent_class)->parse_caps (vdec, s)) {
const gchar *format;
format = gst_structure_get_string (s, "format");
@@ -102,8 +102,7 @@ static gboolean
gst_ducati_vc1dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
{
- gboolean ret =
- GST_DUCATIVIDDEC_GET_CLASS (parent_class)->allocate_params (self,
+ gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
sizeof (IVC1VDEC_Params), sizeof (IVC1VDEC_DynamicParams),
sizeof (IVC1VDEC_Status), sizeof (IVC1VDEC_InArgs),
sizeof (IVC1VDEC_OutArgs));
diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c
index 79370e8..19a35f1 100644
--- a/src/gstducatividdec.c
+++ b/src/gstducatividdec.c
@@ -145,8 +145,10 @@ engine_open (GstDucatiVidDec * self)
static void
codec_delete (GstDucatiVidDec * self)
{
+ GST_DEBUG_OBJECT (self, "deleting codec");
+
if (self->pool) {
- gst_ducati_buffer_pool_destroy (self->pool);
+ gst_object_unref (self->pool);
self->pool = NULL;
}
@@ -198,7 +200,6 @@ codec_create (GstDucatiVidDec * self)
}
self->first_in_buffer = TRUE;
- self->first_out_buffer = TRUE;
/* allocate input buffer and initialize inBufs: */
self->inBufs->numBufs = 1;
@@ -212,37 +213,35 @@ codec_create (GstDucatiVidDec * self)
static inline GstBuffer *
codec_bufferpool_get (GstDucatiVidDec * self, GstBuffer * buf)
{
- if (G_UNLIKELY (!self->pool)) {
- guint size;
+ GstBuffer *outbuf = NULL;
+ GstFlowReturn res;
- size = gst_video_format_get_size (GST_VIDEO_FORMAT_NV12,
- self->padded_width, self->padded_height);
- GST_DEBUG_OBJECT (self, "creating bufferpool");
- self->pool = gst_ducati_buffer_pool_new (GST_ELEMENT (self),
- GST_PAD_CAPS (self->srcpad), size);
- }
- return GST_BUFFER (gst_ducati_buffer_pool_get (self->pool, buf));
+ g_return_val_if_fail (self->pool, NULL);
+ /* Detect wrong new usage. We shouldn't be calling with buf anymore */
+ g_return_val_if_fail (buf == NULL, NULL);
+
+ res = gst_buffer_pool_acquire_buffer (self->pool, &outbuf, NULL);
+
+ if (res != GST_FLOW_OK)
+ GST_WARNING_OBJECT (self, "Couldn't acquire buffer : %s",
+ gst_flow_get_name (res));
+
+ return outbuf;
}
static XDAS_Int32
codec_prepare_outbuf (GstDucatiVidDec * self, GstBuffer * buf)
{
XDAS_Int16 y_type, uv_type;
- guint8 *y_vaddr, *uv_vaddr;
+ GstTITilerMeta *meta = gst_buffer_get_ti_tiler_meta (buf);
SSPtr y_paddr, uv_paddr;
- /* FIXME (0.11) : We can avoid a lot of this by using GstMeta */
-
- /* Virtual addresses */
- y_vaddr = GST_BUFFER_DATA (buf);
- uv_vaddr = y_vaddr + self->stride * self->padded_height;
+ /* FIXME : Check we have a tiler meta */
- /* Physical addresses */
- y_paddr = TilerMem_VirtToPhys (y_vaddr);
- uv_paddr = TilerMem_VirtToPhys (uv_vaddr);
-
- y_type = gst_ducati_get_mem_type (y_paddr);
- uv_type = gst_ducati_get_mem_type (uv_paddr);
+ y_paddr = meta->y_paddr;
+ uv_paddr = meta->uv_paddr;
+ y_type = meta->y_type;
+ uv_type = meta->uv_type;
/* FIXME: workaround for the vc1 codec expecting _RAW when it's actually
* _TILEDPAGE... should be removed once the codec is fixed */
@@ -251,23 +250,23 @@ codec_prepare_outbuf (GstDucatiVidDec * self, GstBuffer * buf)
if (uv_type == XDM_MEMTYPE_TILEDPAGE && self->pageMemType != uv_type)
uv_type = self->pageMemType;
- if (y_type < 0 || uv_type < 0) {
- GST_DEBUG_OBJECT (self, "non TILER buffer, fallback to bufferpool");
- return codec_prepare_outbuf (self, codec_bufferpool_get (self, buf));
- }
-
if (!self->outBufs->numBufs) {
+ GST_DEBUG_OBJECT (self, "Initialize output buffer type");
/* initialize output buffer type */
self->outBufs->numBufs = 2;
self->outBufs->descs[0].memType = y_type;
self->outBufs->descs[1].memType = uv_type;
if (y_type == XDM_MEMTYPE_RAW || y_type == XDM_MEMTYPE_TILEDPAGE) {
+ GST_DEBUG_OBJECT (self, "RAW or TILEDPAGE buffers => size %d %d",
+ self->stride * self->padded_height,
+ self->stride * self->padded_height / 2);
self->outBufs->descs[0].bufSize.bytes =
self->stride * self->padded_height;
self->outBufs->descs[1].bufSize.bytes =
self->stride * self->padded_height / 2;
} else {
+ GST_DEBUG_OBJECT (self, "2D buffers ?");
self->outBufs->descs[0].bufSize.tileMem.width = self->padded_width;
self->outBufs->descs[0].bufSize.tileMem.height = self->padded_height;
/* note that UV interleaved width is same a Y: */
@@ -278,11 +277,6 @@ codec_prepare_outbuf (GstDucatiVidDec * self, GstBuffer * buf)
/* verify output buffer type matches what we've already given
* to the codec
*/
- if ((self->outBufs->descs[0].memType != y_type) ||
- (self->outBufs->descs[1].memType != uv_type)) {
- GST_DEBUG_OBJECT (self, "buffer mismatch, fallback to bufferpool");
- return codec_prepare_outbuf (self, codec_bufferpool_get (self, buf));
- }
}
self->outBufs->descs[0].buf = (XDAS_Int8 *) y_paddr;
@@ -319,6 +313,8 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush)
GstBuffer *outbuf = NULL;
gint i;
+ GST_DEBUG_OBJECT (self, "send:%d, flush:%d", send, flush);
+
self->outArgs->outputID[0] = 0;
self->outArgs->freeBufID[0] = 0;
@@ -348,28 +344,22 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush)
}
for (i = 0; self->outArgs->outputID[i]; i++) {
- if (G_UNLIKELY (self->first_out_buffer) && send) {
- /* send region of interest to sink on first buffer: */
- XDM_Rect *r = &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion);
+ GstVideoCropMeta *cropmeta;
+ XDM_Rect *r = &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion);
+ outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]);
+ GST_DEBUG_OBJECT (self, "i:%d, outbuf:%p");
+ if (send) {
+ /* Add video crop metadata */
+ cropmeta = gst_buffer_add_video_crop_meta (outbuf);
GST_DEBUG_OBJECT (self, "setting crop to %d, %d, %d, %d",
r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y);
-#if 0
- /* FIXME (0.11) Use crop metadata */
- gst_pad_push_event (self->srcpad,
- gst_event_new_crop (r->topLeft.y, r->topLeft.x,
- r->bottomRight.x - r->topLeft.x,
- r->bottomRight.y - r->topLeft.y));
-#endif
- self->first_out_buffer = FALSE;
- }
+ cropmeta->x = r->topLeft.x;
+ cropmeta->y = r->topLeft.y;
+ cropmeta->width = r->bottomRight.x - r->topLeft.x;
+ cropmeta->height = r->bottomRight.y - r->topLeft.y;
- outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]);
- if (send) {
- if (GST_IS_DUCATIBUFFER (outbuf)) {
- outbuf = gst_ducati_buffer_get (GST_DUCATIBUFFER (outbuf));
- }
GST_DEBUG_OBJECT (self, "got buffer: %d %p (%" GST_TIME_FORMAT ")",
i, outbuf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
gst_pad_push (self->srcpad, outbuf);
@@ -445,9 +435,13 @@ gst_ducati_viddec_parse_caps (GstDucatiVidDec * self, GstStructure * s)
if (gst_structure_get_int (s, "width", &w) &&
gst_structure_get_int (s, "height", &h)) {
+ GST_DEBUG_OBJECT (self, "got input width/height %d x %d", w, h);
+
h = ALIGN2 (h, 4); /* round up to MB */
w = ALIGN2 (w, 4); /* round up to MB */
+ GST_DEBUG_OBJECT (self, "aligned input width/height %d x %d", w, h);
+
/* if we've already created codec, but the resolution has changed, we
* need to re-create the codec:
*/
@@ -561,6 +555,61 @@ gst_ducati_viddec_push_input (GstDucatiVidDec * self, GstBuffer * buf)
return NULL;
}
+static GstFlowReturn *
+gst_ducati_viddec_negotiate_pool (GstDucatiVidDec * self, GstCaps * caps)
+{
+ guint size = 0, min, max, prefix, alignment;
+ GstStructure *config;
+ GstQuery *query;
+ gboolean alloc2d = FALSE;
+
+ GST_DEBUG_OBJECT (self, "caps %" GST_PTR_FORMAT, caps);
+
+ /* Do an allocation query downstream */
+ query = gst_query_new_allocation (caps, FALSE);
+
+ if (gst_pad_peer_query (self->srcpad, query)) {
+ /* If downstream handles GstVideoMeta, we can use 2D alloc */
+ alloc2d = gst_query_has_allocation_meta (query, GST_VIDEO_META_API);
+
+ gst_query_parse_allocation_params (query, NULL, &min, &max, &prefix,
+ &alignment, NULL);
+ if (min < self->min_buffers)
+ min = self->min_buffers;
+ } else {
+ GST_DEBUG_OBJECT (self, "Query failed, using defaults");
+ min = self->min_buffers;
+ max = 0;
+ prefix = 0;
+ alignment = 0;
+ }
+
+ gst_query_unref (query);
+
+ if (self->pool) {
+ GST_DEBUG_OBJECT (self, "Deactivating previous pool");
+ gst_buffer_pool_set_active (self->pool, FALSE);
+ g_object_unref (self->pool);
+ }
+ GST_DEBUG_OBJECT (self, "Creating new pool");
+ self->pool = gst_ti_tiler_buffer_pool_new (alloc2d);
+
+ config = gst_buffer_pool_get_config (self->pool);
+ gst_buffer_pool_config_set (config, caps, size, min, max, prefix, alignment);
+
+ /* just set the option, if the pool can support it we will transparently use
+ * it through the video info API. We could also see if the pool support this
+ * option and only activate it then. */
+ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+
+ gst_buffer_pool_set_config (self->pool, config);
+
+ /* Finally activate it */
+ gst_buffer_pool_set_active (self->pool, TRUE);
+
+ return GST_FLOW_OK;
+}
+
/* GstElement vmethod implementations */
static gboolean
@@ -572,60 +621,80 @@ gst_ducati_viddec_set_caps (GstDucatiVidDec * self, GstCaps * caps)
gint frn = 0, frd = 1;
gint par_width, par_height;
gboolean par_present;
+ GstCaps *outcaps;
+ gboolean interlaced = FALSE;
+
+ GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
- if (!klass->parse_caps (self, s)) {
- GST_WARNING_OBJECT (self, "missing required fields");
- ret = FALSE;
- goto out;
- }
- GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+ if (G_UNLIKELY (!klass->parse_caps (self, s)))
+ goto missing_fields;
- if (klass->parse_caps (self, s)) {
- GstCaps *outcaps;
- gboolean interlaced = FALSE;
+ gst_structure_get_fraction (s, "framerate", &frn, &frd);
+ gst_structure_get_boolean (s, "interlaced", &interlaced);
+ par_present = gst_structure_get_fraction (s, "pixel-aspect-ratio",
+ &par_width, &par_height);
- gst_structure_get_fraction (s, "framerate", &frn, &frd);
- gst_structure_get_boolean (s, "interlaced", &interlaced);
- par_present = gst_structure_get_fraction (s, "pixel-aspect-ratio",
- &par_width, &par_height);
+ /* update output/padded sizes:
+ */
+ klass->update_buffer_size (self);
- /* update output/padded sizes:
- */
- klass->update_buffer_size (self);
+ /* FIXME : Use GstVideoInfo */
- self->stride = self->padded_width;
- self->outsize = GST_ROUND_UP_2 (self->stride * self->padded_height * 3) / 2;
+ self->stride = self->padded_width;
+ self->outsize = GST_ROUND_UP_2 (self->stride * self->padded_height * 3) / 2;
- outcaps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", G_TYPE_STRING, "NV12",
- "width", G_TYPE_INT, self->padded_width,
- "height", G_TYPE_INT, self->padded_height,
- "framerate", GST_TYPE_FRACTION, frn, frd, NULL);
+ outcaps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "NV12",
+ "width", G_TYPE_INT, self->padded_width,
+ "height", G_TYPE_INT, self->padded_height,
+ "framerate", GST_TYPE_FRACTION, frn, frd, NULL);
- if (interlaced) {
- gst_caps_set_simple (outcaps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
- }
- if (par_present)
- gst_caps_set_simple (outcaps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
- par_width, par_height, NULL);
+ if (interlaced) {
+ gst_caps_set_simple (outcaps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
+ }
+ if (par_present)
+ gst_caps_set_simple (outcaps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
+ par_width, par_height, NULL);
- GST_DEBUG_OBJECT (self, "outcaps: %" GST_PTR_FORMAT, outcaps);
+ GST_DEBUG_OBJECT (self, "outcaps: %" GST_PTR_FORMAT, outcaps);
- ret = gst_pad_set_caps (self->srcpad, outcaps);
- gst_caps_unref (outcaps);
+ ret = gst_pad_set_caps (self->srcpad, outcaps);
+ gst_caps_unref (outcaps);
- if (!ret) {
- GST_WARNING_OBJECT (self, "failed to set caps");
- return FALSE;
- }
- } else {
+ if (!ret)
+ goto fail_set_caps;
+
+ if (!self->codec)
+ codec_create (self);
+
+ /* Negotiate pool */
+ if (gst_ducati_viddec_negotiate_pool (self, outcaps) != GST_FLOW_OK)
+ goto pool_fail;
+
+ GST_DEBUG_OBJECT (self, "Success setting caps");
+
+ return TRUE;
+
+ /* Error cases */
+fail_set_caps:
+ {
+ GST_WARNING_OBJECT (self, "failed to set caps");
+ return FALSE;
+ }
+
+missing_fields:
+ {
GST_WARNING_OBJECT (self, "missing required fields");
return FALSE;
}
- return gst_pad_set_caps (self->sinkpad, caps);
+pool_fail:
+ {
+ GST_WARNING_OBJECT (self, "Failed to negotiate a bufferpool");
+ return FALSE;
+ }
}
static gboolean
@@ -637,19 +706,6 @@ gst_ducati_viddec_query (GstPad * pad, GstObject * parent, GstQuery * query)
GST_DEBUG_OBJECT (self, "query: %" GST_PTR_FORMAT, query);
switch (GST_QUERY_TYPE (query)) {
-#if 0
- /* FIXME (0.11) Handled by GST_QUERY_ALLOCATION */
- case GST_QUERY_BUFFERS:
- GST_DEBUG_OBJECT (self, "min buffers: %d", self->min_buffers);
- gst_query_set_buffers_count (query, self->min_buffers);
-
- GST_DEBUG_OBJECT (self, "min dimensions: %dx%d",
- self->padded_width, self->padded_height);
- gst_query_set_buffers_dimensions (query,
- self->padded_width, self->padded_height);
- forward = FALSE;
- break;
-#endif
default:
break;
}
@@ -664,62 +720,32 @@ static GstFlowReturn
gst_ducati_viddec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstDucatiVidDec *self = GST_DUCATIVIDDEC (parent);
- GstFlowReturn ret;
Int32 err;
GstBuffer *outbuf = NULL;
- GstCaps *outcaps = NULL;
-
- if (G_UNLIKELY (!self->engine)) {
- GST_ERROR_OBJECT (self, "no engine");
- return GST_FLOW_ERROR;
- }
-#if 0
- /* do this before creating codec to ensure reverse caps negotiation
- * happens first:
- */
-allocate_buffer:
- ret = gst_pad_alloc_buffer (self->srcpad, 0, self->outsize,
- GST_PAD_CAPS (self->srcpad), &outbuf);
-#else
- /* FIXME (0.11) Use ALLOCATION QUERY */
- ret = GST_FLOW_ERROR;
-#endif
- if (ret != GST_FLOW_OK) {
- GST_DEBUG_OBJECT (self, "alloc_buffer failed %s", gst_flow_get_name (ret));
- return ret;
- }
- outcaps = GST_BUFFER_CAPS (outbuf);
- if (outcaps && !gst_caps_is_equal (outcaps, GST_PAD_CAPS (self->srcpad))) {
- GstStructure *s;
+ GST_DEBUG_OBJECT (self, "buffer %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
- GST_INFO_OBJECT (self, "doing upstream negotiation bufsize %d",
- GST_BUFFER_SIZE (outbuf));
+ if (G_UNLIKELY (!self->engine))
+ goto no_engine;
- s = gst_caps_get_structure (outcaps, 0);
- gst_structure_get_int (s, "rowstride", &self->stride);
- self->outsize = gst_video_format_get_size (GST_VIDEO_FORMAT_NV12,
- self->stride, self->padded_height);
+ if (G_UNLIKELY (!self->codec) && !codec_create (self))
+ goto no_codec;
- GST_INFO_OBJECT (self, "outsize %d stride %d outcaps: %" GST_PTR_FORMAT,
- self->outsize, self->stride, outcaps);
+ if (G_UNLIKELY (gst_pad_check_reconfigure (self->srcpad))) {
+ GstCaps *caps;
- gst_pad_set_caps (self->srcpad, outcaps);
+ caps = gst_pad_get_current_caps (self->srcpad);
+ GST_DEBUG_OBJECT (self, "Renegotiating to %" GST_PTR_FORMAT, caps);
- if (GST_BUFFER_SIZE (outbuf) != self->outsize) {
- GST_INFO_OBJECT (self, "dropping buffer (bufsize %d != outsize %d)",
- GST_BUFFER_SIZE (outbuf), self->outsize);
- gst_buffer_unref (outbuf);
- goto allocate_buffer;
- }
+ gst_ducati_viddec_negotiate_pool (self, caps);
+ gst_caps_unref (caps);
}
- if (G_UNLIKELY (!self->codec)) {
- if (!codec_create (self)) {
- GST_ERROR_OBJECT (self, "could not create codec");
- return GST_FLOW_ERROR;
- }
- }
+ outbuf = codec_bufferpool_get (self, NULL);
+
+ if (G_UNLIKELY (outbuf == NULL))
+ goto no_outbuf;
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
@@ -763,7 +789,28 @@ allocate_buffer:
GST_WARNING_OBJECT (self, "TODO... outBufsInUseFlag"); // XXX
}
+ GST_DEBUG_OBJECT (self, "done in chain");
+
return GST_FLOW_OK;
+
+ /* Error cases */
+no_engine:
+ {
+ GST_ERROR_OBJECT (self, "no engine");
+ return GST_FLOW_ERROR;
+ }
+
+no_codec:
+ {
+ GST_ERROR_OBJECT (self, "could not create codec");
+ return GST_FLOW_ERROR;
+ }
+
+no_outbuf:
+ {
+ GST_ERROR_OBJECT (self, "Couldn't get an output buffer");
+ return GST_FLOW_ERROR;
+ }
}
static gboolean
@@ -876,7 +923,7 @@ gst_ducati_viddec_get_property (GObject * obj,
err = VIDDEC3_control (self->codec, XDM_GETVERSION,
self->dynParams, self->status);
if (err) {
- GST_ERROR_OBJECT (self, "failed XDM_GETVERSION");
+ GST_ERROR_OBJECT (self, "failed XDM_GETVERSION (err:%d)", err);
}
self->status->data.buf = NULL;
@@ -913,23 +960,19 @@ gst_ducati_viddec_finalize (GObject * obj)
}
static void
-gst_ducati_viddec_base_init (gpointer gclass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
-}
-
-static void
gst_ducati_viddec_class_init (GstDucatiVidDecClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+ parent_class = (GstElementClass *) g_type_class_peek_parent (klass);
+
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_ducati_viddec_get_property);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ducati_viddec_finalize);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&src_factory));
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_ducati_viddec_change_state);
@@ -971,7 +1014,6 @@ gst_ducati_viddec_init (GstDucatiVidDec * self, GstDucatiVidDecClass * klass)
self->height = 128;
self->first_in_buffer = TRUE;
- self->first_out_buffer = TRUE;
self->pageMemType = XDM_MEMTYPE_TILEDPAGE;
}
diff --git a/src/gstducatividdec.h b/src/gstducatividdec.h
index a9ddd45..1eb91b5 100644
--- a/src/gstducatividdec.h
+++ b/src/gstducatividdec.h
@@ -44,7 +44,7 @@ struct _GstDucatiVidDec
GstPad *sinkpad, *srcpad;
- GstDucatiBufferPool *pool;
+ GstBufferPool *pool;
/* minimum output size required by the codec: */
gint outsize;
@@ -71,7 +71,7 @@ struct _GstDucatiVidDec
* operations like flushing should be avoided if we haven't sent any
* input buffers:
*/
- gboolean first_out_buffer, first_in_buffer;
+ gboolean first_in_buffer;
/* by default, codec_data from sinkpad is prepended to first buffer: */
GstBuffer *codec_data;
diff --git a/src/gstducatividenc.h b/src/gstducatividenc.h
index 90f81af..e61033b 100644
--- a/src/gstducatividenc.h
+++ b/src/gstducatividenc.h
@@ -62,8 +62,8 @@ struct _GstDucatiVidEnc
IVIDENC2_InArgs *inArgs;
IVIDENC2_OutArgs *outArgs;
- GstDucatiBufferPool *input_pool;
- GstDucatiBufferPool *output_pool;
+ GstTITilerBufferPool *input_pool;
+ GstTITilerBufferPool *output_pool;
gboolean configure;
gint bitrate;