CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Thu Sep 23 2004 07:59:34 PDT Log message: * 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. Modified files: . : ChangeLog ext/dirac : Makefile.am gstdirac.cc gstdiracdec.cc ext/gsm : gstgsmdec.c ext/ogg : gstogmparse.c gst-libs/gst/riff: riff-read.c gst/avi : gstavidemux.c gstavidemux.h gst/matroska : ebml-read.c gst/qtdemux : qtdemux.c gst/typefind : gsttypefindfunctions.c Added files: ext/dirac : gstdiracdec.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1083&r2=1.1084 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/dirac/Makefile.am.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/dirac/gstdirac.cc.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/dirac/gstdiracdec.cc.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/dirac/gstdiracdec.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/gsm/gstgsmdec.c.diff?r1=1.23&r2=1.24 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ogg/gstogmparse.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst-libs/gst/riff/riff-read.c.diff?r1=1.28&r2=1.29 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/avi/gstavidemux.c.diff?r1=1.112&r2=1.113 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/avi/gstavidemux.h.diff?r1=1.23&r2=1.24 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/matroska/ebml-read.c.diff?r1=1.11&r2=1.12 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/qtdemux/qtdemux.c.diff?r1=1.65&r2=1.66 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/typefind/gsttypefindfunctions.c.diff?r1=1.48&r2=1.49 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1083 retrieving revision 1.1084 diff -u -d -r1.1083 -r1.1084 --- ChangeLog 23 Sep 2004 12:11:15 -0000 1.1083 +++ ChangeLog 23 Sep 2004 14:59:21 -0000 1.1084 @@ -1,3 +1,43 @@ +2004-09-23 Ronald S. Bultje <rb...@ro...> + + * 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. 2004-09-23 Zaheer Abbas Merali <zaheerabbas at merali dot org> * testsuite/multifilesink/Makefile.am: Index: Makefile.am RCS file: /home/cvs/gstreamer/gst-plugins/ext/dirac/Makefile.am,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Makefile.am 11 May 2004 02:30:16 -0000 1.1 +++ Makefile.am 23 Sep 2004 14:59:21 -0000 1.2 @@ -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 Index: gstdirac.cc RCS file: /home/cvs/gstreamer/gst-plugins/ext/dirac/gstdirac.cc,v --- gstdirac.cc 11 May 2004 02:30:16 -0000 1.1 +++ gstdirac.cc 23 Sep 2004 14:59:21 -0000 1.2 @@ -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 @@ if (!gst_element_register (plugin, "diracdec", GST_RANK_PRIMARY, - gst_diracdec_get_type ())) { + GST_TYPE_DIRACDEC)) { return FALSE; } Index: gstdiracdec.cc RCS file: /home/cvs/gstreamer/gst-plugins/ext/dirac/gstdiracdec.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gstdiracdec.cc 15 Sep 2004 19:29:24 -0000 1.4 +++ gstdiracdec.cc 23 Sep 2004 14:59:21 -0000 1.5 @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2004 David A. Schleef <ds...@sc...> + * Copyright (C) 2004 Ronald S. Bultje <rb...@ro...> * * 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" -#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; -}; -struct _GstDiracDecClass - GstElementClass parent_class; +#include <string.h> -GType gst_diracdec_get_type (void); +#include <gst/video/video.h> /* elementfactory information */ -GstElementDetails gst_diracdec_details = { +static GstElementDetails gst_diracdec_details = { "Dirac stream decoder", "Codec/Decoder/Video", "Decode DIRAC streams", - "David Schleef <ds...@sc...>", + "David Schleef <ds...@sc...>\n" + "Ronald Bultje <rb...@ro...>", }; GST_DEBUG_CATEGORY (diracdec_debug); @@ -90,9 +56,10 @@ 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 @@ g_type_register_static (GST_TYPE_ELEMENT, "GstDiracDec", &diracdec_info, (GTypeFlags) 0); return diracdec_type; } @@ -127,16 +95,15 @@ 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_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_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"); -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 = @@ -184,37 +156,204 @@ 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; - //GstCaps *srccaps; + switch (chroma) { + case Yonly: + fourcc = GST_MAKE_FOURCC ('Y', '8', '0', '0'); + break; + case format422: + fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'); + /* planar? */ + case format420: + case format444: + case format411: + default: + } - structure = gst_caps_get_structure (caps, 0); + return fourcc; - return GST_PAD_LINK_OK; +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; + 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; + } + diracdec->fcc = fourcc; + diracdec->fps = fps; + return FALSE; gst_diracdec_chain (GstPad * pad, GstData * _data) - GstBuffer *buf = GST_BUFFER (_data); - GstDiracDec *diracdec; + GstDiracDec *diracdec = GST_DIRACDEC (gst_pad_get_parent (pad)); + GstBuffer *buf = GST_BUFFER (_data), *out; + gboolean c = TRUE; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); + /* 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; + } - diracdec = GST_DIRACDEC (GST_OBJECT_PARENT (pad)); + case STATE_SEQUENCE:{ + guint8 *buf[3]; - gst_buffer_unref (buf); + /* 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)); + 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] = + dirac_set_buf (diracdec->decoder, buf, NULL); + } + case STATE_SEQUENCE_END: + /* end-of-sequence - free buffer */ + diracdec->decoder->fbuf->buf[0] = NULL; + diracdec->decoder->fbuf->buf[1] = NULL; + diracdec->decoder->fbuf->buf[2] = NULL; + case STATE_PICTURE_START: + /* start of one picture */ + 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 * + 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], + 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)); + case STATE_INVALID: + default: + GST_ELEMENT_ERROR (diracdec, LIBRARY, TOO_LAZY, (NULL), (NULL)); + c = FALSE; +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; + case GST_STATE_READY_TO_NULL: + dirac_decoder_close (diracdec->decoder); + diracdec->width = diracdec->height = -1; + diracdec->fps = 0.; + diracdec->fcc = 0; + return parent_class->change_state (element); --- NEW FILE: gstdiracdec.h --- /* GStreamer * Copyright (C) 2004 David A. Schleef <ds...@sc...> * Copyright (C) 2004 Ronald S. Bultje <rb...@ro...> * * 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__ */ Index: gstgsmdec.c RCS file: /home/cvs/gstreamer/gst-plugins/ext/gsm/gstgsmdec.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstgsmdec.c 21 May 2004 23:28:54 -0000 1.23 +++ gstgsmdec.c 23 Sep 2004 14:59:21 -0000 1.24 @@ -173,6 +173,7 @@ 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; Index: gstogmparse.c RCS file: /home/cvs/gstreamer/gst-plugins/ext/ogg/gstogmparse.c,v --- gstogmparse.c 20 Sep 2004 12:40:40 -0000 1.1 +++ gstogmparse.c 23 Sep 2004 14:59:21 -0000 1.2 @@ -32,7 +32,12 @@ #define GST_CAT_DEFAULT gst_ogm_parse_debug #define GST_TYPE_OGM_VIDEO_PARSE (gst_ogm_video_parse_get_type()) +#define GST_IS_OGM_VIDEO_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_VIDEO_PARSE)) #define GST_TYPE_OGM_AUDIO_PARSE (gst_ogm_audio_parse_get_type()) +#define GST_IS_OGM_AUDIO_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_AUDIO_PARSE)) #define GST_TYPE_OGM_PARSE (gst_ogm_parse_get_type()) #define GST_OGM_PARSE(obj) \ @@ -43,6 +48,8 @@ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_OGM_PARSE)) #define GST_IS_OGM_PARSE_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_OGM_PARSE)) +#define GST_OGM_PARSE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_OGM_PARSE, GstOgmParseClass)) typedef struct _stream_header_video @@ -89,9 +96,13 @@ /* pads */ GstPad *srcpad, *sinkpad; + GstPadTemplate *srcpadtempl; /* audio or video */ stream_header hdr; + /* expected next granulepos (used for timestamp guessing) */ + guint64 next_granulepos; } GstOgmParse; typedef struct _GstOgmParseClass @@ -115,6 +126,8 @@ static void gst_ogm_video_parse_base_init (GstOgmParseClass * klass); static void gst_ogm_parse_class_init (GstOgmParseClass * klass); static void gst_ogm_parse_init (GstOgmParse * ogm); +static void gst_ogm_video_parse_init (GstOgmParse * ogm); +static void gst_ogm_audio_parse_init (GstOgmParse * ogm); static const GstFormat *gst_ogm_parse_get_sink_formats (GstPad * pad); static gboolean gst_ogm_parse_sink_convert (GstPad * pad, GstFormat src_format, @@ -167,7 +180,7 @@ NULL, sizeof (GstOgmParse), 0, - NULL, + (GInstanceInitFunc) gst_ogm_audio_parse_init, }; ogm_audio_parse_type = @@ -193,7 +206,7 @@ + (GInstanceInitFunc) gst_ogm_video_parse_init, ogm_video_parse_type = @@ -220,7 +233,7 @@ gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&ogm_audio_parse_sink_template_factory)); audio_src_templ = gst_pad_template_new ("src", - GST_PAD_SRC, GST_PAD_ALWAYS, caps); + GST_PAD_SRC, GST_PAD_SOMETIMES, caps); gst_element_class_add_pad_template (element_class, audio_src_templ); @@ -240,7 +253,7 @@ gst_static_pad_template_get (&ogm_video_parse_sink_template_factory)); video_src_templ = gst_pad_template_new ("src", gst_element_class_add_pad_template (element_class, video_src_templ); @@ -257,27 +270,51 @@ gst_ogm_parse_init (GstOgmParse * ogm) + /* initalize */ + memset (&ogm->hdr, 0, sizeof (ogm->hdr)); + ogm->next_granulepos = 0; +gst_ogm_audio_parse_init (GstOgmParse * ogm) GstPadTemplate *templ; /* create the pads */ - templ = gst_static_pad_template_get ( - (G_OBJECT_TYPE (ogm) == GST_TYPE_OGM_AUDIO_PARSE) ? - &ogm_audio_parse_sink_template_factory : - &ogm_video_parse_sink_template_factory); + templ = gst_static_pad_template_get (&ogm_audio_parse_sink_template_factory); ogm->sinkpad = gst_pad_new_from_template (templ, "sink"); gst_pad_set_convert_function (ogm->sinkpad, gst_ogm_parse_sink_convert); gst_pad_set_formats_function (ogm->sinkpad, gst_ogm_parse_get_sink_formats); gst_pad_set_chain_function (ogm->sinkpad, gst_ogm_parse_chain); gst_element_add_pad (GST_ELEMENT (ogm), ogm->sinkpad); - templ = (G_OBJECT_TYPE (ogm) == GST_TYPE_OGM_AUDIO_PARSE) ? - audio_src_templ : video_src_templ; - ogm->srcpad = gst_pad_new_from_template (templ, "src"); +#if 0 + ogm->srcpad = gst_pad_new_from_template (audio_src_templ, "src"); gst_pad_use_explicit_caps (ogm->srcpad); gst_element_add_pad (GST_ELEMENT (ogm), ogm->srcpad); +#endif + ogm->srcpadtempl = audio_src_templ; - /* initalize */ - memset (&ogm->hdr, 0, sizeof (ogm->hdr)); +gst_ogm_video_parse_init (GstOgmParse * ogm) + GstPadTemplate *templ; + /* create the pads */ + templ = gst_static_pad_template_get (&ogm_video_parse_sink_template_factory); + ogm->sinkpad = gst_pad_new_from_template (templ, "sink"); + gst_pad_set_convert_function (ogm->sinkpad, gst_ogm_parse_sink_convert); + gst_pad_set_formats_function (ogm->sinkpad, gst_ogm_parse_get_sink_formats); + gst_pad_set_chain_function (ogm->sinkpad, gst_ogm_parse_chain); + gst_element_add_pad (GST_ELEMENT (ogm), ogm->sinkpad); + ogm->srcpad = gst_pad_new_from_template (video_src_templ, "src"); + gst_pad_use_explicit_caps (ogm->srcpad); + gst_element_add_pad (GST_ELEMENT (ogm), ogm->srcpad); + ogm->srcpadtempl = video_src_templ; static const GstFormat * @@ -306,8 +343,8 @@ case GST_FORMAT_TIME: switch (ogm->hdr.streamtype[0]) { case 'a': - //*dest_value = ..; - //res = TRUE; + *dest_value = GST_SECOND * src_value / ogm->hdr.samples_per_unit; + res = TRUE; break; case 'v': *dest_value = (GST_SECOND / 10000000) * @@ -373,7 +410,21 @@ switch (ogm->hdr.streamtype[0]) { case 'a':{ - caps = NULL; + guint codec_id; + if (!sscanf (ogm->hdr.subtype, "%04x", &codec_id)) { + caps = NULL; + break; + } + caps = gst_riff_create_audio_caps (codec_id, NULL, NULL, NULL); + gst_caps_set_simple (caps, + "channels", G_TYPE_INT, ogm->hdr.s.audio.channels, + "rate", G_TYPE_INT, ogm->hdr.samples_per_unit, NULL); + GST_LOG_OBJECT (ogm, "Type: %s, subtype: 0x%04x, " + "channels: %d, samplerate: %d, blockalign: %d, bps: %d", + ogm->hdr.streamtype, codec_id, ogm->hdr.s.audio.channels, + ogm->hdr.samples_per_unit, + ogm->hdr.s.audio.blockalign, ogm->hdr.s.audio.avgbytespersec); break; } case 'v':{ @@ -401,9 +452,15 @@ g_assert_not_reached (); } + ogm->srcpad = gst_pad_new_from_template (ogm->srcpadtempl, "src"); + gst_pad_use_explicit_caps (ogm->srcpad); if (!gst_pad_set_explicit_caps (ogm->srcpad, caps)) { GST_ELEMENT_ERROR (ogm, CORE, NEGOTIATION, (NULL), (NULL)); + //gst_object_unref (GST_OBJECT (ogm->srcpad)); + ogm->srcpad = NULL; + gst_element_add_pad (GST_ELEMENT (ogm), ogm->srcpad); break; } case 0x03: @@ -413,7 +470,7 @@ if ((data[0] & 0x01) == 0) { /* data - push on */ guint len = ((data[0] & 0xc0) >> 6) | ((data[0] & 0x02) << 1); - guint xsize = 0; + guint xsize = 0, n; GstBuffer *sbuf; gboolean keyframe = (data[0] & 0x08) >> 3; @@ -422,25 +479,33 @@ ("Buffer too small"), (NULL)); - for (; len > 0; len--) { - xsize = (xsize << 8) | data[len]; + for (n = len; n > 0; n--) { + xsize = (xsize << 8) | data[n]; GST_DEBUG_OBJECT (ogm, - "[0x%02x] Size of frame: %d, size of buffer: %d\n", - data[0], xsize, size); - /* ? */ - sbuf = gst_buffer_create_sub (buf, 1, size - 1); + "[0x%02x] samples: %d, hdrbytes: %d, datasize: %d", + data[0], xsize, len, size - len - 1); + sbuf = gst_buffer_create_sub (buf, len + 1, size - len - 1); + if (GST_BUFFER_OFFSET_END_IS_VALID (buf)) { + ogm->next_granulepos = GST_BUFFER_OFFSET_END (buf); switch (ogm->hdr.streamtype[0]) { case 'v': if (keyframe) GST_BUFFER_FLAG_SET (sbuf, GST_BUFFER_KEY_UNIT); - GST_BUFFER_TIMESTAMP (sbuf) = GST_BUFFER_TIMESTAMP (buf); + GST_BUFFER_TIMESTAMP (sbuf) = (GST_SECOND / 10000000) * + ogm->next_granulepos * ogm->hdr.time_unit; GST_BUFFER_DURATION (sbuf) = (GST_SECOND / 10000000) * ogm->hdr.time_unit; + ogm->next_granulepos++; break; case 'a': - /* ? */ + GST_BUFFER_TIMESTAMP (sbuf) = GST_SECOND * + ogm->next_granulepos / ogm->hdr.samples_per_unit; + GST_BUFFER_DURATION (sbuf) = GST_SECOND * xsize / + ogm->hdr.samples_per_unit; + ogm->next_granulepos += xsize; default: g_assert_not_reached (); @@ -463,7 +528,12 @@ switch (GST_STATE_TRANSITION (element)) { case GST_STATE_PAUSED_TO_READY: + if (ogm->srcpad) { + gst_element_remove_pad (element, ogm->srcpad); memset (&ogm->hdr, 0, sizeof (ogm->hdr)); + ogm->next_granulepos = 0; default: Index: riff-read.c RCS file: /home/cvs/gstreamer/gst-plugins/gst-libs/gst/riff/riff-read.c,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- riff-read.c 24 Aug 2004 18:25:02 -0000 1.28 +++ riff-read.c 23 Sep 2004 14:59:22 -0000 1.29 @@ -304,7 +304,7 @@ GstEventType type = GST_EVENT_TYPE (event); gst_pad_event_default (riff->sinkpad, event); - if (type == GST_EVENT_EOS) + if (type == GST_EVENT_EOS || type == GST_EVENT_INTERRUPT) return NULL; event = NULL; @@ -890,8 +890,7 @@ if (name && name[0] != '\0') { GValue src = { 0 } - , dest = - { + , dest = { 0}; GType dest_type = gst_tag_get_type (type); Index: gstavidemux.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/avi/gstavidemux.c,v retrieving revision 1.112 retrieving revision 1.113 diff -u -d -r1.112 -r1.113 --- gstavidemux.c 15 Sep 2004 20:06:15 -0000 1.112 +++ gstavidemux.c 23 Sep 2004 14:59:22 -0000 1.113 @@ -31,20 +31,6 @@ GST_DEBUG_CATEGORY_STATIC (avidemux_debug); #define GST_CAT_DEFAULT avidemux_debug -/* AviDemux signals and args */ -enum - /* FILL ME */ - LAST_SIGNAL - ARG_0, - ARG_STREAMINFO - /* FILL ME */ static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink", @@ -73,13 +59,8 @@ static GstElementStateReturn gst_avi_demux_change_state (GstElement * element); -static void gst_avi_demux_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); static GstRiffReadClass *parent_class = NULL; -/*static guint gst_avi_demux_signals[LAST_SIGNAL] = { 0 }; */ GType gst_avi_demux_get_type (void) @@ -145,17 +126,11 @@ gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - g_object_class_install_property (gobject_class, ARG_STREAMINFO, - g_param_spec_boxed ("streaminfo", "Streaminfo", "Streaminfo", - GST_TYPE_CAPS, G_PARAM_READABLE)); GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux", 0, "Demuxer for AVI streams"); parent_class = g_type_class_ref (GST_TYPE_RIFF_READ); - gobject_class->get_property = gst_avi_demux_get_property; gstelement_class->change_state = gst_avi_demux_change_state; gstelement_class->send_event = gst_avi_demux_send_event; @@ -174,7 +149,6 @@ gst_element_set_loop_function (GST_ELEMENT (avi), gst_avi_demux_loop); gst_avi_demux_reset (avi); - avi->streaminfo = NULL; avi->index_entries = NULL; memset (&avi->stream, 0, sizeof (avi->stream)); @@ -208,19 +182,6 @@ avi->us_per_frame = 0; avi->seek_offset = (guint64) - 1; - gst_caps_replace (&avi->streaminfo, NULL); -} -static void -gst_avi_demux_streaminfo (GstAviDemux * avi) - /* compression formats are added later - a bit hacky */ - gst_caps_replace (&avi->streaminfo, - gst_caps_new_simple ("application/x-gst-streaminfo", NULL)); - /*g_object_notify(G_OBJECT(avi), "streaminfo"); */ static gst_avi_index_entry * @@ -341,7 +302,7 @@ /*GstAviDemux *avi = GST_AVI_DEMUX (gst_pad_get_parent (pad)); */ avi_stream_context *stream = gst_pad_get_element_private (pad); - if (stream->strh->type != GST_RIFF_FCC_auds && + if (stream->strh->type == GST_RIFF_FCC_vids && (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES)) @@ -444,12 +405,15 @@ if (stream->strh->samplesize == 1 && stream->blockalign != 0) { *value = stream->current_byte * GST_SECOND / (stream->blockalign * stream->strh->rate); - } else if (stream->strh->rate != 0) { - *value = (gfloat) stream->current_frame * stream->strh->scale * - GST_SECOND / stream->strh->rate; } else if (stream->bitrate != 0) { *value = ((gfloat) stream->current_byte) * GST_SECOND / stream->bitrate; + } else if (stream->total_frames != 0) { + /* calculate timestamps based on video size */ + guint64 len = demux->us_per_frame * demux->num_frames * + GST_USECOND; + *value = len * stream->current_frame / stream->total_frames; } else { *value = 0; } @@ -1289,9 +1253,6 @@ GST_DEBUG ("signaling no more pads"); gst_element_no_more_pads (GST_ELEMENT (avi)); - /* we've got streaminfo now */ - g_object_notify (G_OBJECT (avi), "streaminfo"); /* Now, find the data (i.e. skip all junk between header and data) */ while (1) { if (!(tag = gst_riff_peek_tag (riff, NULL))) @@ -1544,9 +1505,6 @@ GstAviDemux *avi = GST_AVI_DEMUX (element); - case GST_STATE_READY_TO_PAUSED: - gst_avi_demux_streaminfo (avi); - break; gst_avi_demux_reset (avi); @@ -1559,19 +1517,3 @@ return GST_STATE_SUCCESS; -gst_avi_demux_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) - GstAviDemux *avi = GST_AVI_DEMUX (object); - switch (prop_id) { - case ARG_STREAMINFO: - g_value_set_boxed (value, avi->streaminfo); - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } Index: gstavidemux.h RCS file: /home/cvs/gstreamer/gst-plugins/gst/avi/gstavidemux.h,v --- gstavidemux.h 15 Sep 2004 17:14:34 -0000 1.23 +++ gstavidemux.h 23 Sep 2004 14:59:22 -0000 1.24 @@ -114,9 +114,6 @@ /* seeking */ guint64 seek_offset; guint64 last_seek; - /* info */ - GstCaps *streaminfo; } GstAviDemux; typedef struct _GstAviDemuxClass { Index: ebml-read.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/matroska/ebml-read.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- ebml-read.c 1 Sep 2004 12:10:21 -0000 1.11 +++ ebml-read.c 23 Sep 2004 14:59:22 -0000 1.12 @@ -350,7 +350,11 @@ GST_WARNING ("No discontinuity event after seek - seek failed"); } else if (GST_EVENT_TYPE (event) != GST_EVENT_DISCONTINUOUS) { + GstEventType type = GST_EVENT_TYPE (event); gst_pad_event_default (ebml->sinkpad, event); + return NULL; @@ -389,8 +393,9 @@ return gst_bytestream_flush (ebml->bs, length); if (!(event = gst_ebml_read_seek (ebml, - gst_bytestream_tell (ebml->bs) + length))) + gst_bytestream_tell (ebml->bs) + length))) { gst_event_unref (event); Index: qtdemux.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/qtdemux/qtdemux.c,v retrieving revision 1.65 retrieving revision 1.66 diff -u -d -r1.65 -r1.66 --- qtdemux.c 15 Sep 2004 19:29:24 -0000 1.65 +++ qtdemux.c 23 Sep 2004 14:59:22 -0000 1.66 @@ -474,6 +474,7 @@ gst_qtdemux_handle_sink_event (GstQTDemux * qtdemux) + gboolean res = TRUE; guint32 remaining; GstEvent *event; GstEventType type; @@ -495,12 +496,13 @@ //gst_bytestream_flush_fast(qtdemux->bs, remaining); + res = FALSE; g_warning ("unhandled event %d", type); - return TRUE; + return res; static GstElementStateReturn @@ -713,6 +715,7 @@ if (!ret) { g_warning ("seek failed"); + qtdemux->offset = offset; GST_DEBUG ("seek returned %d", ret); return; @@ -780,7 +783,6 @@ /* unreached */ g_assert (0); void @@ -2024,7 +2026,8 @@ GST_FOURCC_ARGS (QTDEMUX_FOURCC_GET (stsd->data + 16 + 4)), stream->caps); } else { - GST_INFO ("unknown subtype"); + GST_INFO ("unknown subtype " GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (stream->subtype)); return; @@ -2156,7 +2159,7 @@ samples_per_chunk * stream->bytes_per_frame / stream->samples_per_packet / stream->compression; else - samples[j].size = 0; + samples[j].size = stream->bytes_per_frame; samples[j].duration = samples_per_chunk * GST_SECOND / (stream->rate / 2); samples[j].timestamp = timestamp; @@ -2208,7 +2211,6 @@ gst_qtdemux_add_stream (qtdemux, stream); @@ -2573,12 +2575,14 @@ case GST_MAKE_FOURCC ('a', 'g', 's', 'm'): /* GSM */ return gst_caps_new_simple ("audio/x-gsm", NULL); + case GST_MAKE_FOURCC ('i', 'm', 'a', '4'): + /* IMA 4:1 */ + return gst_caps_new_simple ("audio/x-adpcm", + "layout", G_TYPE_STRING, "quicktime", NULL); case GST_MAKE_FOURCC ('q', 't', 'v', 'r'): /* ? */ case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'): /* QDesign music */ - case GST_MAKE_FOURCC ('i', 'm', 'a', '4'): - /* IMA 4:1 */ case GST_MAKE_FOURCC ('Q', 'c', 'l', 'p'): /* QUALCOMM PureVoice */ Index: gsttypefindfunctions.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/typefind/gsttypefindfunctions.c,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- gsttypefindfunctions.c 20 Sep 2004 12:40:40 -0000 1.48 +++ gsttypefindfunctions.c 23 Sep 2004 14:59:22 -0000 1.49 @@ -789,6 +789,8 @@ offset += GST_READ_UINT32_BE (data); + if (GST_READ_UINT32_BE (data) < 8) if (tip > 0) { gst_type_find_suggest (tf, tip, QT_CAPS); |