From 85358b4288b46cfa148fc87de3471d61dd6469b7 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 23 Aug 2012 14:42:22 +0200 Subject: initial 1.0 port (some decoders) --- configure.ac | 18 +- src/Makefile.am | 52 ++-- src/gstdmabufmeta.c | 87 ++++++ src/gstdmabufmeta.h | 54 ++++ src/gstdrmbufferpool.c | 280 +++++++++++++++++++ src/gstdrmbufferpool.h | 132 +++++++++ src/gstducati.c | 63 +++-- src/gstducatibufferpriv.c | 92 ------- src/gstducatibufferpriv.h | 75 ----- src/gstducatih264dec.c | 71 +++-- src/gstducatimpeg2dec.c | 67 +++-- src/gstducatimpeg4dec.c | 119 ++++---- src/gstducatiprivmeta.c | 84 ++++++ src/gstducatiprivmeta.h | 62 +++++ src/gstducatirvdec.c | 18 +- src/gstducativc1dec.c | 22 +- src/gstducatividdec.c | 680 +++++++++++++++++++++++----------------------- src/gstducatividdec.h | 17 +- src/gstducatividenc.c | 5 +- src/gstducativp6dec.c | 14 +- src/gstducativp7dec.c | 14 +- 21 files changed, 1286 insertions(+), 740 deletions(-) create mode 100644 src/gstdmabufmeta.c create mode 100644 src/gstdmabufmeta.h create mode 100644 src/gstdrmbufferpool.c create mode 100644 src/gstdrmbufferpool.h delete mode 100644 src/gstducatibufferpriv.c delete mode 100644 src/gstducatibufferpriv.h create mode 100644 src/gstducatiprivmeta.c create mode 100644 src/gstducatiprivmeta.h diff --git a/configure.ac b/configure.ac index 923d7be..2dfe9e7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,11 +2,11 @@ dnl required version of autoconf AC_PREREQ([2.53]) dnl TODO: fill in your package name and package version here -AC_INIT([gst-ducati],[0.10.0]) +AC_INIT([gst-ducati],[1.0.0]) dnl required versions of gstreamer and plugins-base -GST_MAJORMINOR=0.10 -GST_REQUIRED=0.10.30 +GST_MAJORMINOR=1.0 +GST_REQUIRED=0.11 AC_CONFIG_SRCDIR([src/gstducati.c]) AC_CONFIG_HEADERS([config.h]) @@ -79,10 +79,10 @@ PKG_CHECK_MODULES(LIBDCE, [libdce >= 1.0.0]) dnl Check for the required version of GStreamer core (and gst-plugins-base) dnl This will export GST_CFLAGS and GST_LIBS variables for use in Makefile.am PKG_CHECK_MODULES(GST, [ - gstreamer-0.10 >= $GST_REQUIRED - gstreamer-base-0.10 >= $GST_REQUIRED - gstreamer-plugins-base-0.10 >= $GST_REQUIRED - gstreamer-plugins-bad-0.10 + gstreamer-1.0 >= $GST_REQUIRED + gstreamer-base-1.0 >= $GST_REQUIRED + gstreamer-plugins-base-1.0 >= $GST_REQUIRED + gstreamer-plugins-bad-1.0 ], [ AC_SUBST(GST_CFLAGS) AC_SUBST(GST_LIBS) @@ -90,8 +90,8 @@ PKG_CHECK_MODULES(GST, [ AC_MSG_ERROR([ You need to install or upgrade the GStreamer development packages on your system. On debian-based systems these are - libgstreamer0.10-dev and libgstreamer-plugins-base0.10-dev. - on RPM-based systems gstreamer0.10-devel, libgstreamer0.10-devel + libgstreamer1.0-dev and libgstreamer-plugins-base1.0-dev. + on RPM-based systems gstreamer1.0-devel, libgstreamer1.0-devel or similar. The minimum version required is $GST_REQUIRED. ]) ]) diff --git a/src/Makefile.am b/src/Makefile.am index ecb68b3..f23ef9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,37 +2,43 @@ plugin_LTLIBRARIES = libgstducati.la # headers we need but don't want installed noinst_HEADERS = \ - gstducatirvdec.h \ - gstducativp7dec.h \ - gstducativp6dec.h \ - gstducativc1dec.h \ - gstducatimpeg2dec.h \ - gstducatimpeg4dec.h \ + gstdmabufmeta.h \ + gstducatiprivmeta.h \ + gstdrmbufferpool.h \ gstducatih264dec.h \ + gstducatimpeg2dec.h \ gstducatividdec.h \ - gstducatih264enc.h \ - gstducatimpeg4enc.h \ - gstducatividenc.h \ - gstducatibufferpriv.h \ gstducati.h +# gstducatirvdec.h \ +# gstducativp7dec.h \ +# gstducativp6dec.h \ +# gstducativc1dec.h \ +# gstducatimpeg4dec.h \ +# gstducatih264enc.h \ +# gstducatimpeg4enc.h \ +# gstducatividenc.h + # sources used to compile this plug-in libgstducati_la_SOURCES = \ - gstducatirvdec.c \ - gstducativp7dec.c \ - gstducativp6dec.c \ - gstducativc1dec.c \ - gstducatimpeg2dec.c \ - gstducatimpeg4dec.c \ + gstdmabufmeta.c \ + gstducatiprivmeta.c \ + gstdrmbufferpool.c \ gstducatih264dec.c \ + gstducatimpeg2dec.c \ gstducatividdec.c \ - gstducatih264enc.c \ - gstducatimpeg4enc.c \ - gstducatividenc.c \ - gstducatibufferpriv.c \ gstducati.c \ $(noinst_HEADERS) +# gstducatirvdec.c \ +# gstducativp7dec.c \ +# gstducativp6dec.c \ +# gstducativc1dec.c \ +# gstducatimpeg4dec.c \ +# gstducatih264enc.c \ +# gstducatimpeg4enc.c \ +# gstducatividenc.c + # compiler and linker flags used to compile this plugin, set in configure.ac libgstducati_la_CFLAGS = \ $(GST_CFLAGS) \ @@ -42,10 +48,8 @@ libgstducati_la_CFLAGS = \ libgstducati_la_LIBADD = \ $(GST_LIBS) \ $(LIBDCE_LIBS) \ - -lgstdmabuf-0.10 \ - -lgstdrm-0.10 \ - -lgstvideo-0.10 \ - -lgstbasevideo-0.10 + -lgstvideo-1.0 \ + -lgstbasevideo-1.0 libgstducati_la_LDFLAGS = \ $(GST_PLUGIN_LDFLAGS) \ diff --git a/src/gstdmabufmeta.c b/src/gstdmabufmeta.c new file mode 100644 index 0000000..0169327 --- /dev/null +++ b/src/gstdmabufmeta.c @@ -0,0 +1,87 @@ +/* GStreamer + * Copyright (C) <2012> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "gstdmabufmeta.h" + +static void +gst_dma_buf_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstDmaBufMeta *dmeta = (GstDmaBufMeta *) meta; + + close (dmeta->fd); +} + +static gboolean +gst_dma_buf_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GST_WARNING ("Do we need to dup fd ?"); + + return TRUE; +} + + +/** + * gst_buffer_add_dma_buf_meta: + * @buffer: a #GstBuffer + * @fd: the dmabuf fd + * + * Returns: the #GstDmaBufMeta on @buffer. + */ +GstDmaBufMeta * +gst_buffer_add_dma_buf_meta (GstBuffer * buffer, int fd) +{ + GstDmaBufMeta *meta; + + meta = + (GstDmaBufMeta *) gst_buffer_add_meta (buffer, + GST_DMA_BUF_META_INFO, NULL); + + meta->fd = fd; + + return meta; +} + +GType +gst_dma_buf_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = { NULL }; + + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstDmaBufMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +const GstMetaInfo * +gst_dma_buf_meta_get_info (void) +{ + static const GstMetaInfo *dma_buf_meta_info = NULL; + + if (dma_buf_meta_info == NULL) { + dma_buf_meta_info = gst_meta_register (GST_DMA_BUF_META_API_TYPE, "GstDmaBufMeta", sizeof (GstDmaBufMeta), NULL, /* No init needed */ + gst_dma_buf_meta_free, gst_dma_buf_meta_transform); + } + return dma_buf_meta_info; +} diff --git a/src/gstdmabufmeta.h b/src/gstdmabufmeta.h new file mode 100644 index 0000000..5a4e4db --- /dev/null +++ b/src/gstdmabufmeta.h @@ -0,0 +1,54 @@ +/* GStreamer + * Copyright (C) <2012> Edward Hervey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_DMA_BUF_META_H__ +#define __GST_DMA_BUF_META_H__ + +#include + +G_BEGIN_DECLS + +#define GST_DMA_BUF_META_API_TYPE (gst_dma_buf_meta_api_get_type()) +#define GST_DMA_BUF_META_INFO (gst_dma_buf_meta_get_info()) + +typedef struct _GstDmaBufMeta GstDmaBufMeta; + +/** + * GstDmaBufMeta: + * @meta: parent #GstMeta + * @fd: the fd + * + */ +struct _GstDmaBufMeta { + GstMeta meta; + + int fd; +}; + +GType gst_dma_buf_meta_api_get_type (void); +const GstMetaInfo * gst_dma_buf_meta_get_info (void); + +#define gst_buffer_get_dma_buf_meta(b) ((GstDmaBufMeta*)gst_buffer_get_meta((b),GST_DMA_BUF_META_API_TYPE)) + +GstDmaBufMeta * gst_buffer_add_dma_buf_meta (GstBuffer *buffer, + int fd); + +G_END_DECLS + +#endif /* __GST_DMA_BUF_META_H__ */ diff --git a/src/gstdrmbufferpool.c b/src/gstdrmbufferpool.c new file mode 100644 index 0000000..aaa2b02 --- /dev/null +++ b/src/gstdrmbufferpool.c @@ -0,0 +1,280 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * Copyright (C) 2012 Collabora Ltd + * + * Authors: + * Alessandro Decina + * Rob Clark + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "gstdmabufmeta.h" + +#include "gstdrmbufferpool.h" + +GST_DEBUG_CATEGORY (drmbufferpool_debug); +#define GST_CAT_DEFAULT drmbufferpool_debug + +/* + * GstDRMBufferPool: + */ + +#define gst_drm_buffer_pool_parent_class parent_class +G_DEFINE_TYPE (GstDRMBufferPool, gst_drm_buffer_pool, GST_TYPE_BUFFER_POOL); + +GstBufferPool * +gst_drm_buffer_pool_new (GstElement * element, int fd) +{ + GstDRMBufferPool *pool; + + pool = g_object_new (GST_TYPE_DRM_BUFFER_POOL, NULL); + + GST_DEBUG_OBJECT (element, "Created DRM buffer pool"); + + pool->element = gst_object_ref (element); + pool->fd = fd; + pool->dev = omap_device_new (fd); + pool->caps = NULL; + + return (GstBufferPool *) pool; +} + +static const gchar ** +gst_drm_buffer_pool_get_options (GstBufferPool * pool) +{ + static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META, + NULL + }; + + return options; +} + +static gboolean +gst_drm_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) +{ + GstDRMBufferPool *self = (GstDRMBufferPool *) pool; + GstCaps *caps; + GstVideoInfo info; + + if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + goto wrong_config; + + if (caps == NULL) + goto no_caps; + + 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 (self->caps) + gst_caps_unref (self->caps); + self->caps = gst_caps_ref (caps); + + self->info = info; + + return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); + +wrong_config: + { + GST_WARNING_OBJECT (pool, "invalid config"); + return FALSE; + } +no_caps: + { + GST_WARNING_OBJECT (pool, "no caps in config"); + return FALSE; + } +wrong_caps: + { + GST_WARNING_OBJECT (pool, + "failed getting geometry from caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +} + +static GstFlowReturn +gst_drm_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** bufer, + GstBufferPoolAcquireParams * paramts) +{ + GstDRMBufferPool *self = (GstDRMBufferPool *) pool; + GstVideoInfo *info; + GstBuffer *res; + GstDRMMeta *meta; + + info = &self->info; + + res = gst_buffer_new (); + + /* Add DRM Meta (i.e. allocation) */ + meta = gst_buffer_add_drm_meta (res, self); + if (!meta) { + gst_buffer_unref (res); + goto no_buffer; + } + + /* Add DMABuf meta */ + if (!gst_buffer_add_dma_buf_meta (res, omap_bo_dmabuf (meta->bo))) + GST_WARNING_OBJECT (pool, "Failed to add DMABuf Meta"); + + /* Add video meta */ + GST_DEBUG_OBJECT (pool, "Adding GstVideoMeta %dx%d", + GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info)); + gst_buffer_add_video_meta (res, GST_VIDEO_FRAME_FLAG_NONE, + GST_VIDEO_INFO_FORMAT (info), + GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info)); + + *bufer = res; + + return GST_FLOW_OK; + + /* ERROR */ +no_buffer: + { + GST_WARNING_OBJECT (pool, "can't create image"); + return GST_FLOW_ERROR; + } +} + +static void +gst_drm_buffer_pool_finalize (GObject * object) +{ + GstDRMBufferPool *self = (GstDRMBufferPool *) object; + + GST_DEBUG_OBJECT (self->element, "finalize"); + + if (self->caps) + gst_caps_unref (self->caps); + gst_object_unref (self->element); + + omap_device_del (self->dev); + + G_OBJECT_CLASS (gst_drm_buffer_pool_parent_class)->finalize (object); +} + +static void +gst_drm_buffer_pool_class_init (GstDRMBufferPoolClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass; + + GST_DEBUG_CATEGORY_INIT (drmbufferpool_debug, "drmbufferpool", 0, + "DRM buffer pool"); + + gobject_class->finalize = gst_drm_buffer_pool_finalize; + gstbufferpool_class->get_options = gst_drm_buffer_pool_get_options; + gstbufferpool_class->set_config = gst_drm_buffer_pool_set_config; + gstbufferpool_class->alloc_buffer = gst_drm_buffer_pool_alloc_buffer; +} + +static void +gst_drm_buffer_pool_init (GstDRMBufferPool * self) +{ +} + +/* + * GstDRMMeta: + */ + +#if 0 + +/* FIXME : Let the pool do this */ + +void +gst_drm_buffer_initialize (GstDRMMeta * self, + GstDRMMetaPool * pool, struct omap_bo *bo) +{ + self->bo = bo; + + GST_BUFFER_DATA (self) = omap_bo_map (self->bo); + GST_BUFFER_SIZE (self) = pool->size; + +/* attach dmabuf handle to buffer so that elements from other + * plugins can access for zero copy hw accel: + */ +// XXX buffer doesn't take ownership of the GstDRM... + gst_buffer_set_dma_buf (GST_BUFFER (self), + gst_dma_buf_new (omap_bo_dmabuf (self->bo))); + + gst_drm_buffer_set_pool (self, pool); +} +#endif + +GstDRMMeta * +gst_buffer_add_drm_meta (GstBuffer * buffer, GstDRMBufferPool * pool) +{ + GstDRMMeta *meta; + + meta = (GstDRMMeta *) gst_buffer_add_meta (buffer, GST_DRM_META_INFO, NULL); + + meta->bo = + omap_bo_new (pool->dev, GST_VIDEO_INFO_SIZE (&pool->info), OMAP_BO_WC); + + GST_DEBUG ("Got new bo %p", meta->bo); + + meta->uv_offset = GST_VIDEO_INFO_PLANE_OFFSET (&pool->info, 1); + meta->size = GST_VIDEO_INFO_SIZE (&pool->info); + + /* Add the memory */ + gst_buffer_append_memory (buffer, + gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, + omap_bo_map (meta->bo), GST_VIDEO_INFO_SIZE (&pool->info), + 0, GST_VIDEO_INFO_SIZE (&pool->info), NULL, NULL)); + + return meta; +} + +static void +gst_drm_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstDRMMeta *self = (GstDRMMeta *) meta; + + omap_bo_del (self->bo); +} + +GType +gst_drm_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = { + NULL + }; + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstDRMMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +const GstMetaInfo * +gst_drm_meta_get_info (void) +{ + static const GstMetaInfo *drm_meta_info = NULL; + if (drm_meta_info == NULL) { + drm_meta_info = gst_meta_register (GST_DRM_META_API_TYPE, "GstDRMMeta", sizeof (GstDRMMeta), NULL, /* No init needed */ + gst_drm_meta_free, NULL /* No transform needed */ ); + } + return drm_meta_info; +} diff --git a/src/gstdrmbufferpool.h b/src/gstdrmbufferpool.h new file mode 100644 index 0000000..79dc1be --- /dev/null +++ b/src/gstdrmbufferpool.h @@ -0,0 +1,132 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * Copyright (C) 2012 Collabora Ltd + * + * Authors: + * Alessandro Decina + * Rob Clark + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __GSTDRMBUFFERPOOL_H__ +#define __GSTDRMBUFFERPOOL_H__ + +#include + +G_BEGIN_DECLS + +/* TODO replace dependency on libdrm_omap w/ libdrm.. the only thing + * missing is way to allocate buffers, but this should probably be + * done via libdrm? + * + * NOTE: this dependency is only for those who want to subclass us, + * so we could perhaps move the struct definitions into a separate + * header or split out private ptr and move that into the .c file.. + */ +#include +#include +#include + +#include +#include +#include + +#define GST_TYPE_DRM_BUFFER_POOL (gst_drm_buffer_pool_get_type()) +#define GST_IS_DRM_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DRM_BUFFER_POOL)) +#define GST_DRM_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DRM_BUFFER_POOL, GstDRMBufferPool)) +#define GST_DRM_BUFFER_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DRM_BUFFER_POOL, GstDRMBufferPoolClass)) +#define GST_DRM_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DRM_BUFFER_POOL, GstDRMBufferPoolClass)) + +typedef struct _GstDRMBufferPool GstDRMBufferPool; +typedef struct _GstDRMBufferPoolClass GstDRMBufferPoolClass; + +/* + * GstDRMBufferPool: + */ + +struct _GstDRMBufferPool { + GstBufferPool parent; + + int fd; + struct omap_device *dev; + + GstCaps *caps; + GstVideoInfo info; + GstElement *element; /* the element that owns us.. */ + + /* TODO add reserved */ +}; + +struct _GstDRMBufferPoolClass { + GstBufferPoolClass klass; + +#if 0 /* Edward : Not needed afaiu */ + /* allow the subclass to allocate it's own buffers that extend + * GstDRMBuffer: + */ + GstDRMBuffer * (*buffer_alloc)(GstDRMBufferPool * pool); + + /* The a buffer subclass should not override finalize, as that + * would interfere with reviving the buffer and returning to the + * pool. Instead you can implement this vmethod to cleanup a + * buffer. + */ + void (*buffer_cleanup)(GstDRMBufferPool * pool, GstDRMBuffer *buf); +#endif + + /* TODO add reserved */ +}; + +GType gst_drm_buffer_pool_get_type (void); + +GstBufferPool * gst_drm_buffer_pool_new (GstElement * element, + int fd); + +/* + * GstDRMMeta: + */ + +#define GST_DRM_META_API_TYPE (gst_drm_meta_api_get_type()) +#define GST_DRM_META_INFO (gst_drm_meta_get_info()) + +typedef struct _GstDRMMeta GstDRMMeta; + +struct _GstDRMMeta { + GstMeta parent; + + /* FIXME : Do we really want to call this DRMMeta and not OMAPDRMMeta ? */ + struct omap_bo *bo; + + guint uv_offset; + gsize size; + + /* TODO add reserved */ +}; + + +GType gst_drm_meta_api_get_type (void); +const GstMetaInfo * gst_drm_meta_get_info (void); + +#define gst_buffer_get_drm_meta(b) ((GstDRMMeta*)gst_buffer_get_meta((b),GST_DRM_META_API_TYPE)) + +GstDRMMeta * gst_buffer_add_drm_meta (GstBuffer *buffer, + GstDRMBufferPool *pool); + +G_END_DECLS + +#endif /* __GSTDRMBUFFERPOOL_H__ */ diff --git a/src/gstducati.c b/src/gstducati.c index e3d6ae2..0b4586e 100644 --- a/src/gstducati.c +++ b/src/gstducati.c @@ -23,14 +23,14 @@ #include "gstducati.h" #include "gstducatih264dec.h" -#include "gstducatimpeg4dec.h" +/* #include "gstducatimpeg4dec.h" */ #include "gstducatimpeg2dec.h" -#include "gstducativc1dec.h" -#include "gstducativp6dec.h" -#include "gstducativp7dec.h" -#include "gstducatirvdec.h" -#include "gstducatih264enc.h" -#include "gstducatimpeg4enc.h" +/* #include "gstducativc1dec.h" */ +/* #include "gstducativp6dec.h" */ +/* #include "gstducativp7dec.h" */ +/* #include "gstducatirvdec.h" */ +/* #include "gstducatih264enc.h" */ +/* #include "gstducatimpeg4enc.h" */ GST_DEBUG_CATEGORY (gst_ducati_debug); @@ -59,22 +59,39 @@ plugin_init (GstPlugin * plugin) */ return gst_element_register (plugin, "ducatih264dec", GST_RANK_PRIMARY, GST_TYPE_DUCATIH264DEC) && - gst_element_register (plugin, "ducatimpeg4dec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIMPEG4DEC) && gst_element_register (plugin, "ducatimpeg2dec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIMPEG2DEC) && - gst_element_register (plugin, "ducativc1dec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIVC1DEC) && - gst_element_register (plugin, "ducativp6dec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIVP6DEC) && - gst_element_register (plugin, "ducativp7dec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIVP7DEC) && - gst_element_register (plugin, "ducatirvdec", GST_RANK_PRIMARY, - GST_TYPE_DUCATIRVDEC) && - gst_element_register (plugin, "ducatih264enc", GST_RANK_PRIMARY + 1, - GST_TYPE_DUCATIH264ENC) && - gst_element_register (plugin, "ducatimpeg4enc", GST_RANK_PRIMARY + 1, - GST_TYPE_DUCATIMPEG4ENC); + GST_TYPE_DUCATIMPEG2DEC) + + + + + + + + + + + + + + + + /* gst_element_register (plugin, "ducatimpeg4dec", GST_RANK_PRIMARY, */ + /* GST_TYPE_DUCATIMPEG4DEC) && */ + /* gst_element_register (plugin, "ducativc1dec", GST_RANK_PRIMARY, */ + /* GST_TYPE_DUCATIVC1DEC) && */ + /* gst_element_register (plugin, "ducativp6dec", GST_RANK_PRIMARY, */ + /* GST_TYPE_DUCATIVP6DEC) && */ + /* gst_element_register (plugin, "ducativp7dec", GST_RANK_PRIMARY, */ + /* GST_TYPE_DUCATIVP7DEC) && */ + /* gst_element_register (plugin, "ducatirvdec", GST_RANK_PRIMARY, */ + /* GST_TYPE_DUCATIRVDEC) */ + /* && */ + /* gst_element_register (plugin, "ducatih264enc", GST_RANK_PRIMARY + 1, */ + /* GST_TYPE_DUCATIH264ENC) && */ + /* gst_element_register (plugin, "ducatimpeg4enc", GST_RANK_PRIMARY + 1, */ + /* GST_TYPE_DUCATIMPEG4ENC) */ + ; } /* PACKAGE: this is usually set by autotools depending on some _INIT macro @@ -86,6 +103,6 @@ plugin_init (GstPlugin * plugin) # define PACKAGE "ducati" #endif -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "ducati", +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, ducati, "Hardware accelerated codecs for OMAP4", plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/src/gstducatibufferpriv.c b/src/gstducatibufferpriv.c deleted file mode 100644 index 1ea3b46..0000000 --- a/src/gstducatibufferpriv.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * GStreamer - * - * Copyright (C) 2012 Texas Instruments - * Copyright (C) 2012 Collabora Ltd - * - * Authors: - * Alessandro Decina - * Rob Clark - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include -#include - -#include "gstducatibufferpriv.h" - -#define GST_DUCATI_BUFFER_PRIV_QUARK gst_ducati_buffer_priv_quark_get_type() -static GST_BOILERPLATE_QUARK (GstDucatiBufferPriv, gst_ducati_buffer_priv_quark); - -#define DUCATI_BUFFER_PRIV_QUARK ducati_buffer_priv_quark_get_type() -static GST_BOILERPLATE_QUARK (DucatiBufferPriv, ducati_buffer_priv_quark); - -void -gst_ducati_buffer_priv_set (GstBuffer * buf, GstDucatiBufferPriv * priv) -{ - gst_buffer_set_qdata (buf, GST_DUCATI_BUFFER_PRIV_QUARK, - gst_structure_id_new (GST_DUCATI_BUFFER_PRIV_QUARK, - DUCATI_BUFFER_PRIV_QUARK, GST_TYPE_DUCATI_BUFFER_PRIV, priv, NULL)); -} - -GstDucatiBufferPriv * -gst_ducati_buffer_priv_get (GstBuffer * buf) -{ - const GstStructure *s; - const GValue *val; - - s = gst_buffer_get_qdata (buf, GST_DUCATI_BUFFER_PRIV_QUARK); - if (s == NULL) - return NULL; - - val = gst_structure_id_get_value (s, DUCATI_BUFFER_PRIV_QUARK); - if (val == NULL) - return NULL; - - return GST_DUCATI_BUFFER_PRIV (gst_value_get_mini_object (val)); -} - -GstDucatiBufferPriv * -gst_ducati_buffer_priv_new (void) -{ - return (GstDucatiBufferPriv *) gst_mini_object_new (GST_TYPE_DUCATI_BUFFER_PRIV); -} - -static void -gst_ducati_buffer_priv_finalize (GstMiniObject * mini_obj) -{ - GstDucatiBufferPriv *priv = (GstDucatiBufferPriv *) mini_obj; - - omap_bo_del (priv->bo); - - /* not chaining up to GstMiniObject's finalize for now, we know it's empty */ -} - -GST_BOILERPLATE_MINI_OBJECT(GstDucatiBufferPriv, gst_ducati_buffer_priv); - -static void -gst_ducati_buffer_priv_class_init (GstDucatiBufferPrivClass * klass) -{ - GST_MINI_OBJECT_CLASS (klass)->finalize = gst_ducati_buffer_priv_finalize; -} diff --git a/src/gstducatibufferpriv.h b/src/gstducatibufferpriv.h deleted file mode 100644 index 5282493..0000000 --- a/src/gstducatibufferpriv.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GStreamer - * - * Copyright (C) 2012 Texas Instruments - * Copyright (C) 2012 Collabora Ltd - * - * Authors: - * Alessandro Decina - * Rob Clark - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GSTDUCATIBUFFERPRIV_H__ -#define __GSTDUCATIBUFFERPRIV_H__ - -#include -#include - -G_BEGIN_DECLS - -#include - -/* - * per-buffer private data for gst-ducati - */ - -#define GST_TYPE_DUCATI_BUFFER_PRIV \ - (gst_ducati_buffer_priv_get_type ()) -#define GST_DUCATI_BUFFER_PRIV(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DUCATI_BUFFER_PRIV, GstDucatiBufferPriv)) -#define GST_IS_DUCATI_BUFFER_PRIV(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DUCATI_BUFFER_PRIV)) - -typedef struct _GstDucatiBufferPriv GstDucatiBufferPriv; -typedef struct _GstDucatiBufferPrivClass GstDucatiBufferPrivClass; - - -struct _GstDucatiBufferPriv -{ - GstMiniObject parent; - - struct omap_bo *bo; - gint uv_offset, size; -}; - -struct _GstDucatiBufferPrivClass -{ - GstMiniObjectClass parent_class; -}; - - -GType gst_ducati_buffer_priv_get_type (void); - -void gst_ducati_buffer_priv_set (GstBuffer * buf, GstDucatiBufferPriv * priv); -GstDucatiBufferPriv * gst_ducati_buffer_priv_get (GstBuffer * buf); -GstDucatiBufferPriv * gst_ducati_buffer_priv_new (void); - - -G_END_DECLS - - -#endif /* __GSTDUCATIBUFFERPRIV_H__ */ diff --git a/src/gstducatih264dec.c b/src/gstducatih264dec.c index 167b454..6885f6c 100644 --- a/src/gstducatih264dec.c +++ b/src/gstducatih264dec.c @@ -42,30 +42,22 @@ #define PADX 32 #define PADY 24 - -GST_BOILERPLATE (GstDucatiH264Dec, gst_ducati_h264dec, GstDucatiVidDec, - GST_TYPE_DUCATIVIDDEC); +#define gst_ducati_h264dec_parent_class parent_class +G_DEFINE_TYPE (GstDucatiH264Dec, gst_ducati_h264dec, GST_TYPE_DUCATIVIDDEC); static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-h264, " - "stream-format = byte-stream, " /* only byte-stream */ - "alignment = au, " /* only entire frames */ - "width = (int)[ 16, 2048 ], " - "height = (int)[ 16, 2048 ], " - "framerate = (fraction)[ 0, max ]," - "profile = (string){constrained-baseline, baseline, main, extended};" - "video/x-h264, " - "stream-format = byte-stream, " /* only byte-stream */ - "alignment = au, " /* only entire frames */ + GST_STATIC_CAPS ("video/x-h264, " "stream-format = byte-stream, " /* only byte-stream */ + "alignment = au, " /* only entire frames */ + "width = (int)[ 16, 2048 ], " "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ]," "profile = (string){constrained-baseline, baseline, main, extended};" "video/x-h264, " "stream-format = byte-stream, " /* only byte-stream */ + "alignment = au, " /* only entire frames */ "width = (int)[ 16, 2048 ], " "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ]," "profile = (string) {high, high-10-intra, high-10, high-4:2:2-intra, " "high-4:2:2, high-4:4:4-intra, high-4:4:4, cavlc-4:4:4-intra}, " - "level = (string) {1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2};" - ) + "level = (string) {1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2};") ); /* *INDENT-OFF* */ @@ -111,7 +103,9 @@ 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 = parent_class->allocate_params (self, + gboolean ret; + + ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self, sizeof (IH264VDEC_Params), sizeof (IH264VDEC_DynamicParams), sizeof (IH264VDEC_Status), sizeof (IH264VDEC_InArgs), sizeof (IH264VDEC_OutArgs)); @@ -147,8 +141,9 @@ gst_ducati_h264dec_handle_error (GstDucatiVidDec * self, gint ret, self->needs_flushing = TRUE; } - ret = parent_class->handle_error (self, ret, extended_error, - status_extended_error); + ret = + GST_DUCATIVIDDEC_CLASS (parent_class)->handle_error (self, ret, + extended_error, status_extended_error); return ret; } @@ -157,7 +152,7 @@ static gboolean gst_ducati_h264dec_query (GstDucatiVidDec * vdec, GstPad * pad, GstQuery * query, gboolean * forward) { - GstDucatiH264Dec * self = GST_DUCATIH264DEC (vdec); + GstDucatiH264Dec *self = GST_DUCATIH264DEC (vdec); gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { @@ -174,8 +169,7 @@ gst_ducati_h264dec_query (GstDucatiVidDec * vdec, GstPad * pad, gst_query_parse_latency (query, &live, &min, &max); if (vdec->fps_n != 0) - latency = gst_util_uint64_scale (GST_SECOND, - vdec->fps_d, vdec->fps_n); + latency = gst_util_uint64_scale (GST_SECOND, vdec->fps_d, vdec->fps_n); else latency = 0; @@ -190,7 +184,8 @@ gst_ducati_h264dec_query (GstDucatiVidDec * vdec, GstPad * pad, if (max != GST_CLOCK_TIME_NONE) max += latency; - GST_INFO_OBJECT (self, "latency %"GST_TIME_FORMAT " ours %"GST_TIME_FORMAT, + GST_INFO_OBJECT (self, + "latency %" GST_TIME_FORMAT " ours %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (latency)); gst_query_set_latency (query, live, min, max); break; @@ -200,7 +195,9 @@ gst_ducati_h264dec_query (GstDucatiVidDec * vdec, GstPad * pad, } if (res) - res = parent_class->query (vdec, pad, query, forward); + res = + GST_DUCATIVIDDEC_CLASS (parent_class)->query (vdec, pad, query, + forward); return res; } @@ -401,25 +398,13 @@ gst_ducati_h264dec_on_flush (GstDucatiVidDec * self, gboolean eos) /* GObject vmethod implementations */ -static void -gst_ducati_h264dec_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "DucatiH264Dec", - "Codec/Decoder/Video", - "Decodes video in H.264/bytestream format with ducati", - "Rob Clark "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); -} static void gst_ducati_h264dec_class_init (GstDucatiH264DecClass * klass) { + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass); + bclass->codec_name = "ivahd_h264dec"; bclass->update_buffer_size = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_update_buffer_size); @@ -432,11 +417,19 @@ gst_ducati_h264dec_class_init (GstDucatiH264DecClass * klass) bclass->push_output = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_push_output); bclass->on_flush = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_on_flush); bclass->set_sink_caps = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_set_sink_caps); + + gst_element_class_set_details_simple (element_class, + "DucatiH264Dec", + "Codec/Decoder/Video", + "Decodes video in H.264/bytestream format with ducati", + "Rob Clark "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); } static void -gst_ducati_h264dec_init (GstDucatiH264Dec * self, - GstDucatiH264DecClass * gclass) +gst_ducati_h264dec_init (GstDucatiH264Dec * self) { self->backlog_maxframes = 0; self->backlog_nframes = 0; diff --git a/src/gstducatimpeg2dec.c b/src/gstducatimpeg2dec.c index f8ae4d6..4859bfe 100644 --- a/src/gstducatimpeg2dec.c +++ b/src/gstducatimpeg2dec.c @@ -36,19 +36,17 @@ #include "gstducatimpeg2dec.h" -GST_BOILERPLATE (GstDucatiMpeg2Dec, gst_ducati_mpeg2dec, GstDucatiVidDec, - GST_TYPE_DUCATIVIDDEC); +#define gst_ducati_mpeg2dec_parent_class parent_class +G_DEFINE_TYPE (GstDucatiMpeg2Dec, gst_ducati_mpeg2dec, GST_TYPE_DUCATIVIDDEC); static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int)[ 1, 2 ], " // XXX check on MPEG-1.. + GST_STATIC_CAPS ("video/mpeg, " "mpegversion = (int)[ 1, 2 ], " // XXX check on MPEG-1.. "systemstream = (boolean)false, " "parsed = (boolean)true, " "width = (int)[ 64, 2048 ], " - "height = (int)[ 64, 2048 ], " - "framerate = (fraction)[ 0, max ];") + "height = (int)[ 64, 2048 ], " "framerate = (fraction)[ 0, max ];") ); /* GstDucatiVidDec vmethod implementations */ @@ -69,7 +67,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 = 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)); @@ -80,28 +78,50 @@ gst_ducati_mpeg2dec_allocate_params (GstDucatiVidDec * self, gint params_sz, return ret; } +static gboolean +compare_buffers (GstBuffer * a, GstBuffer * b) +{ + GstMapInfo mapa, mapb; + gboolean ret; + + if (!a || !b) + return FALSE; + if (gst_buffer_get_size (a) != gst_buffer_get_size (b)) + return FALSE; + + gst_buffer_map (a, &mapa, GST_MAP_READ); + gst_buffer_map (b, &mapb, GST_MAP_READ); + + ret = !memcmp (mapa.data, mapb.data, mapa.size); + gst_buffer_unmap (a, &mapa); + gst_buffer_unmap (b, &mapb); + + return ret; +} + static GstBuffer * gst_ducati_mpeg2dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) { GstDucatiMpeg2Dec *self = GST_DUCATIMPEG2DEC (vdec); - guint sz = GST_BUFFER_SIZE (buf); - guint8 *data = GST_BUFFER_DATA (buf); /* skip codec_data, which is same as first buffer from mpegvideoparse (and * appears to be periodically resent) and instead prepend to next frame.. */ - if (vdec->codec_data && (sz == GST_BUFFER_SIZE (vdec->codec_data)) && - !memcmp (data, GST_BUFFER_DATA (vdec->codec_data), sz)) { + if (compare_buffers (vdec->codec_data, buf)) { GST_DEBUG_OBJECT (self, "skipping codec_data buffer"); self->prepend_codec_data = TRUE; } else { + GstMapInfo map; if (self->prepend_codec_data) { GST_DEBUG_OBJECT (self, "prepending codec_data buffer"); - push_input (vdec, GST_BUFFER_DATA (vdec->codec_data), - GST_BUFFER_SIZE (vdec->codec_data)); + gst_buffer_map (vdec->codec_data, &map, GST_MAP_READ); + push_input (vdec, map.data, map.size); + gst_buffer_unmap (vdec->codec_data, &map); self->prepend_codec_data = FALSE; } - push_input (vdec, data, sz); + gst_buffer_map (buf, &map, GST_MAP_READ); + push_input (vdec, map.data, map.size); + gst_buffer_unmap (buf, &map); } gst_buffer_unref (buf); @@ -112,36 +132,29 @@ gst_ducati_mpeg2dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) /* GObject vmethod implementations */ static void -gst_ducati_mpeg2dec_base_init (gpointer gclass) +gst_ducati_mpeg2dec_class_init (GstDucatiMpeg2DecClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass); gst_element_class_set_details_simple (element_class, "DucatiMpeg2Dec", "Codec/Decoder/Video", - "Decodes video in MPEG-2 format with ducati", - "Rob Clark "); + "Decodes video in MPEG-2 format with ducati", "Rob Clark "); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sink_factory)); -} -static void -gst_ducati_mpeg2dec_class_init (GstDucatiMpeg2DecClass * klass) -{ - GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass); bclass->codec_name = "ivahd_mpeg2vdec"; bclass->update_buffer_size = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_mpeg2dec_push_input); } static void -gst_ducati_mpeg2dec_init (GstDucatiMpeg2Dec * self, - GstDucatiMpeg2DecClass * gclass) +gst_ducati_mpeg2dec_init (GstDucatiMpeg2Dec * self) { GstDucatiVidDec *vdec = GST_DUCATIVIDDEC (self); vdec->pageMemType = XDM_MEMTYPE_RAW; diff --git a/src/gstducatimpeg4dec.c b/src/gstducatimpeg4dec.c index cee2515..a63bc5a 100644 --- a/src/gstducatimpeg4dec.c +++ b/src/gstducatimpeg4dec.c @@ -54,19 +54,11 @@ GST_BOILERPLATE (GstDucatiMpeg4Dec, gst_ducati_mpeg4dec, GstDucatiVidDec, static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "video/mpeg, " - "mpegversion = (int)4, " - "systemstream = (boolean)false, " - MPEG4DEC_SINKCAPS_COMMON ";" - "video/x-divx, " - "divxversion = (int)[4, 5], " /* TODO check this */ - MPEG4DEC_SINKCAPS_COMMON ";" + GST_STATIC_CAPS ("video/mpeg, " "mpegversion = (int)4, " "systemstream = (boolean)false, " MPEG4DEC_SINKCAPS_COMMON ";" "video/x-divx, " "divxversion = (int)[4, 5], " /* TODO check this */ + MPEG4DEC_SINKCAPS_COMMON ";" "video/x-xvid, " - MPEG4DEC_SINKCAPS_COMMON ";" - "video/x-3ivx, " - MPEG4DEC_SINKCAPS_COMMON ";" - ) + MPEG4DEC_SINKCAPS_COMMON ";" + "video/x-3ivx, " MPEG4DEC_SINKCAPS_COMMON ";") ); /* GstDucatiVidDec vmethod implementations */ @@ -105,19 +97,20 @@ gst_ducati_mpeg4dec_allocate_params (GstDucatiVidDec * self, gint params_sz, return ret; } -#define VOS_START_CODE 0xb0 /* + visual object sequence */ +#define VOS_START_CODE 0xb0 /* + visual object sequence */ #define VOS_END_CODE 0xb1 -#define UD_START_CODE 0xb2 /* user data */ -#define GVOP_START_CODE 0xb3 /* + group of VOP */ +#define UD_START_CODE 0xb2 /* user data */ +#define GVOP_START_CODE 0xb3 /* + group of VOP */ #define VS_ERROR_CODE 0xb4 -#define VO_START_CODE 0xb5 /* visual object */ -#define VOP_START_CODE 0xb6 /* + */ +#define VO_START_CODE 0xb5 /* visual object */ +#define VOP_START_CODE 0xb6 /* + */ + +static const guint8 sc[] = { 0x00, 0x00, 0x01 }; /* start code */ -static const guint8 sc[] = {0x00, 0x00, 0x01}; /* start code */ #define SC_SZ G_N_ELEMENTS (sc) /* start code size */ static GstBitReader * -get_bit_reader (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) +get_bit_reader (GstDucatiMpeg4Dec * self, const guint8 * data, guint size) { if (self->br) { gst_bit_reader_init (self->br, data, size); @@ -128,48 +121,48 @@ get_bit_reader (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) } static void -decode_vol_header (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) +decode_vol_header (GstDucatiMpeg4Dec * self, const guint8 * data, guint size) { GstBitReader *br = get_bit_reader (self, data, size); guint32 is_oli = 0, vc_param = 0, vbv_param = 0; guint32 ar_info = 0, vop_tir = 0; - gst_bit_reader_skip (br, 1); /* random_accessible_vol */ - gst_bit_reader_skip (br, 8); /* video_object_type_indication */ + gst_bit_reader_skip (br, 1); /* random_accessible_vol */ + gst_bit_reader_skip (br, 8); /* video_object_type_indication */ - gst_bit_reader_get_bits_uint32 (br, /* is_object_layer_identifier */ + gst_bit_reader_get_bits_uint32 (br, /* is_object_layer_identifier */ &is_oli, 1); if (is_oli) { - gst_bit_reader_skip (br, 4); /* video_object_layer_verid */ - gst_bit_reader_skip (br, 3); /* video_object_layer_priority */ + gst_bit_reader_skip (br, 4); /* video_object_layer_verid */ + gst_bit_reader_skip (br, 3); /* video_object_layer_priority */ } - gst_bit_reader_get_bits_uint32 (br, /* aspect_ratio_info */ + gst_bit_reader_get_bits_uint32 (br, /* aspect_ratio_info */ &ar_info, 4); if (ar_info == 0xf) { - gst_bit_reader_skip (br, 8); /* par_width */ - gst_bit_reader_skip (br, 8); /* par_height */ + gst_bit_reader_skip (br, 8); /* par_width */ + gst_bit_reader_skip (br, 8); /* par_height */ } - gst_bit_reader_get_bits_uint32 (br, /* vol_control_parameters */ + gst_bit_reader_get_bits_uint32 (br, /* vol_control_parameters */ &vc_param, 1); if (vc_param) { - gst_bit_reader_skip (br, 2); /* chroma_format */ - gst_bit_reader_skip (br, 1); /* low_delay */ - gst_bit_reader_get_bits_uint32 ( /* vbv_parameters */ + gst_bit_reader_skip (br, 2); /* chroma_format */ + gst_bit_reader_skip (br, 1); /* low_delay */ + gst_bit_reader_get_bits_uint32 ( /* vbv_parameters */ br, &vbv_param, 1); if (vbv_param) { - gst_bit_reader_skip (br, 79); /* don't care */ + gst_bit_reader_skip (br, 79); /* don't care */ } } - gst_bit_reader_skip (br, 2); /* video_object_layer_shape */ - gst_bit_reader_skip (br, 1); /* marker_bit */ - gst_bit_reader_get_bits_uint32 (br, /* vop_time_increment_resolution */ + gst_bit_reader_skip (br, 2); /* video_object_layer_shape */ + gst_bit_reader_skip (br, 1); /* marker_bit */ + gst_bit_reader_get_bits_uint32 (br, /* vop_time_increment_resolution */ &vop_tir, 16); - gst_bit_reader_skip (br, 1); /* marker_bit */ + gst_bit_reader_skip (br, 1); /* marker_bit */ - self->time_increment_bits = (guint32)log2((double)(vop_tir - 1)) + 1; + self->time_increment_bits = (guint32) log2 ((double) (vop_tir - 1)) + 1; GST_DEBUG_OBJECT (self, "vop_tir=%d, time_increment_bits=%d", vop_tir, self->time_increment_bits); @@ -181,17 +174,17 @@ decode_vol_header (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) } static void -decode_user_data (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) +decode_user_data (GstDucatiMpeg4Dec * self, const guint8 * data, guint size) { GstDucatiVidDec *vdec = GST_DUCATIVIDDEC (self); - const char *buf = (const char *)data; + const char *buf = (const char *) data; int n, ver, build; char c; /* divx detection: */ - n = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &c); + n = sscanf (buf, "DivX%dBuild%d%c", &ver, &build, &c); if (n < 2) - n = sscanf(buf, "DivX%db%d%c", &ver, &build, &c); + n = sscanf (buf, "DivX%db%d%c", &ver, &build, &c); if (n >= 2) { GST_INFO_OBJECT (self, "DivX: version %d, build %d", ver, build); if ((n == 3) && (c == 'p')) { @@ -202,7 +195,7 @@ decode_user_data (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) } /* xvid detection: */ - n = sscanf(buf, "XviD%d", &build); + n = sscanf (buf, "XviD%d", &build); if (n == 1) { GST_INFO_OBJECT (self, "XviD: build %d", build); /* I believe we only get this in avi container, which means @@ -213,23 +206,22 @@ decode_user_data (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) } static gboolean -is_vop_coded (GstDucatiMpeg4Dec *self, const guint8 * data, guint size) +is_vop_coded (GstDucatiMpeg4Dec * self, const guint8 * data, guint size) { - GstBitReader *br = - get_bit_reader (self, data, size); + GstBitReader *br = get_bit_reader (self, data, size); guint32 b = 0; - gst_bit_reader_skip (br, 2); /* vop_coding_type */ + gst_bit_reader_skip (br, 2); /* vop_coding_type */ - do { /* modulo_time_base */ + do { /* modulo_time_base */ gst_bit_reader_get_bits_uint32 (br, &b, 1); } while (b != 0); - gst_bit_reader_skip (br, 1); /* marker_bit */ - gst_bit_reader_skip (br, /* vop_time_increment */ + gst_bit_reader_skip (br, 1); /* marker_bit */ + gst_bit_reader_skip (br, /* vop_time_increment */ self->time_increment_bits); - gst_bit_reader_skip (br, 1); /* marker_bit */ - gst_bit_reader_get_bits_uint32 (br, /* vop_coded */ + gst_bit_reader_skip (br, 1); /* marker_bit */ + gst_bit_reader_get_bits_uint32 (br, /* vop_coded */ &b, 1); return b; @@ -241,7 +233,7 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) GstDucatiMpeg4Dec *self = GST_DUCATIMPEG4DEC (vdec); GstBuffer *remaining = NULL; gint insize = GST_BUFFER_SIZE (buf); - const guint8 *in = GST_BUFFER_DATA (buf); + const guint8 *in = GST_BUFFER_DATA (buf); gint size = 0; guint8 last_start_code = 0xff; @@ -259,10 +251,7 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) if (size > 0) { /* check if we've found a potential start of frame: */ - if ((start_code == VOS_START_CODE) || - (start_code == GVOP_START_CODE) || - (start_code == VOP_START_CODE) || - (start_code <= 0x1f)) { /* 00->0f is video_object_start_code */ + if ((start_code == VOS_START_CODE) || (start_code == GVOP_START_CODE) || (start_code == VOP_START_CODE) || (start_code <= 0x1f)) { /* 00->0f is video_object_start_code */ /* if last was a VOP, or if this is first VOP, then what follows * must be the next frame: */ @@ -278,8 +267,7 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) last_start_code = start_code; - nal_size = SC_SZ + - find_start_code (sc, SC_SZ, in + SC_SZ, insize - SC_SZ); + nal_size = SC_SZ + find_start_code (sc, SC_SZ, in + SC_SZ, insize - SC_SZ); if ((start_code == VOP_START_CODE) && (nal_size < 20)) { /* suspiciously small nal.. check for !vop_coded and filter @@ -290,10 +278,10 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) * are all 7 bytes but need to come up with some sane * threshold */ - skip = ! is_vop_coded (self, in + SC_SZ + 1, insize - SC_SZ - 1); + skip = !is_vop_coded (self, in + SC_SZ + 1, insize - SC_SZ - 1); if (skip) GST_DEBUG_OBJECT (self, "skipping non-coded VOP"); - } else if (start_code == UD_START_CODE){ + } else if (start_code == UD_START_CODE) { decode_user_data (self, in + SC_SZ + 1, nal_size - SC_SZ - 1); } @@ -344,8 +332,7 @@ gst_ducati_mpeg4dec_base_init (gpointer gclass) gst_element_class_set_details_simple (element_class, "DucatiMpeg4Dec", "Codec/Decoder/Video", - "Decodes video in MPEG-4 format with ducati", - "Rob Clark "); + "Decodes video in MPEG-4 format with ducati", "Rob Clark "); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sink_factory)); @@ -357,16 +344,14 @@ gst_ducati_mpeg4dec_class_init (GstDucatiMpeg4DecClass * klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass); - gobject_class->finalize = - GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_finalize); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_finalize); bclass->codec_name = "ivahd_mpeg4dec"; bclass->update_buffer_size = GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_mpeg4dec_push_input); } static void diff --git a/src/gstducatiprivmeta.c b/src/gstducatiprivmeta.c new file mode 100644 index 0000000..da64941 --- /dev/null +++ b/src/gstducatiprivmeta.c @@ -0,0 +1,84 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * Copyright (C) 2012 Collabora Ltd + * + * Authors: + * Alessandro Decina + * Rob Clark + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include + +#include "gstducatiprivmeta.h" + +static void +gst_ducati_priv_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstDucatiPrivMeta *smeta = (GstDucatiPrivMeta *) meta; + + /* FIXME : Shouldn't we check if the bo is valid ? */ + omap_bo_del (smeta->bo); +} + +/** + * gst_buffer_add_ducati_priv_meta: + * @buffer: a #GstBuffer + * + * Returns: the #GstDucatiPrivMeta on @buffer. + */ +GstDucatiPrivMeta * +gst_buffer_add_ducati_priv_meta (GstBuffer * buffer) +{ + return (GstDucatiPrivMeta *) gst_buffer_add_meta (buffer, + GST_DUCATI_PRIV_META_INFO, NULL); +} + +GType +gst_ducati_priv_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = { NULL }; + + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstDucatiPrivMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +const GstMetaInfo * +gst_ducati_priv_meta_get_info (void) +{ + static const GstMetaInfo *ducati_priv_meta_info = NULL; + + if (ducati_priv_meta_info == NULL) { + ducati_priv_meta_info = gst_meta_register (GST_DUCATI_PRIV_META_API_TYPE, "GstDucatiPrivMeta", sizeof (GstDucatiPrivMeta), NULL, /* No init needed */ + gst_ducati_priv_meta_free, NULL /* FIXME : No transform needed ? */ ); + } + return ducati_priv_meta_info; +} diff --git a/src/gstducatiprivmeta.h b/src/gstducatiprivmeta.h new file mode 100644 index 0000000..8773455 --- /dev/null +++ b/src/gstducatiprivmeta.h @@ -0,0 +1,62 @@ +/* + * GStreamer + * + * Copyright (C) 2012 Texas Instruments + * Copyright (C) 2012 Collabora Ltd + * + * Authors: + * Alessandro Decina + * Rob Clark + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __GSTDUCATIBUFFERPRIV_H__ +#define __GSTDUCATIBUFFERPRIV_H__ + +#include +#include + +G_BEGIN_DECLS + +/* + * per-buffer private data for gst-ducati + */ + +#define GST_DUCATI_PRIV_META_API_TYPE (gst_ducati_priv_meta_api_get_type()) +#define GST_DUCATI_PRIV_META_INFO (gst_ducati_priv_meta_get_info()) + +typedef struct _GstDucatiPrivMeta GstDucatiPrivMeta; + + +struct _GstDucatiPrivMeta +{ + GstMeta meta; + + struct omap_bo *bo; + gint uv_offset, size; +}; + + +GType gst_ducati_priv_meta_api_get_type (void); +const GstMetaInfo * gst_ducati_priv_meta_get_info (void); + +GstDucatiPrivMeta* gst_buffer_add_ducati_priv_meta(GstBuffer *buffer); +#define gst_buffer_get_ducati_priv_meta(b) ((GstDucatiPrivMeta*)gst_buffer_get_meta((b), GST_DUCATI_PRIV_META_API_TYPE)) + +G_END_DECLS + + +#endif /* __GSTDUCATIBUFFERPRIV_H__ */ diff --git a/src/gstducatirvdec.c b/src/gstducatirvdec.c index f1b650e..ae149ea 100644 --- a/src/gstducatirvdec.c +++ b/src/gstducatirvdec.c @@ -51,8 +51,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", "systemstream = (boolean)false, " "rmversion = (int){ 3, 4 }, " "width = (int)[ 16, 2048 ], " - "height = (int)[ 16, 2048 ], " - "framerate = (fraction)[ 0, max ];") + "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];") ); /* GstDucatiVidDec vmethod implementations */ @@ -104,7 +103,7 @@ gst_ducati_rvdec_allocate_params (GstDucatiVidDec * vdec, gint params_sz, sizeof (IrealVDEC_OutArgs)); if (ret) { - /*IrealVDEC_Params *params = (IrealVDEC_Params *) vdec->params;*/ + /*IrealVDEC_Params *params = (IrealVDEC_Params *) vdec->params; */ vdec->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_1; vdec->dynParams->newFrameFlag = FALSE; vdec->dynParams->lateAcquireArg = -1; @@ -135,9 +134,9 @@ gst_ducati_rvdec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) /* stream type */ if (self->rmversion == 3) { - push_input (vdec, (guint8 *)"VIDORV30", 8); + push_input (vdec, (guint8 *) "VIDORV30", 8); } else if (self->rmversion == 4) { - push_input (vdec, (guint8 *)"VIDORV40", 8); + push_input (vdec, (guint8 *) "VIDORV40", 8); } /* horiz x vert resolution */ @@ -239,18 +238,15 @@ gst_ducati_rvdec_class_init (GstDucatiRVDecClass * klass) { GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass); bclass->codec_name = "ivahd_realvdec"; - bclass->parse_caps = - GST_DEBUG_FUNCPTR (gst_ducati_rvdec_parse_caps); + bclass->parse_caps = GST_DEBUG_FUNCPTR (gst_ducati_rvdec_parse_caps); bclass->update_buffer_size = GST_DEBUG_FUNCPTR (gst_ducati_rvdec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_rvdec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_rvdec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_rvdec_push_input); } static void -gst_ducati_rvdec_init (GstDucatiRVDec * self, - GstDucatiRVDecClass * gclass) +gst_ducati_rvdec_init (GstDucatiRVDec * self, GstDucatiRVDecClass * gclass) { } diff --git a/src/gstducativc1dec.c b/src/gstducativc1dec.c index 8815d2b..2465b01 100644 --- a/src/gstducativc1dec.c +++ b/src/gstducativc1dec.c @@ -52,8 +52,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", "wmvversion = (int) 3, " "format = (fourcc){ WVC1, WMV3 }, " "width = (int)[ 16, 2048 ], " - "height = (int)[ 16, 2048 ], " - "framerate = (fraction)[ 0, max ];") + "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];") ); /* GstDucatiVidDec vmethod implementations */ @@ -118,7 +117,7 @@ gst_ducati_vc1dec_allocate_params (GstDucatiVidDec * self, gint params_sz, params->frameLayerDataPresentFlag = FALSE; /* enable concealment */ - params->ErrorConcealmentON = 1; + params->ErrorConcealmentON = 1; /* codec wants lateAcquireArg = -1 */ self->dynParams->lateAcquireArg = -1; @@ -167,7 +166,8 @@ gst_ducati_vc1dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) push_input (vdec, (guint8 *) & val, 4); val = vdec->width; push_input (vdec, (guint8 *) & val, 4); - GST_INFO_OBJECT (vdec, "seq hdr resolution: %dx%d", vdec->width, vdec->height); + GST_INFO_OBJECT (vdec, "seq hdr resolution: %dx%d", vdec->width, + vdec->height); val = 0x0000000c; push_input (vdec, (guint8 *) & val, 4); @@ -185,7 +185,7 @@ gst_ducati_vc1dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) static guint8 sc[] = { 0x00, 0x00, 0x01, 0x0d }; /* start code */ push_input (vdec, sc, sizeof (sc)); } - + if (params->frameLayerDataPresentFlag) { val = GST_BUFFER_SIZE (buf); if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) @@ -235,8 +235,7 @@ gst_ducati_vc1dec_can_drop_frame (GstDucatiVidDec * self, GstBuffer * buf, /* GstElement vmethod implementations */ static GstStateChangeReturn -gst_ducati_vc1dec_change_state (GstElement * element, - GstStateChange transition) +gst_ducati_vc1dec_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (element); @@ -292,21 +291,18 @@ gst_ducati_vc1dec_class_init (GstDucatiVC1DecClass * klass) GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_change_state); bclass->codec_name = "ivahd_vc1vdec"; - bclass->parse_caps = - GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_parse_caps); + bclass->parse_caps = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_parse_caps); bclass->update_buffer_size = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_push_input); bclass->handle_error = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_handle_error); bclass->can_drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_vc1dec_can_drop_frame); } static void -gst_ducati_vc1dec_init (GstDucatiVC1Dec * self, - GstDucatiVC1DecClass * gclass) +gst_ducati_vc1dec_init (GstDucatiVC1Dec * self, GstDucatiVC1DecClass * gclass) { GstDucatiVidDec *vdec = GST_DUCATIVIDDEC (self); diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c index 5264da7..e230799 100644 --- a/src/gstducatividdec.c +++ b/src/gstducatividdec.c @@ -23,15 +23,51 @@ #endif #include "gstducatividdec.h" -#include "gstducatibufferpriv.h" - -GST_BOILERPLATE (GstDucatiVidDec, gst_ducati_viddec, GstElement, - GST_TYPE_ELEMENT); +#include "gstducatiprivmeta.h" +#include "gstdmabufmeta.h" + +/* No, we can't use G_DEFINE_TYPE since _init() needs the proper class */ +/* NOTE (Edward): Do not use G_DEFINE_* because we need to have + * a GClassInitFunc called with the target class (which the macros + * don't handle). */ +static void gst_ducati_viddec_class_init (GstDucatiVidDecClass * klass); +static void gst_ducati_viddec_init (GstDucatiVidDec * dec, + GstDucatiVidDecClass * klass); +static GstFlowReturn *gst_ducati_viddec_negotiate_pool (GstDucatiVidDec * self, + GstCaps * caps); + +static GstElementClass *parent_class = NULL; + +GType +gst_ducati_viddec_get_type (void) +{ + static volatile gsize ducati_viddec_type = 0; + + if (g_once_init_enter (&ducati_viddec_type)) { + GType _type; + static const GTypeInfo ducati_viddec_info = { + sizeof (GstDucatiVidDecClass), + NULL, + NULL, + (GClassInitFunc) gst_ducati_viddec_class_init, + NULL, + NULL, + sizeof (GstDucatiVidDec), + 0, + (GInstanceInitFunc) gst_ducati_viddec_init, + }; + + _type = g_type_register_static (GST_TYPE_ELEMENT, + "GstDucatiVidDec", &ducati_viddec_info, G_TYPE_FLAG_ABSTRACT); + g_once_init_leave (&ducati_viddec_type, _type); + } + return ducati_viddec_type; +} static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED ("NV12", "[ 0, max ]")) + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("NV12")) ); enum @@ -129,7 +165,7 @@ static void codec_delete (GstDucatiVidDec * self) { if (self->pool) { - gst_drm_buffer_pool_destroy (self->pool); + gst_object_unref (self->pool); self->pool = NULL; } @@ -147,15 +183,12 @@ codec_delete (GstDucatiVidDec * self) static gboolean codec_create (GstDucatiVidDec * self) { - gint err; const gchar *codec_name; codec_delete (self); - if (G_UNLIKELY (!self->engine)) { - GST_ERROR_OBJECT (self, "no engine"); - return FALSE; - } + if (G_UNLIKELY (!self->engine)) + goto no_engine; /* these need to be set before VIDDEC3_create */ self->params->maxWidth = self->width; @@ -168,18 +201,14 @@ codec_create (GstDucatiVidDec * self) self->codec = VIDDEC3_create (self->engine, (String) codec_name, self->params); - if (!self->codec) { - return FALSE; - } + if (!self->codec) + goto no_codec; - err = - VIDDEC3_control (self->codec, XDM_SETPARAMS, self->dynParams, - self->status); - if (err) { - GST_ERROR_OBJECT (self, "failed XDM_SETPARAMS"); - return FALSE; - } + if (VIDDEC3_control (self->codec, XDM_SETPARAMS, self->dynParams, + self->status)) + goto setparams_fail; + GST_DEBUG_OBJECT (self, "Resetting first in/out_buffer to TRUE"); self->first_in_buffer = TRUE; self->first_out_buffer = TRUE; @@ -192,104 +221,67 @@ codec_create (GstDucatiVidDec * self) self->inBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (self->input_bo); return TRUE; -} -static inline GstBuffer * -codec_buffer_pool_get (GstDucatiVidDec * self, GstBuffer * buf) -{ - if (G_UNLIKELY (!self->pool)) { - guint size = gst_video_format_get_size (GST_VIDEO_FORMAT_NV12, - self->padded_width, self->padded_height); + /* Error cases */ +no_engine: + { + GST_ERROR_OBJECT (self, "no engine"); + return FALSE; + } + +no_codec: + { + GST_ERROR_OBJECT (self, "Failed to create codec %s", codec_name); + return FALSE; + } - GST_DEBUG_OBJECT (self, "creating bufferpool"); - self->pool = gst_drm_buffer_pool_new (GST_ELEMENT (self), - dce_get_fd (), GST_PAD_CAPS (self->srcpad), size); +setparams_fail: + { + GST_ERROR_OBJECT (self, "failed XDM_SETPARAMS"); + return FALSE; } - return GST_BUFFER (gst_drm_buffer_pool_get (self->pool, FALSE)); } -static GstDucatiBufferPriv * -get_buffer_priv (GstDucatiVidDec * self, GstBuffer * buf) +static inline GstBuffer * +codec_buffer_pool_get (GstDucatiVidDec * self) { - GstDucatiBufferPriv *priv = gst_ducati_buffer_priv_get (buf); - if (!priv) { - GstVideoFormat format = GST_VIDEO_FORMAT_NV12; - GstDmaBuf *dmabuf = gst_buffer_get_dma_buf (buf); - - /* if it isn't a dmabuf buffer that we can import, then there - * is nothing we can do with it: - */ - if (!dmabuf) { - GST_DEBUG_OBJECT (self, "not importing non dmabuf buffer"); - return NULL; - } + GstBuffer *outbuf = NULL; + GstFlowReturn res; - priv = gst_ducati_buffer_priv_new (); + g_return_val_if_fail (self->pool, NULL); - priv->bo = omap_bo_from_dmabuf (self->device, gst_dma_buf_get_fd (dmabuf)); + res = gst_buffer_pool_acquire_buffer (self->pool, &outbuf, NULL); - priv->uv_offset = gst_video_format_get_component_offset (format, - 1, self->stride, self->padded_height); - priv->size = gst_video_format_get_size (format, - self->stride, self->padded_height); + if (res != GST_FLOW_OK) + GST_WARNING_OBJECT (self, "Couldn't acquire buffer : %s", + gst_flow_get_name (res)); - gst_ducati_buffer_priv_set (buf, priv); - gst_mini_object_unref (GST_MINI_OBJECT (priv)); - } - return priv; + return outbuf; } + static XDAS_Int32 codec_prepare_outbuf (GstDucatiVidDec * self, GstBuffer ** buf, gboolean force_internal) { - GstDucatiBufferPriv *priv = NULL; + GstDRMMeta *drm_meta = gst_buffer_get_drm_meta (*buf); - if (!force_internal) - priv = get_buffer_priv (self, *buf); - - if (!priv) { - GstBuffer *orig = *buf; - - GST_DEBUG_OBJECT (self, "internal bufferpool forced"); - *buf = codec_buffer_pool_get (self, NULL); - GST_BUFFER_TIMESTAMP (*buf) = GST_BUFFER_TIMESTAMP (orig); - GST_BUFFER_DURATION (*buf) = GST_BUFFER_DURATION (orig); - gst_buffer_unref (orig); - return codec_prepare_outbuf (self, buf, FALSE); + if (G_UNLIKELY (drm_meta == NULL)) { + GST_ERROR_OBJECT (self, "Buffer from pool doesn't have DRMMETA !"); + return (XDAS_Int32) NULL; } self->outBufs->numBufs = 2; self->outBufs->descs[0].memType = XDM_MEMTYPE_BO; - self->outBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (priv->bo); - self->outBufs->descs[0].bufSize.bytes = priv->uv_offset; + self->outBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (drm_meta->bo); + self->outBufs->descs[0].bufSize.bytes = drm_meta->uv_offset; self->outBufs->descs[1].memType = XDM_MEMTYPE_BO_OFFSET; - self->outBufs->descs[1].buf = (XDAS_Int8 *) priv->uv_offset; - self->outBufs->descs[1].bufSize.bytes = priv->size - priv->uv_offset; + self->outBufs->descs[1].buf = (XDAS_Int8 *) drm_meta->uv_offset; + self->outBufs->descs[1].bufSize.bytes = drm_meta->size - drm_meta->uv_offset; return (XDAS_Int32) * buf; // XXX use lookup table } -static GstBuffer * -codec_get_outbuf (GstDucatiVidDec * self, XDAS_Int32 id) -{ - GstBuffer *buf = (GstBuffer *) id; // XXX use lookup table - if (buf) { - gst_buffer_ref (buf); - } - return buf; -} - -static void -codec_unlock_outbuf (GstDucatiVidDec * self, XDAS_Int32 id) -{ - GstBuffer *buf = (GstBuffer *) id; // XXX use lookup table - if (buf) { - GST_DEBUG_OBJECT (self, "free buffer: %d %p", id, buf); - gst_buffer_unref (buf); - } -} - static void gst_ducati_viddec_on_flush (GstDucatiVidDec * self, gboolean eos) { @@ -346,7 +338,7 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) { gboolean interlaced; - outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]); + outbuf = (GstBuffer *) self->outArgs->outputID[i]; interlaced = self->outArgs->decodedBufs.contentType == @@ -364,13 +356,11 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, self->interlaced = interlaced; - caps = - gst_caps_make_writable (gst_pad_get_negotiated_caps (self->srcpad)); + caps = gst_caps_make_writable (gst_pad_get_current_caps (self->srcpad)); GST_INFO_OBJECT (self, "changing interlace field in caps"); gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, interlaced, NULL); - gst_drm_buffer_pool_set_caps (self->pool, caps); - if (!gst_pad_set_caps (self->srcpad, caps)) { + if (gst_ducati_viddec_negotiate_pool (self, caps) != GST_FLOW_OK) { GST_ERROR_OBJECT (self, "downstream didn't want to change interlace mode"); err = XDM_EFAIL; @@ -381,7 +371,7 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, send = FALSE; } - if (G_UNLIKELY (self->send_crop_event) && send) { + if (G_UNLIKELY (self->calculate_crop) && send) { gint crop_width, crop_height; /* send region of interest to sink on first buffer: */ @@ -399,29 +389,13 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y, crop_width, crop_height); - gst_pad_push_event (self->srcpad, - gst_event_new_crop (r->topLeft.y, r->topLeft.x, - crop_width, crop_height)); - - if (self->crop) - gst_video_crop_unref (self->crop); - - self->crop = gst_video_crop_new (r->topLeft.y, r->topLeft.x, - crop_width, crop_height); - - self->send_crop_event = FALSE; - } - - if (G_UNLIKELY (self->first_out_buffer) && send) { - GstDRMBufferPool *pool; - self->first_out_buffer = FALSE; + self->crop.top = r->topLeft.y; + self->crop.left = r->topLeft.x; + self->crop.width = crop_width; + self->crop.height = crop_height; - /* Destroy the pool so the buffers we used so far are eventually released. - * The pool will be recreated if needed. - */ - pool = self->pool; - self->pool = NULL; - gst_drm_buffer_pool_destroy (pool); + self->need_crop = TRUE; + self->calculate_crop = FALSE; } if (send) { @@ -455,21 +429,20 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, i, outbuf, GST_TIME_ARGS (ts)); } - if (GST_BUFFER_CAPS (outbuf) && - !gst_caps_is_equal (GST_BUFFER_CAPS (outbuf), - GST_PAD_CAPS (self->srcpad))) { - /* this looks a bit scary but it's really just to change the interlace= - * field in caps when we start as !interlaced and the codec detects - * otherwise */ - GST_WARNING_OBJECT (self, "overriding buffer caps to fix " - "interlace mismatch"); - outbuf = gst_buffer_make_metadata_writable (outbuf); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad)); - } + if (FALSE && self->need_crop) { + GstVideoCropMeta *cropmeta = gst_buffer_add_video_crop_meta (outbuf); - if (self->crop) - gst_buffer_set_video_crop (outbuf, self->crop); + GST_DEBUG_OBJECT (self, "Adding crop meta x,y,width,height:%d,%d,%d,%d", + self->crop.left, + self->crop.top, self->crop.width, self->crop.height); + cropmeta->x = self->crop.left; + cropmeta->y = self->crop.top; + cropmeta->width = self->crop.width; + cropmeta->height = self->crop.height; + } + /* We keep a reference */ + gst_buffer_ref (outbuf); ret = klass->push_output (self, outbuf); if (flow_ret) *flow_ret = ret; @@ -480,13 +453,14 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, } } else { GST_DEBUG_OBJECT (self, "free buffer: %d %p", i, outbuf); - gst_buffer_unref (outbuf); } } skip_outbuf_processing: for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) { - codec_unlock_outbuf (self, self->outArgs->freeBufID[i]); + GST_DEBUG_OBJECT (self, "free buffer: %d 0x%x", i, + self->outArgs->freeBufID[i]); + gst_buffer_unref ((GstBuffer *) self->outArgs->freeBufID[i]); } return err; @@ -645,7 +619,7 @@ gst_ducati_viddec_allocate_params (GstDucatiVidDec * self, gint params_sz, if (G_UNLIKELY (!self->status)) { return FALSE; } - memset(self->status, 0, status_sz); + memset (self->status, 0, status_sz); self->status->size = status_sz; /* allocate inBufs/outBufs: */ @@ -670,13 +644,24 @@ gst_ducati_viddec_allocate_params (GstDucatiVidDec * self, gint params_sz, static GstBuffer * gst_ducati_viddec_push_input (GstDucatiVidDec * self, GstBuffer * buf) { + GstMapInfo map; + + GST_DEBUG_OBJECT (self, "buf:%p (first_in_buffer:%d, codec_data:%p)", buf, + self->first_in_buffer, self->codec_data); + if (G_UNLIKELY (self->first_in_buffer) && self->codec_data) { - push_input (self, GST_BUFFER_DATA (self->codec_data), - GST_BUFFER_SIZE (self->codec_data)); + GST_DEBUG_OBJECT (self, "Pushing codec_data"); + if (gst_buffer_map (self->codec_data, &map, GST_MAP_READ)) { + push_input (self, map.data, map.size); + gst_buffer_unmap (self->codec_data, &map); + } } /* just copy entire buffer */ - push_input (self, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + if (gst_buffer_map (buf, &map, GST_MAP_READ)) { + push_input (self, map.data, map.size); + gst_buffer_unmap (buf, &map); + } gst_buffer_unref (buf); return NULL; @@ -700,6 +685,58 @@ gst_ducati_viddec_handle_error (GstDucatiVidDec * self, gint ret, return ret; } +static GstFlowReturn * +gst_ducati_viddec_negotiate_pool (GstDucatiVidDec * self, GstCaps * caps) +{ + guint size = 0, min, max; + GstStructure *config; + GstQuery *query; + + 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) && + gst_query_get_n_allocation_pools (query)) { + gst_query_parse_nth_allocation_pool (query, 0, NULL, &size, &min, &max); + if (min < self->min_buffers) + min = self->min_buffers; + } else { + GST_DEBUG_OBJECT (self, "Query failed, using defaults"); + min = self->min_buffers; + max = 0; + } + + gst_query_unref (query); + + /* GST_WARNING_OBJECT (self, "OVERRIDDING MINIMUM BUFFERS"); */ + /* min = 0; */ + + 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_drm_buffer_pool_new (GST_ELEMENT (self), dce_get_fd ()); + + config = gst_buffer_pool_get_config (self->pool); + gst_buffer_pool_config_set_params (config, caps, size, min, max); + + /* 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 @@ -709,16 +746,13 @@ gst_ducati_viddec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps) GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self); GstStructure *s; GstCaps *outcaps = NULL; - GstStructure *out_s; gint par_width, par_height; gboolean par_present; + GstVideoInfo info; s = gst_caps_get_structure (caps, 0); - if (!klass->parse_caps (self, s)) { - GST_WARNING_OBJECT (self, "missing required fields"); - ret = FALSE; - goto out; - } + if (!klass->parse_caps (self, s)) + goto missing_fields; /* update output/padded sizes */ klass->update_buffer_size (self); @@ -731,48 +765,25 @@ gst_ducati_viddec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps) par_present = gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_width, &par_height); - outcaps = gst_pad_get_allowed_caps (self->srcpad); - if (outcaps) { - outcaps = gst_caps_make_writable (outcaps); - gst_caps_truncate (outcaps); - if (gst_caps_is_empty (outcaps)) { - gst_caps_unref (outcaps); - outcaps = NULL; - } - } - - if (!outcaps) { - /* note: default to non-strided for better compatibility with - * other gst elements that don't understand stride: - */ - outcaps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('N', 'V', '1', '2'), NULL); - } - out_s = gst_caps_get_structure (outcaps, 0); - gst_structure_set (out_s, + 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, self->fps_n, self->fps_d, NULL); if (par_present) - gst_structure_set (out_s, "pixel-aspect-ratio", GST_TYPE_FRACTION, + gst_caps_set_simple (outcaps, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_width, par_height, NULL); if (self->interlaced) - gst_structure_set (out_s, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL); + gst_caps_set_simple (outcaps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL); - if (!strcmp (gst_structure_get_name (out_s), "video/x-raw-yuv-strided")) { - if (!gst_structure_get_int (out_s, "rowstride", &self->stride)) { - self->stride = 4096; - gst_structure_set (out_s, "rowstride", G_TYPE_INT, self->stride, NULL); - } - } else { - self->stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_NV12, - 0, self->padded_width); - } + /* NO COMMENTS ! */ + if (!gst_video_info_from_caps (&info, outcaps)) + goto fail_video_info; - self->outsize = gst_video_format_get_size (GST_VIDEO_FORMAT_NV12, - self->stride, self->padded_height); + self->stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, 0); + self->outsize = GST_VIDEO_INFO_SIZE (&info); GST_INFO_OBJECT (self, "outsize %d stride %d outcaps: %" GST_PTR_FORMAT, self->outsize, self->stride, outcaps); @@ -787,76 +798,74 @@ gst_ducati_viddec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps) } /* (re)send a crop event when caps change */ - self->send_crop_event = TRUE; + self->calculate_crop = TRUE; ret = gst_pad_set_caps (self->srcpad, outcaps); + gst_caps_unref (outcaps); - GST_INFO_OBJECT (self, "set caps done %d, %" GST_PTR_FORMAT, ret, outcaps); + if (!ret) + goto fail_set_caps; -out: - if (outcaps) - gst_caps_unref (outcaps); + { + gchar *lala = gst_caps_to_string (outcaps); + GST_INFO_OBJECT (self, "set caps done %d, %s", ret, lala); + g_free (lala); + } - return ret; -} + if (!self->codec) + codec_create (self); -static gboolean -gst_ducati_viddec_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - gboolean ret = TRUE; - GstDucatiVidDec *self = GST_DUCATIVIDDEC (gst_pad_get_parent (pad)); - GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self); + /* Negotiate pool */ + if (gst_ducati_viddec_negotiate_pool (self, outcaps) != GST_FLOW_OK) + goto pool_fail; - GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (self, "Success setting caps"); - ret = klass->set_sink_caps (self, caps); + return TRUE; - gst_object_unref (self); + /* Error cases */ +fail_set_caps: + { + GST_WARNING_OBJECT (self, "failed to set caps"); + return FALSE; + } - return ret; -} +missing_fields: + { + GST_WARNING_OBJECT (self, "missing required fields"); + return FALSE; + } -static GstCaps * -gst_ducati_viddec_src_getcaps (GstPad * pad) -{ - GstCaps *caps = NULL; - GstCaps *outcaps = NULL; - int i; +pool_fail: + { + GST_WARNING_OBJECT (self, "Failed to negotiate a bufferpool"); + return FALSE; + } - caps = GST_PAD_CAPS (pad); - if (caps == NULL) { - outcaps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - return outcaps; +fail_video_info: + { + GST_WARNING_OBJECT (self, "Could not get GstVideoInfo from GstCaps"); + return FALSE; } +} - outcaps = gst_caps_new_empty (); +static gboolean +gst_ducati_viddec_sink_set_caps (GstDucatiVidDec * self, GstCaps * caps) +{ + gboolean ret = TRUE; + GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self); + gchar *lala; - /* allow -rowstrided and regular yuv */ - for (i = 0; i < gst_caps_get_size (caps); i++) { - GstStructure *structure; - GstStructure *modified_structure; - GValue value = { 0 }; + lala = gst_caps_to_string (caps); + GST_INFO_OBJECT (self, "setcaps (sink): %s", lala); + g_free (lala); - structure = gst_caps_get_structure (caps, i); - gst_caps_append_structure (outcaps, gst_structure_copy (structure)); - modified_structure = gst_structure_copy (structure); + ret = klass->set_sink_caps (self, caps); - if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - gst_structure_set_name (modified_structure, "video/x-raw-yuv-strided"); - g_value_init (&value, GST_TYPE_INT_RANGE); - gst_value_set_int_range (&value, 0, G_MAXINT); - gst_structure_set_value (modified_structure, "rowstride", &value); - gst_caps_append_structure (outcaps, modified_structure); - g_value_unset (&value); - } else { - gst_structure_set_name (modified_structure, "video/x-raw-yuv"); - gst_structure_remove_field (modified_structure, "rowstride"); - gst_caps_append_structure (outcaps, modified_structure); - } - } - return outcaps; + return ret; } + static gboolean gst_ducati_viddec_query (GstDucatiVidDec * self, GstPad * pad, GstQuery * query, gboolean * forward) @@ -864,16 +873,16 @@ gst_ducati_viddec_query (GstDucatiVidDec * self, GstPad * pad, gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { - 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; + /* 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; */ default: break; } @@ -883,16 +892,16 @@ gst_ducati_viddec_query (GstDucatiVidDec * self, GstPad * pad, } static gboolean -gst_ducati_viddec_src_query (GstPad * pad, GstQuery * query) +gst_ducati_viddec_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean res = TRUE, forward = TRUE; - GstDucatiVidDec *self = GST_DUCATIVIDDEC (GST_OBJECT_PARENT (pad)); + GstDucatiVidDec *self = GST_DUCATIVIDDEC (parent); GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self); GST_DEBUG_OBJECT (self, "query: %" GST_PTR_FORMAT, query); res = klass->query (self, pad, query, &forward); if (res && forward) - res = gst_pad_query_default (pad, query); + res = gst_pad_query_default (pad, parent, query); return res; } @@ -904,6 +913,8 @@ gst_ducati_viddec_do_qos (GstDucatiVidDec * self, GstBuffer * buf) GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self); gint64 diff; + return TRUE; + if (self->wait_keyframe) { if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) { GST_INFO_OBJECT (self, "skipping until the next keyframe"); @@ -959,29 +970,37 @@ gst_ducati_viddec_can_drop_frame (GstDucatiVidDec * self, GstBuffer * buf, } static GstFlowReturn -gst_ducati_viddec_chain (GstPad * pad, GstBuffer * buf) +gst_ducati_viddec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { - GstDucatiVidDec *self = GST_DUCATIVIDDEC (GST_OBJECT_PARENT (pad)); + GstDucatiVidDec *self = GST_DUCATIVIDDEC (parent); GstClockTime ts = GST_BUFFER_TIMESTAMP (buf); GstFlowReturn ret = GST_FLOW_OK; Int32 err; GstBuffer *outbuf = NULL; - GstCaps *outcaps = NULL; - gboolean decode; - if (G_UNLIKELY (!self->engine)) { - GST_ERROR_OBJECT (self, "no engine"); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } + if (G_UNLIKELY (!self->engine)) + goto no_engine; + + if (G_UNLIKELY (!self->codec) && !codec_create (self)) + goto no_codec; GST_DEBUG_OBJECT (self, "chain: %" GST_TIME_FORMAT " (%d bytes, flags %d)", - GST_TIME_ARGS (ts), GST_BUFFER_SIZE (buf), GST_BUFFER_FLAGS (buf)); + GST_TIME_ARGS (ts), gst_buffer_get_size (buf), GST_BUFFER_FLAGS (buf)); - decode = gst_ducati_viddec_do_qos (self, buf); - if (!decode) { - gst_buffer_unref (buf); - return GST_FLOW_OK; + if (!gst_ducati_viddec_do_qos (self, buf)) + goto drop_qos; + + if (G_UNLIKELY (gst_pad_check_reconfigure (self->srcpad))) { + GstCaps *caps; + gchar *lala; + + caps = gst_pad_get_current_caps (self->srcpad); + lala = gst_caps_to_string (caps); + GST_DEBUG_OBJECT (self, "Renegotiating to %s", lala); + g_free (lala); + + gst_ducati_viddec_negotiate_pool (self, caps); + gst_caps_unref (caps); } if (!self->need_out_buf) @@ -991,48 +1010,9 @@ gst_ducati_viddec_chain (GstPad * pad, GstBuffer * buf) * happens first: */ allocate_buffer: - ret = gst_pad_alloc_buffer (self->srcpad, 0, self->outsize, - GST_PAD_CAPS (self->srcpad), &outbuf); - if (ret != GST_FLOW_OK) { - GST_WARNING_OBJECT (self, "alloc_buffer failed %s", - gst_flow_get_name (ret)); - gst_buffer_unref (buf); - return ret; - } - - outcaps = GST_BUFFER_CAPS (outbuf); - if (outcaps && !gst_caps_is_equal (outcaps, GST_PAD_CAPS (self->srcpad))) { - GstStructure *s; - - GST_INFO_OBJECT (self, "doing upstream negotiation bufsize %d", - GST_BUFFER_SIZE (outbuf)); - - 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); - - GST_INFO_OBJECT (self, "outsize %d stride %d outcaps: %" GST_PTR_FORMAT, - self->outsize, self->stride, outcaps); - - gst_pad_set_caps (self->srcpad, outcaps); - - 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; - } - } - - if (G_UNLIKELY (!self->codec)) { - if (!codec_create (self)) { - GST_ERROR_OBJECT (self, "could not create codec"); - gst_buffer_unref (buf); - gst_buffer_unref (outbuf); - return GST_FLOW_ERROR; - } - } + outbuf = codec_buffer_pool_get (self); + if (G_UNLIKELY (outbuf == NULL)) + goto no_outbuf; GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf); @@ -1088,6 +1068,7 @@ have_out_buf: return ret; } + GST_DEBUG_OBJECT (self, "Resetting first_in_buffer"); self->first_in_buffer = FALSE; if (self->params->inputDataMode != IVIDEO_ENTIREFRAME) { @@ -1095,11 +1076,11 @@ have_out_buf: but it seems to be rare and for not many bytes */ GST_DEBUG_OBJECT (self, "Consumed %d/%d (%d) bytes, %d left", self->outArgs->bytesConsumed, self->in_size, - self->inArgs->numBytes, - self->in_size - self->outArgs->bytesConsumed); + self->inArgs->numBytes, self->in_size - self->outArgs->bytesConsumed); if (self->outArgs->bytesConsumed > 0) { if (self->outArgs->bytesConsumed > self->in_size) { - GST_WARNING_OBJECT (self, "Codec claims to have used more bytes than supplied"); + GST_WARNING_OBJECT (self, + "Codec claims to have used more bytes than supplied"); self->in_size = 0; } else { if (self->outArgs->bytesConsumed < self->in_size) { @@ -1122,7 +1103,7 @@ have_out_buf: if (buf) { GST_DEBUG_OBJECT (self, "found remaining data: %d bytes", - GST_BUFFER_SIZE (buf)); + gst_buffer_get_size (buf)); ts = GST_BUFFER_TIMESTAMP (buf); goto allocate_buffer; } @@ -1131,30 +1112,70 @@ have_out_buf: gst_ducati_viddec_codec_flush (self, FALSE); return GST_FLOW_OK; + + /* EARLY out */ + +drop_qos: + { + gst_buffer_unref (buf); + return GST_FLOW_OK; + } + + /* ERROR CASES */ + +no_engine: + { + GST_ERROR_OBJECT (self, "no engine"); + gst_buffer_unref (buf); + 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 -gst_ducati_viddec_event (GstPad * pad, GstEvent * event) +gst_ducati_viddec_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event) { - GstDucatiVidDec *self = GST_DUCATIVIDDEC (GST_OBJECT_PARENT (pad)); + GstDucatiVidDec *self = GST_DUCATIVIDDEC (parent); gboolean ret = TRUE; + gboolean drop = FALSE; GST_DEBUG_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: + case GST_EVENT_SEGMENT: { - gboolean update; - GstFormat fmt; - gint64 start, stop, time; - gdouble rate, arate; - - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt, - &start, &stop, &time); - gst_segment_set_newsegment_full (&self->segment, update, - rate, arate, fmt, start, stop, time); + gst_event_copy_segment (event, &self->segment); break; } + case GST_EVENT_CAPS: + { + GstCaps *caps, *curcaps; + + gst_event_parse_caps (event, &caps); + curcaps = gst_pad_get_current_caps (self->sinkpad); + if (!curcaps || !gst_caps_is_equal (curcaps, caps)) + ret = gst_ducati_viddec_sink_set_caps (self, caps); + else + GST_DEBUG_OBJECT (self, "Got identical caps ?"); + if (curcaps) + gst_caps_unref (curcaps); + + gst_event_unref (event); + drop = TRUE; + } + break; case GST_EVENT_EOS: if (!gst_ducati_viddec_codec_flush (self, TRUE)) { GST_ERROR_OBJECT (self, "could not flush on eos"); @@ -1176,7 +1197,7 @@ gst_ducati_viddec_event (GstPad * pad, GstEvent * event) break; } - if (ret) + if (ret && !drop) ret = gst_pad_push_event (self->srcpad, event); GST_LOG_OBJECT (self, "end"); @@ -1184,9 +1205,9 @@ gst_ducati_viddec_event (GstPad * pad, GstEvent * event) } static gboolean -gst_ducati_viddec_src_event (GstPad * pad, GstEvent * event) +gst_ducati_viddec_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { - GstDucatiVidDec *self = GST_DUCATIVIDDEC (GST_OBJECT_PARENT (pad)); + GstDucatiVidDec *self = GST_DUCATIVIDDEC (parent); gboolean ret = TRUE; GST_LOG_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event)); @@ -1198,7 +1219,7 @@ gst_ducati_viddec_src_event (GstPad * pad, GstEvent * event) GstClockTimeDiff diff; GstClockTime timestamp; - gst_event_parse_qos (event, &proportion, &diff, ×tamp); + gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp); GST_OBJECT_LOCK (self); self->qos_proportion = proportion; @@ -1262,7 +1283,7 @@ gst_ducati_viddec_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: self->interlaced = FALSE; - self->send_crop_event = TRUE; + self->calculate_crop = TRUE; gst_ducati_viddec_codec_flush (self, FALSE); break; case GST_STATE_CHANGE_READY_TO_NULL: @@ -1345,26 +1366,21 @@ gst_ducati_viddec_finalize (GObject * obj) G_OBJECT_CLASS (parent_class)->finalize (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); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_ducati_viddec_change_state); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&src_factory)); klass->parse_caps = GST_DEBUG_FUNCPTR (gst_ducati_viddec_parse_caps); klass->allocate_params = @@ -1391,20 +1407,16 @@ gst_ducati_viddec_init (GstDucatiVidDec * self, GstDucatiVidDecClass * klass) self->sinkpad = gst_pad_new_from_template (gst_element_class_get_pad_template (gstelement_class, "sink"), "sink"); - gst_pad_set_setcaps_function (self->sinkpad, - GST_DEBUG_FUNCPTR (gst_ducati_viddec_sink_setcaps)); gst_pad_set_chain_function (self->sinkpad, GST_DEBUG_FUNCPTR (gst_ducati_viddec_chain)); gst_pad_set_event_function (self->sinkpad, - GST_DEBUG_FUNCPTR (gst_ducati_viddec_event)); + GST_DEBUG_FUNCPTR (gst_ducati_viddec_sink_event)); self->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); gst_pad_set_event_function (self->srcpad, GST_DEBUG_FUNCPTR (gst_ducati_viddec_src_event)); gst_pad_set_query_function (self->srcpad, GST_DEBUG_FUNCPTR (gst_ducati_viddec_src_query)); - gst_pad_set_getcaps_function (self->srcpad, - GST_DEBUG_FUNCPTR (gst_ducati_viddec_src_getcaps)); gst_element_add_pad (GST_ELEMENT (self), self->sinkpad); gst_element_add_pad (GST_ELEMENT (self), self->srcpad); @@ -1422,7 +1434,7 @@ gst_ducati_viddec_init (GstDucatiVidDec * self, GstDucatiVidDecClass * klass) self->first_in_buffer = TRUE; self->first_out_buffer = TRUE; self->interlaced = FALSE; - self->send_crop_event = TRUE; + self->calculate_crop = TRUE; #ifdef USE_DTS_PTS_CODE self->dts_ridx = self->dts_widx = 0; diff --git a/src/gstducatividdec.h b/src/gstducatividdec.h index ea69e59..92d44b5 100644 --- a/src/gstducatividdec.h +++ b/src/gstducatividdec.h @@ -26,11 +26,10 @@ #include #include "gstducati.h" -#include "gstducatibufferpriv.h" +#include "gstducatiprivmeta.h" -#include +#include "gstdrmbufferpool.h" #include -#include G_BEGIN_DECLS @@ -44,13 +43,18 @@ G_BEGIN_DECLS typedef struct _GstDucatiVidDec GstDucatiVidDec; typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass; +typedef struct _PrivateCrop PrivateCrop; +struct _PrivateCrop { + gint top, left, width, height; +}; + struct _GstDucatiVidDec { GstElement parent; GstPad *sinkpad, *srcpad; - GstDRMBufferPool *pool; + GstBufferPool *pool; /* minimum output size required by the codec: */ gint outsize; @@ -82,14 +86,15 @@ struct _GstDucatiVidDec gint in_size; /* the crop to attach to output buffers: */ - GstVideoCrop *crop; + gboolean need_crop; + PrivateCrop crop; /* on first output buffer, we need to send crop info to sink.. and some * operations like flushing should be avoided if we haven't sent any * input buffers: */ gboolean first_out_buffer, first_in_buffer; - gboolean send_crop_event; + gboolean calculate_crop; GstSegment segment; gdouble qos_proportion; diff --git a/src/gstducatividenc.c b/src/gstducatividenc.c index 2c43719..97e7488 100644 --- a/src/gstducatividenc.c +++ b/src/gstducatividenc.c @@ -161,8 +161,9 @@ gst_ducati_videnc_class_init (GstDucatiVidEncClass * klass) G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_INTRA_INTERVAL, - g_param_spec_int ("intra-interval", "Intra-frame interval", "Interval between intra frames (keyframes)", 0, - INT_MAX, DEFAULT_INTRA_INTERVAL, G_PARAM_READWRITE)); + g_param_spec_int ("intra-interval", "Intra-frame interval", + "Interval between intra frames (keyframes)", 0, INT_MAX, + DEFAULT_INTRA_INTERVAL, G_PARAM_READWRITE)); } static void diff --git a/src/gstducativp6dec.c b/src/gstducativp6dec.c index d2bcc36..b341bbd 100644 --- a/src/gstducativp6dec.c +++ b/src/gstducativp6dec.c @@ -49,8 +49,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-vp6, " "width = (int)[ 16, 2048 ], " - "height = (int)[ 16, 2048 ], " - "framerate = (fraction)[ 0, max ];") + "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];") ); /* GstDucatiVidDec vmethod implementations */ @@ -102,7 +101,7 @@ gst_ducati_vp6dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) /* current codec version requires size prepended on input buffer: */ sz = GST_BUFFER_SIZE (buf); - push_input (vdec, (guint8 *)&sz, 4); + push_input (vdec, (guint8 *) & sz, 4); push_input (vdec, GST_BUFFER_DATA (buf), sz); gst_buffer_unref (buf); @@ -121,8 +120,7 @@ gst_ducati_vp6dec_base_init (gpointer gclass) gst_element_class_set_details_simple (element_class, "DucatiVP6Dec", "Codec/Decoder/Video", - "Decodes video in On2 VP6 format with ducati", - "Rob Clark "); + "Decodes video in On2 VP6 format with ducati", "Rob Clark "); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sink_factory)); @@ -137,12 +135,10 @@ gst_ducati_vp6dec_class_init (GstDucatiVP6DecClass * klass) GST_DEBUG_FUNCPTR (gst_ducati_vp6dec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_vp6dec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_vp6dec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_vp6dec_push_input); } static void -gst_ducati_vp6dec_init (GstDucatiVP6Dec * self, - GstDucatiVP6DecClass * gclass) +gst_ducati_vp6dec_init (GstDucatiVP6Dec * self, GstDucatiVP6DecClass * gclass) { } diff --git a/src/gstducativp7dec.c b/src/gstducativp7dec.c index 6e53303..a2baf4f 100644 --- a/src/gstducativp7dec.c +++ b/src/gstducativp7dec.c @@ -49,8 +49,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-vp7, " "width = (int)[ 16, 2048 ], " - "height = (int)[ 16, 2048 ], " - "framerate = (fraction)[ 0, max ];") + "height = (int)[ 16, 2048 ], " "framerate = (fraction)[ 0, max ];") ); /* GstDucatiVidDec vmethod implementations */ @@ -102,7 +101,7 @@ gst_ducati_vp7dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf) /* current codec version requires size prepended on input buffer: */ sz = GST_BUFFER_SIZE (buf); - push_input (vdec, (guint8 *)&sz, 4); + push_input (vdec, (guint8 *) & sz, 4); push_input (vdec, GST_BUFFER_DATA (buf), sz); gst_buffer_unref (buf); @@ -121,8 +120,7 @@ gst_ducati_vp7dec_base_init (gpointer gclass) gst_element_class_set_details_simple (element_class, "DucatiVP7Dec", "Codec/Decoder/Video", - "Decodes video in On2 VP7 format with ducati", - "Rob Clark "); + "Decodes video in On2 VP7 format with ducati", "Rob Clark "); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sink_factory)); @@ -137,12 +135,10 @@ gst_ducati_vp7dec_class_init (GstDucatiVP7DecClass * klass) GST_DEBUG_FUNCPTR (gst_ducati_vp7dec_update_buffer_size); bclass->allocate_params = GST_DEBUG_FUNCPTR (gst_ducati_vp7dec_allocate_params); - bclass->push_input = - GST_DEBUG_FUNCPTR (gst_ducati_vp7dec_push_input); + bclass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_vp7dec_push_input); } static void -gst_ducati_vp7dec_init (GstDucatiVP7Dec * self, - GstDucatiVP7DecClass * gclass) +gst_ducati_vp7dec_init (GstDucatiVP7Dec * self, GstDucatiVP7DecClass * gclass) { } -- cgit v1.2.3