summaryrefslogtreecommitdiffstats
path: root/ext/dirac
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2004-09-23 14:59:22 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2004-09-23 14:59:22 +0000
commit0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea (patch)
tree6f0b0703d63c693bfdb2dcde29fc378bba12b561 /ext/dirac
parent18c8223577d50dcee845b5920b3b8dbaee45a1bb (diff)
downloadgst-plugins-bad-0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea.tar.gz
gst-plugins-bad-0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea.tar.bz2
gst-plugins-bad-0771c17fede0ac6ae1a531a4d4d7d68fc72b24ea.zip
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/dirac')
-rw-r--r--ext/dirac/Makefile.am11
-rw-r--r--ext/dirac/gstdirac.cc12
-rw-r--r--ext/dirac/gstdiracdec.cc287
-rw-r--r--ext/dirac/gstdiracdec.h69
4 files changed, 294 insertions, 85 deletions
diff --git a/ext/dirac/Makefile.am b/ext/dirac/Makefile.am
index f4928f17..0b047493 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 ba6fcac7..6f5dda21 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 5a767c45..6a9c3abf 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 00000000..88adc513
--- /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__ */