diff options
author | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | 2004-09-23 14:59:22 +0000 |
---|---|---|
committer | Ronald S. Bultje <rbultje@ronald.bitfreak.net> | 2004-09-23 14:59:22 +0000 |
commit | 0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea (patch) | |
tree | 6f0b0703d63c693bfdb2dcde29fc378bba12b561 /ext | |
parent | 18c8223577d50dcee845b5920b3b8dbaee45a1bb (diff) | |
download | gstreamer-plugins-bad-0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea.tar.gz |
ext/dirac/: Do something. Don't actually know if this works because I don't have a demuxer yet.
Original commit message from CVS:
* ext/dirac/Makefile.am:
* ext/dirac/gstdirac.cc:
* ext/dirac/gstdiracdec.cc:
* ext/dirac/gstdiracdec.h:
Do something. Don't actually know if this works because I don't
have a demuxer yet.
* ext/gsm/gstgsmdec.c: (gst_gsmdec_getcaps):
Add channels=1 to caps returned from _getcaps().
* ext/ogg/gstogmparse.c: (gst_ogm_audio_parse_get_type),
(gst_ogm_video_parse_get_type), (gst_ogm_audio_parse_base_init),
(gst_ogm_video_parse_base_init), (gst_ogm_parse_init),
(gst_ogm_audio_parse_init), (gst_ogm_video_parse_init),
(gst_ogm_parse_sink_convert), (gst_ogm_parse_chain),
(gst_ogm_parse_change_state):
Separate between audio/video so ogmaudioparse actually uses the
audio pad templates. Both audio and video work now, including
autoplugging. Also use sometimes-srcpad hack.
* gst-libs/gst/riff/riff-read.c: (gst_riff_read_seek):
Handle events better. Don't hang on infinite loops.
* gst/avi/gstavidemux.c: (gst_avi_demux_class_init),
(gst_avi_demux_init), (gst_avi_demux_reset),
(gst_avi_demux_src_convert), (gst_avi_demux_handle_src_query),
(gst_avi_demux_stream_header), (gst_avi_demux_stream_data),
(gst_avi_demux_change_state):
* gst/avi/gstavidemux.h:
Improve A/V sync. Still not perfect.
* gst/matroska/ebml-read.c: (gst_ebml_read_seek),
(gst_ebml_read_skip):
Handle events better.
* gst/qtdemux/qtdemux.c: (gst_qtdemux_handle_sink_event),
(gst_qtdemux_loop_header), (qtdemux_parse_trak),
(qtdemux_audio_caps):
Add IMA4. Improve event handling. Save offset after a seek when
the headers are at the end of the file so that we don't end up in
an infinite loop.
* gst/typefind/gsttypefindfunctions.c: (qt_type_find):
Add low-priority typefind support for files with no length.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/dirac/Makefile.am | 11 | ||||
-rw-r--r-- | ext/dirac/gstdirac.cc | 12 | ||||
-rw-r--r-- | ext/dirac/gstdiracdec.cc | 287 | ||||
-rw-r--r-- | ext/dirac/gstdiracdec.h | 69 | ||||
-rw-r--r-- | ext/gsm/gstgsmdec.c | 1 |
5 files changed, 295 insertions, 85 deletions
diff --git a/ext/dirac/Makefile.am b/ext/dirac/Makefile.am index f4928f17a..0b0474930 100644 --- a/ext/dirac/Makefile.am +++ b/ext/dirac/Makefile.am @@ -1,9 +1,12 @@ - plugin_LTLIBRARIES = libgstdirac.la -libgstdirac_la_SOURCES = gstdirac.cc gstdiracdec.cc -#gstdiracenc.c +libgstdirac_la_SOURCES = \ + gstdirac.cc \ + gstdiracdec.cc + libgstdirac_la_CXXFLAGS = $(GST_CFLAGS) $(DIRAC_CFLAGS) -libgstdirac_la_LIBADD = $(DIRAC_LIBS) +libgstdirac_la_LIBADD = $(DIRAC_LIBS) -lz -lm libgstdirac_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +noinst_HEADERS = \ + gstdiracdec.h diff --git a/ext/dirac/gstdirac.cc b/ext/dirac/gstdirac.cc index ba6fcac72..6f5dda217 100644 --- a/ext/dirac/gstdirac.cc +++ b/ext/dirac/gstdirac.cc @@ -16,16 +16,14 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ + #ifdef HAVE_CONFIG_H -#include <config.h> +#include "config.h" #endif -#include <gst/gst.h> - -extern GType gst_diracdec_get_type (void); - -//extern GType gst_diracenc_get_type (void); +#include <gst/gst.h> +#include "gstdiracdec.h" static gboolean plugin_init (GstPlugin * plugin) @@ -38,7 +36,7 @@ plugin_init (GstPlugin * plugin) #endif if (!gst_element_register (plugin, "diracdec", GST_RANK_PRIMARY, - gst_diracdec_get_type ())) { + GST_TYPE_DIRACDEC)) { return FALSE; } diff --git a/ext/dirac/gstdiracdec.cc b/ext/dirac/gstdiracdec.cc index 5a767c455..6a9c3abf6 100644 --- a/ext/dirac/gstdiracdec.cc +++ b/ext/dirac/gstdiracdec.cc @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2004 David A. Schleef <ds@schleef.org> + * Copyright (C) 2004 Ronald S. Bultje <rbultje@ronald.bitfreak.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,54 +23,19 @@ #include "config.h" #endif -#include <gst/gst.h> -#include <gst/video/video.h> - -#include <libdirac_decoder/seq_decompress.h> -#include <libdirac_common/pic_io.h> - -#define GST_TYPE_DIRACDEC \ - (gst_diracdec_get_type()) -#define GST_DIRACDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DIRACDEC,GstDiracDec)) -#define GST_DIRACDEC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DIRACDEC,GstDiracDec)) -#define GST_IS_DIRACDEC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DIRACDEC)) -#define GST_IS_DIRACDEC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIRACDEC)) - -typedef struct _GstDiracDec GstDiracDec; -typedef struct _GstDiracDecClass GstDiracDecClass; - -struct _GstDiracDec -{ - GstElement element; - - /* pads */ - GstPad *sinkpad, *srcpad; - - SequenceDecompressor *decompress; - - std::istream * input_stream; - PicOutput *output_image; - -}; +#include <string.h> -struct _GstDiracDecClass -{ - GstElementClass parent_class; -}; - -GType gst_diracdec_get_type (void); +#include <gst/video/video.h> +#include "gstdiracdec.h" /* elementfactory information */ -GstElementDetails gst_diracdec_details = { +static GstElementDetails gst_diracdec_details = { "Dirac stream decoder", "Codec/Decoder/Video", "Decode DIRAC streams", - "David Schleef <ds@schleef.org>", + "David Schleef <ds@schleef.org>\n" + "Ronald Bultje <rbultje@ronald.bitfreak.net>", }; GST_DEBUG_CATEGORY (diracdec_debug); @@ -90,9 +56,10 @@ enum static void gst_diracdec_base_init (gpointer g_class); static void gst_diracdec_class_init (GstDiracDec * klass); static void gst_diracdec_init (GstDiracDec * diracdec); +static void gst_diracdec_dispose (GObject * object); -static void gst_diracdec_chain (GstPad * pad, GstData * _data); -static GstPadLinkReturn gst_diracdec_link (GstPad * pad, const GstCaps * caps); +static void gst_diracdec_chain (GstPad * pad, GstData * data); +static GstElementStateReturn gst_diracdec_change_state (GstElement * element); static GstElementClass *parent_class = NULL; @@ -120,6 +87,7 @@ gst_diracdec_get_type (void) g_type_register_static (GST_TYPE_ELEMENT, "GstDiracDec", &diracdec_info, (GTypeFlags) 0); } + return diracdec_type; } @@ -127,16 +95,15 @@ static GstStaticPadTemplate gst_diracdec_src_pad_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) + /* FIXME: 444 (planar? packed?), 411 (Y41B? Y41P?) */ + GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, Y800 }")) ); static GstStaticPadTemplate gst_diracdec_sink_pad_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/dirac, " - "width = (int) [ 16, 4096 ], " - "height = (int) [ 16, 4096 ], " "framerate = (double) [ 1, MAX ]") + GST_STATIC_CAPS ("video/x-dirac") ); static void @@ -154,29 +121,34 @@ gst_diracdec_base_init (gpointer g_class) static void gst_diracdec_class_init (GstDiracDec * klass) { - GstElementClass *gstelement_class; - - gstelement_class = (GstElementClass *) klass; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT)); + gobject_class->dispose = gst_diracdec_dispose; + element_class->change_state = gst_diracdec_change_state; + GST_DEBUG_CATEGORY_INIT (diracdec_debug, "diracdec", 0, "DIRAC decoder"); } static void -gst_diracdec_init (GstDiracDec * diracdec) +gst_diracdec_dispose (GObject * object) { - SeqParams params; + G_OBJECT_CLASS (parent_class)->dispose (object); +} +static void +gst_diracdec_init (GstDiracDec * diracdec) +{ GST_DEBUG ("gst_diracdec_init: initializing"); /* create the sink and src pads */ diracdec->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&gst_diracdec_sink_pad_template), "sink"); - gst_element_add_pad (GST_ELEMENT (diracdec), diracdec->sinkpad); gst_pad_set_chain_function (diracdec->sinkpad, gst_diracdec_chain); - gst_pad_set_link_function (diracdec->sinkpad, gst_diracdec_link); + gst_element_add_pad (GST_ELEMENT (diracdec), diracdec->sinkpad); diracdec->srcpad = gst_pad_new_from_template (gst_static_pad_template_get @@ -184,37 +156,204 @@ gst_diracdec_init (GstDiracDec * diracdec) gst_pad_use_explicit_caps (diracdec->srcpad); gst_element_add_pad (GST_ELEMENT (diracdec), diracdec->srcpad); - //diracdec->input_stream = new std::istream (); - diracdec->input_stream = NULL; - diracdec->decompress = - new SequenceDecompressor (diracdec->input_stream, FALSE); - diracdec->output_image = new PicOutput ("moo", params, (bool) FALSE); + /* no capsnego done yet */ + diracdec->width = -1; + diracdec->height = -1; + diracdec->fps = 0; + diracdec->fcc = 0; } -static GstPadLinkReturn -gst_diracdec_link (GstPad * pad, const GstCaps * caps) +static guint32 +gst_diracdec_chroma_to_fourcc (dirac_chroma_t chroma) { - //GstDiracDec *diracdec = GST_DIRACDEC (gst_pad_get_parent (pad)); - GstStructure *structure; + guint32 fourcc = 0; + + switch (chroma) { + case Yonly: + fourcc = GST_MAKE_FOURCC ('Y', '8', '0', '0'); + break; + case format422: + fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'); + break; + /* planar? */ + case format420: + case format444: + case format411: + default: + break; + } - //GstCaps *srccaps; + return fourcc; +} - structure = gst_caps_get_structure (caps, 0); +static gboolean +gst_diracdec_link (GstDiracDec * diracdec, + gint width, gint height, gdouble fps, guint32 fourcc) +{ + GstCaps *caps; + + if (width == diracdec->width && + height == diracdec->height && + fps == diracdec->fps && fourcc == diracdec->fcc) { + return TRUE; + } - return GST_PAD_LINK_OK; + if (!fourcc) { + g_warning ("Chroma not supported\n"); + return FALSE; + } + + caps = gst_caps_new_simple ("video/x-raw-yuv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "format", GST_TYPE_FOURCC, fourcc, "framerate", G_TYPE_DOUBLE, fps, NULL); + + if (gst_pad_set_explicit_caps (diracdec->srcpad, caps)) { + diracdec->width = width; + diracdec->height = height; + switch (fourcc) { + case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): + diracdec->size = width * height * 2; + break; + case GST_MAKE_FOURCC ('Y', '8', '0', '0'): + diracdec->size = width * height; + break; + } + diracdec->fcc = fourcc; + diracdec->fps = fps; + + return TRUE; + } + + return FALSE; } static void gst_diracdec_chain (GstPad * pad, GstData * _data) { - GstBuffer *buf = GST_BUFFER (_data); - GstDiracDec *diracdec; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); + GstDiracDec *diracdec = GST_DIRACDEC (gst_pad_get_parent (pad)); + GstBuffer *buf = GST_BUFFER (_data), *out; + gboolean c = TRUE; + + /* get state and do something */ + while (c) { + switch (dirac_parse (diracdec->decoder)) { + case STATE_BUFFER: + if (buf) { + /* provide data to decoder */ + dirac_buffer (diracdec->decoder, GST_BUFFER_DATA (buf), + GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf)); + gst_buffer_unref (buf); + buf = NULL; + } else { + /* need more data */ + c = FALSE; + } + break; + + case STATE_SEQUENCE:{ + guint8 *buf[3]; + + /* start-of-sequence - allocate buffer */ + if (!gst_diracdec_link (diracdec, + diracdec->decoder->seq_params.width, + diracdec->decoder->seq_params.height, + gst_diracdec_chroma_to_fourcc (diracdec->decoder->seq_params. + chroma), diracdec->decoder->seq_params.frame_rate)) { + GST_ELEMENT_ERROR (diracdec, CORE, NEGOTIATION, (NULL), + ("Failed to set caps to %dx%d @ %d fps (format=" GST_FOURCC_FORMAT + "/%d)", diracdec->decoder->seq_params.width, + diracdec->decoder->seq_params.height, + diracdec->decoder->seq_params.frame_rate, + gst_diracdec_chroma_to_fourcc (diracdec->decoder->seq_params. + chroma), diracdec->decoder->seq_params.chroma)); + c = FALSE; + break; + } + + g_free (diracdec->decoder->fbuf->buf[0]); + g_free (diracdec->decoder->fbuf->buf[1]); + g_free (diracdec->decoder->fbuf->buf[2]); + buf[0] = (guchar *) g_malloc (diracdec->decoder->seq_params.width * + diracdec->decoder->seq_params.height); + if (diracdec->decoder->seq_params.chroma != Yonly) { + buf[1] = + (guchar *) g_malloc (diracdec->decoder->seq_params.chroma_width * + diracdec->decoder->seq_params.chroma_height); + buf[2] = + (guchar *) g_malloc (diracdec->decoder->seq_params.chroma_width * + diracdec->decoder->seq_params.chroma_height); + } + dirac_set_buf (diracdec->decoder, buf, NULL); + break; + } + + case STATE_SEQUENCE_END: + /* end-of-sequence - free buffer */ + g_free (diracdec->decoder->fbuf->buf[0]); + diracdec->decoder->fbuf->buf[0] = NULL; + g_free (diracdec->decoder->fbuf->buf[1]); + diracdec->decoder->fbuf->buf[1] = NULL; + g_free (diracdec->decoder->fbuf->buf[2]); + diracdec->decoder->fbuf->buf[2] = NULL; + break; + + case STATE_PICTURE_START: + /* start of one picture */ + break; + + case STATE_PICTURE_AVAIL: + /* one picture is decoded */ + out = gst_pad_alloc_buffer (diracdec->srcpad, 0, diracdec->size); + memcpy (GST_BUFFER_DATA (out), diracdec->decoder->fbuf->buf[0], + diracdec->width * diracdec->height); + if (diracdec->fcc != GST_MAKE_FOURCC ('Y', '8', '0', '0')) { + memcpy (GST_BUFFER_DATA (out) + (diracdec->width * + diracdec->height), diracdec->decoder->fbuf->buf[1], + diracdec->decoder->seq_params.chroma_width * + diracdec->decoder->seq_params.chroma_height); + memcpy (GST_BUFFER_DATA (out) + + (diracdec->decoder->seq_params.chroma_width * + diracdec->decoder->seq_params.chroma_height) + + (diracdec->width * diracdec->height), + diracdec->decoder->fbuf->buf[2], + diracdec->decoder->seq_params.chroma_width * + diracdec->decoder->seq_params.chroma_height); + } + GST_BUFFER_TIMESTAMP (out) = (guint64) (GST_SECOND * + diracdec->decoder->frame_params.fnum / diracdec->fps); + GST_BUFFER_DURATION (out) = (guint64) (GST_SECOND / diracdec->fps); + gst_pad_push (diracdec->srcpad, GST_DATA (out)); + break; + + case STATE_INVALID: + default: + GST_ELEMENT_ERROR (diracdec, LIBRARY, TOO_LAZY, (NULL), (NULL)); + c = FALSE; + break; + } + } +} - diracdec = GST_DIRACDEC (GST_OBJECT_PARENT (pad)); +static GstElementStateReturn +gst_diracdec_change_state (GstElement * element) +{ + GstDiracDec *diracdec = GST_DIRACDEC (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + if (!(diracdec->decoder = dirac_decoder_init (0))) + return GST_STATE_FAILURE; + break; + case GST_STATE_READY_TO_NULL: + dirac_decoder_close (diracdec->decoder); + diracdec->width = diracdec->height = -1; + diracdec->fps = 0.; + diracdec->fcc = 0; + break; + default: + break; + } - gst_buffer_unref (buf); + return parent_class->change_state (element); } diff --git a/ext/dirac/gstdiracdec.h b/ext/dirac/gstdiracdec.h new file mode 100644 index 000000000..88adc5139 --- /dev/null +++ b/ext/dirac/gstdiracdec.h @@ -0,0 +1,69 @@ +/* GStreamer + * Copyright (C) 2004 David A. Schleef <ds@schleef.org> + * Copyright (C) 2004 Ronald S. Bultje <rbultje@ronald.bitfreak.net> + * + * 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_DIRACDEC_H__ +#define __GST_DIRACDEC_H__ + +#include <gst/gst.h> + +#include <libdirac_decoder/decoder_types.h> +#include <libdirac_decoder/dirac_parser.h> + +G_BEGIN_DECLS + +#define GST_TYPE_DIRACDEC \ + (gst_diracdec_get_type()) +#define GST_DIRACDEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DIRACDEC,GstDiracDec)) +#define GST_DIRACDEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DIRACDEC,GstDiracDec)) +#define GST_IS_DIRACDEC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DIRACDEC)) +#define GST_IS_DIRACDEC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIRACDEC)) + +typedef struct _GstDiracDec GstDiracDec; +typedef struct _GstDiracDecClass GstDiracDecClass; + +struct _GstDiracDec +{ + GstElement element; + + /* pads */ + GstPad *sinkpad, *srcpad; + + dirac_decoder_t *decoder; + + /* size is size of buf */ + gint width, height, size; + gdouble fps; + guint32 fcc; +}; + +struct _GstDiracDecClass +{ + GstElementClass parent_class; +}; + +GType gst_diracdec_get_type (void); + +G_END_DECLS + +#endif /* __GST_DIRACDEC_H__ */ diff --git a/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c index 8e184121a..26b6d02cb 100644 --- a/ext/gsm/gstgsmdec.c +++ b/ext/gsm/gstgsmdec.c @@ -173,6 +173,7 @@ gst_gsmdec_getcaps (GstPad * pad) 0), "rate"); gst_structure_set_value (gst_caps_get_structure (basecaps, 0), "rate", rate_value); + gst_caps_set_simple (basecaps, "channels", G_TYPE_INT, 1, NULL); return basecaps; } |