diff options
author | Rob Clark <rob@ti.com> | 2010-12-04 09:50:36 -0600 |
---|---|---|
committer | Rob Clark <rob@ti.com> | 2010-12-04 20:01:09 -0600 |
commit | 63867fc44b8b3bd2d6afd05eeef646a1ccff2d03 (patch) | |
tree | ead088317b32a7e579ad7339bd8f127673510b85 | |
parent | 9f6cab5c40b4ae02a1faefd9510905f7b0b7ae1f (diff) |
mpeg2dec: add MPEG-2 support
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/gstducati.c | 2 | ||||
-rw-r--r-- | src/gstducati.h | 3 | ||||
-rw-r--r-- | src/gstducatimpeg2dec.c | 150 | ||||
-rw-r--r-- | src/gstducatimpeg2dec.h | 57 | ||||
-rw-r--r-- | src/gstducatividdec.c | 7 |
6 files changed, 222 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b336abf..6224927 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ noinst_HEADERS = \ gstducativp7dec.h \ gstducativp6dec.h \ gstducativc1dec.h \ + gstducatimpeg2dec.h \ gstducatimpeg4dec.h \ gstducatih264dec.h \ gstducatividdec.h \ @@ -15,6 +16,7 @@ libgstducati_la_SOURCES = \ gstducativp7dec.c \ gstducativp6dec.c \ gstducativc1dec.c \ + gstducatimpeg2dec.c \ gstducatimpeg4dec.c \ gstducatih264dec.c \ gstducatividdec.c \ @@ -24,5 +26,5 @@ libgstducati_la_SOURCES = \ # compiler and linker flags used to compile this plugin, set in configure.ac libgstducati_la_CFLAGS = $(GST_CFLAGS) $(MEMMGR_CFLAGS) $(LIBDCE_CFLAGS) libgstducati_la_LIBADD = $(GST_LIBS) $(MEMMGR_LIBS) $(LIBDCE_LIBS) -libgstducati_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_ALL_LDFLAGS) +libgstducati_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_ALL_LDFLAGS) --no-undefined libgstducati_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/src/gstducati.c b/src/gstducati.c index fe98e9a..1fcbaa7 100644 --- a/src/gstducati.c +++ b/src/gstducati.c @@ -25,6 +25,7 @@ #include "gstducatih264dec.h" #include "gstducatimpeg4dec.h" +#include "gstducatimpeg2dec.h" #include "gstducativc1dec.h" #include "gstducativp6dec.h" #include "gstducativp7dec.h" @@ -41,6 +42,7 @@ 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); diff --git a/src/gstducati.h b/src/gstducati.h index 9897eab..60cee7e 100644 --- a/src/gstducati.h +++ b/src/gstducati.h @@ -38,6 +38,9 @@ G_BEGIN_DECLS GST_DEBUG_CATEGORY_EXTERN (gst_ducati_debug); #define GST_CAT_DEFAULT gst_ducati_debug +/* align x to next highest multiple of 2^n */ +#define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1)) + void * gst_ducati_alloc_1d (gint sz); void * gst_ducati_alloc_2d (gint width, gint height); XDAS_Int16 gst_ducati_get_mem_type (SSPtr paddr); diff --git a/src/gstducatimpeg2dec.c b/src/gstducatimpeg2dec.c new file mode 100644 index 0000000..3dcbe0f --- /dev/null +++ b/src/gstducatimpeg2dec.c @@ -0,0 +1,150 @@ +/* + * GStreamer + * Copyright (c) 2010, Texas Instruments Incorporated + * + * 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 + */ + +/** + * SECTION:element-ducatimpeg2dec + * + * FIXME:Describe ducatimpeg2dec here. + * + * <refsect2> + * <title>Example launch line</title> + * |[ + * gst-launch -v -m fakesrc ! ducatimpeg2dec ! fakesink silent=TRUE + * ]| + * </refsect2> + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gst/gst.h> +#include <gst/video/video.h> + +#include "gstducatimpeg2dec.h" + +GST_BOILERPLATE (GstDucatiMpeg2Dec, gst_ducati_mpeg2dec, GstDucatiVidDec, + 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.. + "systemstream = (boolean)false, " + "width = (int)[ 64, 2048 ], " + "height = (int)[ 64, 2048 ], " + "framerate = (fraction)[ 0, max ];") + ); + +/* GstDucatiVidDec vmethod implementations */ + +static void +gst_ducati_mpeg2dec_update_buffer_size (GstDucatiVidDec * self) +{ + gint w = self->width; + gint h = self->height; + + /* calculate output buffer parameters: */ + self->padded_width = ALIGN2 (w, 7); + self->padded_height = h; + self->min_buffers = 8; +} + +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, + sizeof (IMPEG2VDEC_Params), sizeof (IMPEG2VDEC_DynamicParams), + sizeof (IMPEG2VDEC_Status), sizeof (IMPEG2VDEC_InArgs), + sizeof (IMPEG2VDEC_OutArgs)); + + if (ret) { + IMPEG2VDEC_Params *params = (IMPEG2VDEC_Params *) self->params; + self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO; + } + + 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)) { + GST_DEBUG_OBJECT (self, "skipping codec_data buffer"); + self->prepend_codec_data = TRUE; + } else { + 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)); + self->prepend_codec_data = FALSE; + } + push_input (vdec, data, sz); + } + + gst_buffer_unref (buf); + + return NULL; +} + +/* GObject vmethod implementations */ + +static void +gst_ducati_mpeg2dec_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "DucatiMpeg2Dec", + "Codec/Decoder/Video", + "Decodes video in MPEG-2 format with ducati", + "Rob Clark <rob@ti.com>"); + + 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); +} + +static void +gst_ducati_mpeg2dec_init (GstDucatiMpeg2Dec * self, + GstDucatiMpeg2DecClass * gclass) +{ +} diff --git a/src/gstducatimpeg2dec.h b/src/gstducatimpeg2dec.h new file mode 100644 index 0000000..cddd364 --- /dev/null +++ b/src/gstducatimpeg2dec.h @@ -0,0 +1,57 @@ +/* + * GStreamer + * Copyright (c) 2010, Texas Instruments Incorporated + * + * 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 __GST_DUCATIMPEG2DEC_H__ +#define __GST_DUCATIMPEG2DEC_H__ + +#include <gst/gst.h> + +#include "gstducatividdec.h" + +#include <ti/sdo/codecs/mpeg2vdec/impeg2vdec.h> + + +G_BEGIN_DECLS + +#define GST_TYPE_DUCATIMPEG2DEC (gst_ducati_mpeg2dec_get_type()) +#define GST_DUCATIMPEG2DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_DUCATIMPEG2DEC, GstDucatiMpeg2Dec)) +#define GST_DUCATIMPEG2DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_DUCATIMPEG2DEC, GstDucatiMpeg2DecClass)) +#define GST_IS_DUCATIMPEG2DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_DUCATIMPEG2DEC)) +#define GST_IS_DUCATIMPEG2DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_DUCATIMPEG2DEC)) + +typedef struct _GstDucatiMpeg2Dec GstDucatiMpeg2Dec; +typedef struct _GstDucatiMpeg2DecClass GstDucatiMpeg2DecClass; + +struct _GstDucatiMpeg2Dec +{ + GstDucatiVidDec parent; + + gboolean prepend_codec_data; +}; + +struct _GstDucatiMpeg2DecClass +{ + GstDucatiVidDecClass parent_class; +}; + +GType gst_ducati_mpeg2dec_get_type (void); + +G_END_DECLS + +#endif /* __GST_DUCATIMPEG2DEC_H__ */ diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c index 94b6043..dca6162 100644 --- a/src/gstducatividdec.c +++ b/src/gstducatividdec.c @@ -563,6 +563,13 @@ gst_ducati_viddec_chain (GstPad * pad, GstBuffer * buf) self->in_size = 0; buf = GST_DUCATIVIDDEC_GET_CLASS (self)->push_input (self, buf); + + if (self->in_size == 0) { + GST_DEBUG_OBJECT (self, "no input, skipping process"); + gst_buffer_unref (outbuf); + return GST_FLOW_OK; + } + self->inArgs->numBytes = self->in_size; self->inBufs->descs[0].bufSize.bytes = self->in_size; |