From 823e63b7058ecdce11b6e91008c94c288b9b4eba Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Tue, 12 Jun 2007 19:36:11 +0000 Subject: Move qtdemux to -good. Original commit message from CVS: * configure.ac: * docs/plugins/Makefile.am: * docs/plugins/gst-plugins-bad-plugins-docs.sgml: * docs/plugins/gst-plugins-bad-plugins-sections.txt: * gst/qtdemux/Makefile.am: * gst/qtdemux/gstrtpxqtdepay.c: * gst/qtdemux/gstrtpxqtdepay.h: * gst/qtdemux/qtdemux.c: * gst/qtdemux/qtdemux.h: * gst/qtdemux/qtdemux.vcproj: * gst/qtdemux/qtdemux_dump.c: * gst/qtdemux/qtdemux_dump.h: * gst/qtdemux/qtdemux_fourcc.h: * gst/qtdemux/qtdemux_types.c: * gst/qtdemux/qtdemux_types.h: * gst/qtdemux/qtpalette.h: * gst/qtdemux/quicktime.c: * win32/MANIFEST: * win32/vs6/libgstqtdemux.dsp: Move qtdemux to -good. * gst-plugins-bad.spec.in: Update spec file to reflect wavpack & qtdemux moving to -good. --- ChangeLog | 26 + configure.ac | 16 +- docs/plugins/Makefile.am | 1 - docs/plugins/gst-plugins-bad-plugins-docs.sgml | 2 - docs/plugins/gst-plugins-bad-plugins-sections.txt | 8 - gst-plugins-bad.spec.in | 5 +- gst/qtdemux/Makefile.am | 16 - gst/qtdemux/gstrtpxqtdepay.c | 735 ---- gst/qtdemux/gstrtpxqtdepay.h | 63 - gst/qtdemux/qtdemux.c | 3996 --------------------- gst/qtdemux/qtdemux.h | 101 - gst/qtdemux/qtdemux.vcproj | 148 - gst/qtdemux/qtdemux_dump.c | 417 --- gst/qtdemux/qtdemux_dump.h | 51 - gst/qtdemux/qtdemux_fourcc.h | 133 - gst/qtdemux/qtdemux_types.c | 129 - gst/qtdemux/qtdemux_types.h | 58 - gst/qtdemux/qtpalette.h | 137 - gst/qtdemux/quicktime.c | 53 - win32/MANIFEST | 1 - win32/vs6/libgstqtdemux.dsp | 142 - 21 files changed, 30 insertions(+), 6208 deletions(-) delete mode 100644 gst/qtdemux/Makefile.am delete mode 100644 gst/qtdemux/gstrtpxqtdepay.c delete mode 100644 gst/qtdemux/gstrtpxqtdepay.h delete mode 100644 gst/qtdemux/qtdemux.c delete mode 100644 gst/qtdemux/qtdemux.h delete mode 100644 gst/qtdemux/qtdemux.vcproj delete mode 100644 gst/qtdemux/qtdemux_dump.c delete mode 100644 gst/qtdemux/qtdemux_dump.h delete mode 100644 gst/qtdemux/qtdemux_fourcc.h delete mode 100644 gst/qtdemux/qtdemux_types.c delete mode 100644 gst/qtdemux/qtdemux_types.h delete mode 100644 gst/qtdemux/qtpalette.h delete mode 100644 gst/qtdemux/quicktime.c delete mode 100644 win32/vs6/libgstqtdemux.dsp diff --git a/ChangeLog b/ChangeLog index 5d87fed6..2105c483 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2007-06-12 Jan Schmidt + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * gst/qtdemux/Makefile.am: + * gst/qtdemux/gstrtpxqtdepay.c: + * gst/qtdemux/gstrtpxqtdepay.h: + * gst/qtdemux/qtdemux.c: + * gst/qtdemux/qtdemux.h: + * gst/qtdemux/qtdemux.vcproj: + * gst/qtdemux/qtdemux_dump.c: + * gst/qtdemux/qtdemux_dump.h: + * gst/qtdemux/qtdemux_fourcc.h: + * gst/qtdemux/qtdemux_types.c: + * gst/qtdemux/qtdemux_types.h: + * gst/qtdemux/qtpalette.h: + * gst/qtdemux/quicktime.c: + * win32/MANIFEST: + * win32/vs6/libgstqtdemux.dsp: + Move qtdemux to -good. + + * gst-plugins-bad.spec.in: + Update spec file to reflect wavpack & qtdemux moving to -good. + 2007-06-12 Jan Schmidt * docs/plugins/Makefile.am: diff --git a/configure.ac b/configure.ac index eaf5bb4e..a835f186 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ dnl check if this is a release version AS_NANO(GST_CVS="no", GST_CVS="yes") dnl can autoconf find the source ? -AC_CONFIG_SRCDIR([gst/qtdemux/qtdemux.c]) +AC_CONFIG_SRCDIR([docs/plugins/gst-plugins-bad-plugins-docs.sgml]) dnl define the output header for config AM_CONFIG_HEADER([config.h]) @@ -101,7 +101,6 @@ GST_PLUGINS_ALL="\ spectrum \ speed \ switch \ - qtdemux \ tta \ videocrop \ videoparse \ @@ -885,17 +884,6 @@ AG_GST_CHECK_FEATURE(DVB, [DVB Source], dvb, [ AC_CHECK_HEADER(linux/dvb/frontend.h, [HAVE_DVB="yes"], [HAVE_DVB="no"]) ]) -dnl *** qtdemux prefers to have zlib *** -translit(dnm, m, l) AM_CONDITIONAL(USE_ZLIB, true) -AG_GST_CHECK_FEATURE(ZLIB, [zlib support for qtdemux],, [ - AG_GST_CHECK_LIBHEADER(ZLIB, - z, uncompress,, zlib.h, [ - HAVE_ZLIB="yes" - ZLIB_LIBS="-lz" - AC_SUBST(ZLIB_LIBS) - ]) -]) - else dnl not building plugins with external dependencies, @@ -935,7 +923,6 @@ AM_CONDITIONAL(USE_X264, false) AM_CONDITIONAL(USE_XVID, false) AM_CONDITIONAL(USE_WILDMIDI, false) AM_CONDITIONAL(USE_DVB, false) -AM_CONDITIONAL(USE_ZLIB, false) fi dnl of EXT plugins @@ -1011,7 +998,6 @@ gst/rtpmanager/Makefile gst/spectrum/Makefile gst/speed/Makefile gst/switch/Makefile -gst/qtdemux/Makefile gst/tta/Makefile gst/videocrop/Makefile gst/videoparse/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 64517b41..279c30d2 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -95,7 +95,6 @@ EXTRA_HFILES = \ $(top_srcdir)/ext/musicbrainz/gsttrm.h \ $(top_srcdir)/ext/sdl/sdlaudiosink.h \ $(top_srcdir)/ext/sdl/sdlvideosink.h \ - $(top_srcdir)/gst/qtdemux/qtdemux.h \ $(top_srcdir)/gst/replaygain/gstrganalysis.h \ $(top_srcdir)/gst/replaygain/gstrglimiter.h \ $(top_srcdir)/gst/replaygain/gstrgvolume.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index ed7f145d..a5c5f115 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -14,7 +14,6 @@ gst-plugins-bad Elements - @@ -50,7 +49,6 @@ - diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index 8baf5b72..f9ce4f1f 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -15,14 +15,6 @@ GstJackConnect GstJackAudioSinkClass -
-element-qtdemux -GstQTDemux -qtdemux - -GstQTDemuxClass -
-
element-osxvideosink GstOSXVideoSink diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in index 78f187d1..43e9badc 100644 --- a/gst-plugins-bad.spec.in +++ b/gst-plugins-bad.spec.in @@ -81,7 +81,6 @@ rm -rf $RPM_BUILD_ROOT %doc AUTHORS COPYING README REQUIREMENTS gst-plugins-bad.doap # non-core plugins without external dependencies -%{_libdir}/gstreamer-%{majorminor}/libgstqtdemux.so %{_libdir}/gstreamer-%{majorminor}/libgsttta.so %{_libdir}/gstreamer-%{majorminor}/libgstspeed.so %{_libdir}/gstreamer-%{majorminor}/libgstcdxaparse.so @@ -130,7 +129,6 @@ rm -rf $RPM_BUILD_ROOT @USE_LIBMMS_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstmms.so @USE_XVID_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstxvid.so @USE_BZ2_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstbz2.so -@USE_WAVPACK_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstwavpack.so @USE_IVORBIS_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstivorbis.so @USE_NEON_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstneonhttpsrc.so @USE_ALSA_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstalsaspdif.so @@ -142,6 +140,9 @@ rm -rf $RPM_BUILD_ROOT @USE_X264_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstx264.so %changelog +* Tue Jun 12 2007 Jan Schmidt +- wavpack and qtdemux have moved to good. + * Thu Mar 22 2007 Christian Schaller - Add x264 and mpegvideoparse plugins diff --git a/gst/qtdemux/Makefile.am b/gst/qtdemux/Makefile.am deleted file mode 100644 index 2c4aa52a..00000000 --- a/gst/qtdemux/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ - -plugin_LTLIBRARIES = libgstqtdemux.la - -libgstqtdemux_la_CFLAGS = ${GST_CFLAGS} $(GST_PLUGINS_BASE_CFLAGS) -libgstqtdemux_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(ZLIB_LIBS) \ - -lgstrtp-@GST_MAJORMINOR@ -libgstqtdemux_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} -libgstqtdemux_la_SOURCES = quicktime.c gstrtpxqtdepay.c qtdemux.c qtdemux_types.c qtdemux_dump.c - -noinst_HEADERS = \ - qtdemux.h \ - qtdemux_types.h \ - qtdemux_dump.h \ - qtdemux_fourcc.h \ - qtpalette.h \ - gstrtpxqtdepay.h diff --git a/gst/qtdemux/gstrtpxqtdepay.c b/gst/qtdemux/gstrtpxqtdepay.c deleted file mode 100644 index 0a147ef4..00000000 --- a/gst/qtdemux/gstrtpxqtdepay.c +++ /dev/null @@ -1,735 +0,0 @@ -/* GStreamer - * Copyright (C) <2006> Wim Taymans - * - * 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. - */ - -/* - * based on http://developer.apple.com/quicktime/icefloe/dispatch026.html - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include "gstrtpxqtdepay.h" - -#define MAKE_TLV(a,b) (((a)<<8)|(b)) - -#define TLV_sd MAKE_TLV ('s','d') -#define TLV_qt MAKE_TLV ('q','t') -#define TLV_ti MAKE_TLV ('t','i') -#define TLV_ly MAKE_TLV ('l','y') -#define TLV_vo MAKE_TLV ('v','o') -#define TLV_mx MAKE_TLV ('m','x') -#define TLV_tr MAKE_TLV ('t','r') -#define TLV_tw MAKE_TLV ('t','w') -#define TLV_th MAKE_TLV ('t','h') -#define TLV_la MAKE_TLV ('l','a') -#define TLV_rt MAKE_TLV ('r','t') -#define TLV_gm MAKE_TLV ('g','m') -#define TLV_oc MAKE_TLV ('o','c') -#define TLV_cr MAKE_TLV ('c','r') -#define TLV_du MAKE_TLV ('d','u') -#define TLV_po MAKE_TLV ('p','o') - -#define QT_UINT32(a) (GST_READ_UINT32_BE(a)) -#define QT_UINT24(a) (GST_READ_UINT32_BE(a) >> 8) -#define QT_UINT16(a) (GST_READ_UINT16_BE(a)) -#define QT_UINT8(a) (GST_READ_UINT8(a)) -#define QT_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0) -#define QT_FP16(a) ((GST_READ_UINT16_BE(a))/256.0) -#define QT_FOURCC(a) (GST_READ_UINT32_LE(a)) -#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4)) - -#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') -#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C') - -GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug); -#define GST_CAT_DEFAULT (rtpxqtdepay_debug) - -/* elementfactory information */ -static const GstElementDetails gst_rtp_xqtdepay_details = -GST_ELEMENT_DETAILS ("RTP packet depayloader", - "Codec/Depayloader/Network", - "Extracts Quicktime audio/video from RTP packets", - "Wim Taymans "); - -/* RtpXQTDepay signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, -}; - -static GstStaticPadTemplate gst_rtp_xqt_depay_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate gst_rtp_xqt_depay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp, " - "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " - "media = (string) { \"audio\", \"video\" }, clock-rate = (int) [1, MAX], " - "encoding-name = (string) { \"X-QT\", \"X-QUICKTIME\" }") - ); - -GST_BOILERPLATE (GstRtpXQTDepay, gst_rtp_xqt_depay, GstBaseRTPDepayload, - GST_TYPE_BASE_RTP_DEPAYLOAD); - -static void gst_rtp_xqt_depay_finalize (GObject * object); - -static gboolean gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload, - GstCaps * caps); -static GstBuffer *gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, - GstBuffer * buf); - -static void gst_rtp_xqt_depay_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_rtp_xqt_depay_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstStateChangeReturn gst_rtp_xqt_depay_change_state (GstElement * - element, GstStateChange transition); - -static void -gst_rtp_xqt_depay_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_xqt_depay_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_xqt_depay_sink_template)); - - gst_element_class_set_details (element_class, &gst_rtp_xqtdepay_details); -} - -static void -gst_rtp_xqt_depay_class_init (GstRtpXQTDepayClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseRTPDepayloadClass *gstbasertpdepayload_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = gst_rtp_xqt_depay_finalize; - - gobject_class->set_property = gst_rtp_xqt_depay_set_property; - gobject_class->get_property = gst_rtp_xqt_depay_get_property; - - gstelement_class->change_state = gst_rtp_xqt_depay_change_state; - - gstbasertpdepayload_class->set_caps = gst_rtp_xqt_depay_setcaps; - gstbasertpdepayload_class->process = gst_rtp_xqt_depay_process; - - GST_DEBUG_CATEGORY_INIT (rtpxqtdepay_debug, "rtpxqtdepay", 0, - "QT Media RTP Depayloader"); -} - -static void -gst_rtp_xqt_depay_init (GstRtpXQTDepay * rtpxqtdepay, - GstRtpXQTDepayClass * klass) -{ - rtpxqtdepay->adapter = gst_adapter_new (); -} - -static void -gst_rtp_xqt_depay_finalize (GObject * object) -{ - GstRtpXQTDepay *rtpxqtdepay; - - rtpxqtdepay = GST_RTP_XQT_DEPAY (object); - - g_object_unref (rtpxqtdepay->adapter); - rtpxqtdepay->adapter = NULL; - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data, - guint data_len) -{ - gint len; - guint32 fourcc; - - if (data_len < 8) - goto too_short; - - len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - if (len > data_len) - goto too_short; - - fourcc = QT_FOURCC (data + 4); - - GST_DEBUG_OBJECT (rtpxqtdepay, "parsing %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - - switch (fourcc) { - case FOURCC_avc1: - { - guint32 chlen; - - if (len < 0x56) - goto too_short; - len -= 0x56; - data += 0x56; - - /* find avcC */ - while (len >= 8) { - chlen = QT_UINT32 (data); - fourcc = QT_FOURCC (data + 4); - if (fourcc == FOURCC_avcC) { - GstBuffer *buf; - gint size; - GstCaps *caps; - - GST_DEBUG_OBJECT (rtpxqtdepay, "found avcC codec_data in sd, %u", - chlen); - - /* parse, if found */ - if (chlen < len) - size = chlen - 8; - else - size = len - 8; - - buf = gst_buffer_new_and_alloc (size); - memcpy (GST_BUFFER_DATA (buf), data + 8, size); - caps = gst_caps_new_simple ("video/x-h264", - "codec_data", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD (rtpxqtdepay)->srcpad, caps); - gst_caps_unref (caps); - break; - } - len -= chlen; - data += chlen; - } - break; - } - default: - break; - } - return TRUE; - - /* ERRORS */ -too_short: - { - return FALSE; - } -} - -static gboolean -gst_rtp_xqt_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) -{ - GstStructure *structure; - GstRtpXQTDepay *rtpxqtdepay; - gint clock_rate = 90000; /* default */ - - rtpxqtdepay = GST_RTP_XQT_DEPAY (depayload); - - structure = gst_caps_get_structure (caps, 0); - - gst_structure_get_int (structure, "clock-rate", &clock_rate); - depayload->clock_rate = clock_rate; - - return TRUE; -} - -static GstBuffer * -gst_rtp_xqt_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) -{ - GstRtpXQTDepay *rtpxqtdepay; - GstBuffer *outbuf; - gboolean m; - - rtpxqtdepay = GST_RTP_XQT_DEPAY (depayload); - - if (!gst_rtp_buffer_validate (buf)) - goto bad_packet; - - if (GST_BUFFER_IS_DISCONT (buf)) { - /* discont, clear adapter and try to find a new packet start */ - gst_adapter_clear (rtpxqtdepay->adapter); - rtpxqtdepay->need_resync = TRUE; - } - - m = gst_rtp_buffer_get_marker (buf); - GST_LOG_OBJECT (rtpxqtdepay, "marker: %d", m); - - { - gint payload_len; - guint avail; - guint8 *payload; - guint32 timestamp; - guint8 ver, pck; - gboolean s, q, l, d; - - payload_len = gst_rtp_buffer_get_payload_len (buf); - payload = gst_rtp_buffer_get_payload (buf); - - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | VER |PCK|S|Q|L| RES |D| QuickTime Payload ID | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - if (payload_len <= 4) - goto wrong_length; - - ver = (payload[0] & 0xf0) >> 4; - if (ver > 1) - goto wrong_version; - - pck = (payload[0] & 0x0c) >> 2; - if (pck == 0) - goto pck_reserved; - - s = (payload[0] & 0x02) != 0; /* contains sync sample */ - q = (payload[0] & 0x01) != 0; /* has payload description */ - l = (payload[1] & 0x80) != 0; /* has packet specific information description */ - d = (payload[2] & 0x80) != 0; /* don't cache info for payload id */ - /* id used for caching info */ - rtpxqtdepay->current_id = ((payload[2] & 0x7f) << 8) | payload[3]; - - GST_LOG_OBJECT (rtpxqtdepay, - "VER: %d, PCK: %d, S: %d, Q: %d, L: %d, D: %d, ID: %d", ver, pck, s, q, - l, d, rtpxqtdepay->current_id); - - if (rtpxqtdepay->need_resync) { - /* we need to find the boundary of a new packet after a DISCONT */ - if (pck != 3 || q) { - /* non-fragmented packet or payload description present, packet starts - * here. */ - rtpxqtdepay->need_resync = FALSE; - } else { - /* fragmented packet without description */ - if (m) { - /* marker bit set, next packet is start of new one */ - rtpxqtdepay->need_resync = FALSE; - } - goto need_resync; - } - } - - payload += 4; - payload_len -= 4; - - if (q) { - gboolean k, f, a, z; - guint pdlen, pdpadded; - gint padding; - guint32 media_type, timescale; - - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |K|F|A|Z| RES | QuickTime Payload Desc Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . QuickTime Payload Desc Data ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - if (payload_len <= 4) - goto wrong_length; - - k = (payload[0] & 0x80) != 0; /* keyframe */ - f = (payload[0] & 0x40) != 0; /* sparse */ - a = (payload[0] & 0x20) != 0; /* start of payload */ - z = (payload[0] & 0x10) != 0; /* end of payload */ - pdlen = (payload[2] << 8) | payload[3]; - - if (pdlen < 12) - goto wrong_length; - - /* calc padding */ - pdpadded = pdlen + 3; - pdpadded -= pdpadded % 4; - if (payload_len < pdpadded) - goto wrong_length; - - padding = pdpadded - pdlen; - GST_LOG_OBJECT (rtpxqtdepay, - "K: %d, F: %d, A: %d, Z: %d, len: %d, padding %d", k, f, a, z, pdlen, - padding); - - payload += 4; - payload_len -= 4; - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | QuickTime Media Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Timescale | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . QuickTime TLVs ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - media_type = - (payload[0] << 24) | (payload[1] << 16) | (payload[2] << 8) | - payload[3]; - timescale = - (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) | - payload[7]; - - GST_LOG_OBJECT (rtpxqtdepay, "media_type: %c%c%c%c, timescale %u", - payload[0], payload[1], payload[2], payload[3], timescale); - - payload += 8; - payload_len -= 8; - pdlen -= 12; - - /* parse TLV (type-length-value triplets */ - while (pdlen > 3) { - guint16 tlv_len, tlv_type; - - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | QuickTime TLV Length | QuickTime TLV Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . QuickTime TLV Value ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - tlv_len = (payload[0] << 8) | payload[1]; - tlv_type = (payload[2] << 8) | payload[3]; - pdlen -= 4; - if (tlv_len > pdlen) - goto wrong_length; - - GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2], - payload[3], tlv_len); - - payload += 4; - payload_len -= 4; - - switch (tlv_type) { - case TLV_sd: - /* Session description */ - gst_rtp_quicktime_parse_sd (rtpxqtdepay, payload, tlv_len); - break; - case TLV_qt: - case TLV_ti: - case TLV_ly: - case TLV_vo: - case TLV_mx: - case TLV_tr: - case TLV_tw: - case TLV_th: - case TLV_la: - case TLV_rt: - case TLV_gm: - case TLV_oc: - case TLV_cr: - case TLV_du: - case TLV_po: - default: - break; - } - - pdlen -= tlv_len; - payload += tlv_len; - payload_len -= tlv_len; - } - payload += padding; - payload_len -= padding; - } - - if (l) { - guint ssilen, ssipadded; - gint padding; - - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | RES | Sample-Specific Info Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . QuickTime TLVs ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - if (payload_len <= 4) - goto wrong_length; - - ssilen = (payload[2] << 8) | payload[3]; - if (ssilen < 4) - goto wrong_length; - - /* calc padding */ - ssipadded = ssilen + 3; - ssipadded -= ssipadded % 4; - if (payload_len < ssipadded) - goto wrong_length; - - padding = ssipadded - ssilen; - GST_LOG_OBJECT (rtpxqtdepay, "len: %d, padding %d", ssilen, padding); - - payload += 4; - payload_len -= 4; - ssilen -= 4; - - /* parse TLV (type-length-value triplets */ - while (ssilen > 3) { - guint16 tlv_len, tlv_type; - - /* 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | QuickTime TLV Length | QuickTime TLV Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . QuickTime TLV Value ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - tlv_len = (payload[0] << 8) | payload[1]; - tlv_type = (payload[2] << 8) | payload[3]; - ssilen -= 4; - if (tlv_len > ssilen) - goto wrong_length; - - GST_LOG_OBJECT (rtpxqtdepay, "TLV '%c%c', len %d", payload[2], - payload[3], tlv_len); - - payload += 4; - payload_len -= 4; - - switch (tlv_type) { - case TLV_sd: - case TLV_qt: - case TLV_ti: - case TLV_ly: - case TLV_vo: - case TLV_mx: - case TLV_tr: - case TLV_tw: - case TLV_th: - case TLV_la: - case TLV_rt: - case TLV_gm: - case TLV_oc: - case TLV_cr: - case TLV_du: - case TLV_po: - default: - break; - } - - ssilen -= tlv_len; - payload += tlv_len; - payload_len -= tlv_len; - } - payload += padding; - payload_len -= padding; - } - - timestamp = gst_rtp_buffer_get_timestamp (buf); - rtpxqtdepay->previous_id = rtpxqtdepay->current_id; - - switch (pck) { - case 1: - { - /* multiple samples per packet. */ - outbuf = gst_buffer_new_and_alloc (payload_len); - memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len); - return outbuf; - } - case 2: - { - guint slen, timestamp; - - /* multiple samples per packet. - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |S| Reserved | Sample Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sample Timestamp | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . Sample Data ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |S| Reserved | Sample Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sample Timestamp | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . Sample Data ... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . ...... . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - while (payload_len > 8) { - s = (payload[0] & 0x80) != 0; /* contains sync sample */ - slen = (payload[2] << 8) | payload[3]; - timestamp = - (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) | - payload[7]; - - payload += 8; - payload_len -= 8; - - if (slen > payload_len) - slen = payload_len; - - outbuf = gst_buffer_new_and_alloc (slen); - memcpy (GST_BUFFER_DATA (outbuf), payload, slen); - if (!s) - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); - - gst_base_rtp_depayload_push (depayload, outbuf); - - /* aligned on 32 bit boundary */ - slen = GST_ROUND_UP_4 (slen); - - payload += slen; - payload_len -= slen; - } - break; - } - case 3: - { - /* one sample per packet, use adapter to combine based on marker bit. */ - outbuf = gst_buffer_new_and_alloc (payload_len); - memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len); - - gst_adapter_push (rtpxqtdepay->adapter, outbuf); - - if (!m) - goto done; - - avail = gst_adapter_available (rtpxqtdepay->adapter); - outbuf = gst_adapter_take_buffer (rtpxqtdepay->adapter, avail); - - GST_DEBUG_OBJECT (rtpxqtdepay, - "gst_rtp_xqt_depay_chain: pushing buffer of size %u", avail); - - return outbuf; - } - } - } - -done: - return NULL; - -bad_packet: - { - GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE, - ("Packet did not validate."), (NULL)); - return NULL; - } -need_resync: - { - GST_DEBUG_OBJECT (rtpxqtdepay, "waiting for marker"); - return NULL; - } -wrong_version: - { - GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE, - ("Unknown payload version."), (NULL)); - return NULL; - } -pck_reserved: - { - GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE, - ("PCK reserved 0."), (NULL)); - return NULL; - } -wrong_length: - { - GST_ELEMENT_WARNING (rtpxqtdepay, STREAM, DECODE, - ("Wrong payload length."), (NULL)); - return NULL; - } -} - -static void -gst_rtp_xqt_depay_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstRtpXQTDepay *rtpxqtdepay; - - rtpxqtdepay = GST_RTP_XQT_DEPAY (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rtp_xqt_depay_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstRtpXQTDepay *rtpxqtdepay; - - rtpxqtdepay = GST_RTP_XQT_DEPAY (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstStateChangeReturn -gst_rtp_xqt_depay_change_state (GstElement * element, GstStateChange transition) -{ - GstRtpXQTDepay *rtpxqtdepay; - GstStateChangeReturn ret; - - rtpxqtdepay = GST_RTP_XQT_DEPAY (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_adapter_clear (rtpxqtdepay->adapter); - rtpxqtdepay->previous_id = -1; - rtpxqtdepay->current_id = -1; - rtpxqtdepay->need_resync = FALSE; - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_adapter_clear (rtpxqtdepay->adapter); - default: - break; - } - return ret; -} - -gboolean -gst_rtp_xqt_depay_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "rtpxqtdepay", - GST_RANK_MARGINAL, GST_TYPE_RTP_XQT_DEPAY); -} diff --git a/gst/qtdemux/gstrtpxqtdepay.h b/gst/qtdemux/gstrtpxqtdepay.h deleted file mode 100644 index 23cf6eea..00000000 --- a/gst/qtdemux/gstrtpxqtdepay.h +++ /dev/null @@ -1,63 +0,0 @@ -/* GStreamer - * Copyright (C) <2005> Wim Taymans - * - * 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_RTP_XQT_DEPAY_H__ -#define __GST_RTP_XQT_DEPAY_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_RTP_XQT_DEPAY \ - (gst_rtp_xqt_depay_get_type()) -#define GST_RTP_XQT_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_XQT_DEPAY,GstRtpXQTDepay)) -#define GST_RTP_XQT_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_XQT_DEPAY,GstRtpXQTDepayClass)) -#define GST_IS_RTP_XQT_DEPAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_XQT_DEPAY)) -#define GST_IS_RTP_XQT_DEPAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_XQT_DEPAY)) - -typedef struct _GstRtpXQTDepay GstRtpXQTDepay; -typedef struct _GstRtpXQTDepayClass GstRtpXQTDepayClass; - -struct _GstRtpXQTDepay -{ - GstBaseRTPDepayload depayload; - - GstAdapter *adapter; - - gboolean need_resync; - guint16 previous_id; - guint16 current_id; -}; - -struct _GstRtpXQTDepayClass -{ - GstBaseRTPDepayloadClass parent_class; -}; - -GType gst_rtp_xqt_depay_get_type (void); - -G_END_DECLS - -#endif /* __GST_RTP_XQT_DEPAY_H__ */ diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c deleted file mode 100644 index ce3f18b1..00000000 --- a/gst/qtdemux/qtdemux.c +++ /dev/null @@ -1,3996 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) <2003> David A. Schleef - * Copyright (C) <2006> Wim Taymans - * - * 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. - */ - -/** - * SECTION:element-qtdemux - * - * - * - * Demuxes a .mov file into raw or compressed audio and/or video streams. - * - * - * This element supports both push and pull-based scheduling, depending on the - * capabilities of the upstream elements. - * - * Example launch line - * - * - * gst-launch filesrc location=test.mov ! qtdemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink - * - * Play (parse and decode) a .mov file and try to output it to - * an automatically detected soundcard and videosink. If the MOV file contains - * compressed audio or video data, this will only work if you have the - * right decoder elements/plugins installed. - * - * - * - * Last reviewed on 2006-12-29 (0.10.5) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gst/gst-i18n-plugin.h" - -#include "qtdemux_types.h" -#include "qtdemux_dump.h" -#include "qtdemux_fourcc.h" -#include "qtdemux.h" -#include "qtpalette.h" - -#include -#include - -#ifdef HAVE_ZLIB -# include -#endif - -GST_DEBUG_CATEGORY (qtdemux_debug); - -#if 0 -#define qtdemux_dump_mem(a,b) gst_util_dump_mem(a,b) -#else -#define qtdemux_dump_mem(a,b) /* */ -#endif - -typedef struct _QtNode QtNode; -typedef struct _QtDemuxSegment QtDemuxSegment; -typedef struct _QtDemuxSample QtDemuxSample; - -struct _QtNode -{ - guint32 type; - guint8 *data; - gint len; -}; - -struct _QtDemuxSample -{ - guint32 chunk; - guint32 size; - guint64 offset; - GstClockTimeDiff pts_offset; /* Add this value to timestamp to get the pts */ - guint64 timestamp; /* In GstClockTime */ - guint64 duration; /* in GstClockTime */ - gboolean keyframe; /* TRUE when this packet is a keyframe */ -}; - -struct _QtDemuxSegment -{ - /* global time and duration, all gst time */ - guint64 time; - guint64 stop_time; - guint64 duration; - /* media time of trak, all gst time */ - guint64 media_start; - guint64 media_stop; - gdouble rate; -}; - -struct _QtDemuxStream -{ - GstPad *pad; - - /* stream type */ - guint32 subtype; - GstCaps *caps; - guint32 fourcc; - - /* duration/scale */ - guint64 duration; /* in timescale */ - guint32 timescale; - - /* our samples */ - guint32 n_samples; - QtDemuxSample *samples; - gboolean all_keyframe; /* TRUE when all samples are keyframes (no stss) */ - guint32 min_duration; /* duration in timescale of first sample, used for figuring out - the framerate, in timescale units */ - - /* if we use chunks or samples */ - gboolean sampled; - - /* video info */ - gint width; - gint height; - /* Numerator/denominator framerate */ - gint fps_n; - gint fps_d; - guint16 bits_per_sample; - guint16 color_table_id; - - /* audio info */ - gdouble rate; - gint n_channels; - guint samples_per_packet; - guint samples_per_frame; - guint bytes_per_packet; - guint bytes_per_sample; - guint bytes_per_frame; - guint compression; - - /* when a discontinuity is pending */ - gboolean discont; - - /* current position */ - guint32 segment_index; - guint32 sample_index; - guint64 time_position; /* in gst time */ - - /* last GstFlowReturn */ - GstFlowReturn last_ret; - - /* quicktime segments */ - guint32 n_segments; - QtDemuxSegment *segments; - gboolean segment_pending; -}; - -enum QtDemuxState -{ - QTDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */ - QTDEMUX_STATE_HEADER, /* Parsing the header */ - QTDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */ - QTDEMUX_STATE_BUFFER_MDAT /* Buffering the mdat atom */ -}; - -static GNode *qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc); -static GNode *qtdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc); - -static const GstElementDetails gst_qtdemux_details = -GST_ELEMENT_DETAILS ("QuickTime demuxer", - "Codec/Demuxer", - "Demultiplex a QuickTime file into audio and video streams", - "David Schleef , Wim Taymans "); - -static GstStaticPadTemplate gst_qtdemux_sink_template = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/quicktime; audio/x-m4a; application/x-3gp") - ); - -static GstStaticPadTemplate gst_qtdemux_videosrc_template = -GST_STATIC_PAD_TEMPLATE ("audio_%02d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate gst_qtdemux_audiosrc_template = -GST_STATIC_PAD_TEMPLATE ("video_%02d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS_ANY); - -static GstElementClass *parent_class = NULL; - -static void gst_qtdemux_class_init (GstQTDemuxClass * klass); -static void gst_qtdemux_base_init (GstQTDemuxClass * klass); -static void gst_qtdemux_init (GstQTDemux * quicktime_demux); -static void gst_qtdemux_dispose (GObject * object); - -static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element, - GstStateChange transition); -static gboolean qtdemux_sink_activate (GstPad * sinkpad); -static gboolean qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active); -static gboolean qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active); - -static void gst_qtdemux_loop (GstPad * pad); -static GstFlowReturn gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf); -static gboolean gst_qtdemux_handle_sink_event (GstPad * pad, GstEvent * event); - -static gboolean qtdemux_parse_moov (GstQTDemux * qtdemux, guint8 * buffer, - int length); -static gboolean qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, - guint8 * buffer, int length); -static gboolean qtdemux_parse_tree (GstQTDemux * qtdemux); - -static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux, - QtDemuxStream * stream, GNode * esds, GstTagList * list); -static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, - const guint8 * stsd_data, const gchar ** codec_name); -static GstCaps *qtdemux_audio_caps (GstQTDemux * qtdemux, - QtDemuxStream * stream, guint32 fourcc, const guint8 * data, int len, - const gchar ** codec_name); - -GType -gst_qtdemux_get_type (void) -{ - static GType qtdemux_type = 0; - - if (!qtdemux_type) { - static const GTypeInfo qtdemux_info = { - sizeof (GstQTDemuxClass), - (GBaseInitFunc) gst_qtdemux_base_init, NULL, - (GClassInitFunc) gst_qtdemux_class_init, - NULL, NULL, sizeof (GstQTDemux), 0, - (GInstanceInitFunc) gst_qtdemux_init, - }; - - qtdemux_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstQTDemux", &qtdemux_info, - 0); - } - return qtdemux_type; -} - -static void -gst_qtdemux_base_init (GstQTDemuxClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_qtdemux_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_qtdemux_videosrc_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_qtdemux_audiosrc_template)); - gst_element_class_set_details (element_class, &gst_qtdemux_details); - - GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin"); -} - -static void -gst_qtdemux_class_init (GstQTDemuxClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->dispose = gst_qtdemux_dispose; - - gstelement_class->change_state = gst_qtdemux_change_state; -} - -static void -gst_qtdemux_init (GstQTDemux * qtdemux) -{ - qtdemux->sinkpad = - gst_pad_new_from_static_template (&gst_qtdemux_sink_template, "sink"); - gst_pad_set_activate_function (qtdemux->sinkpad, qtdemux_sink_activate); - gst_pad_set_activatepull_function (qtdemux->sinkpad, - qtdemux_sink_activate_pull); - gst_pad_set_activatepush_function (qtdemux->sinkpad, - qtdemux_sink_activate_push); - gst_pad_set_chain_function (qtdemux->sinkpad, gst_qtdemux_chain); - gst_pad_set_event_function (qtdemux->sinkpad, gst_qtdemux_handle_sink_event); - gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), qtdemux->sinkpad); - - qtdemux->state = QTDEMUX_STATE_INITIAL; - /* FIXME, use segment last_stop for this */ - qtdemux->last_ts = GST_CLOCK_TIME_NONE; - qtdemux->pullbased = FALSE; - qtdemux->neededbytes = 16; - qtdemux->todrop = 0; - qtdemux->adapter = gst_adapter_new (); - qtdemux->offset = 0; - qtdemux->mdatoffset = GST_CLOCK_TIME_NONE; - qtdemux->mdatbuffer = NULL; - gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME); -} - -static void -gst_qtdemux_dispose (GObject * object) -{ - GstQTDemux *qtdemux = GST_QTDEMUX (object); - - if (qtdemux->adapter) { - g_object_unref (G_OBJECT (qtdemux->adapter)); - qtdemux->adapter = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -#if 0 -static gboolean -gst_qtdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, - GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - QtDemuxStream *stream = gst_pad_get_element_private (pad); - - if (stream->subtype == GST_MAKE_FOURCC ('v', 'i', 'd', 'e') && - (src_format == GST_FORMAT_BYTES || *dest_format == GST_FORMAT_BYTES)) - return FALSE; - - switch (src_format) { - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_BYTES: - *dest_value = src_value * 1; /* FIXME */ - break; - case GST_FORMAT_DEFAULT: - *dest_value = src_value * 1; /* FIXME */ - break; - default: - res = FALSE; - break; - } - break; - case GST_FORMAT_BYTES: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = src_value * 1; /* FIXME */ - break; - default: - res = FALSE; - break; - } - break; - case GST_FORMAT_DEFAULT: - switch (*dest_format) { - case GST_FORMAT_TIME: - *dest_value = src_value * 1; /* FIXME */ - break; - default: - res = FALSE; - break; - } - break; - default: - res = FALSE; - } - - return res; -} -#endif - -static const GstQueryType * -gst_qtdemux_get_src_query_types (GstPad * pad) -{ - static const GstQueryType src_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_SEEKING, - 0 - }; - - return src_types; -} - -static gboolean -gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration) -{ - gboolean res = TRUE; - - *duration = GST_CLOCK_TIME_NONE; - - if (qtdemux->duration != 0) { - if (qtdemux->duration != G_MAXINT32 && qtdemux->timescale != 0) { - *duration = gst_util_uint64_scale (qtdemux->duration, - GST_SECOND, qtdemux->timescale); - } - } - return res; -} - -static gboolean -gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query) -{ - gboolean res = FALSE; - GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION: - if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.last_stop)) { - gst_query_set_position (query, GST_FORMAT_TIME, - qtdemux->segment.last_stop); - res = TRUE; - } - break; - case GST_QUERY_DURATION:{ - GstFormat fmt; - - gst_query_parse_duration (query, &fmt, NULL); - if (fmt == GST_FORMAT_TIME) { - gint64 duration = -1; - - gst_qtdemux_get_duration (qtdemux, &duration); - if (duration > 0) { - gst_query_set_duration (query, GST_FORMAT_TIME, duration); - res = TRUE; - } - } - break; - } - case GST_QUERY_SEEKING:{ - GstFormat fmt; - - gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); - if (fmt == GST_FORMAT_TIME) { - gint64 duration = -1; - - gst_qtdemux_get_duration (qtdemux, &duration); - gst_query_set_seeking (query, GST_FORMAT_TIME, qtdemux->pullbased, - 0, duration); - res = TRUE; - } - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - - gst_object_unref (qtdemux); - - return res; -} - -/* push event on all source pads; takes ownership of the event */ -static void -gst_qtdemux_push_event (GstQTDemux * qtdemux, GstEvent * event) -{ - guint n; - - GST_DEBUG_OBJECT (qtdemux, "pushing %s event on all source pads", - GST_EVENT_TYPE_NAME (event)); - - for (n = 0; n < qtdemux->n_streams; n++) { - GstPad *pad; - - if ((pad = qtdemux->streams[n]->pad)) - gst_pad_push_event (pad, gst_event_ref (event)); - } - gst_event_unref (event); -} - -/* find the index of the sample that includes the data for @media_time - * - * Returns the index of the sample or n_samples when the sample was not - * found. - */ -/* FIXME, binary search would be nice here */ -static guint32 -gst_qtdemux_find_index (GstQTDemux * qtdemux, QtDemuxStream * str, - guint64 media_time) -{ - guint32 i; - - if (str->n_samples == 0) - return 0; - - for (i = 0; i < str->n_samples; i++) { - if (str->samples[i].timestamp > media_time) { - /* first sample after media_time, we need the previous one */ - return (i == 0 ? 0 : i - 1); - } - } - return str->n_samples - 1; -} - -/* find the index of the keyframe needed to decode the sample at @index - * of stream @str. - * - * Returns the index of the keyframe. - */ -static guint32 -gst_qtdemux_find_keyframe (GstQTDemux * qtdemux, QtDemuxStream * str, - guint32 index) -{ - if (index >= str->n_samples) - return str->n_samples; - - /* all keyframes, return index */ - if (str->all_keyframe) - return index; - - /* else go back until we have a keyframe */ - while (TRUE) { - if (str->samples[index].keyframe) - break; - - if (index == 0) - break; - - index--; - } - return index; -} - -/* find the segment for @time_position for @stream - * - * Returns -1 if the segment cannot be found. - */ -static guint32 -gst_qtdemux_find_segment (GstQTDemux * qtdemux, QtDemuxStream * stream, - guint64 time_position) -{ - gint i; - guint32 seg_idx; - - /* find segment corresponding to time_position if we are looking - * for a segment. */ - seg_idx = -1; - for (i = 0; i < stream->n_segments; i++) { - QtDemuxSegment *segment = &stream->segments[i]; - - if (segment->time <= time_position && time_position < segment->stop_time) { - seg_idx = i; - break; - } - } - return seg_idx; -} - -/* move the stream @str to the sample position @index. - * - * Updates @str->sample_index and marks discontinuity if needed. - */ -static void -gst_qtdemux_move_stream (GstQTDemux * qtdemux, QtDemuxStream * str, - guint32 index) -{ - /* no change needed */ - if (index == str->sample_index) - return; - - GST_DEBUG_OBJECT (qtdemux, "moving to sample %u of %u", index, - str->n_samples); - - /* position changed, we have a discont */ - str->sample_index = index; - str->discont = TRUE; -} - -/* perform the seek. - * - * We set all segment_indexes in the streams to unknown and - * adjust the time_position to the desired position. this is enough - * to trigger a segment switch in the streaming thread to start - * streaming from the desired position. - * - * Keyframe seeking is a little more complicated when dealing with - * segments. Ideally we want to move to the previous keyframe in - * the segment but there might not be a keyframe in the segment. In - * fact, none of the segments could contain a keyframe. We take a - * practical approach: seek to the previous keyframe in the segment, - * if there is none, seek to the beginning of the segment. - * - * Called with STREAM_LOCK - */ -static gboolean -gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment) -{ - gint64 desired_offset; - gint n; - - desired_offset = segment->last_stop; - - GST_DEBUG_OBJECT (qtdemux, "seeking to %" GST_TIME_FORMAT, - GST_TIME_ARGS (desired_offset)); - - if (segment->flags & GST_SEEK_FLAG_KEY_UNIT) { - guint64 min_offset; - - min_offset = desired_offset; - - /* for each stream, find the index of the sample in the segment - * and move back to the previous keyframe. */ - for (n = 0; n < qtdemux->n_streams; n++) { - QtDemuxStream *str; - guint32 index, kindex; - guint32 seg_idx; - guint64 media_start; - guint64 media_time; - guint64 seg_time; - QtDemuxSegment *seg; - - str = qtdemux->streams[n]; - - seg_idx = gst_qtdemux_find_segment (qtdemux, str, desired_offset); - GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx); - - /* segment not found, continue with normal flow */ - if (seg_idx == -1) - continue; - - /* get segment and time in the segment */ - seg = &str->segments[seg_idx]; - seg_time = desired_offset - seg->time; - - /* get the media time in the segment */ - media_start = seg->media_start + seg_time; - - /* get the index of the sample with media time */ - index = gst_qtdemux_find_index (qtdemux, str, media_start); - GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u", - GST_TIME_ARGS (media_start), index); - - /* find previous keyframe */ - kindex = gst_qtdemux_find_keyframe (qtdemux, str, index); - - GST_DEBUG_OBJECT (qtdemux, "keyframe at %u", kindex); - - /* if the keyframe is at a different position, we need to update the - * requiested seek time */ - if (index != kindex) { - index = kindex; - - /* get timestamp of keyframe */ - media_time = str->samples[kindex].timestamp; - GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT, - kindex, GST_TIME_ARGS (media_time)); - - /* keyframes in the segment get a chance to change the - * desired_offset. keyframes out of the segment are - * ignored. */ - if (media_time >= seg->media_start) { - guint64 seg_time; - - /* this keyframe is inside the segment, convert back to - * segment time */ - seg_time = (media_time - seg->media_start) + seg->time; - if (seg_time < min_offset) - min_offset = seg_time; - } - } - } - GST_DEBUG_OBJECT (qtdemux, "keyframe seek, align to %" - GST_TIME_FORMAT, GST_TIME_ARGS (desired_offset)); - desired_offset = min_offset; - } - - /* and set all streams to the final position */ - for (n = 0; n < qtdemux->n_streams; n++) { - QtDemuxStream *stream = qtdemux->streams[n]; - - stream->time_position = desired_offset; - stream->sample_index = 0; - stream->segment_index = -1; - stream->last_ret = GST_FLOW_OK; - } - segment->last_stop = desired_offset; - segment->time = desired_offset; - - /* we stop at the end */ - if (segment->stop == -1) - segment->stop = segment->duration; - - return TRUE; -} - -/* do a seek in pull based mode */ -static gboolean -gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event) -{ - gdouble rate; - GstFormat format; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gboolean flush; - gboolean res; - gboolean update; - GstSegment seeksegment; - int i; - - if (event) { - GST_DEBUG_OBJECT (qtdemux, "doing seek with event"); - - gst_event_parse_seek (event, &rate, &format, &flags, - &cur_type, &cur, &stop_type, &stop); - - /* we have to have a format as the segment format. Try to convert - * if not. */ - if (format != GST_FORMAT_TIME) { - GstFormat fmt; - - fmt = GST_FORMAT_TIME; - res = TRUE; - if (cur_type != GST_SEEK_TYPE_NONE) - res = gst_pad_query_convert (pad, format, cur, &fmt, &cur); - if (res && stop_type != GST_SEEK_TYPE_NONE) - res = gst_pad_query_convert (pad, format, stop, &fmt, &stop); - if (!res) - goto no_format; - - format = fmt; - } - } else { - GST_DEBUG_OBJECT (qtdemux, "doing seek without event"); - flags = 0; - } - - flush = flags & GST_SEEK_FLAG_FLUSH; - - GST_DEBUG_OBJECT (qtdemux, "seek format %d", format); - - /* stop streaming, either by flushing or by pausing the task */ - if (flush) { - /* unlock upstream pull_range */ - gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_start ()); - /* make sure out loop function exits */ - gst_qtdemux_push_event (qtdemux, gst_event_new_flush_start ()); - } else { - /* non flushing seek, pause the task */ - gst_pad_pause_task (qtdemux->sinkpad); - } - - /* wait for streaming to finish */ - GST_PAD_STREAM_LOCK (qtdemux->sinkpad); - - /* copy segment, we need this because we still need the old - * segment when we close the current segment. */ - memcpy (&seeksegment, &qtdemux->segment, sizeof (GstSegment)); - - if (event) { - /* configure the segment with the seek variables */ - GST_DEBUG_OBJECT (qtdemux, "configuring seek"); - gst_segment_set_seek (&seeksegment, rate, format, flags, - cur_type, cur, stop_type, stop, &update); - } - - /* now do the seek, this actually never returns FALSE */ - res = gst_qtdemux_perform_seek (qtdemux, &seeksegment); - - /* prepare for streaming again */ - if (flush) { - gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop ()); - gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop ()); - } else if (qtdemux->segment_running) { - /* we are running the current segment and doing a non-flushing seek, - * close the segment first based on the last_stop. */ - GST_DEBUG_OBJECT (qtdemux, "closing running segment %" G_GINT64_FORMAT - " to %" G_GINT64_FORMAT, qtdemux->segment.start, - qtdemux->segment.last_stop); - - /* FIXME, needs to be done from the streaming thread. Also, the rate is the - * product of the global rate and the (quicktime) segment rate. */ - gst_qtdemux_push_event (qtdemux, - gst_event_new_new_segment (TRUE, - qtdemux->segment.rate, qtdemux->segment.format, - qtdemux->segment.start, qtdemux->segment.last_stop, - qtdemux->segment.time)); - } - - /* commit the new segment */ - memcpy (&qtdemux->segment, &seeksegment, sizeof (GstSegment)); - - if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) { - gst_element_post_message (GST_ELEMENT_CAST (qtdemux), - gst_message_new_segment_start (GST_OBJECT_CAST (qtdemux), - qtdemux->segment.format, qtdemux->segment.last_stop)); - } - - /* restart streaming, NEWSEGMENT will be sent from the streaming - * thread. */ - qtdemux->segment_running = TRUE; - for (i = 0; i < qtdemux->n_streams; i++) - qtdemux->streams[i]->last_ret = GST_FLOW_OK; - - gst_pad_start_task (qtdemux->sinkpad, (GstTaskFunction) gst_qtdemux_loop, - qtdemux->sinkpad); - - GST_PAD_STREAM_UNLOCK (qtdemux->sinkpad); - - return TRUE; - - /* ERRORS */ -no_format: - { - GST_DEBUG_OBJECT (qtdemux, "unsupported format given, seek aborted."); - return FALSE; - } -} - -static gboolean -gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - if (qtdemux->pullbased) { - res = gst_qtdemux_do_seek (qtdemux, pad, event); - } else { - GST_DEBUG_OBJECT (qtdemux, "cannot seek in streaming mode"); - res = FALSE; - } - break; - default: - res = FALSE; - break; - } - - gst_object_unref (qtdemux); - - gst_event_unref (event); - - return res; -} - -static gboolean -gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event) -{ - GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad)); - gboolean res; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - /* We need to convert it to a GST_FORMAT_TIME new segment */ - gst_event_unref (event); - res = TRUE; - break; - default: - res = gst_pad_event_default (demux->sinkpad, event); - break; - } - - return res; -} - -static GstStateChangeReturn -gst_qtdemux_change_state (GstElement * element, GstStateChange transition) -{ - GstQTDemux *qtdemux = GST_QTDEMUX (element); - GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE; - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - default: - break; - } - - result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY:{ - gint n; - - qtdemux->state = QTDEMUX_STATE_INITIAL; - qtdemux->last_ts = GST_CLOCK_TIME_NONE; - qtdemux->neededbytes = 16; - qtdemux->todrop = 0; - qtdemux->pullbased = FALSE; - qtdemux->offset = 0; - qtdemux->mdatoffset = GST_CLOCK_TIME_NONE; - if (qtdemux->mdatbuffer) - gst_buffer_unref (qtdemux->mdatbuffer); - qtdemux->mdatbuffer = NULL; - gst_adapter_clear (qtdemux->adapter); - for (n = 0; n < qtdemux->n_streams; n++) { - QtDemuxStream *stream = qtdemux->streams[n]; - - if (stream->pad) - gst_element_remove_pad (element, stream->pad); - g_free (stream->samples); - if (stream->caps) - gst_caps_unref (stream->caps); - g_free (stream->segments); - g_free (stream); - } - qtdemux->n_streams = 0; - qtdemux->n_video_streams = 0; - qtdemux->n_audio_streams = 0; - gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME); - break; - } - default: - break; - } - - return result; -} - -static void -extract_initial_length_and_fourcc (guint8 * data, guint64 * plength, - guint32 * pfourcc) -{ - guint64 length; - guint32 fourcc; - - length = QT_UINT32 (data); - GST_DEBUG ("length %08" G_GINT64_MODIFIER "x", length); - fourcc = QT_FOURCC (data + 4); - GST_DEBUG ("atom type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc)); - - if (length == 0) { - length = G_MAXUINT32; - } else if (length == 1) { - /* this means we have an extended size, which is the 64 bit value of - * the next 8 bytes */ - length = QT_UINT64 (data + 8); - GST_DEBUG ("length %08llx", length); - } - - if (plength) - *plength = length; - if (pfourcc) - *pfourcc = fourcc; -} - -static GstFlowReturn -gst_qtdemux_loop_state_header (GstQTDemux * qtdemux) -{ - guint64 length; - guint32 fourcc; - GstBuffer *buf = NULL; - GstFlowReturn ret = GST_FLOW_OK; - guint64 cur_offset = qtdemux->offset; - - ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, 16, &buf); - if (ret != GST_FLOW_OK) - goto beach; - extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), &length, &fourcc); - gst_buffer_unref (buf); - - switch (fourcc) { - case FOURCC_mdat: - case FOURCC_free: - case FOURCC_wide: - case FOURCC_PICT: - case FOURCC_pnot: - { - GST_LOG_OBJECT (qtdemux, - "skipping atom '%" GST_FOURCC_FORMAT "' at %" G_GUINT64_FORMAT, - GST_FOURCC_ARGS (fourcc), cur_offset); - cur_offset += length; - qtdemux->offset += length; - break; - } - case FOURCC_moov: - { - GstBuffer *moov; - - ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &moov); - if (ret != GST_FLOW_OK) - goto beach; - if (length != GST_BUFFER_SIZE (moov)) { - GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE, - (_("This file is incomplete and cannot be played.")), - ("We got less than expected (received %u, wanted %u)", - GST_BUFFER_SIZE (moov), (guint) length)); - ret = GST_FLOW_ERROR; - goto beach; - } - cur_offset += length; - qtdemux->offset += length; - - qtdemux_parse_moov (qtdemux, GST_BUFFER_DATA (moov), length); - qtdemux_node_dump (qtdemux, qtdemux->moov_node); - - qtdemux_parse_tree (qtdemux); - g_node_destroy (qtdemux->moov_node); - gst_buffer_unref (moov); - qtdemux->moov_node = NULL; - qtdemux->state = QTDEMUX_STATE_MOVIE; - GST_DEBUG_OBJECT (qtdemux, "switching state to STATE_MOVIE (%d)", - qtdemux->state); - break; - } - default: - { - GST_LOG_OBJECT (qtdemux, - "unknown %08x '%" GST_FOURCC_FORMAT "' at %" G_GUINT64_FORMAT, fourcc, - GST_FOURCC_ARGS (fourcc), cur_offset); - cur_offset += length; - qtdemux->offset += length; - break; - } - } - -beach: - return ret; -} - -/* activate the given segment number @seg_idx of @stream at time @offset. - * @offset is an absolute global position over all the segments. - * - * This will push out a NEWSEGMENT event with the right values and - * position the stream index to the first decodable sample before - * @offset. - */ -static gboolean -gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream, - guint32 seg_idx, guint64 offset) -{ - GstEvent *event; - QtDemuxSegment *segment; - guint32 index, kf_index; - guint64 seg_time; - guint64 start, stop; - gdouble rate; - - /* update the current segment */ - stream->segment_index = seg_idx; - - /* get the segment */ - segment = &stream->segments[seg_idx]; - - if (offset < segment->time) - return FALSE; - - /* get time in this segment */ - seg_time = offset - segment->time; - - if (seg_time >= segment->duration) - return FALSE; - - /* calc media start/stop */ - if (qtdemux->segment.stop == -1) - stop = segment->media_stop; - else - stop = MIN (segment->media_stop, qtdemux->segment.stop); - start = MIN (segment->media_start + seg_time, stop); - - GST_DEBUG_OBJECT (qtdemux, "newsegment %d from %" GST_TIME_FORMAT - " to %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, seg_idx, - GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (offset)); - - /* combine global rate with that of the segment */ - rate = segment->rate * qtdemux->segment.rate; - event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME, - start, stop, offset); - - if (stream->pad) - gst_pad_push_event (stream->pad, event); - - /* and move to the keyframe before the indicated media time of the - * segment */ - index = gst_qtdemux_find_index (qtdemux, stream, start); - - GST_DEBUG_OBJECT (qtdemux, "moving data pointer to %" GST_TIME_FORMAT - ", index: %u", GST_TIME_ARGS (start), index); - - /* we're at the right spot */ - if (index == stream->sample_index) - return TRUE; - - /* find keyframe of the target index */ - kf_index = gst_qtdemux_find_keyframe (qtdemux, stream, index); - - /* if we move forwards, we don't have to go back to the previous - * keyframe since we already sent that. We can also just jump to - * the keyframe right before the target index if there is one. */ - if (index > stream->sample_index) { - /* moving forwards check if we move past a keyframe */ - if (kf_index > stream->sample_index) { - GST_DEBUG_OBJECT (qtdemux, "moving forwards to keyframe at %u", kf_index); - gst_qtdemux_move_stream (qtdemux, stream, kf_index); - } else { - GST_DEBUG_OBJECT (qtdemux, "moving forwards, keyframe at %u already sent", - kf_index); - } - } else { - GST_DEBUG_OBJECT (qtdemux, "moving backwards to keyframe at %u", kf_index); - gst_qtdemux_move_stream (qtdemux, stream, kf_index); - } - - return TRUE; -} - -/* prepare to get the current sample of @stream, getting essential values. - * - * This function will also prepare and send the segment when needed. - * - * Return FALSE if the stream is EOS. - */ -static gboolean -gst_qtdemux_prepare_current_sample (GstQTDemux * qtdemux, - QtDemuxStream * stream, guint64 * offset, guint * size, guint64 * timestamp, - guint64 * duration, gboolean * keyframe) -{ - QtDemuxSample *sample; - guint64 time_position; - guint32 seg_idx; - - g_return_val_if_fail (stream != NULL, FALSE); - - time_position = stream->time_position; - if (time_position == -1) - goto eos; - - seg_idx = stream->segment_index; - if (seg_idx == -1) { - /* find segment corresponding to time_position if we are looking - * for a segment. */ - seg_idx = gst_qtdemux_find_segment (qtdemux, stream, time_position); - - /* nothing found, we're really eos */ - if (seg_idx == -1) - goto eos; - } - - /* different segment, activate it, sample_index will be set. */ - if (stream->segment_index != seg_idx) - gst_qtdemux_activate_segment (qtdemux, stream, seg_idx, time_position); - - GST_LOG_OBJECT (qtdemux, "segment active, index = %u of %u", - stream->sample_index, stream->n_samples); - - if (stream->sample_index >= stream->n_samples) - goto eos; - - /* now get the info for the sample we're at */ - sample = &stream->samples[stream->sample_index]; - - *timestamp = sample->timestamp + sample->pts_offset; - *offset = sample->offset; - *size = sample->size; - *duration = sample->duration; - *keyframe = stream->all_keyframe || sample->keyframe; - - return TRUE; - - /* special cases */ -eos: - { - stream->time_position = -1; - return FALSE; - } -} - -/* move to the next sample in @stream. - * - * Moves to the next segment when needed. - */ -static void -gst_qtdemux_advance_sample (GstQTDemux * qtdemux, QtDemuxStream * stream) -{ - QtDemuxSample *sample; - QtDemuxSegment *segment; - - /* move to next sample */ - stream->sample_index++; - - /* get current segment */ - segment = &stream->segments[stream->segment_index]; - - /* reached the last sample, we need the next segment */ - if (stream->sample_index >= stream->n_samples) - goto next_segment; - - /* get next sample */ - sample = &stream->samples[stream->sample_index]; - - /* see if we are past the segment */ - if (sample->timestamp >= segment->media_stop) - goto next_segment; - - if (sample->timestamp >= segment->media_start) { - /* inside the segment, update time_position, looks very familiar to - * GStreamer segments, doesn't it? */ - stream->time_position = - (sample->timestamp - segment->media_start) + segment->time; - } else { - /* not yet in segment, time does not yet increment. This means - * that we are still prerolling keyframes to the decoder so it can - * decode the first sample of the segment. */ - stream->time_position = segment->time; - } - return; - - /* move to the next segment */ -next_segment: - { - GST_DEBUG_OBJECT (qtdemux, "segment %d ended ", stream->segment_index); - - if (stream->segment_index == stream->n_segments - 1) { - /* are we at the end of the last segment, we're EOS */ - stream->time_position = -1; - } else { - /* else we're only at the end of the current segment */ - stream->time_position = segment->stop_time; - } - /* make sure we select a new segment */ - stream->segment_index = -1; - } -} - -static GstFlowReturn -gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream, - GstFlowReturn ret) -{ - gint i; - - /* store the value */ - stream->last_ret = ret; - - /* any other error that is not-linked can be returned right - * away */ - if (ret != GST_FLOW_NOT_LINKED) - goto done; - - /* only return NOT_LINKED if all other pads returned NOT_LINKED */ - for (i = 0; i < demux->n_streams; i++) { - QtDemuxStream *ostream = demux->streams[i]; - - ret = ostream->last_ret; - /* some other return value (must be SUCCESS but we can return - * other values as well) */ - if (ret != GST_FLOW_NOT_LINKED) - goto done; - } - /* if we get here, all other pads were unlinked and we return - * NOT_LINKED then */ -done: - GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret)); - return ret; -} - -static GstFlowReturn -gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux) -{ - GstFlowReturn ret = GST_FLOW_OK; - GstBuffer *buf = NULL; - QtDemuxStream *stream; - guint64 min_time; - guint64 offset; - guint64 timestamp; - guint64 duration; - gboolean keyframe; - guint size; - gint index; - gint i; - - /* Figure out the next stream sample to output, min_time is expressed in - * global time and runs over the edit list segments. */ - min_time = G_MAXUINT64; - index = -1; - for (i = 0; i < qtdemux->n_streams; i++) { - guint64 position; - - stream = qtdemux->streams[i]; - position = stream->time_position; - - /* position of -1 is EOS */ - if (position != -1 && position < min_time) { - min_time = position; - index = i; - } - } - /* all are EOS */ - if (index == -1) - goto eos; - - /* check for segment end */ - if (qtdemux->segment.stop != -1 && qtdemux->segment.stop < min_time) - goto eos; - - stream = qtdemux->streams[index]; - - /* fetch info for the current sample of this stream */ - if (!gst_qtdemux_prepare_current_sample (qtdemux, stream, &offset, &size, - ×tamp, &duration, &keyframe)) - goto eos; - - GST_LOG_OBJECT (qtdemux, - "pushing from stream %d, offset=%" G_GUINT64_FORMAT - ",size=%d timestamp=%" GST_TIME_FORMAT, - index, offset, size, GST_TIME_ARGS (timestamp)); - - /* hmm, empty sample, skip and move to next sample */ - if (G_UNLIKELY (size <= 0)) - goto next; - - GST_LOG_OBJECT (qtdemux, "reading %d bytes @ %" G_GUINT64_FORMAT, size, - offset); - - ret = gst_pad_pull_range (qtdemux->sinkpad, offset, size, &buf); - if (ret != GST_FLOW_OK) - goto beach; - - if (stream->fourcc == FOURCC_rtsp) { - GstMessage *m; - gchar *url; - - url = g_strndup ((gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - - /* we have RTSP redirect now */ - m = gst_message_new_element (GST_OBJECT_CAST (qtdemux), - gst_structure_new ("redirect", - "new-location", G_TYPE_STRING, url, NULL)); - g_free (url); - - gst_element_post_message (GST_ELEMENT_CAST (qtdemux), m); - } - - qtdemux->last_ts = min_time; - gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, min_time); - - if (stream->pad) { - /* we're going to modify the metadata */ - buf = gst_buffer_make_metadata_writable (buf); - - if (stream->discont) { - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); - stream->discont = FALSE; - } - - GST_BUFFER_TIMESTAMP (buf) = timestamp; - GST_BUFFER_DURATION (buf) = duration; - - if (!keyframe) - GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); - - gst_buffer_set_caps (buf, stream->caps); - - GST_LOG_OBJECT (qtdemux, - "Pushing buffer with time %" GST_TIME_FORMAT ", duration %" - GST_TIME_FORMAT " on pad %s", - GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration), - GST_PAD_NAME (stream->pad)); - ret = gst_pad_push (stream->pad, buf); - } else { - ret = GST_FLOW_OK; - } - - /* combine flows */ - ret = gst_qtdemux_combine_flows (qtdemux, stream, ret); - -next: - gst_qtdemux_advance_sample (qtdemux, stream); - -beach: - return ret; - - /* special cases */ -eos: - { - GST_DEBUG_OBJECT (qtdemux, "No samples left for any streams - EOS"); - ret = GST_FLOW_UNEXPECTED; - goto beach; - } -} - -static void -gst_qtdemux_loop (GstPad * pad) -{ - GstQTDemux *qtdemux; - guint64 cur_offset; - GstFlowReturn ret; - - qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad)); - - cur_offset = qtdemux->offset; - GST_LOG_OBJECT (qtdemux, "loop at position %" G_GUINT64_FORMAT ", state %d", - cur_offset, qtdemux->state); - - switch (qtdemux->state) { - case QTDEMUX_STATE_INITIAL: - case QTDEMUX_STATE_HEADER: - ret = gst_qtdemux_loop_state_header (qtdemux); - break; - case QTDEMUX_STATE_MOVIE: - ret = gst_qtdemux_loop_state_movie (qtdemux); - break; - default: - /* ouch */ - goto invalid_state; - } - - /* if something went wrong, pause */ - if (ret != GST_FLOW_OK) - goto pause; - -done: - gst_object_unref (qtdemux); - return; - - /* ERRORS */ -invalid_state: - { - GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED, - (NULL), ("streaming stopped, invalid state")); - qtdemux->segment_running = FALSE; - gst_pad_pause_task (pad); - gst_qtdemux_push_event (qtdemux, gst_event_new_eos ()); - goto done; - } -pause: - { - const gchar *reason = gst_flow_get_name (ret); - - GST_LOG_OBJECT (qtdemux, "pausing task, reason %s", reason); - - qtdemux->segment_running = FALSE; - gst_pad_pause_task (pad); - - /* fatal errors need special actions */ - if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) { - /* check EOS */ - if (ret == GST_FLOW_UNEXPECTED) { - if (qtdemux->n_streams == 0) { - /* we have no streams, post an error */ - GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE, - (_("This file contains no playable streams.")), - ("no known streams found")); - } - if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) { - gint64 stop; - - if ((stop = qtdemux->segment.stop) == -1) - stop = qtdemux->segment.duration; - - GST_LOG_OBJECT (qtdemux, "Sending segment done, at end of segment"); - gst_element_post_message (GST_ELEMENT_CAST (qtdemux), - gst_message_new_segment_done (GST_OBJECT_CAST (qtdemux), - GST_FORMAT_TIME, stop)); - } else { - GST_LOG_OBJECT (qtdemux, "Sending EOS at end of segment"); - gst_qtdemux_push_event (qtdemux, gst_event_new_eos ()); - } - } else { - GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED, - (NULL), ("streaming stopped, reason %s", reason)); - gst_qtdemux_push_event (qtdemux, gst_event_new_eos ()); - } - } - goto done; - } -} - -/* - * next_entry_size - * - * Returns the size of the first entry at the current offset. - * If -1, there are none (which means EOS or empty file). - */ -static guint64 -next_entry_size (GstQTDemux * demux) -{ - QtDemuxStream *stream; - int i; - int smallidx = -1; - guint64 smalloffs = (guint64) - 1; - - GST_LOG_OBJECT (demux, "Finding entry at offset %lld", demux->offset); - - for (i = 0; i < demux->n_streams; i++) { - stream = demux->streams[i]; - - GST_LOG_OBJECT (demux, - "Checking Stream %d (sample_index:%d / offset:%lld / size:%d / chunk:%d)", - i, stream->sample_index, stream->samples[stream->sample_index].offset, - stream->samples[stream->sample_index].size, - stream->samples[stream->sample_index].chunk); - - if (((smalloffs == -1) - || (stream->samples[stream->sample_index].offset < smalloffs)) - && (stream->samples[stream->sample_index].size)) { - smallidx = i; - smalloffs = stream->samples[stream->sample_index].offset; - } - } - - GST_LOG_OBJECT (demux, "stream %d offset %lld demux->offset :%lld", - smallidx, smalloffs, demux->offset); - - if (smallidx == -1) - return -1; - stream = demux->streams[smallidx]; - - if (stream->samples[stream->sample_index].offset >= demux->offset) { - demux->todrop = - stream->samples[stream->sample_index].offset - demux->offset; - return stream->samples[stream->sample_index].size + demux->todrop; - } - - GST_DEBUG_OBJECT (demux, "There wasn't any entry at offset %lld", - demux->offset); - return -1; -} - -static void -gst_qtdemux_post_progress (GstQTDemux * demux, gint num, gint denom) -{ - gint perc = (gint) ((gdouble) num * 100.0 / (gdouble) denom); - - gst_element_post_message (GST_ELEMENT_CAST (demux), - gst_message_new_element (GST_OBJECT_CAST (demux), - gst_structure_new ("progress", "percent", G_TYPE_INT, perc, NULL))); -} - -/* FIXME, unverified after edit list updates */ -static GstFlowReturn -gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf) -{ - GstQTDemux *demux; - GstFlowReturn ret = GST_FLOW_OK; - - demux = GST_QTDEMUX (gst_pad_get_parent (sinkpad)); - - gst_adapter_push (demux->adapter, inbuf); - - GST_DEBUG_OBJECT (demux, "pushing in inbuf %p, neededbytes:%u, available:%u", - inbuf, demux->neededbytes, gst_adapter_available (demux->adapter)); - - while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) && - (ret == GST_FLOW_OK)) { - - GST_DEBUG_OBJECT (demux, - "state:%d , demux->neededbytes:%d, demux->offset:%lld", demux->state, - demux->neededbytes, demux->offset); - - switch (demux->state) { - case QTDEMUX_STATE_INITIAL:{ - const guint8 *data; - guint32 fourcc; - guint64 size; - - data = gst_adapter_peek (demux->adapter, demux->neededbytes); - - /* get fourcc/length, set neededbytes */ - extract_initial_length_and_fourcc ((guint8 *) data, &size, &fourcc); - GST_DEBUG_OBJECT (demux, - "Peeking found [%" GST_FOURCC_FORMAT "] size: %u", - GST_FOURCC_ARGS (fourcc), (guint) size); - if (fourcc == FOURCC_mdat) { - if (demux->n_streams > 0) { - demux->state = QTDEMUX_STATE_MOVIE; - demux->neededbytes = next_entry_size (demux); - } else { - demux->state = QTDEMUX_STATE_BUFFER_MDAT; - demux->neededbytes = size; - demux->mdatoffset = demux->offset; - } - } else { - demux->neededbytes = size; - demux->state = QTDEMUX_STATE_HEADER; - } - break; - } - case QTDEMUX_STATE_HEADER:{ - guint8 *data; - guint32 fourcc; - - GST_DEBUG_OBJECT (demux, "In header"); - - data = gst_adapter_take (demux->adapter, demux->neededbytes); - - /* parse the header */ - extract_initial_length_and_fourcc (data, NULL, &fourcc); - if (fourcc == FOURCC_moov) { - GST_DEBUG_OBJECT (demux, "Parsing [moov]"); - - qtdemux_parse_moov (demux, data, demux->neededbytes); - qtdemux_node_dump (demux, demux->moov_node); - qtdemux_parse_tree (demux); - - g_node_destroy (demux->moov_node); - g_free (data); - demux->moov_node = NULL; - } else { - GST_WARNING_OBJECT (demux, - "Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - /* Let's jump that one and go back to initial state */ - } - - GST_DEBUG_OBJECT (demux, "Finished parsing the header"); - if (demux->mdatbuffer && demux->n_streams) { - /* the mdat was before the header */ - GST_DEBUG_OBJECT (demux, "We have n_streams:%d and mdatbuffer:%p", - demux->n_streams, demux->mdatbuffer); - gst_adapter_clear (demux->adapter); - GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (QT_UINT32 (demux->mdatbuffer))); - gst_adapter_push (demux->adapter, demux->mdatbuffer); - demux->mdatbuffer = NULL; - demux->offset = demux->mdatoffset; - demux->neededbytes = next_entry_size (demux); - demux->state = QTDEMUX_STATE_MOVIE; - } else { - GST_DEBUG_OBJECT (demux, "Carrying on normally"); - demux->offset += demux->neededbytes; - demux->neededbytes = 16; - demux->state = QTDEMUX_STATE_INITIAL; - } - - break; - } - case QTDEMUX_STATE_BUFFER_MDAT:{ - GST_DEBUG_OBJECT (demux, "Got our buffer at offset %lld", - demux->mdatoffset); - if (demux->mdatbuffer) - gst_buffer_unref (demux->mdatbuffer); - demux->mdatbuffer = gst_buffer_new (); - gst_buffer_set_data (demux->mdatbuffer, - gst_adapter_take (demux->adapter, demux->neededbytes), - demux->neededbytes); - GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (QT_UINT32 (demux->mdatbuffer))); - demux->offset += demux->neededbytes; - demux->neededbytes = 16; - demux->state = QTDEMUX_STATE_INITIAL; - gst_qtdemux_post_progress (demux, 1, 1); - - break; - } - case QTDEMUX_STATE_MOVIE:{ - guint8 *data; - GstBuffer *outbuf; - QtDemuxStream *stream = NULL; - int i = -1; - - GST_DEBUG_OBJECT (demux, "BEGIN // in MOVIE for offset %lld", - demux->offset); - - if (demux->todrop) { - gst_adapter_flush (demux->adapter, demux->todrop); - demux->neededbytes -= demux->todrop; - demux->offset += demux->todrop; - } - - /* Figure out which stream this is packet belongs to */ - for (i = 0; i < demux->n_streams; i++) { - stream = demux->streams[i]; - GST_LOG_OBJECT (demux, - "Checking stream %d (sample_index:%d / offset:%lld / size:%d / chunk:%d)", - i, stream->sample_index, - stream->samples[stream->sample_index].offset, - stream->samples[stream->sample_index].size, - stream->samples[stream->sample_index].chunk); - - if (stream->samples[stream->sample_index].offset == demux->offset) - break; - } - - if (stream == NULL) - goto unknown_stream; - - /* first buffer? */ - /* FIXME : this should be handled in sink_event */ - if (demux->last_ts == GST_CLOCK_TIME_NONE) { - gst_qtdemux_push_event (demux, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - 0, GST_CLOCK_TIME_NONE, 0)); - } - - /* get data */ - data = gst_adapter_take (demux->adapter, demux->neededbytes); - - /* Put data in a buffer, set timestamps, caps, ... */ - outbuf = gst_buffer_new (); - gst_buffer_set_data (outbuf, data, demux->neededbytes); - GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (stream->fourcc)); - - if (stream->samples[stream->sample_index].pts_offset) { - demux->last_ts = stream->samples[stream->sample_index].timestamp; - GST_BUFFER_TIMESTAMP (outbuf) = demux->last_ts + - stream->samples[stream->sample_index].pts_offset; - } else { - GST_BUFFER_TIMESTAMP (outbuf) = - stream->samples[stream->sample_index].timestamp; - demux->last_ts = GST_BUFFER_TIMESTAMP (outbuf); - } - GST_BUFFER_DURATION (outbuf) = - stream->samples[stream->sample_index].duration; - - /* send buffer */ - if (stream->pad) { - GST_LOG_OBJECT (demux, - "Pushing buffer with time %" GST_TIME_FORMAT " on pad %p", - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), stream->pad); - gst_buffer_set_caps (outbuf, stream->caps); - ret = gst_pad_push (stream->pad, outbuf); - } else { - gst_buffer_unref (outbuf); - ret = GST_FLOW_OK; - } - - /* combine flows */ - ret = gst_qtdemux_combine_flows (demux, stream, ret); - - stream->sample_index++; - - /* update current offset and figure out size of next buffer */ - GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u", - demux->offset, demux->neededbytes); - demux->offset += demux->neededbytes; - GST_LOG_OBJECT (demux, "offset is now %lld", demux->offset); - - if ((demux->neededbytes = next_entry_size (demux)) == -1) - goto eos; - break; - } - default: - goto invalid_state; - } - } - - /* when buffering movie data, at least show user something is happening */ - if (ret == GST_FLOW_OK && demux->state == QTDEMUX_STATE_BUFFER_MDAT && - gst_adapter_available (demux->adapter) <= demux->neededbytes) { - gst_qtdemux_post_progress (demux, gst_adapter_available (demux->adapter), - demux->neededbytes); - } -done: - gst_object_unref (demux); - - return ret; - - /* ERRORS */ -unknown_stream: - { - GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), ("unknown stream found")); - ret = GST_FLOW_ERROR; - goto done; - } -eos: - { - GST_DEBUG_OBJECT (demux, "no next entry, EOS"); - ret = GST_FLOW_UNEXPECTED; - goto done; - } -invalid_state: - { - GST_ELEMENT_ERROR (demux, STREAM, FAILED, - (NULL), ("qtdemuxer invalid state %d", demux->state)); - ret = GST_FLOW_ERROR; - goto done; - } -} - -static gboolean -qtdemux_sink_activate (GstPad * sinkpad) -{ - if (gst_pad_check_pull_range (sinkpad)) - return gst_pad_activate_pull (sinkpad, TRUE); - else - return gst_pad_activate_push (sinkpad, TRUE); -} - -static gboolean -qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active) -{ - GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad)); - - if (active) { - demux->pullbased = TRUE; - demux->segment_running = TRUE; - gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop, sinkpad); - } else { - demux->segment_running = FALSE; - gst_pad_stop_task (sinkpad); - } - - return TRUE; -} - -static gboolean -qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active) -{ - GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad)); - - demux->pullbased = FALSE; - - return TRUE; -} - -#ifdef HAVE_ZLIB -static void * -qtdemux_zalloc (void *opaque, unsigned int items, unsigned int size) -{ - return g_malloc (items * size); -} - -static void -qtdemux_zfree (void *opaque, void *addr) -{ - g_free (addr); -} - -static void * -qtdemux_inflate (void *z_buffer, int z_length, int length) -{ - guint8 *buffer; - z_stream *z; - int ret; - - z = g_new0 (z_stream, 1); - z->zalloc = qtdemux_zalloc; - z->zfree = qtdemux_zfree; - z->opaque = NULL; - - z->next_in = z_buffer; - z->avail_in = z_length; - - buffer = (guint8 *) g_malloc (length); - ret = inflateInit (z); - while (z->avail_in > 0) { - if (z->avail_out == 0) { - length += 1024; - buffer = (guint8 *) g_realloc (buffer, length); - z->next_out = buffer + z->total_out; - z->avail_out = 1024; - } - ret = inflate (z, Z_SYNC_FLUSH); - if (ret != Z_OK) - break; - } - if (ret != Z_STREAM_END) { - g_warning ("inflate() returned %d", ret); - } - - g_free (z); - return buffer; -} -#endif /* HAVE_ZLIB */ - -static gboolean -qtdemux_parse_moov (GstQTDemux * qtdemux, guint8 * buffer, int length) -{ - GNode *cmov; - - qtdemux->moov_node = g_node_new (buffer); - - GST_DEBUG_OBJECT (qtdemux, "parsing 'moov' atom"); - qtdemux_parse_node (qtdemux, qtdemux->moov_node, buffer, length); - - cmov = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_cmov); - if (cmov) { - guint32 method; - GNode *dcom; - GNode *cmvd; - - dcom = qtdemux_tree_get_child_by_type (cmov, FOURCC_dcom); - cmvd = qtdemux_tree_get_child_by_type (cmov, FOURCC_cmvd); - if (dcom == NULL || cmvd == NULL) - goto invalid_compression; - - method = QT_FOURCC ((guint8 *) dcom->data + 8); - switch (method) { -#ifdef HAVE_ZLIB - case GST_MAKE_FOURCC ('z', 'l', 'i', 'b'):{ - int uncompressed_length; - int compressed_length; - guint8 *buf; - - uncompressed_length = QT_UINT32 ((guint8 *) cmvd->data + 8); - compressed_length = QT_UINT32 ((guint8 *) cmvd->data + 4) - 12; - GST_LOG ("length = %d", uncompressed_length); - - buf = - (guint8 *) qtdemux_inflate ((guint8 *) cmvd->data + 12, - compressed_length, uncompressed_length); - - qtdemux->moov_node_compressed = qtdemux->moov_node; - qtdemux->moov_node = g_node_new (buf); - - qtdemux_parse_node (qtdemux, qtdemux->moov_node, buf, - uncompressed_length); - break; - } -#endif /* HAVE_ZLIB */ - default: - GST_WARNING_OBJECT (qtdemux, "unknown or unhandled header compression " - "type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (method)); - break; - } - } - return TRUE; - - /* ERRORS */ -invalid_compression: - { - GST_ERROR_OBJECT (qtdemux, "invalid compressed header"); - return FALSE; - } -} - -static gboolean -qtdemux_parse_container (GstQTDemux * qtdemux, GNode * node, guint8 * buf, - guint8 * end) -{ - while (buf < end) { - GNode *child; - guint32 len; - - if (buf + 4 > end) { - GST_LOG_OBJECT (qtdemux, "buffer overrun"); - break; - } - len = QT_UINT32 (buf); - if (len == 0) { - GST_LOG_OBJECT (qtdemux, "empty container"); - break; - } - if (len < 8) { - GST_WARNING_OBJECT (qtdemux, "length too short (%d < 8)", len); - break; - } - if (len > (end - buf)) { - GST_WARNING_OBJECT (qtdemux, "length too long (%d > %d)", len, end - buf); - break; - } - - child = g_node_new (buf); - g_node_append (node, child); - qtdemux_parse_node (qtdemux, child, buf, len); - - buf += len; - } - return TRUE; -} - -static gboolean -qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, guint8 * buffer, - int length) -{ - guint32 fourcc; - guint32 node_length; - const QtNodeType *type; - guint8 *end; - - GST_LOG_OBJECT (qtdemux, "qtdemux_parse buffer %p length %d", buffer, length); - - node_length = QT_UINT32 (buffer); - fourcc = QT_FOURCC (buffer + 4); - - type = qtdemux_type_get (fourcc); - - /* ignore empty nodes */ - if (fourcc == 0 || node_length == 8) - return TRUE; - - end = buffer + length; - - GST_LOG_OBJECT (qtdemux, - "parsing '%" GST_FOURCC_FORMAT "', length=%d, name '%s'", - GST_FOURCC_ARGS (fourcc), node_length, type->name); - - if (type->flags & QT_FLAG_CONTAINER) { - qtdemux_parse_container (qtdemux, node, buffer + 8, end); - } else { - switch (fourcc) { - case FOURCC_stsd: - { - if (node_length < 20) { - GST_LOG_OBJECT (qtdemux, "skipping small stsd box"); - break; - } - GST_DEBUG_OBJECT (qtdemux, - "parsing stsd (sample table, sample description) atom"); - qtdemux_parse_container (qtdemux, node, buffer + 16, end); - break; - } - case FOURCC_mp4a: - { - guint32 version; - guint32 offset; - - if (length < 20) { - GST_LOG_OBJECT (qtdemux, "skipping small mp4a box"); - break; - } - version = QT_UINT32 (buffer + 16); - - GST_WARNING_OBJECT (qtdemux, "mp4a version 0x%08x", version); - - /* parse any esds descriptors */ - switch (version) { - case 0x00000000: - case 0x00010000: - offset = 0x24; - break; - case 0x00020000: - offset = 0x48; - break; - default: - GST_WARNING_OBJECT (qtdemux, "unhandled mp4a version 0x%08x", - version); - offset = 0; - break; - } - if (offset) - qtdemux_parse_container (qtdemux, node, buffer + offset, end); - break; - } - case FOURCC_mp4v: - { - guint8 *buf; - guint32 version; - int tlen; - - GST_DEBUG_OBJECT (qtdemux, "parsing in mp4v"); - version = QT_UINT32 (buffer + 16); - GST_DEBUG_OBJECT (qtdemux, "version %08x", version); - if (1 || version == 0x00000000) { - buf = buffer + 0x32; - - /* FIXME Quicktime uses PASCAL string while - * the iso format uses C strings. Check the file - * type before attempting to parse the string here. */ - tlen = QT_UINT8 (buf); - GST_DEBUG_OBJECT (qtdemux, "tlen = %d", tlen); - buf++; - GST_DEBUG_OBJECT (qtdemux, "string = %.*s", tlen, (char *) buf); - /* the string has a reserved space of 32 bytes so skip - * the remaining 31 */ - buf += 31; - buf += 4; /* and 4 bytes reserved */ - - qtdemux_dump_mem (buf, end - buf); - - qtdemux_parse_container (qtdemux, node, buf, end); - } - break; - } - case FOURCC_meta: - { - GST_DEBUG_OBJECT (qtdemux, "parsing meta atom"); - qtdemux_parse_container (qtdemux, node, buffer + 12, end); - break; - } - default: - break; - } - } - GST_LOG_OBJECT (qtdemux, "parsed '%" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - return TRUE; -} - -static GNode * -qtdemux_tree_get_child_by_type (GNode * node, guint32 fourcc) -{ - GNode *child; - guint8 *buffer; - guint32 child_fourcc; - - for (child = g_node_first_child (node); child; - child = g_node_next_sibling (child)) { - buffer = (guint8 *) child->data; - - child_fourcc = QT_FOURCC (buffer + 4); - - if (child_fourcc == fourcc) { - return child; - } - } - return NULL; -} - -static GNode * -qtdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc) -{ - GNode *child; - guint8 *buffer; - guint32 child_fourcc; - - for (child = g_node_next_sibling (node); child; - child = g_node_next_sibling (child)) { - buffer = (guint8 *) child->data; - - child_fourcc = QT_FOURCC (buffer + 4); - - if (child_fourcc == fourcc) { - return child; - } - } - return NULL; -} - -static gboolean -gst_qtdemux_add_stream (GstQTDemux * qtdemux, - QtDemuxStream * stream, GstTagList * list) -{ - if (qtdemux->n_streams >= GST_QTDEMUX_MAX_STREAMS) - goto too_many_streams; - - if (stream->subtype == FOURCC_vide) { - gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams); - - stream->pad = - gst_pad_new_from_static_template (&gst_qtdemux_videosrc_template, name); - g_free (name); - - /* fps is calculated base on the duration of the first frames since - * qt does not have a fixed framerate. */ - if ((stream->n_samples == 1) && (stream->min_duration == 0)) { - /* still frame */ - stream->fps_n = 0; - stream->fps_d = 1; - } else { - stream->fps_n = stream->timescale; - if (stream->min_duration == 0) - stream->fps_d = 1; - else - stream->fps_d = stream->min_duration; - } - - if (stream->caps) { - gboolean gray; - gint depth, palette_count; - const guint32 *palette_data = NULL; - - gst_caps_set_simple (stream->caps, - "width", G_TYPE_INT, stream->width, - "height", G_TYPE_INT, stream->height, - "framerate", GST_TYPE_FRACTION, stream->fps_n, stream->fps_d, NULL); - - depth = stream->bits_per_sample; - - /* more than 32 bits means grayscale */ - gray = (depth > 32); - /* low 32 bits specify the depth */ - depth &= 0x1F; - - /* different number of palette entries is determined by depth. */ - palette_count = 0; - if ((depth == 1) || (depth == 2) || (depth == 4) || (depth == 8)) - palette_count = (1 << depth); - - switch (palette_count) { - case 0: - break; - case 2: - palette_data = ff_qt_default_palette_2; - break; - case 4: - palette_data = ff_qt_default_palette_4; - break; - case 16: - if (gray) - palette_data = ff_qt_grayscale_palette_16; - else - palette_data = ff_qt_default_palette_16; - break; - case 256: - if (gray) - palette_data = ff_qt_grayscale_palette_256; - else - palette_data = ff_qt_default_palette_256; - break; - default: - GST_ELEMENT_WARNING (qtdemux, STREAM, DECODE, - (_("The video in this file might not play correctly.")), - ("unsupported palette depth %d", depth)); - break; - } - if (palette_data) { - GstBuffer *palette; - - /* make sure it's not writable. We leave MALLOCDATA to NULL so that we - * don't free any of the buffer data. */ - palette = gst_buffer_new (); - GST_BUFFER_FLAG_SET (palette, GST_BUFFER_FLAG_READONLY); - GST_BUFFER_DATA (palette) = (guint8 *) palette_data; - GST_BUFFER_SIZE (palette) = sizeof (guint32) * palette_count; - - gst_caps_set_simple (stream->caps, "palette_data", - GST_TYPE_BUFFER, palette, NULL); - gst_buffer_unref (palette); - } else if (palette_count != 0) { - GST_ELEMENT_WARNING (qtdemux, STREAM, NOT_IMPLEMENTED, - (NULL), ("Unsupported palette depth %d. Ignoring stream.", depth)); - - gst_object_unref (stream->pad); - stream->pad = NULL; - } - } - qtdemux->n_video_streams++; - } else if (stream->subtype == FOURCC_soun) { - gchar *name = g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams); - - stream->pad = - gst_pad_new_from_static_template (&gst_qtdemux_audiosrc_template, name); - g_free (name); - if (stream->caps) { - gst_caps_set_simple (stream->caps, - "rate", G_TYPE_INT, (int) stream->rate, - "channels", G_TYPE_INT, stream->n_channels, NULL); - } - qtdemux->n_audio_streams++; - } else if (stream->subtype == FOURCC_strm) { - GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad"); - } else { - GST_DEBUG_OBJECT (qtdemux, "unknown stream type"); - goto done; - } - - qtdemux->streams[qtdemux->n_streams] = stream; - qtdemux->n_streams++; - GST_DEBUG_OBJECT (qtdemux, "n_streams is now %d", qtdemux->n_streams); - - if (stream->pad) { - GST_PAD_ELEMENT_PRIVATE (stream->pad) = stream; - - gst_pad_use_fixed_caps (stream->pad); - gst_pad_set_event_function (stream->pad, gst_qtdemux_handle_src_event); - gst_pad_set_query_type_function (stream->pad, - gst_qtdemux_get_src_query_types); - gst_pad_set_query_function (stream->pad, gst_qtdemux_handle_src_query); - - GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps); - gst_pad_set_caps (stream->pad, stream->caps); - - GST_DEBUG_OBJECT (qtdemux, "adding pad %s %p to qtdemux %p", - GST_OBJECT_NAME (stream->pad), stream->pad, qtdemux); - gst_pad_set_active (stream->pad, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), stream->pad); - if (list) - gst_element_found_tags_for_pad (GST_ELEMENT_CAST (qtdemux), stream->pad, - list); - } -done: - return TRUE; - -too_many_streams: - { - GST_ELEMENT_WARNING (qtdemux, STREAM, DECODE, - (_("This file contains too many streams. Only playing first %d"), - GST_QTDEMUX_MAX_STREAMS), (NULL)); - return TRUE; - } -} - -/* collect all samples for @stream by reading the info from @stbl - */ -static gboolean -qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, - GNode * stbl) -{ - int offset; - GNode *stsc; - GNode *stsz; - GNode *stco; - GNode *co64; - GNode *stts; - GNode *stss; - GNode *ctts; - const guint8 *stsc_data, *stsz_data, *stco_data; - int sample_size; - int sample_index; - int n_samples; - int n_samples_per_chunk; - int n_sample_times; - QtDemuxSample *samples; - gint i, j, k; - int index; - guint64 timestamp, time; - - /* sample to chunk */ - if (!(stsc = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsc))) - goto corrupt_file; - stsc_data = (const guint8 *) stsc->data; - /* sample size */ - if (!(stsz = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsz))) - goto corrupt_file; - stsz_data = (const guint8 *) stsz->data; - /* chunk offsets */ - stco = qtdemux_tree_get_child_by_type (stbl, FOURCC_stco); - co64 = qtdemux_tree_get_child_by_type (stbl, FOURCC_co64); - if (stco) { - stco_data = (const guint8 *) stco->data; - } else { - stco_data = NULL; - if (co64 == NULL) - goto corrupt_file; - } - /* sample time */ - if (!(stts = qtdemux_tree_get_child_by_type (stbl, FOURCC_stts))) - goto corrupt_file; - - /* sample sync, can be NULL */ - stss = qtdemux_tree_get_child_by_type (stbl, FOURCC_stss); - - sample_size = QT_UINT32 (stsz_data + 12); - if (sample_size == 0 || stream->sampled) { - n_samples = QT_UINT32 (stsz_data + 16); - GST_DEBUG_OBJECT (qtdemux, "stsz sample_size 0, allocating n_samples %d", - n_samples); - stream->n_samples = n_samples; - samples = g_new0 (QtDemuxSample, n_samples); - stream->samples = samples; - - for (i = 0; i < n_samples; i++) { - if (sample_size == 0) - samples[i].size = QT_UINT32 (stsz_data + i * 4 + 20); - else - samples[i].size = sample_size; - - GST_LOG_OBJECT (qtdemux, "sample %d has size %d", i, samples[i].size); - /* init other fields to defaults for this sample */ - samples[i].keyframe = FALSE; - } - n_samples_per_chunk = QT_UINT32 (stsc_data + 12); - index = 0; - for (i = 0; i < n_samples_per_chunk; i++) { - guint32 first_chunk, last_chunk; - guint32 samples_per_chunk; - - first_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 0) - 1; - if (i == n_samples_per_chunk - 1) { - last_chunk = G_MAXUINT32; - } else { - last_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 12) - 1; - } - samples_per_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 4); - - for (j = first_chunk; j < last_chunk; j++) { - guint64 chunk_offset; - - if (stco) { - chunk_offset = QT_UINT32 (stco_data + 16 + j * 4); - } else { - chunk_offset = QT_UINT64 ((guint8 *) co64->data + 16 + j * 8); - } - for (k = 0; k < samples_per_chunk; k++) { - GST_LOG_OBJECT (qtdemux, "Creating entry %d with offset %lld", - index, chunk_offset); - samples[index].chunk = j; - samples[index].offset = chunk_offset; - chunk_offset += samples[index].size; - index++; - if (index >= n_samples) - goto done2; - } - } - } - done2: - - n_sample_times = QT_UINT32 ((guint8 *) stts->data + 12); - timestamp = 0; - stream->min_duration = 0; - time = 0; - index = 0; - for (i = 0; i < n_sample_times; i++) { - guint32 n; - guint32 duration; - - n = QT_UINT32 ((guint8 *) stts->data + 16 + 8 * i); - duration = QT_UINT32 ((guint8 *) stts->data + 16 + 8 * i + 4); - for (j = 0; j < n; j++) { - GST_INFO_OBJECT (qtdemux, "sample %d: timestamp %" GST_TIME_FORMAT, - index, GST_TIME_ARGS (timestamp)); - - samples[index].timestamp = timestamp; - /* take first duration for fps */ - if (stream->min_duration == 0) - stream->min_duration = duration; - /* add non-scaled values to avoid rounding errors */ - time += duration; - timestamp = gst_util_uint64_scale (time, GST_SECOND, stream->timescale); - samples[index].duration = timestamp - samples[index].timestamp; - - index++; - } - } - if (stss) { - /* mark keyframes */ - guint32 n_sample_syncs; - - n_sample_syncs = QT_UINT32 ((guint8 *) stss->data + 12); - if (n_sample_syncs == 0) { - stream->all_keyframe = TRUE; - } else { - offset = 16; - for (i = 0; i < n_sample_syncs; i++) { - /* note that the first sample is index 1, not 0 */ - index = QT_UINT32 ((guint8 *) stss->data + offset); - samples[index - 1].keyframe = TRUE; - offset += 4; - } - } - } else { - /* no stss, all samples are keyframes */ - stream->all_keyframe = TRUE; - } - } else { - GST_DEBUG_OBJECT (qtdemux, - "stsz sample_size %d != 0, treating chunks as samples", sample_size); - - /* treat chunks as samples */ - if (stco) { - n_samples = QT_UINT32 (stco_data + 12); - } else { - n_samples = QT_UINT32 ((guint8 *) co64->data + 12); - } - stream->n_samples = n_samples; - GST_DEBUG_OBJECT (qtdemux, "allocating n_samples %d", n_samples); - samples = g_new0 (QtDemuxSample, n_samples); - stream->samples = samples; - - n_samples_per_chunk = QT_UINT32 (stsc_data + 12); - GST_DEBUG_OBJECT (qtdemux, "n_samples_per_chunk %d", n_samples_per_chunk); - sample_index = 0; - timestamp = 0; - for (i = 0; i < n_samples_per_chunk; i++) { - guint32 first_chunk, last_chunk; - guint32 samples_per_chunk; - - first_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 0) - 1; - /* the last chunk of each entry is calculated by taking the first chunk - * of the next entry; except if there is no next, where we fake it with - * INT_MAX */ - if (i == n_samples_per_chunk - 1) { - last_chunk = G_MAXUINT32; - } else { - last_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 12) - 1; - } - samples_per_chunk = QT_UINT32 (stsc_data + 16 + i * 12 + 4); - - GST_LOG_OBJECT (qtdemux, - "entry %d has first_chunk %d, last_chunk %d, samples_per_chunk %d", i, - first_chunk, last_chunk, samples_per_chunk); - - for (j = first_chunk; j < last_chunk; j++) { - guint64 chunk_offset; - - if (j >= n_samples) - goto done; - - if (stco) { - chunk_offset = QT_UINT32 (stco_data + 16 + j * 4); - } else { - chunk_offset = QT_UINT64 ((guint8 *) co64->data + 16 + j * 8); - } - GST_LOG_OBJECT (qtdemux, - "Creating entry %d with offset %" G_GUINT64_FORMAT, j, - chunk_offset); - - samples[j].chunk = j; - samples[j].offset = chunk_offset; - - if (stream->samples_per_frame * stream->bytes_per_frame) { - samples[j].size = (samples_per_chunk * stream->n_channels) / - stream->samples_per_frame * stream->bytes_per_frame; - } else { - samples[j].size = samples_per_chunk; - } - - GST_INFO_OBJECT (qtdemux, "sample %d: timestamp %" GST_TIME_FORMAT - ", size %u", j, GST_TIME_ARGS (timestamp), samples[j].size); - - samples[j].timestamp = timestamp; - sample_index += samples_per_chunk; - - timestamp = gst_util_uint64_scale (sample_index, - GST_SECOND, stream->timescale); - samples[j].duration = timestamp - samples[j].timestamp; - - samples[j].keyframe = TRUE; - } - } - } - - /* composition time to sample */ - if ((ctts = qtdemux_tree_get_child_by_type (stbl, FOURCC_ctts))) { - const guint8 *ctts_data = (const guint8 *) ctts->data; - guint32 n_entries = QT_UINT32 (ctts_data + 12); - guint32 count; - gint32 soffset; - - /* Fill in the pts_offsets */ - for (i = 0, j = 0; (j < stream->n_samples) && (i < n_entries); i++) { - count = QT_UINT32 (ctts_data + 16 + i * 8); - soffset = QT_UINT32 (ctts_data + 20 + i * 8); - for (k = 0; k < count; k++, j++) { - /* we operate with very small soffset values here, it shouldn't overflow */ - samples[j].pts_offset = soffset * GST_SECOND / stream->timescale; - } - } - } -done: - return TRUE; - -/* ERRORS */ -corrupt_file: - { - GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE, - (_("This file is corrupt and cannot be played.")), (NULL)); - return FALSE; - } -} - -/* collect all segment info for @stream. - */ -static gboolean -qtdemux_parse_segments (GstQTDemux * qtdemux, QtDemuxStream * stream, - GNode * trak) -{ - GNode *edts; - - /* parse and prepare segment info from the edit list */ - GST_DEBUG_OBJECT (qtdemux, "looking for edit list container"); - stream->n_segments = 0; - stream->segments = NULL; - if ((edts = qtdemux_tree_get_child_by_type (trak, FOURCC_edts))) { - GNode *elst; - gint n_segments; - gint i, count; - guint64 time, stime; - guint8 *buffer; - - GST_DEBUG_OBJECT (qtdemux, "looking for edit list"); - if (!(elst = qtdemux_tree_get_child_by_type (edts, FOURCC_elst))) - goto done; - - buffer = elst->data; - - n_segments = QT_UINT32 (buffer + 12); - - /* we might allocate a bit too much, at least allocate 1 segment */ - stream->segments = g_new (QtDemuxSegment, MAX (n_segments, 1)); - - /* segments always start from 0 */ - time = 0; - stime = 0; - count = 0; - for (i = 0; i < n_segments; i++) { - guint64 duration; - guint64 media_time; - QtDemuxSegment *segment; - - media_time = QT_UINT32 (buffer + 20 + i * 12); - - /* -1 media time is an empty segment, just ignore it */ - if (media_time == G_MAXUINT32) - continue; - - duration = QT_UINT32 (buffer + 16 + i * 12); - - segment = &stream->segments[count++]; - - /* time and duration expressed in global timescale */ - segment->time = stime; - /* add non scaled values so we don't cause roundoff errors */ - time += duration; - stime = gst_util_uint64_scale (time, GST_SECOND, qtdemux->timescale); - segment->stop_time = stime; - segment->duration = stime - segment->time; - /* media_time expressed in stream timescale */ - segment->media_start = - gst_util_uint64_scale (media_time, GST_SECOND, stream->timescale); - segment->media_stop = segment->media_start + segment->duration; - segment->rate = QT_FP32 (buffer + 24 + i * 12); - - GST_DEBUG_OBJECT (qtdemux, "created segment %d time %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT ", media_time %" GST_TIME_FORMAT - ", rate %g", i, GST_TIME_ARGS (segment->time), - GST_TIME_ARGS (segment->duration), - GST_TIME_ARGS (segment->media_start), segment->rate); - } - GST_DEBUG_OBJECT (qtdemux, "found %d non-empty segments", count); - stream->n_segments = count; - } -done: - - /* no segments, create one to play the complete trak */ - if (stream->n_segments == 0) { - if (stream->segments == NULL) - stream->segments = g_new (QtDemuxSegment, 1); - - stream->segments[0].time = 0; - stream->segments[0].stop_time = qtdemux->segment.duration; - stream->segments[0].duration = qtdemux->segment.duration; - stream->segments[0].media_start = 0; - stream->segments[0].media_stop = qtdemux->segment.duration; - stream->segments[0].rate = 1.0; - - GST_DEBUG_OBJECT (qtdemux, "created dummy segment"); - stream->n_segments = 1; - } - GST_DEBUG_OBJECT (qtdemux, "using %d segments", stream->n_segments); - - return TRUE; -} - -/* parse the traks. - * With each track we associate a new QtDemuxStream that contains all the info - * about the trak. - * traks that do not decode to something (like strm traks) will not have a pad. - */ -static gboolean -qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) -{ - int offset; - GNode *tkhd; - GNode *mdia; - GNode *mdhd; - GNode *hdlr; - GNode *minf; - GNode *stbl; - GNode *stsd; - GNode *mp4a; - GNode *mp4v; - GNode *wave; - GNode *esds; - QtDemuxStream *stream; - GstTagList *list = NULL; - const gchar *codec = NULL; - const guint8 *stsd_data; - guint32 version; - - /* new streams always need a discont */ - stream = g_new0 (QtDemuxStream, 1); - stream->discont = TRUE; - stream->segment_index = -1; - stream->time_position = 0; - stream->sample_index = 0; - stream->last_ret = GST_FLOW_OK; - - if (!(tkhd = qtdemux_tree_get_child_by_type (trak, FOURCC_tkhd))) - goto corrupt_file; - - GST_LOG_OBJECT (qtdemux, "track[tkhd] version/flags: 0x%08x", - QT_UINT32 ((guint8 *) tkhd->data + 8)); - - if (!(mdia = qtdemux_tree_get_child_by_type (trak, FOURCC_mdia))) - goto corrupt_file; - - if (!(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mdhd))) - goto corrupt_file; - - version = QT_UINT32 ((guint8 *) mdhd->data + 8); - GST_LOG_OBJECT (qtdemux, "track version/flags: %08x", version); - if (version == 0x01000000) { - stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 28); - stream->duration = QT_UINT64 ((guint8 *) mdhd->data + 32); - } else { - stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 20); - stream->duration = QT_UINT32 ((guint8 *) mdhd->data + 24); - } - - GST_LOG_OBJECT (qtdemux, "track timescale: %" G_GUINT32_FORMAT, - stream->timescale); - GST_LOG_OBJECT (qtdemux, "track duration: %" G_GUINT64_FORMAT, - stream->duration); - - if (qtdemux->duration != G_MAXINT32 && stream->duration != G_MAXINT32) { - guint64 tdur1, tdur2; - - /* don't overflow */ - tdur1 = stream->timescale * (guint64) qtdemux->duration; - tdur2 = qtdemux->timescale * (guint64) stream->duration; - - /* HACK: - * some of those trailers, nowadays, have prologue images that are - * themselves vide tracks as well. I haven't really found a way to - * identify those yet, except for just looking at their duration. */ - if (tdur1 != 0 && (tdur2 * 10 / tdur1) < 2) { - GST_WARNING_OBJECT (qtdemux, - "Track shorter than 20%% (%" G_GUINT64_FORMAT "/%" G_GUINT32_FORMAT - " vs. %" G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT ") of the stream " - "found, assuming preview image or something; skipping track", - stream->duration, stream->timescale, qtdemux->duration, - qtdemux->timescale); - g_free (stream); - return TRUE; - } - } - - if (!(hdlr = qtdemux_tree_get_child_by_type (mdia, FOURCC_hdlr))) - goto corrupt_file; - - GST_LOG_OBJECT (qtdemux, "track type: %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (QT_FOURCC ((guint8 *) hdlr->data + 12))); - - stream->subtype = QT_FOURCC ((guint8 *) hdlr->data + 16); - GST_LOG_OBJECT (qtdemux, "track subtype: %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (stream->subtype)); - - if (!(minf = qtdemux_tree_get_child_by_type (mdia, FOURCC_minf))) - goto corrupt_file; - - if (!(stbl = qtdemux_tree_get_child_by_type (minf, FOURCC_stbl))) - goto corrupt_file; - - /* parse stsd */ - if (!(stsd = qtdemux_tree_get_child_by_type (stbl, FOURCC_stsd))) - goto corrupt_file; - stsd_data = (const guint8 *) stsd->data; - - if (stream->subtype == FOURCC_vide) { - guint32 fourcc; - - stream->sampled = TRUE; - - offset = 16; - stream->fourcc = fourcc = QT_FOURCC (stsd_data + offset + 4); - GST_LOG_OBJECT (qtdemux, "st type: %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - - stream->width = QT_UINT16 (stsd_data + offset + 32); - stream->height = QT_UINT16 (stsd_data + offset + 34); - stream->fps_n = 0; /* this is filled in later */ - stream->fps_d = 0; /* this is filled in later */ - stream->bits_per_sample = QT_UINT16 (stsd_data + offset + 82); - stream->color_table_id = QT_UINT16 (stsd_data + offset + 84); - - GST_LOG_OBJECT (qtdemux, "frame count: %u", - QT_UINT16 (stsd_data + offset + 48)); - - if (fourcc == FOURCC_drms) - goto error_encrypted; - - stream->caps = qtdemux_video_caps (qtdemux, fourcc, stsd_data, &codec); - if (codec) { - list = gst_tag_list_new (); - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_VIDEO_CODEC, codec, NULL); - } - - esds = NULL; - mp4v = qtdemux_tree_get_child_by_type (stsd, FOURCC_mp4v); - if (mp4v) - esds = qtdemux_tree_get_child_by_type (mp4v, FOURCC_esds); - - if (esds) { - gst_qtdemux_handle_esds (qtdemux, stream, esds, list); - } else { - switch (fourcc) { - case FOURCC_avc1: - { - gint len = QT_UINT32 (stsd_data) - 0x66; - const guint8 *avc_data = stsd_data + 0x66; - - /* find avcC */ - while (len >= 0x8 && - QT_FOURCC (avc_data + 0x4) != FOURCC_avcC && - QT_UINT32 (avc_data) < len) { - len -= QT_UINT32 (avc_data); - avc_data += QT_UINT32 (avc_data); - } - - /* parse, if found */ - if (len > 0x8 && QT_FOURCC (avc_data + 0x4) == FOURCC_avcC) { - GstBuffer *buf; - gint size; - - if (QT_UINT32 (avc_data) < len) - size = QT_UINT32 (avc_data) - 0x8; - else - size = len - 0x8; - - GST_DEBUG_OBJECT (qtdemux, "found avcC codec_data in stsd"); - - buf = gst_buffer_new_and_alloc (size); - memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size); - gst_caps_set_simple (stream->caps, - "codec_data", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - } - break; - } - case FOURCC_SVQ3: - case FOURCC_VP31: - { - GstBuffer *buf; - gint len = QT_UINT32 (stsd_data); - - GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd"); - - buf = gst_buffer_new_and_alloc (len); - memcpy (GST_BUFFER_DATA (buf), stsd_data, len); - gst_caps_set_simple (stream->caps, - "codec_data", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - break; - } - case FOURCC_rle_: - { - gst_caps_set_simple (stream->caps, - "depth", G_TYPE_INT, QT_UINT16 (stsd_data + offset + 82), NULL); - break; - } - default: - break; - } - } - - GST_INFO_OBJECT (qtdemux, - "type %" GST_FOURCC_FORMAT " caps %" GST_PTR_FORMAT, - GST_FOURCC_ARGS (fourcc), stream->caps); - - } else if (stream->subtype == FOURCC_soun) { - int version, samplesize; - guint32 fourcc; - int len; - guint16 compression_id; - - len = QT_UINT32 (stsd_data + 16); - GST_LOG_OBJECT (qtdemux, "stsd len: %d", len); - - stream->fourcc = fourcc = QT_FOURCC (stsd_data + 16 + 4); - GST_LOG_OBJECT (qtdemux, "stsd type: %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (stream->fourcc)); - - offset = 32; - - version = QT_UINT32 (stsd_data + offset); - stream->n_channels = QT_UINT16 (stsd_data + offset + 8); - samplesize = QT_UINT16 (stsd_data + offset + 10); - compression_id = QT_UINT16 (stsd_data + offset + 12); - stream->rate = QT_FP32 (stsd_data + offset + 16); - - GST_LOG_OBJECT (qtdemux, "version/rev: %08x", version); - GST_LOG_OBJECT (qtdemux, "vendor: %08x", - QT_UINT32 (stsd_data + offset + 4)); - GST_LOG_OBJECT (qtdemux, "n_channels: %d", stream->n_channels); - GST_LOG_OBJECT (qtdemux, "sample_size: %d", samplesize); - GST_LOG_OBJECT (qtdemux, "compression_id: %d", compression_id); - GST_LOG_OBJECT (qtdemux, "packet size: %d", - QT_UINT16 (stsd_data + offset + 14)); - GST_LOG_OBJECT (qtdemux, "sample rate: %g", stream->rate); - - if (compression_id == 0xfffe) - stream->sampled = TRUE; - - /* first assume uncompressed audio */ - stream->bytes_per_sample = samplesize / 8; - stream->samples_per_frame = stream->n_channels; - stream->bytes_per_frame = stream->n_channels * stream->bytes_per_sample; - stream->samples_per_packet = stream->samples_per_frame; - stream->bytes_per_packet = stream->bytes_per_sample; - - offset = 52; - switch (fourcc) { - /* Yes, these have to be hard-coded */ - case FOURCC_MAC6: - { - stream->samples_per_packet = 6; - stream->bytes_per_packet = 1; - stream->bytes_per_frame = 1 * stream->n_channels; - stream->bytes_per_sample = 1; - stream->samples_per_frame = 6 * stream->n_channels; - break; - } - case FOURCC_MAC3: - { - stream->samples_per_packet = 3; - stream->bytes_per_packet = 1; - stream->bytes_per_frame = 1 * stream->n_channels; - stream->bytes_per_sample = 1; - stream->samples_per_frame = 3 * stream->n_channels; - break; - } - case FOURCC_ima4: - { - stream->samples_per_packet = 64; - stream->bytes_per_packet = 34; - stream->bytes_per_frame = 34 * stream->n_channels; - stream->bytes_per_sample = 2; - stream->samples_per_frame = 64 * stream->n_channels; - break; - } - case FOURCC_ulaw: - case FOURCC_alaw: - { - stream->samples_per_packet = 1; - stream->bytes_per_packet = 1; - stream->bytes_per_frame = 1 * stream->n_channels; - stream->bytes_per_sample = 1; - stream->samples_per_frame = 1 * stream->n_channels; - break; - } - default: - break; - } - if (version == 0x00010000) { - switch (fourcc) { - case FOURCC_twos: - case FOURCC_sowt: - case FOURCC_raw_: - break; - default: - { - /* only parse extra decoding config for non-pcm audio */ - stream->samples_per_packet = QT_UINT32 (stsd_data + offset); - stream->bytes_per_packet = QT_UINT32 (stsd_data + offset + 4); - stream->bytes_per_frame = QT_UINT32 (stsd_data + offset + 8); - stream->bytes_per_sample = QT_UINT32 (stsd_data + offset + 12); - - GST_LOG_OBJECT (qtdemux, "samples/packet: %d", - stream->samples_per_packet); - GST_LOG_OBJECT (qtdemux, "bytes/packet: %d", - stream->bytes_per_packet); - GST_LOG_OBJECT (qtdemux, "bytes/frame: %d", - stream->bytes_per_frame); - GST_LOG_OBJECT (qtdemux, "bytes/sample: %d", - stream->bytes_per_sample); - - if (!stream->sampled && stream->bytes_per_packet) { - stream->samples_per_frame = (stream->bytes_per_frame / - stream->bytes_per_packet) * stream->samples_per_packet; - GST_LOG_OBJECT (qtdemux, "samples/frame: %d", - stream->samples_per_frame); - } - break; - } - } - offset = 68; - } else if (version == 0x00020000) { - union - { - gdouble fp; - guint64 val; - } qtfp; - - stream->samples_per_packet = QT_UINT32 (stsd_data + offset); - qtfp.val = QT_UINT64 (stsd_data + offset + 4); - stream->rate = qtfp.fp; - stream->n_channels = QT_UINT32 (stsd_data + offset + 12); - - GST_LOG_OBJECT (qtdemux, "samples/packet: %d", - stream->samples_per_packet); - GST_LOG_OBJECT (qtdemux, "sample rate: %g", stream->rate); - GST_LOG_OBJECT (qtdemux, "n_channels: %d", stream->n_channels); - - offset = 68; - } else { - GST_WARNING_OBJECT (qtdemux, "unknown version %08x", version); - } - - if (fourcc == FOURCC_drms) - goto error_encrypted; - - stream->caps = qtdemux_audio_caps (qtdemux, stream, fourcc, NULL, 0, - &codec); - - if (codec) { - list = gst_tag_list_new (); - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, codec, NULL); - } - - mp4a = qtdemux_tree_get_child_by_type (stsd, FOURCC_mp4a); - wave = NULL; - esds = NULL; - if (mp4a) { - wave = qtdemux_tree_get_child_by_type (mp4a, FOURCC_wave); - if (wave) - esds = qtdemux_tree_get_child_by_type (wave, FOURCC_esds); - if (!esds) - esds = qtdemux_tree_get_child_by_type (mp4a, FOURCC_esds); - } - - if (esds) { - gst_qtdemux_handle_esds (qtdemux, stream, esds, list); - } else { - switch (fourcc) { - case FOURCC_QDM2: - { - gint len = QT_UINT32 (stsd_data); - - if (len > 0x4C) { - GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x4C); - - memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x4C, len - 0x4C); - gst_caps_set_simple (stream->caps, - "codec_data", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - } - gst_caps_set_simple (stream->caps, - "samplesize", G_TYPE_INT, samplesize, NULL); - break; - } - case FOURCC_alac: - { - gint len = QT_UINT32 (stsd_data); - - if (len > 0x34) { - GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x34); - - memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x34, len - 0x34); - gst_caps_set_simple (stream->caps, - "codec_data", GST_TYPE_BUFFER, buf, NULL); - gst_buffer_unref (buf); - } - gst_caps_set_simple (stream->caps, - "samplesize", G_TYPE_INT, samplesize, NULL); - break; - } - default: - break; - } - } - GST_INFO_OBJECT (qtdemux, - "type %" GST_FOURCC_FORMAT " caps %" GST_PTR_FORMAT, - GST_FOURCC_ARGS (fourcc), stream->caps); - - } else if (stream->subtype == FOURCC_strm) { - guint32 fourcc; - - stream->fourcc = fourcc = QT_FOURCC (stsd_data + 16 + 4); - GST_LOG_OBJECT (qtdemux, "stsd type: %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - - if (fourcc != FOURCC_rtsp) { - GST_INFO_OBJECT (qtdemux, "unhandled stream type %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - goto unknown_stream; - } - stream->sampled = TRUE; - } else { - goto unknown_stream; - } - - /* promote to sampled format */ - if (stream->fourcc == FOURCC_samr) { - /* force mono 8000 Hz for AMR */ - stream->sampled = TRUE; - stream->n_channels = 1; - stream->rate = 8000; - } else if (stream->fourcc == FOURCC_sawb) { - /* force mono 16000 Hz for AMR-WB */ - stream->sampled = TRUE; - stream->n_channels = 1; - stream->rate = 16000; - } else if (stream->fourcc == FOURCC_mp4a) { - stream->sampled = TRUE; - } - - /* collect sample information */ - if (!qtdemux_parse_samples (qtdemux, stream, stbl)) - goto samples_failed; - - /* configure segments */ - if (!qtdemux_parse_segments (qtdemux, stream, trak)) - goto segments_failed; - - /* now we are ready to add the stream */ - gst_qtdemux_add_stream (qtdemux, stream, list); - - return TRUE; - -/* ERRORS */ -corrupt_file: - { - GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE, - (_("This file is corrupt and cannot be played.")), (NULL)); - g_free (stream); - return FALSE; - } -error_encrypted: - { - GST_ELEMENT_ERROR (qtdemux, STREAM, DECODE, - (_("This file is encrypted and cannot be played.")), (NULL)); - g_free (stream); - return FALSE; - } -samples_failed: - { - /* we posted an error already */ - g_free (stream); - return FALSE; - } -segments_failed: - { - /* we posted an error already */ - g_free (stream); - return FALSE; - } -unknown_stream: - { - GST_INFO_OBJECT (qtdemux, "unknown subtype %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (stream->subtype)); - g_free (stream); - return TRUE; - } -} - -static void -qtdemux_tag_add_str (GstQTDemux * qtdemux, const char *tag, GNode * node) -{ - GNode *data; - char *s; - int len; - int type; - - data = qtdemux_tree_get_child_by_type (node, FOURCC_data); - if (data) { - len = QT_UINT32 (data->data); - type = QT_UINT32 ((guint8 *) data->data + 8); - if (type == 0x00000001) { - s = g_strndup ((char *) data->data + 16, len - 16); - GST_DEBUG_OBJECT (qtdemux, "adding tag %s", s); - gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, s, NULL); - g_free (s); - } - } -} - -static void -qtdemux_tag_add_num (GstQTDemux * qtdemux, const char *tag1, - const char *tag2, GNode * node) -{ - GNode *data; - int len; - int type; - int n1, n2; - - data = qtdemux_tree_get_child_by_type (node, FOURCC_data); - if (data) { - len = QT_UINT32 (data->data); - type = QT_UINT32 ((guint8 *) data->data + 8); - if (type == 0x00000000 && len >= 22) { - n1 = QT_UINT16 ((guint8 *) data->data + 18); - n2 = QT_UINT16 ((guint8 *) data->data + 20); - GST_DEBUG_OBJECT (qtdemux, "adding tag %d/%d", n1, n2); - gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, - tag1, n1, tag2, n2, NULL); - } - } -} - -static void -qtdemux_tag_add_date (GstQTDemux * qtdemux, const char *tag, GNode * node) -{ - GNode *data; - char *s; - int len; - int type; - - data = qtdemux_tree_get_child_by_type (node, FOURCC_data); - if (data) { - len = QT_UINT32 (data->data); - type = QT_UINT32 ((guint8 *) data->data + 8); - if (type == 0x00000001) { - guint y, m = 1, d = 1; - gint ret; - - s = g_strndup ((char *) data->data + 16, len - 16); - GST_DEBUG_OBJECT (qtdemux, "adding date '%s'", s); - ret = sscanf (s, "%u-%u-%u", &y, &m, &d); - if (ret >= 1 && y > 1500 && y < 3000) { - GDate *date; - - date = g_date_new_dmy (d, m, y); - gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, tag, - date, NULL); - g_date_free (date); - } else { - GST_DEBUG_OBJECT (qtdemux, "could not parse date string '%s'", s); - } - g_free (s); - } - } -} - -static void -qtdemux_tag_add_gnre (GstQTDemux * qtdemux, const char *tag, GNode * node) -{ - static const gchar *genres[] = { - "N/A", "Blues", "Classic Rock", "Country", "Dance", "Disco", - "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", - "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", - "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", - "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", - "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", - "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", - "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", - "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", - "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", - "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", - "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", - "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", - "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", - "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", - "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", "Bebob", - "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", - "Gothic Rock", "Progressive Rock", "Psychedelic Rock", - "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", - "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", - "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", - "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", - "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", - "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", - "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club House", - "Hardcore", "Terror", "Indie", "BritPop", "NegerPunk", - "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal", - "Black Metal", "Crossover", "Contemporary C", "Christian Rock", - "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "SynthPop" - }; - GNode *data; - int len; - int type; - int n; - - data = qtdemux_tree_get_child_by_type (node, FOURCC_data); - if (data) { - len = QT_UINT32 (data->data); - type = QT_UINT32 ((guint8 *) data->data + 8); - if (type == 0x00000000 && len >= 18) { - n = QT_UINT16 ((guint8 *) data->data + 16); - if (n > 0 && n < sizeof (genres) / sizeof (char *)) { - GST_DEBUG_OBJECT (qtdemux, "adding %d [%s]", n, genres[n]); - gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE, - tag, genres[n], NULL); - } - } - } -} - -static void -qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta) -{ - GNode *meta; - GNode *ilst; - GNode *node; - - meta = qtdemux_tree_get_child_by_type (udta, FOURCC_meta); - if (meta == NULL) { - GST_LOG_OBJECT (qtdemux, "no meta"); - return; - } - - ilst = qtdemux_tree_get_child_by_type (meta, FOURCC_ilst); - if (ilst == NULL) { - GST_LOG_OBJECT (qtdemux, "no ilst"); - return; - } - - GST_DEBUG_OBJECT (qtdemux, "new tag list"); - qtdemux->tag_list = gst_tag_list_new (); - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__nam); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_TITLE, node); - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__ART); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); - } else { - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__wrt); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); - } else { - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__grp); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_ARTIST, node); - } - } - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__alb); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_ALBUM, node); - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__day); - if (node) { - qtdemux_tag_add_date (qtdemux, GST_TAG_DATE, node); - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__too); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_COMMENT, node); - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC_trkn); - if (node) { - qtdemux_tag_add_num (qtdemux, GST_TAG_TRACK_NUMBER, - GST_TAG_TRACK_COUNT, node); - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC_disc); - if (node) { - qtdemux_tag_add_num (qtdemux, GST_TAG_ALBUM_VOLUME_NUMBER, - GST_TAG_ALBUM_VOLUME_COUNT, node); - } else { - node = qtdemux_tree_get_child_by_type (ilst, FOURCC_disk); - if (node) { - qtdemux_tag_add_num (qtdemux, GST_TAG_ALBUM_VOLUME_NUMBER, - GST_TAG_ALBUM_VOLUME_COUNT, node); - } - } - - node = qtdemux_tree_get_child_by_type (ilst, FOURCC_gnre); - if (node) { - qtdemux_tag_add_gnre (qtdemux, GST_TAG_GENRE, node); - } else { - node = qtdemux_tree_get_child_by_type (ilst, FOURCC__gen); - if (node) { - qtdemux_tag_add_str (qtdemux, GST_TAG_GENRE, node); - } - } -} - -typedef struct -{ - GstStructure *structure; /* helper for sort function */ - gchar *location; - guint min_req_bitrate; - guint min_req_qt_version; -} GstQtReference; - -static gint -qtdemux_redirects_sort_func (gconstpointer a, gconstpointer b) -{ - GstQtReference *ref_a = (GstQtReference *) a; - GstQtReference *ref_b = (GstQtReference *) b; - - if (ref_b->min_req_qt_version != ref_a->min_req_qt_version) - return ref_b->min_req_qt_version - ref_a->min_req_qt_version; - - /* known bitrates go before unknown; higher bitrates go first */ - return ref_b->min_req_bitrate - ref_a->min_req_bitrate; -} - -/* sort the redirects and post a message for the application. - */ -static void -qtdemux_process_redirects (GstQTDemux * qtdemux, GList * references) -{ - GstQtReference *best; - GstStructure *s; - GstMessage *msg; - GValue list_val = { 0, }; - GList *l; - - g_assert (references != NULL); - - references = g_list_sort (references, qtdemux_redirects_sort_func); - - best = (GstQtReference *) references->data; - - g_value_init (&list_val, GST_TYPE_LIST); - - for (l = references; l != NULL; l = l->next) { - GstQtReference *ref = (GstQtReference *) l->data; - GValue struct_val = { 0, }; - - ref->structure = gst_structure_new ("redirect", - "new-location", G_TYPE_STRING, ref->location, NULL); - - if (ref->min_req_bitrate > 0) { - gst_structure_set (ref->structure, "minimum-bitrate", G_TYPE_INT, - ref->min_req_bitrate, NULL); - } - - g_value_init (&struct_val, GST_TYPE_STRUCTURE); - g_value_set_boxed (&struct_val, ref->structure); - gst_value_list_append_value (&list_val, &struct_val); - g_value_unset (&struct_val); - /* don't free anything here yet, since we need best->structure below */ - } - - g_assert (best != NULL); - s = gst_structure_copy (best->structure); - - if (g_list_length (references) > 1) { - gst_structure_set_value (s, "locations", &list_val); - } - - g_value_unset (&list_val); - - for (l = references; l != NULL; l = l->next) { - GstQtReference *ref = (GstQtReference *) l->data; - - gst_structure_free (ref->structure); - g_free (ref->location); - g_free (ref); - } - g_list_free (references); - - GST_INFO_OBJECT (qtdemux, "posting redirect message: %" GST_PTR_FORMAT, s); - msg = gst_message_new_element (GST_OBJECT_CAST (qtdemux), s); - gst_element_post_message (GST_ELEMENT_CAST (qtdemux), msg); -} - -/* look for redirect nodes, collect all redirect information and - * process it. - */ -static gboolean -qtdemux_parse_redirects (GstQTDemux * qtdemux) -{ - GNode *rmra, *rmda, *rdrf; - - rmra = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_rmra); - if (rmra) { - GList *redirects = NULL; - - rmda = qtdemux_tree_get_child_by_type (rmra, FOURCC_rmda); - while (rmda) { - GstQtReference ref = { NULL, NULL, 0, 0 }; - GNode *rmdr, *rmvc; - - if ((rmdr = qtdemux_tree_get_child_by_type (rmda, FOURCC_rmdr))) { - ref.min_req_bitrate = QT_UINT32 ((guint8 *) rmdr->data + 12); - GST_LOG_OBJECT (qtdemux, "data rate atom, required bitrate = %u", - ref.min_req_bitrate); - } - - if ((rmvc = qtdemux_tree_get_child_by_type (rmda, FOURCC_rmvc))) { - guint32 package = QT_FOURCC ((guint8 *) rmvc->data + 12); - guint version = QT_UINT32 ((guint8 *) rmvc->data + 16); - -#ifndef GST_DISABLE_GST_DEBUG - guint bitmask = QT_UINT32 ((guint8 *) rmvc->data + 20); -#endif - guint check_type = QT_UINT16 ((guint8 *) rmvc->data + 24); - - GST_LOG_OBJECT (qtdemux, - "version check atom [%" GST_FOURCC_FORMAT "], version=0x%08x" - ", mask=%08x, check_type=%u", GST_FOURCC_ARGS (package), version, - bitmask, check_type); - if (package == FOURCC_qtim && check_type == 0) { - ref.min_req_qt_version = version; - } - } - - rdrf = qtdemux_tree_get_child_by_type (rmda, FOURCC_rdrf); - if (rdrf) { - guint32 ref_type; - guint8 *ref_data; - - ref_type = QT_FOURCC ((guint8 *) rdrf->data + 12); - ref_data = (guint8 *) rdrf->data + 20; - if (ref_type == FOURCC_alis) { - guint record_len, record_version, fn_len; - - /* MacOSX alias record, google for alias-layout.txt */ - record_len = QT_UINT16 (ref_data + 4); - record_version = QT_UINT16 (ref_data + 4 + 2); - fn_len = QT_UINT8 (ref_data + 50); - if (record_len > 50 && record_version == 2 && fn_len > 0) { - ref.location = g_strndup ((gchar *) ref_data + 51, fn_len); - } - } else if (ref_type == FOURCC_url_) { - ref.location = g_strdup ((gchar *) ref_data); - } else { - GST_DEBUG_OBJECT (qtdemux, - "unknown rdrf reference type %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (ref_type)); - } - if (ref.location != NULL) { - GST_INFO_OBJECT (qtdemux, "New location: %s", ref.location); - redirects = g_list_prepend (redirects, g_memdup (&ref, sizeof (ref))); - } else { - GST_WARNING_OBJECT (qtdemux, - "Failed to extract redirect location from rdrf atom"); - } - } - - /* look for others */ - rmda = qtdemux_tree_get_sibling_by_type (rmda, FOURCC_rmda); - } - - if (redirects != NULL) { - qtdemux_process_redirects (qtdemux, redirects); - } - } - return TRUE; -} - -/* we have read th complete moov node now. - * This function parses all of the relevant info, creates the traks and - * prepares all data structures for playback - */ -static gboolean -qtdemux_parse_tree (GstQTDemux * qtdemux) -{ - GNode *mvhd; - GNode *trak; - GNode *udta; - gint64 duration; - - mvhd = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_mvhd); - if (mvhd == NULL) { - GST_LOG_OBJECT (qtdemux, "No mvhd node found, looking for redirects."); - return qtdemux_parse_redirects (qtdemux); - } - - qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20); - qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24); - - GST_INFO_OBJECT (qtdemux, "timescale: %u", qtdemux->timescale); - GST_INFO_OBJECT (qtdemux, "duration: %u", qtdemux->duration); - - /* set duration in the segment info */ - gst_qtdemux_get_duration (qtdemux, &duration); - gst_segment_set_duration (&qtdemux->segment, GST_FORMAT_TIME, duration); - - /* parse all traks */ - trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak); - while (trak) { - qtdemux_parse_trak (qtdemux, trak); - /* iterate all siblings */ - trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak); - } - gst_element_no_more_pads (GST_ELEMENT_CAST (qtdemux)); - - /* find and push tags, we do this after adding the pads so we can push the - * tags downstream as well. */ - udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta); - if (udta) { - qtdemux_parse_udta (qtdemux, udta); - - if (qtdemux->tag_list) { - GST_DEBUG_OBJECT (qtdemux, - "calling gst_element_found_tags with %" GST_PTR_FORMAT, - qtdemux->tag_list); - gst_element_found_tags (GST_ELEMENT_CAST (qtdemux), qtdemux->tag_list); - qtdemux->tag_list = NULL; - } - } else { - GST_LOG_OBJECT (qtdemux, "No udta node found."); - } - return TRUE; -} - -/* taken from ffmpeg */ -static unsigned int -get_size (guint8 * ptr, guint8 ** end) -{ - int count = 4; - int len = 0; - - while (count--) { - int c = *ptr; - - ptr++; - len = (len << 7) | (c & 0x7f); - if (!(c & 0x80)) - break; - } - if (end) - *end = ptr; - return len; -} - -/* this can change the codec originally present in @list */ -static void -gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream, - GNode * esds, GstTagList * list) -{ - int len = QT_UINT32 (esds->data); - guint8 *ptr = esds->data; - guint8 *end = ptr + len; - int tag; - guint8 *data_ptr = NULL; - int data_len = 0; - guint8 object_type_id = 0; - - qtdemux_dump_mem (ptr, len); - ptr += 8; - GST_DEBUG_OBJECT (qtdemux, "version/flags = %08x", QT_UINT32 (ptr)); - ptr += 4; - while (ptr < end) { - tag = QT_UINT8 (ptr); - GST_DEBUG_OBJECT (qtdemux, "tag = %02x", tag); - ptr++; - len = get_size (ptr, &ptr); - GST_DEBUG_OBJECT (qtdemux, "len = %d", len); - - switch (tag) { - case 0x03: - GST_DEBUG_OBJECT (qtdemux, "ID %04x", QT_UINT16 (ptr)); - GST_DEBUG_OBJECT (qtdemux, "priority %04x", QT_UINT8 (ptr + 2)); - ptr += 3; - break; - case 0x04: - object_type_id = QT_UINT8 (ptr); - GST_DEBUG_OBJECT (qtdemux, "object_type_id %02x", object_type_id); - GST_DEBUG_OBJECT (qtdemux, "stream_type %02x", QT_UINT8 (ptr + 1)); - GST_DEBUG_OBJECT (qtdemux, "buffer_size_db %02x", QT_UINT24 (ptr + 2)); - GST_DEBUG_OBJECT (qtdemux, "max bitrate %d", QT_UINT32 (ptr + 5)); - GST_DEBUG_OBJECT (qtdemux, "avg bitrate %d", QT_UINT32 (ptr + 9)); - ptr += 13; - break; - case 0x05: - GST_DEBUG_OBJECT (qtdemux, "data:"); - qtdemux_dump_mem (ptr, len); - data_ptr = ptr; - data_len = len; - ptr += len; - break; - case 0x06: - GST_DEBUG_OBJECT (qtdemux, "data %02x", QT_UINT8 (ptr)); - ptr += 1; - break; - default: - GST_ERROR_OBJECT (qtdemux, "parse error"); - } - } - - if (data_ptr) { - GstBuffer *buffer; - - buffer = gst_buffer_new_and_alloc (data_len); - memcpy (GST_BUFFER_DATA (buffer), data_ptr, data_len); - qtdemux_dump_mem (GST_BUFFER_DATA (buffer), data_len); - - GST_DEBUG_OBJECT (qtdemux, "setting codec_data from esds"); - - gst_caps_set_simple (stream->caps, "codec_data", GST_TYPE_BUFFER, - buffer, NULL); - gst_buffer_unref (buffer); - } - /* object_type_id in the stsd atom in mp4a tells us about AAC or plain - * MPEG audio and other formats */ - switch (object_type_id) { - case 107: - /* change to mpeg1 layer 3 audio */ - gst_caps_set_simple (stream->caps, "layer", G_TYPE_INT, 3, - "mpegversion", G_TYPE_INT, 1, NULL); - if (list) - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, "MPEG-1 layer 3", NULL); - break; - case 0xE1: - { - GstStructure *structure; - - /* QCELP, the codec_data is a riff tag (little endian) with - * more info (http://ftp.3gpp2.org/TSGC/Working/2003/2003-05-SanDiego/TSG-C-2003-05-San%20Diego/WG1/SWG12/C12-20030512-006%20=%20C12-20030217-015_Draft_Baseline%20Text%20of%20FFMS_R2.doc). */ - structure = gst_caps_get_structure (stream->caps, 0); - gst_structure_set_name (structure, "audio/qcelp"); - gst_structure_remove_fields (structure, "mpegversion", "framed", NULL); - - if (list) - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, "QCELP", NULL); - break; - } - default: - break; - } -} - -#define _codec(name) \ - do { \ - if (codec_name) { \ - *codec_name = name; \ - } \ - } while (0) - -static GstCaps * -qtdemux_video_caps (GstQTDemux * qtdemux, guint32 fourcc, - const guint8 * stsd_data, const gchar ** codec_name) -{ - switch (fourcc) { - case GST_MAKE_FOURCC ('p', 'n', 'g', ' '): - _codec ("PNG still images"); - return gst_caps_from_string ("image/png"); - case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'): - _codec ("JPEG still images"); - return gst_caps_from_string ("image/jpeg"); - case GST_MAKE_FOURCC ('m', 'j', 'p', 'a'): - case GST_MAKE_FOURCC ('A', 'V', 'D', 'J'): - _codec ("Motion-JPEG"); - return gst_caps_from_string ("image/jpeg"); - case GST_MAKE_FOURCC ('m', 'j', 'p', 'b'): - _codec ("Motion-JPEG format B"); - return gst_caps_from_string ("video/x-mjpeg-b"); - case GST_MAKE_FOURCC ('S', 'V', 'Q', '3'): - _codec ("Sorensen video v.3"); - return gst_caps_from_string ("video/x-svq, " "svqversion = (int) 3"); - case GST_MAKE_FOURCC ('s', 'v', 'q', 'i'): - case GST_MAKE_FOURCC ('S', 'V', 'Q', '1'): - _codec ("Sorensen video v.1"); - return gst_caps_from_string ("video/x-svq, " "svqversion = (int) 1"); - case GST_MAKE_FOURCC ('r', 'a', 'w', ' '): - { - guint16 bps; - GstCaps *caps; - - _codec ("Raw RGB video"); - bps = QT_UINT16 (stsd_data + 98); - /* set common stuff */ - caps = gst_caps_new_simple ("video/x-raw-rgb", - "endianness", G_TYPE_INT, G_BYTE_ORDER, "depth", G_TYPE_INT, bps, - NULL); - - switch (bps) { - case 15: - gst_caps_set_simple (caps, - "bpp", G_TYPE_INT, 16, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "red_mask", G_TYPE_INT, 0x7c00, - "green_mask", G_TYPE_INT, 0x03e0, - "blue_mask", G_TYPE_INT, 0x001f, NULL); - break; - case 16: - gst_caps_set_simple (caps, - "bpp", G_TYPE_INT, 16, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "red_mask", G_TYPE_INT, 0xf800, - "green_mask", G_TYPE_INT, 0x07e0, - "blue_mask", G_TYPE_INT, 0x001f, NULL); - break; - case 24: - gst_caps_set_simple (caps, - "bpp", G_TYPE_INT, 24, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "red_mask", G_TYPE_INT, 0xff0000, - "green_mask", G_TYPE_INT, 0x00ff00, - "blue_mask", G_TYPE_INT, 0x0000ff, NULL); - break; - case 32: - gst_caps_set_simple (caps, - "bpp", G_TYPE_INT, 32, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "alpha_mask", G_TYPE_INT, 0xff000000, - "red_mask", G_TYPE_INT, 0x00ff0000, - "green_mask", G_TYPE_INT, 0x0000ff00, - "blue_mask", G_TYPE_INT, 0x000000ff, NULL); - break; - default: - /* unknown */ - break; - } - return caps; - } - case GST_MAKE_FOURCC ('y', 'v', '1', '2'): - _codec ("Raw planar YUV 4:2:0"); - return gst_caps_from_string ("video/x-raw-yuv, " - "format = (fourcc) I420"); - case GST_MAKE_FOURCC ('y', 'u', 'v', '2'): - case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'): - _codec ("Raw packed YUV 4:2:2"); - return gst_caps_from_string ("video/x-raw-yuv, " - "format = (fourcc) YUY2"); - case GST_MAKE_FOURCC ('m', 'p', 'e', 'g'): - _codec ("MPEG-1 video"); - return gst_caps_from_string ("video/mpeg, " - "systemstream = (boolean) false, " "mpegversion = (int) 1"); - case GST_MAKE_FOURCC ('g', 'i', 'f', ' '): - _codec ("GIF still images"); - return gst_caps_from_string ("image/gif"); - case GST_MAKE_FOURCC ('h', '2', '6', '3'): - case GST_MAKE_FOURCC ('H', '2', '6', '3'): - case GST_MAKE_FOURCC ('s', '2', '6', '3'): - case GST_MAKE_FOURCC ('U', '2', '6', '3'): - _codec ("H.263"); - /* ffmpeg uses the height/width props, don't know why */ - return gst_caps_from_string ("video/x-h263"); - case GST_MAKE_FOURCC ('m', 'p', '4', 'v'): - _codec ("MPEG-4 video"); - return gst_caps_from_string ("video/mpeg, " - "mpegversion = (int) 4, " "systemstream = (boolean) false"); - case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'): - case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'): - _codec ("Microsoft MPEG-4 4.3"); /* FIXME? */ - return gst_caps_from_string ("video/x-msmpeg, msmpegversion = (int) 43"); - case GST_MAKE_FOURCC ('3', 'I', 'V', '1'): - case GST_MAKE_FOURCC ('3', 'I', 'V', '2'): - _codec ("3ivX video"); - return gst_caps_from_string ("video/x-3ivx"); - case GST_MAKE_FOURCC ('D', 'I', 'V', '3'): - _codec ("DivX 3"); - return gst_caps_from_string ("video/x-divx," "divxversion= (int) 3"); - case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'): - _codec ("DivX 4"); - return gst_caps_from_string ("video/x-divx," "divxversion= (int) 4"); - - case GST_MAKE_FOURCC ('D', 'X', '5', '0'): - _codec ("DivX 5"); - return gst_caps_from_string ("video/x-divx," "divxversion= (int) 5"); - case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'): - _codec ("Cinepak"); - return gst_caps_from_string ("video/x-cinepak"); - case GST_MAKE_FOURCC ('q', 'd', 'r', 'w'): - _codec ("Apple QuickDraw"); - return gst_caps_from_string ("video/x-qdrw"); - case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'): - _codec ("Apple video"); - return gst_caps_from_string ("video/x-apple-video"); - case GST_MAKE_FOURCC ('a', 'v', 'c', '1'): - _codec ("H.264 / AVC"); - return gst_caps_from_string ("video/x-h264"); - case GST_MAKE_FOURCC ('r', 'l', 'e', ' '): - _codec ("Run-length encoding"); - return gst_caps_from_string ("video/x-rle, layout=(string)quicktime"); - case GST_MAKE_FOURCC ('i', 'v', '3', '2'): - _codec ("Indeo Video 3"); - return gst_caps_from_string ("video/x-indeo, indeoversion=(int)3"); - case GST_MAKE_FOURCC ('I', 'V', '4', '1'): - case GST_MAKE_FOURCC ('i', 'v', '4', '1'): - _codec ("Intel Video 4"); - return gst_caps_from_string ("video/x-indeo, indeoversion=(int)4"); - case GST_MAKE_FOURCC ('d', 'v', 'c', 'p'): - case GST_MAKE_FOURCC ('d', 'v', 'c', ' '): - case GST_MAKE_FOURCC ('d', 'v', 's', 'd'): - case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'): - case GST_MAKE_FOURCC ('d', 'v', 'c', 's'): - case GST_MAKE_FOURCC ('D', 'V', 'C', 'S'): - case GST_MAKE_FOURCC ('d', 'v', '2', '5'): - case GST_MAKE_FOURCC ('d', 'v', 'p', 'p'): - _codec ("DV Video"); - return gst_caps_from_string ("video/x-dv, systemstream=(boolean)false"); - case GST_MAKE_FOURCC ('s', 'm', 'c', ' '): - _codec ("Apple Graphics (SMC)"); - return gst_caps_from_string ("video/x-smc"); - case GST_MAKE_FOURCC ('V', 'P', '3', '1'): - _codec ("VP3"); - return gst_caps_from_string ("video/x-vp3"); - case GST_MAKE_FOURCC ('k', 'p', 'c', 'd'): - default: - { - char *s; - - s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - return gst_caps_new_simple (s, NULL); - } - } -} - -static GstCaps * -qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream, - guint32 fourcc, const guint8 * data, int len, const gchar ** codec_name) -{ - switch (fourcc) { - case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'): - case GST_MAKE_FOURCC ('r', 'a', 'w', ' '): - _codec ("Raw 8-bit PCM audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) false"); - case GST_MAKE_FOURCC ('t', 'w', 'o', 's'): - if (stream->bytes_per_frame == 1) { - _codec ("Raw 8-bit PCM audio"); - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) true"); - } else { - _codec ("Raw 16-bit PCM audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 16, " - "depth = (int) 16, " - "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true"); - } - case GST_MAKE_FOURCC ('s', 'o', 'w', 't'): - if (stream->bytes_per_frame == 1) { - _codec ("Raw 8-bit PCM audio"); - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 8, " "depth = (int) 8, " "signed = (boolean) true"); - } else { - _codec ("Raw 16-bit PCM audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 16, " - "depth = (int) 16, " - "endianness = (int) LITTLE_ENDIAN, " "signed = (boolean) true"); - } - case GST_MAKE_FOURCC ('f', 'l', '6', '4'): - _codec ("Raw 64-bit floating-point audio"); - return gst_caps_from_string ("audio/x-raw-float, " - "width = (int) 64, " "endianness = (int) BIG_ENDIAN"); - case GST_MAKE_FOURCC ('f', 'l', '3', '2'): - _codec ("Raw 32-bit floating-point audio"); - return gst_caps_from_string ("audio/x-raw-float, " - "width = (int) 32, " "endianness = (int) BIG_ENDIAN"); - case GST_MAKE_FOURCC ('i', 'n', '2', '4'): - _codec ("Raw 24-bit PCM audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 24, " - "depth = (int) 24, " - "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true"); - case GST_MAKE_FOURCC ('i', 'n', '3', '2'): - _codec ("Raw 32-bit PCM audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) 32, " - "endianness = (int) BIG_ENDIAN, " "signed = (boolean) true"); - case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'): - _codec ("Mu-law audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-mulaw"); - case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'): - _codec ("A-law audio"); - /* FIXME */ - return gst_caps_from_string ("audio/x-alaw"); - case 0x6d730002: - _codec ("Microsoft ADPCM"); - /* Microsoft ADPCM-ACM code 2 */ - return gst_caps_from_string ("audio/x-adpcm, " - "layout = (string) microsoft"); - case 0x6d730011: - case 0x6d730017: - _codec ("DVI/Intel IMA ADPCM"); - /* FIXME DVI/Intel IMA ADPCM/ACM code 17 */ - return gst_caps_from_string ("audio/x-adpcm, " - "layout = (string) quicktime"); - case 0x6d730055: - /* MPEG layer 3, CBR only (pre QT4.1) */ - case 0x5500736d: - case GST_MAKE_FOURCC ('.', 'm', 'p', '3'): - _codec ("MPEG-1 layer 3"); - /* MPEG layer 3, CBR & VBR (QT4.1 and later) */ - return gst_caps_from_string ("audio/mpeg, " - "layer = (int) 3, " "mpegversion = (int) 1"); - case GST_MAKE_FOURCC ('M', 'A', 'C', '3'): - _codec ("MACE-3"); - return gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 3"); - case GST_MAKE_FOURCC ('M', 'A', 'C', '6'): - _codec ("MACE-6"); - return gst_caps_from_string ("audio/x-mace, " "maceversion = (int) 6"); - case GST_MAKE_FOURCC ('O', 'g', 'g', 'V'): - /* ogg/vorbis */ - return gst_caps_from_string ("application/ogg"); - case GST_MAKE_FOURCC ('d', 'v', 'c', 'a'): - _codec ("DV audio"); - return gst_caps_from_string ("audio/x-dv"); - case GST_MAKE_FOURCC ('m', 'p', '4', 'a'): - _codec ("MPEG-4 AAC audio"); - return gst_caps_new_simple ("audio/mpeg", - "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE, NULL); - case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'): - _codec ("QDesign Music v.2"); - /* FIXME: QDesign music version 2 (no constant) */ - if (data) { - return gst_caps_new_simple ("audio/x-qdm2", - "framesize", G_TYPE_INT, QT_UINT32 (data + 52), - "bitrate", G_TYPE_INT, QT_UINT32 (data + 40), - "blocksize", G_TYPE_INT, QT_UINT32 (data + 44), NULL); - } else { - return gst_caps_new_simple ("audio/x-qdm2", NULL); - } - case GST_MAKE_FOURCC ('a', 'g', 's', 'm'): - _codec ("GSM audio"); - return gst_caps_new_simple ("audio/x-gsm", NULL); - case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'): - _codec ("AMR audio"); - return gst_caps_new_simple ("audio/AMR", NULL); - case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'): - _codec ("AMR-WB audio"); - return gst_caps_new_simple ("audio/AMR-WB", NULL); - case GST_MAKE_FOURCC ('i', 'm', 'a', '4'): - _codec ("Quicktime IMA ADPCM"); - return gst_caps_new_simple ("audio/x-adpcm", - "layout", G_TYPE_STRING, "quicktime", NULL); - case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'): - _codec ("Apple lossless audio"); - return gst_caps_new_simple ("audio/x-alac", NULL); - case GST_MAKE_FOURCC ('q', 't', 'v', 'r'): - /* ? */ - case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'): - /* QDesign music */ - case GST_MAKE_FOURCC ('Q', 'c', 'l', 'p'): - /* QUALCOMM PureVoice */ - default: - { - char *s; - - s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - return gst_caps_new_simple (s, NULL); - } - } -} diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h deleted file mode 100644 index 984f26dc..00000000 --- a/gst/qtdemux/qtdemux.h +++ /dev/null @@ -1,101 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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_QTDEMUX_H__ -#define __GST_QTDEMUX_H__ - -#include -#include - -G_BEGIN_DECLS - -GST_DEBUG_CATEGORY_EXTERN (qtdemux_debug); -#define GST_CAT_DEFAULT qtdemux_debug - -#define GST_TYPE_QTDEMUX \ - (gst_qtdemux_get_type()) -#define GST_QTDEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_QTDEMUX,GstQTDemux)) -#define GST_QTDEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_QTDEMUX,GstQTDemuxClass)) -#define GST_IS_QTDEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_QTDEMUX)) -#define GST_IS_QTDEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_QTDEMUX)) - -#define GST_QTDEMUX_CAST(obj) ((GstQTDemux *)(obj)) - -#define GST_QTDEMUX_MAX_STREAMS 8 - -typedef struct _GstQTDemux GstQTDemux; -typedef struct _GstQTDemuxClass GstQTDemuxClass; -typedef struct _QtDemuxStream QtDemuxStream; - -struct _GstQTDemux { - GstElement element; - - /* pads */ - GstPad *sinkpad; - - QtDemuxStream *streams[GST_QTDEMUX_MAX_STREAMS]; - gint n_streams; - gint n_video_streams; - gint n_audio_streams; - - GNode *moov_node; - GNode *moov_node_compressed; - - guint32 timescale; - guint32 duration; - - gint state; - - gboolean pullbased; - - /* push based variables */ - guint neededbytes; - guint todrop; - GstAdapter *adapter; - GstBuffer *mdatbuffer; - - /* offset of the media data (i.e.: Size of header) */ - guint64 offset; - /* offset of the mdat atom */ - guint64 mdatoffset; - - GstTagList *tag_list; - - /* track stuff */ - guint64 last_ts; - - /* configured playback region */ - GstSegment segment; - gboolean segment_running; -}; - -struct _GstQTDemuxClass { - GstElementClass parent_class; -}; - -GType gst_qtdemux_get_type (void); - -G_END_DECLS - -#endif /* __GST_QTDEMUX_H__ */ diff --git a/gst/qtdemux/qtdemux.vcproj b/gst/qtdemux/qtdemux.vcproj deleted file mode 100644 index e00260d9..00000000 --- a/gst/qtdemux/qtdemux.vcproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gst/qtdemux/qtdemux_dump.c b/gst/qtdemux/qtdemux_dump.c deleted file mode 100644 index 391d67a0..00000000 --- a/gst/qtdemux/qtdemux_dump.c +++ /dev/null @@ -1,417 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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 "qtdemux_types.h" -#include "qtdemux_dump.h" - -#if 0 -#define qtdemux_dump_mem(a,b) gst_util_dump_mem(a,b) -#else -#define qtdemux_dump_mem(a,b) /* */ -#endif - -void -qtdemux_dump_mvhd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s creation time: %u", depth, "", QT_UINT32 (buffer + 12)); - GST_LOG ("%*s modify time: %u", depth, "", QT_UINT32 (buffer + 16)); - GST_LOG ("%*s time scale: 1/%u sec", depth, "", QT_UINT32 (buffer + 20)); - GST_LOG ("%*s duration: %u", depth, "", QT_UINT32 (buffer + 24)); - GST_LOG ("%*s pref. rate: %g", depth, "", QT_FP32 (buffer + 28)); - GST_LOG ("%*s pref. volume: %g", depth, "", QT_FP16 (buffer + 32)); - GST_LOG ("%*s preview time: %u", depth, "", QT_UINT32 (buffer + 80)); - GST_LOG ("%*s preview dur.: %u", depth, "", QT_UINT32 (buffer + 84)); - GST_LOG ("%*s poster time: %u", depth, "", QT_UINT32 (buffer + 88)); - GST_LOG ("%*s select time: %u", depth, "", QT_UINT32 (buffer + 92)); - GST_LOG ("%*s select dur.: %u", depth, "", QT_UINT32 (buffer + 96)); - GST_LOG ("%*s current time: %u", depth, "", QT_UINT32 (buffer + 100)); - GST_LOG ("%*s next track ID: %d", depth, "", QT_UINT32 (buffer + 104)); -} - -void -qtdemux_dump_tkhd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s creation time: %u", depth, "", QT_UINT32 (buffer + 12)); - GST_LOG ("%*s modify time: %u", depth, "", QT_UINT32 (buffer + 16)); - GST_LOG ("%*s track ID: %u", depth, "", QT_UINT32 (buffer + 20)); - GST_LOG ("%*s duration: %u", depth, "", QT_UINT32 (buffer + 28)); - GST_LOG ("%*s layer: %u", depth, "", QT_UINT16 (buffer + 36)); - GST_LOG ("%*s alt group: %u", depth, "", QT_UINT16 (buffer + 38)); - GST_LOG ("%*s volume: %g", depth, "", QT_FP16 (buffer + 44)); - GST_LOG ("%*s track width: %g", depth, "", QT_FP32 (buffer + 84)); - GST_LOG ("%*s track height: %g", depth, "", QT_FP32 (buffer + 88)); - -} - -void -qtdemux_dump_elst (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %u", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - for (i = 0; i < n; i++) { - GST_LOG ("%*s track dur: %u", depth, "", - QT_UINT32 (buffer + 16 + i * 12)); - GST_LOG ("%*s media time: %u", depth, "", - QT_UINT32 (buffer + 20 + i * 12)); - GST_LOG ("%*s media rate: %g", depth, "", - QT_FP32 (buffer + 24 + i * 12)); - } -} - -void -qtdemux_dump_mdhd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - guint32 version; - guint64 duration, ctime, mtime; - guint32 time_scale; - guint16 language, quality; - - version = QT_UINT32 (buffer + 8); - GST_LOG ("%*s version/flags: %08x", depth, "", version); - - if (version == 0x01000000) { - ctime = QT_UINT64 (buffer + 12); - mtime = QT_UINT64 (buffer + 20); - time_scale = QT_UINT32 (buffer + 28); - duration = QT_UINT64 (buffer + 32); - language = QT_UINT16 (buffer + 40); - quality = QT_UINT16 (buffer + 42); - } else { - ctime = QT_UINT32 (buffer + 12); - mtime = QT_UINT32 (buffer + 16); - time_scale = QT_UINT32 (buffer + 20); - duration = QT_UINT32 (buffer + 24); - language = QT_UINT16 (buffer + 28); - quality = QT_UINT16 (buffer + 30); - } - - GST_LOG ("%*s creation time: %" G_GUINT64_FORMAT, depth, "", ctime); - GST_LOG ("%*s modify time: %" G_GUINT64_FORMAT, depth, "", mtime); - GST_LOG ("%*s time scale: 1/%u sec", depth, "", time_scale); - GST_LOG ("%*s duration: %" G_GUINT64_FORMAT, depth, "", duration); - GST_LOG ("%*s language: %u", depth, "", language); - GST_LOG ("%*s quality: %u", depth, "", quality); -} - -void -qtdemux_dump_hdlr (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + 12))); - GST_LOG ("%*s subtype: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + 16))); - GST_LOG ("%*s manufacturer: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + 20))); - GST_LOG ("%*s flags: %08x", depth, "", QT_UINT32 (buffer + 24)); - GST_LOG ("%*s flags mask: %08x", depth, "", QT_UINT32 (buffer + 28)); - GST_LOG ("%*s name: %*s", depth, "", - QT_UINT8 (buffer + 32), (char *) (buffer + 33)); - -} - -void -qtdemux_dump_vmhd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s mode/color: %08x", depth, "", QT_UINT32 (buffer + 16)); -} - -void -qtdemux_dump_dref (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int n; - int i; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %u", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s size: %u", depth, "", - QT_UINT32 (buffer + offset)); - GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 4))); - offset += QT_UINT32 (buffer + offset); - } -} - -void -qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s size: %u", depth, "", - QT_UINT32 (buffer + offset)); - GST_LOG ("%*s type: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 4))); - GST_LOG ("%*s data reference:%d", depth, "", - QT_UINT16 (buffer + offset + 14)); - - GST_LOG ("%*s version/rev.: %08x", depth, "", - QT_UINT32 (buffer + offset + 16)); - GST_LOG ("%*s vendor: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + offset + 20))); - GST_LOG ("%*s temporal qual: %u", depth, "", - QT_UINT32 (buffer + offset + 24)); - GST_LOG ("%*s spatial qual: %u", depth, "", - QT_UINT32 (buffer + offset + 28)); - GST_LOG ("%*s width: %u", depth, "", - QT_UINT16 (buffer + offset + 32)); - GST_LOG ("%*s height: %u", depth, "", - QT_UINT16 (buffer + offset + 34)); - GST_LOG ("%*s horiz. resol: %g", depth, "", - QT_FP32 (buffer + offset + 36)); - GST_LOG ("%*s vert. resol.: %g", depth, "", - QT_FP32 (buffer + offset + 40)); - GST_LOG ("%*s data size: %u", depth, "", - QT_UINT32 (buffer + offset + 44)); - GST_LOG ("%*s frame count: %u", depth, "", - QT_UINT16 (buffer + offset + 48)); - GST_LOG ("%*s compressor: %d %d %d", depth, "", - QT_UINT8 (buffer + offset + 49), - QT_UINT8 (buffer + offset + 50), QT_UINT8 (buffer + offset + 51)); - //(char *) (buffer + offset + 51)); - GST_LOG ("%*s depth: %u", depth, "", - QT_UINT16 (buffer + offset + 82)); - GST_LOG ("%*s color table ID:%u", depth, "", - QT_UINT16 (buffer + offset + 84)); - - offset += QT_UINT32 (buffer + offset); - } -} - -void -qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s count: %u", depth, "", - QT_UINT32 (buffer + offset)); - GST_LOG ("%*s duration: %u", depth, "", - QT_UINT32 (buffer + offset + 4)); - - offset += 8; - } -} - -void -qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s sample: %u", depth, "", - QT_UINT32 (buffer + offset)); - - offset += 4; - } -} - -void -qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s first chunk: %u", depth, "", - QT_UINT32 (buffer + offset)); - GST_LOG ("%*s sample per ch: %u", depth, "", - QT_UINT32 (buffer + offset + 4)); - GST_LOG ("%*s sample desc id:%08x", depth, "", - QT_UINT32 (buffer + offset + 8)); - - offset += 12; - } -} - -void -qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - //int i; - int n; - int offset; - int sample_size; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - sample_size = QT_UINT32 (buffer + 12); - GST_LOG ("%*s sample size: %d", depth, "", sample_size); - if (sample_size == 0) { - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 16)); - n = QT_UINT32 (buffer + 16); - offset = 20; -#if 0 - for (i = 0; i < n; i++) { - GST_LOG ("%*s sample size: %u", depth, "", - QT_UINT32 (buffer + offset)); - - offset += 4; - } -#endif - } -} - -void -qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - n = QT_UINT32 (buffer + 12); - GST_LOG ("%*s n entries: %d", depth, "", n); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s chunk offset: %d", depth, "", - QT_UINT32 (buffer + offset)); - - offset += 4; - } -} - -void -qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - n = QT_UINT32 (buffer + 12); - GST_LOG ("%*s n entries: %d", depth, "", n); - offset = 16; - for (i = 0; i < n; i++) { - GST_LOG ("%*s sample count :%8d offset: %8d", - depth, "", QT_UINT32 (buffer + offset), - QT_UINT32 (buffer + offset + 4)); - - offset += 8; - } -} - -void -qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - //int i; - int n; - int offset; - - GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8)); - GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12)); - n = QT_UINT32 (buffer + 12); - offset = 16; -#if 0 - for (i = 0; i < n; i++) { - GST_LOG ("%*s chunk offset: %" G_GUINT64_FORMAT, depth, "", - QTDEMUX_GUINT64_GET (buffer + offset)); - - offset += 8; - } -#endif -} - -void -qtdemux_dump_dcom (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s compression type: %" GST_FOURCC_FORMAT, depth, "", - GST_FOURCC_ARGS (QT_FOURCC (buffer + 8))); -} - -void -qtdemux_dump_cmvd (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - GST_LOG ("%*s length: %d", depth, "", QT_UINT32 (buffer + 8)); -} - -void -qtdemux_dump_unknown (GstQTDemux * qtdemux, guint8 * buffer, int depth) -{ - int len; - - GST_LOG ("%*s length: %d", depth, "", QT_UINT32 (buffer + 0)); - - len = QT_UINT32 (buffer + 0); - qtdemux_dump_mem (buffer, len); - -} - -static gboolean -qtdemux_node_dump_foreach (GNode * node, gpointer qtdemux) -{ - guint8 *buffer = (guint8 *) node->data; - guint32 node_length; - guint32 fourcc; - const QtNodeType *type; - int depth; - - node_length = GST_READ_UINT32_BE (buffer); - fourcc = GST_READ_UINT32_LE (buffer + 4); - - type = qtdemux_type_get (fourcc); - - depth = (g_node_depth (node) - 1) * 2; - GST_LOG ("%*s'%" GST_FOURCC_FORMAT "', [%d], %s", - depth, "", GST_FOURCC_ARGS (fourcc), node_length, type->name); - - if (type->dump) - type->dump (GST_QTDEMUX_CAST (qtdemux), buffer, depth); - - return FALSE; -} - -void -qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node) -{ - g_node_traverse (qtdemux->moov_node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - qtdemux_node_dump_foreach, qtdemux); -} diff --git a/gst/qtdemux/qtdemux_dump.h b/gst/qtdemux/qtdemux_dump.h deleted file mode 100644 index adfbeae4..00000000 --- a/gst/qtdemux/qtdemux_dump.h +++ /dev/null @@ -1,51 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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_QTDEMUX_DUMP_H__ -#define __GST_QTDEMUX_DUMP_H__ - -#include -#include - -G_BEGIN_DECLS - -void qtdemux_dump_mvhd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_tkhd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_elst (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_mdhd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_hdlr (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_vmhd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_dref (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_dcom (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_cmvd (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth); -void qtdemux_dump_unknown (GstQTDemux * qtdemux, guint8 * buffer, int depth); - -void qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node); - -G_END_DECLS - -#endif /* __GST_QTDEMUX_DUMP_H__ */ diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h deleted file mode 100644 index c196768a..00000000 --- a/gst/qtdemux/qtdemux_fourcc.h +++ /dev/null @@ -1,133 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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_QTDEMUX_FOURCC_H__ -#define __GST_QTDEMUX_FOURCC_H__ - -#include - -G_BEGIN_DECLS - -#define FOURCC_moov GST_MAKE_FOURCC('m','o','o','v') -#define FOURCC_mvhd GST_MAKE_FOURCC('m','v','h','d') -#define FOURCC_clip GST_MAKE_FOURCC('c','l','i','p') -#define FOURCC_trak GST_MAKE_FOURCC('t','r','a','k') -#define FOURCC_udta GST_MAKE_FOURCC('u','d','t','a') -#define FOURCC_ctab GST_MAKE_FOURCC('c','t','a','b') -#define FOURCC_tkhd GST_MAKE_FOURCC('t','k','h','d') -#define FOURCC_crgn GST_MAKE_FOURCC('c','r','g','n') -#define FOURCC_matt GST_MAKE_FOURCC('m','a','t','t') -#define FOURCC_kmat GST_MAKE_FOURCC('k','m','a','t') -#define FOURCC_edts GST_MAKE_FOURCC('e','d','t','s') -#define FOURCC_elst GST_MAKE_FOURCC('e','l','s','t') -#define FOURCC_load GST_MAKE_FOURCC('l','o','a','d') -#define FOURCC_tref GST_MAKE_FOURCC('t','r','e','f') -#define FOURCC_imap GST_MAKE_FOURCC('i','m','a','p') -#define FOURCC___in GST_MAKE_FOURCC(' ',' ','i','n') -#define FOURCC___ty GST_MAKE_FOURCC(' ',' ','t','y') -#define FOURCC_mdia GST_MAKE_FOURCC('m','d','i','a') -#define FOURCC_mdhd GST_MAKE_FOURCC('m','d','h','d') -#define FOURCC_hdlr GST_MAKE_FOURCC('h','d','l','r') -#define FOURCC_minf GST_MAKE_FOURCC('m','i','n','f') -#define FOURCC_vmhd GST_MAKE_FOURCC('v','m','h','d') -#define FOURCC_smhd GST_MAKE_FOURCC('s','m','h','d') -#define FOURCC_gmhd GST_MAKE_FOURCC('g','m','h','d') -#define FOURCC_gmin GST_MAKE_FOURCC('g','m','i','n') -#define FOURCC_dinf GST_MAKE_FOURCC('d','i','n','f') -#define FOURCC_dref GST_MAKE_FOURCC('d','r','e','f') -#define FOURCC_stbl GST_MAKE_FOURCC('s','t','b','l') -#define FOURCC_stsd GST_MAKE_FOURCC('s','t','s','d') -#define FOURCC_stts GST_MAKE_FOURCC('s','t','t','s') -#define FOURCC_stss GST_MAKE_FOURCC('s','t','s','s') -#define FOURCC_stsc GST_MAKE_FOURCC('s','t','s','c') -#define FOURCC_stsz GST_MAKE_FOURCC('s','t','s','z') -#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o') -#define FOURCC_vide GST_MAKE_FOURCC('v','i','d','e') -#define FOURCC_soun GST_MAKE_FOURCC('s','o','u','n') -#define FOURCC_strm GST_MAKE_FOURCC('s','t','r','m') -#define FOURCC_rtsp GST_MAKE_FOURCC('r','t','s','p') -#define FOURCC_co64 GST_MAKE_FOURCC('c','o','6','4') -#define FOURCC_cmov GST_MAKE_FOURCC('c','m','o','v') -#define FOURCC_dcom GST_MAKE_FOURCC('d','c','o','m') -#define FOURCC_cmvd GST_MAKE_FOURCC('c','m','v','d') -#define FOURCC_hint GST_MAKE_FOURCC('h','i','n','t') -#define FOURCC_mp4a GST_MAKE_FOURCC('m','p','4','a') -#define FOURCC_mp4v GST_MAKE_FOURCC('m','p','4','v') -#define FOURCC_wave GST_MAKE_FOURCC('w','a','v','e') -#define FOURCC_appl GST_MAKE_FOURCC('a','p','p','l') -#define FOURCC_esds GST_MAKE_FOURCC('e','s','d','s') -#define FOURCC_hnti GST_MAKE_FOURCC('h','n','t','i') -#define FOURCC_rtp_ GST_MAKE_FOURCC('r','t','p',' ') -#define FOURCC_sdp_ GST_MAKE_FOURCC('s','d','p',' ') -#define FOURCC_meta GST_MAKE_FOURCC('m','e','t','a') -#define FOURCC_ilst GST_MAKE_FOURCC('i','l','s','t') -#define FOURCC__nam GST_MAKE_FOURCC(0xa9,'n','a','m') -#define FOURCC__ART GST_MAKE_FOURCC(0xa9,'A','R','T') -#define FOURCC__wrt GST_MAKE_FOURCC(0xa9,'w','r','t') -#define FOURCC__grp GST_MAKE_FOURCC(0xa9,'g','r','p') -#define FOURCC__alb GST_MAKE_FOURCC(0xa9,'a','l','b') -#define FOURCC__day GST_MAKE_FOURCC(0xa9,'d','a','y') -#define FOURCC_gnre GST_MAKE_FOURCC('g','n','r','e') -#define FOURCC_disc GST_MAKE_FOURCC('d','i','s','c') -#define FOURCC_disk GST_MAKE_FOURCC('d','i','s','k') -#define FOURCC_trkn GST_MAKE_FOURCC('t','r','k','n') -#define FOURCC_cpil GST_MAKE_FOURCC('c','p','i','l') -#define FOURCC_tmpo GST_MAKE_FOURCC('t','m','p','o') -#define FOURCC__too GST_MAKE_FOURCC(0xa9,'t','o','o') -#define FOURCC_____ GST_MAKE_FOURCC('-','-','-','-') -#define FOURCC_free GST_MAKE_FOURCC('f','r','e','e') -#define FOURCC_data GST_MAKE_FOURCC('d','a','t','a') -#define FOURCC_SVQ3 GST_MAKE_FOURCC('S','V','Q','3') -#define FOURCC_rmra GST_MAKE_FOURCC('r','m','r','a') -#define FOURCC_rmda GST_MAKE_FOURCC('r','m','d','a') -#define FOURCC_rdrf GST_MAKE_FOURCC('r','d','r','f') -#define FOURCC__gen GST_MAKE_FOURCC(0xa9, 'g', 'e', 'n') -#define FOURCC_rmdr GST_MAKE_FOURCC('r','m','d','r') -#define FOURCC_rmvc GST_MAKE_FOURCC('r','m','v','c') -#define FOURCC_qtim GST_MAKE_FOURCC('q','t','i','m') -#define FOURCC_drms GST_MAKE_FOURCC('d','r','m','s') -#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') -#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C') -#define FOURCC_VP31 GST_MAKE_FOURCC('V','P','3','1') -#define FOURCC_rle_ GST_MAKE_FOURCC('r','l','e',' ') -#define FOURCC_MAC6 GST_MAKE_FOURCC('M','A','C','6') -#define FOURCC_MAC3 GST_MAKE_FOURCC('M','A','C','3') -#define FOURCC_ima4 GST_MAKE_FOURCC('i','m','a','4') -#define FOURCC_ulaw GST_MAKE_FOURCC('u','l','a','w') -#define FOURCC_alaw GST_MAKE_FOURCC('a','l','a','w') -#define FOURCC_twos GST_MAKE_FOURCC('t','w','o','s') -#define FOURCC_sowt GST_MAKE_FOURCC('s','o','w','t') -#define FOURCC_raw_ GST_MAKE_FOURCC('r','a','w',' ') -#define FOURCC_QDM2 GST_MAKE_FOURCC('Q','D','M','2') -#define FOURCC_alac GST_MAKE_FOURCC('a','l','a','c') -#define FOURCC_samr GST_MAKE_FOURCC('s','a','m','r') -#define FOURCC_sawb GST_MAKE_FOURCC('s','a','w','b') -#define FOURCC_mdat GST_MAKE_FOURCC('m','d','a','t') -#define FOURCC_wide GST_MAKE_FOURCC('w','i','d','e') -#define FOURCC_PICT GST_MAKE_FOURCC('P','I','C','T') -#define FOURCC_pnot GST_MAKE_FOURCC('p','n','o','t') -#define FOURCC_zlib GST_MAKE_FOURCC('z','l','i','b') -#define FOURCC_alis GST_MAKE_FOURCC('a','l','i','s') -#define FOURCC_url_ GST_MAKE_FOURCC('u','r','l',' ') -#define FOURCC_frma GST_MAKE_FOURCC('f','r','m','a') -#define FOURCC_ctts GST_MAKE_FOURCC('c','t','t','s') - -G_END_DECLS - -#endif /* __GST_QTDEMUX_FOURCC_H__ */ diff --git a/gst/qtdemux/qtdemux_types.c b/gst/qtdemux/qtdemux_types.c deleted file mode 100644 index 76813b06..00000000 --- a/gst/qtdemux/qtdemux_types.c +++ /dev/null @@ -1,129 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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 "qtdemux_types.h" -#include "qtdemux_dump.h" -#include "qtdemux_fourcc.h" - -static const QtNodeType qt_node_types[] = { - {FOURCC_moov, "movie", QT_FLAG_CONTAINER,}, - {FOURCC_mvhd, "movie header", 0, - qtdemux_dump_mvhd}, - {FOURCC_clip, "clipping", QT_FLAG_CONTAINER,}, - {FOURCC_trak, "track", QT_FLAG_CONTAINER,}, - {FOURCC_udta, "user data", QT_FLAG_CONTAINER,}, /* special container */ - {FOURCC_ctab, "color table", 0,}, - {FOURCC_tkhd, "track header", 0, - qtdemux_dump_tkhd}, - {FOURCC_crgn, "clipping region", 0,}, - {FOURCC_matt, "track matte", QT_FLAG_CONTAINER,}, - {FOURCC_kmat, "compressed matte", 0,}, - {FOURCC_edts, "edit", QT_FLAG_CONTAINER,}, - {FOURCC_elst, "edit list", 0, - qtdemux_dump_elst}, - {FOURCC_load, "track load settings", 0,}, - {FOURCC_tref, "track reference", QT_FLAG_CONTAINER,}, - {FOURCC_imap, "track input map", QT_FLAG_CONTAINER,}, - {FOURCC___in, "track input", 0,}, /* special container */ - {FOURCC___ty, "input type", 0,}, - {FOURCC_mdia, "media", QT_FLAG_CONTAINER}, - {FOURCC_mdhd, "media header", 0, - qtdemux_dump_mdhd}, - {FOURCC_hdlr, "handler reference", 0, - qtdemux_dump_hdlr}, - {FOURCC_minf, "media information", QT_FLAG_CONTAINER}, - {FOURCC_vmhd, "video media information", 0, - qtdemux_dump_vmhd}, - {FOURCC_smhd, "sound media information", 0}, - {FOURCC_gmhd, "base media information header", 0}, - {FOURCC_gmin, "base media info", 0}, - {FOURCC_dinf, "data information", QT_FLAG_CONTAINER}, - {FOURCC_dref, "data reference", 0, - qtdemux_dump_dref}, - {FOURCC_stbl, "sample table", QT_FLAG_CONTAINER}, - {FOURCC_stsd, "sample description", 0, - qtdemux_dump_stsd}, - {FOURCC_stts, "time-to-sample", 0, - qtdemux_dump_stts}, - {FOURCC_stss, "sync sample", 0, - qtdemux_dump_stss}, - {FOURCC_stsc, "sample-to-chunk", 0, - qtdemux_dump_stsc}, - {FOURCC_stsz, "sample size", 0, - qtdemux_dump_stsz}, - {FOURCC_stco, "chunk offset", 0, - qtdemux_dump_stco}, - {FOURCC_co64, "64-bit chunk offset", 0, - qtdemux_dump_co64}, - {FOURCC_vide, "video media", 0}, - {FOURCC_cmov, "compressed movie", QT_FLAG_CONTAINER}, - {FOURCC_dcom, "compressed data", 0, qtdemux_dump_dcom}, - {FOURCC_cmvd, "compressed movie data", 0, qtdemux_dump_cmvd}, - {FOURCC_hint, "hint", 0,}, - {FOURCC_mp4a, "mp4a", 0,}, - {FOURCC_mp4v, "mp4v", 0,}, - {FOURCC_wave, "wave", QT_FLAG_CONTAINER}, - {FOURCC_appl, "appl", QT_FLAG_CONTAINER}, - {FOURCC_esds, "esds", 0}, - {FOURCC_hnti, "hnti", QT_FLAG_CONTAINER}, - {FOURCC_rtp_, "rtp ", 0, qtdemux_dump_unknown}, - {FOURCC_sdp_, "sdp ", 0, qtdemux_dump_unknown}, - {FOURCC_meta, "meta", 0, qtdemux_dump_unknown}, - {FOURCC_ilst, "ilst", QT_FLAG_CONTAINER,}, - {FOURCC__nam, "Name", QT_FLAG_CONTAINER,}, - {FOURCC__ART, "Artist", QT_FLAG_CONTAINER,}, - {FOURCC__wrt, "Writer", QT_FLAG_CONTAINER,}, - {FOURCC__grp, "Group", QT_FLAG_CONTAINER,}, - {FOURCC__alb, "Album", QT_FLAG_CONTAINER,}, - {FOURCC__day, "Date", QT_FLAG_CONTAINER,}, - {FOURCC_gnre, "Genre", QT_FLAG_CONTAINER,}, - {FOURCC_trkn, "Track Number", QT_FLAG_CONTAINER,}, - {FOURCC_disc, "Disc Number", QT_FLAG_CONTAINER,}, - {FOURCC_disk, "Disc Number", QT_FLAG_CONTAINER,}, - {FOURCC_cpil, "cpil", QT_FLAG_CONTAINER,}, - {FOURCC_tmpo, "Tempo", QT_FLAG_CONTAINER,}, - {FOURCC__too, "too", QT_FLAG_CONTAINER,}, - {FOURCC_____, "----", QT_FLAG_CONTAINER,}, - {FOURCC_data, "data", 0, qtdemux_dump_unknown}, - {FOURCC_free, "free", 0,}, - {FOURCC_SVQ3, "SVQ3", 0,}, - {FOURCC_rmra, "rmra", QT_FLAG_CONTAINER,}, - {FOURCC_rmda, "rmda", QT_FLAG_CONTAINER,}, - {FOURCC_rdrf, "rdrf", 0,}, - {FOURCC__gen, "Custom Genre", QT_FLAG_CONTAINER,}, - {FOURCC_ctts, "Composition time to sample", 0, qtdemux_dump_ctts}, - {0, "unknown", 0,}, -}; -static const int n_qt_node_types = - sizeof (qt_node_types) / sizeof (qt_node_types[0]); - -const QtNodeType * -qtdemux_type_get (guint32 fourcc) -{ - int i; - - for (i = 0; i < n_qt_node_types; i++) { - if (qt_node_types[i].fourcc == fourcc) - return qt_node_types + i; - } - - GST_WARNING ("unknown QuickTime node type %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (fourcc)); - return qt_node_types + n_qt_node_types - 1; -} diff --git a/gst/qtdemux/qtdemux_types.h b/gst/qtdemux/qtdemux_types.h deleted file mode 100644 index 7142410f..00000000 --- a/gst/qtdemux/qtdemux_types.h +++ /dev/null @@ -1,58 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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_QTDEMUX_TYPES_H__ -#define __GST_QTDEMUX_TYPES_H__ - -#include - -#include "qtdemux.h" - -G_BEGIN_DECLS - -typedef void (*QtDumpFunc) (GstQTDemux * qtdemux, guint8 * buffer, int depth); - -typedef struct _QtNodeType QtNodeType; - -#define QT_UINT32(a) (GST_READ_UINT32_BE(a)) -#define QT_UINT24(a) (GST_READ_UINT32_BE(a) >> 8) -#define QT_UINT16(a) (GST_READ_UINT16_BE(a)) -#define QT_UINT8(a) (GST_READ_UINT8(a)) -#define QT_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0) -#define QT_FP16(a) ((GST_READ_UINT16_BE(a))/256.0) -#define QT_FOURCC(a) (GST_READ_UINT32_LE(a)) -#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4)) - -typedef enum { - QT_FLAG_NONE = (0), - QT_FLAG_CONTAINER = (1 << 0) -} QtFlags; - -struct _QtNodeType { - guint32 fourcc; - const gchar *name; - QtFlags flags; - QtDumpFunc dump; -}; - -const QtNodeType *qtdemux_type_get (guint32 fourcc); - -G_END_DECLS - -#endif /* __GST_QTDEMUX_TYPES_H__ */ diff --git a/gst/qtdemux/qtpalette.h b/gst/qtdemux/qtpalette.h deleted file mode 100644 index 80ece2ae..00000000 --- a/gst/qtdemux/qtpalette.h +++ /dev/null @@ -1,137 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * - * 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_QTPALLETE_H__ -#define __GST_QTPALLETE_H__ - -#include - -G_BEGIN_DECLS - -static const guint32 ff_qt_default_palette_2[2] = { - 0xffffff, 0x000000 -}; - -static const guint32 ff_qt_default_palette_4[4] = { - 0x93655e, 0xffffff, 0xdfd0ab, 0x000000 -}; - -static const guint32 ff_qt_default_palette_16[16] = { - 0xfffbff, 0xefd9bb, 0xe8c9b1, 0x93655e, - 0xfcdee8, 0x9d8891, 0xffffff, 0xffffff, - 0xffffff, 0x474837, 0x7a5e55, 0xdfd0ab, - 0xfffbf9, 0xe8cac5, 0x8a7c77, 0x000000 -}; -static const guint32 ff_qt_default_palette_256[256] = { - 0xFFFFFF, 0xFFFFCC, 0xFFFF99, 0xFFFF66, 0xFFFF33, 0xFFFF00, - 0xFFCCFF, 0xFFCCCC, 0xFFCC99, 0xFFCC66, 0xFFCC33, 0xFFCC00, - 0xFF99FF, 0xFF99CC, 0xFF9999, 0xFF9966, 0xFF9933, 0xFF9900, - 0xFF66FF, 0xFF66CC, 0xFF6699, 0xFF6666, 0xFF6633, 0xFF6600, - 0xFF33FF, 0xFF33CC, 0xFF3399, 0xFF3366, 0xFF3333, 0xFF3300, - 0xFF00FF, 0xFF00CC, 0xFF0099, 0xFF0066, 0xFF0033, 0xFF0000, - 0xCCFFFF, 0xCCFFCC, 0xCCFF99, 0xCCFF66, 0xCCFF33, 0xCCFF00, - 0xCCCCFF, 0xCCCCCC, 0xCCCC99, 0xCCCC66, 0xCCCC33, 0xCCCC00, - 0xCC99FF, 0xCC99CC, 0xCC9999, 0xCC9966, 0xCC9933, 0xCC9900, - 0xCC66FF, 0xCC66CC, 0xCC6699, 0xCC6666, 0xCC6633, 0xCC6600, - 0xCC33FF, 0xCC33CC, 0xCC3399, 0xCC3366, 0xCC3333, 0xCC3300, - 0xCC00FF, 0xCC00CC, 0xCC0099, 0xCC0066, 0xCC0033, 0xCC0000, - 0x99FFFF, 0x99FFCC, 0x99FF99, 0x99FF66, 0x99FF33, 0x99FF00, - 0x99CCFF, 0x99CCCC, 0x99CC99, 0x99CC66, 0x99CC33, 0x99CC00, - 0x9999FF, 0x9999CC, 0x999999, 0x999966, 0x999933, 0x999900, - 0x9966FF, 0x9966CC, 0x996699, 0x996666, 0x996633, 0x996600, - 0x9933FF, 0x9933CC, 0x993399, 0x993366, 0x993333, 0x993300, - 0x9900FF, 0x9900CC, 0x990099, 0x990066, 0x990033, 0x990000, - 0x66FFFF, 0x66FFCC, 0x66FF99, 0x66FF66, 0x66FF33, 0x66FF00, - 0x66CCFF, 0x66CCCC, 0x66CC99, 0x66CC66, 0x66CC33, 0x66CC00, - 0x6699FF, 0x6699CC, 0x669999, 0x669966, 0x669933, 0x669900, - 0x6666FF, 0x6666CC, 0x666699, 0x666666, 0x666633, 0x666600, - 0x6633FF, 0x6633CC, 0x663399, 0x663366, 0x663333, 0x663300, - 0x6600FF, 0x6600CC, 0x660099, 0x660066, 0x660033, 0x660000, - 0x33FFFF, 0x33FFCC, 0x33FF99, 0x33FF66, 0x33FF33, 0x33FF00, - 0x33CCFF, 0x33CCCC, 0x33CC99, 0x33CC66, 0x33CC33, 0x33CC00, - 0x3399FF, 0x3399CC, 0x339999, 0x339966, 0x339933, 0x339900, - 0x3366FF, 0x3366CC, 0x336699, 0x336666, 0x336633, 0x336600, - 0x3333FF, 0x3333CC, 0x333399, 0x333366, 0x333333, 0x333300, - 0x3300FF, 0x3300CC, 0x330099, 0x330066, 0x330033, 0x330000, - 0x00FFFF, 0x00FFCC, 0x00FF99, 0x00FF66, 0x00FF33, 0x00FF00, - 0x00CCFF, 0x00CCCC, 0x00CC99, 0x00CC66, 0x00CC33, 0x00CC00, - 0x0099FF, 0x0099CC, 0x009999, 0x009966, 0x009933, 0x009900, - 0x0066FF, 0x0066CC, 0x006699, 0x006666, 0x006633, 0x006600, - 0x0033FF, 0x0033CC, 0x003399, 0x003366, 0x003333, 0x003300, - 0x0000FF, 0x0000CC, 0x000099, 0x000066, 0x000033, 0xEE0000, - 0xDD0000, 0xBB0000, 0xAA0000, 0x880000, 0x770000, 0x550000, - 0x440000, 0x220000, 0x110000, 0x00EE00, 0x00DD00, 0x00BB00, - 0x00AA00, 0x008800, 0x007700, 0x005500, 0x004400, 0x002200, - 0x001100, 0x0000EE, 0x0000DD, 0x0000BB, 0x0000AA, 0x000088, - 0x000077, 0x000055, 0x000044, 0x000022, 0x000011, 0xEEEEEE, - 0xDDDDDD, 0xBBBBBB, 0xAAAAAA, 0x888888, 0x777777, 0x555555, - 0x444444, 0x222222, 0x111111, 0x000000 -}; - -static const guint32 ff_qt_grayscale_palette_16[16] = { - 0xffffff, 0xeeeeee, 0xdddddd, 0xcccccc, - 0xbbbbbb, 0xaaaaaa, 0x999999, 0x888888, - 0x777777, 0x666666, 0x555555, 0x444444, - 0x333333, 0x222222, 0x111111, 0x000000 -}; - -static const guint32 ff_qt_grayscale_palette_256[256] = { - 0xffffff, 0xfefefe, 0xfdfdfd, 0xfcfcfc, 0xfbfbfb, 0xfafafa, 0xf9f9f9, - 0xf8f8f8, 0xf7f7f7, 0xf6f6f6, 0xf5f5f5, 0xf4f4f4, 0xf3f3f3, 0xf2f2f2, - 0xf1f1f1, 0xf0f0f0, 0xefefef, 0xeeeeee, 0xededed, 0xececec, 0xebebeb, - 0xeaeaea, 0xe9e9e9, 0xe8e8e8, 0xe7e7e7, 0xe6e6e6, 0xe5e5e5, 0xe4e4e4, - 0xe3e3e3, 0xe2e2e2, 0xe1e1e1, 0xe0e0e0, 0xdfdfdf, 0xdedede, 0xdddddd, - 0xdcdcdc, 0xdbdbdb, 0xdadada, 0xd9d9d9, 0xd8d8d8, 0xd7d7d7, 0xd6d6d6, - 0xd5d5d5, 0xd4d4d4, 0xd3d3d3, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, - 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, - 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, - 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, - 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, - 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, - 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, - 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, - 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, - 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, - 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, - 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, - 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, - 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, - 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, - 0x6c6c6c, 0x6b6b6b, 0x6a6a6a, 0x696969, 0x686868, 0x676767, 0x666666, - 0x656565, 0x646464, 0x636363, 0x626262, 0x616161, 0x606060, 0x5f5f5f, - 0x5e5e5e, 0x5d5d5d, 0x5c5c5c, 0x5b5b5b, 0x5a5a5a, 0x595959, 0x585858, - 0x575757, 0x565656, 0x555555, 0x545454, 0x535353, 0x525252, 0x515151, - 0x505050, 0x4f4f4f, 0x4e4e4e, 0x4d4d4d, 0x4c4c4c, 0x4b4b4b, 0x4a4a4a, - 0x494949, 0x484848, 0x474747, 0x464646, 0x454545, 0x444444, 0x434343, - 0x424242, 0x414141, 0x404040, 0x3f3f3f, 0x3e3e3e, 0x3d3d3d, 0x3c3c3c, - 0x3b3b3b, 0x3a3a3a, 0x393939, 0x383838, 0x373737, 0x363636, 0x353535, - 0x343434, 0x333333, 0x323232, 0x313131, 0x303030, 0x2f2f2f, 0x2e2e2e, - 0x2d2d2d, 0x2c2c2c, 0x2b2b2b, 0x2a2a2a, 0x292929, 0x282828, 0x272727, - 0x262626, 0x252525, 0x242424, 0x232323, 0x222222, 0x212121, 0x202020, - 0x1f1f1f, 0x1e1e1e, 0x1d1d1d, 0x1c1c1c, 0x1b1b1b, 0x1a1a1a, 0x191919, - 0x181818, 0x171717, 0x161616, 0x151515, 0x141414, 0x131313, 0x121212, - 0x111111, 0x101010, 0x0f0f0f, 0x0e0e0e, 0x0d0d0d, 0x0c0c0c, 0x0b0b0b, - 0x0a0a0a, 0x090909, 0x080808, 0x070707, 0x060606, 0x050505, 0x040404, - 0x030303, 0x020202, 0x010101, 0x000000 -}; - -G_END_DECLS - -#endif /* __GST_QTPALETTE_H__ */ diff --git a/gst/qtdemux/quicktime.c b/gst/qtdemux/quicktime.c deleted file mode 100644 index f7b880c8..00000000 --- a/gst/qtdemux/quicktime.c +++ /dev/null @@ -1,53 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) <2003> David A. Schleef - * Copyright (C) <2006> Wim Taymans - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "gst/gst-i18n-plugin.h" - -#include "qtdemux.h" -#include "gstrtpxqtdepay.h" - -static gboolean -plugin_init (GstPlugin * plugin) -{ -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); -#endif /* ENABLE_NLS */ - - if (!gst_element_register (plugin, "qtdemux", - GST_RANK_PRIMARY, GST_TYPE_QTDEMUX)) - return FALSE; - - if (!gst_element_register (plugin, "rtpxqtdepay", - GST_RANK_MARGINAL, GST_TYPE_RTP_XQT_DEPAY)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "quicktime", - "Quicktime support", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/win32/MANIFEST b/win32/MANIFEST index 63dd54d6..30c81ac0 100644 --- a/win32/MANIFEST +++ b/win32/MANIFEST @@ -3,6 +3,5 @@ win32/common/config.h win32/common/config.h.in win32/vs6/gst_plugins_bad.dsw win32/vs6/libgstneon.dsp -win32/vs6/libgstqtdemux.dsp win32/vs7/gst-plugins-bad.sln win32/vs8/gst-plugins-bad.sln diff --git a/win32/vs6/libgstqtdemux.dsp b/win32/vs6/libgstqtdemux.dsp deleted file mode 100644 index 34e4ec0c..00000000 --- a/win32/vs6/libgstqtdemux.dsp +++ /dev/null @@ -1,142 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgstqtdemux" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=libgstqtdemux - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libgstqtdemux.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libgstqtdemux.mak" CFG="libgstqtdemux - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgstqtdemux - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "libgstqtdemux - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libgstqtdemux - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTQTDEMUX_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /I "../../../gst-plugins-bad/gst/qtdemux" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTQTDEMUX_EXPORTS" /D "HAVE_CONFIG_H" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 glib-2.0.lib gobject-2.0.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstrtp-0.10.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"../../../gst-plugins-base/win32/vs6/release" /libpath:"./release" -# Begin Special Build Tool -TargetPath=.\Release\libgstqtdemux.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\lib\gstreamer-0.10 -# End Special Build Tool - -!ELSEIF "$(CFG)" == "libgstqtdemux - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTQTDEMUX_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /I "../../../gst-plugins-bad/gst/qtdemux" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTQTDEMUX_EXPORTS" /D "HAVE_CONFIG_H" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 glib-2.0D.lib gobject-2.0D.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstrtp-0.10.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug" -# Begin Special Build Tool -TargetPath=.\Debug\libgstqtdemux.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\debug\lib\gstreamer-0.10 -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "libgstqtdemux - Win32 Release" -# Name "libgstqtdemux - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\gst\qtdemux\gstrtpxqtdepay.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=..\..\gst\qtdemux\qtdemux.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=..\..\gst\qtdemux\qtdemux_dump.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=..\..\gst\qtdemux\qtdemux_types.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=..\..\gst\qtdemux\quicktime.c -# SUBTRACT CPP /YX -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\gst\qtdemux\qtdemux.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project -- cgit v1.2.1