diff --git a/Android.mk b/Android.mk index 2094bf5519..0474067e8f 100644 --- a/Android.mk +++ b/Android.mk @@ -6,8 +6,6 @@ GST_PLUGINS_UGLY_TOP := $(LOCAL_PATH) GST_PLUGINS_UGLY_BUILT_SOURCES = \ ext/mad/Android.mk \ gst/synaesthesia/Android.mk \ - gst/mpegaudioparse/Android.mk \ - gst/mpegstream/Android.mk \ gst/realmedia/Android.mk \ gst/dvdsub/Android.mk \ gst/dvdlpcmdec/Android.mk \ @@ -42,9 +40,6 @@ CONFIGURE_TARGETS += gst-plugins-ugly-configure -include $(GST_PLUGINS_UGLY_TOP)/ext/mad/Android.mk -include $(GST_PLUGINS_UGLY_TOP)/ext/x264/Android.mk -include $(GST_PLUGINS_UGLY_TOP)/gst/synaesthesia/Android.mk --include $(GST_PLUGINS_UGLY_TOP)/gst/iec958/Android.mk --include $(GST_PLUGINS_UGLY_TOP)/gst/mpegaudioparse/Android.mk --include $(GST_PLUGINS_UGLY_TOP)/gst/mpegstream/Android.mk -include $(GST_PLUGINS_UGLY_TOP)/gst/realmedia/Android.mk -include $(GST_PLUGINS_UGLY_TOP)/gst/dvdsub/Android.mk -include $(GST_PLUGINS_UGLY_TOP)/gst/dvdlpcmdec/Android.mk diff --git a/configure.ac b/configure.ac index 03d3d1c531..8384b61b7a 100644 --- a/configure.ac +++ b/configure.ac @@ -210,7 +210,7 @@ dnl *** plug-ins to include *** dnl Non ported plugins (non-dependant, then dependant) dnl Make sure you have a space before and after all plugins -GST_PLUGINS_NONPORTED=" synaesthesia xingmux mpegstream " +GST_PLUGINS_NONPORTED=" synaesthesia xingmux " AC_SUBST(GST_PLUGINS_NONPORTED) dnl these are all the gst plug-ins, compilable without additional libs @@ -218,7 +218,6 @@ AG_GST_CHECK_PLUGIN(asfdemux) AG_GST_CHECK_PLUGIN(dvdlpcmdec) AG_GST_CHECK_PLUGIN(dvdsub) AG_GST_CHECK_PLUGIN(xingmux) -AG_GST_CHECK_PLUGIN(mpegstream) AG_GST_CHECK_PLUGIN(realmedia) AG_GST_CHECK_PLUGIN(synaesthesia) @@ -441,7 +440,6 @@ gst/Makefile gst/asfdemux/Makefile gst/dvdlpcmdec/Makefile gst/dvdsub/Makefile -gst/mpegstream/Makefile gst/realmedia/Makefile gst/synaesthesia/Makefile gst/xingmux/Makefile diff --git a/docs/plugins/gst-plugins-ugly-plugins-docs.sgml b/docs/plugins/gst-plugins-ugly-plugins-docs.sgml index f5ae329a3a..29471737dd 100644 --- a/docs/plugins/gst-plugins-ugly-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-ugly-plugins-docs.sgml @@ -22,7 +22,6 @@ - @@ -50,7 +49,6 @@ - diff --git a/docs/plugins/inspect/plugin-mpegstream.xml b/docs/plugins/inspect/plugin-mpegstream.xml deleted file mode 100644 index ddaa0fe06a..0000000000 --- a/docs/plugins/inspect/plugin-mpegstream.xml +++ /dev/null @@ -1,130 +0,0 @@ - - mpegstream - MPEG system stream parser - ../../gst/mpegstream/.libs/libgstmpegstream.so - libgstmpegstream.so - 0.10.18.1 - LGPL - gst-plugins-ugly - GStreamer Ugly Plug-ins git - Unknown package origin - - - dvddemux - DVD Demuxer - Codec/Demuxer - Demultiplexes DVD (VOB) MPEG2 streams - Martin Soto <martinsoto@users.sourceforge.net> - - - sink - sink - always -
video/mpeg, mpegversion=(int)2, systemstream=(boolean)true
-
- - current_audio - source - always -
audio/mpeg, mpegversion=(int)1; audio/x-lpcm, width=(int){ 16, 20, 24 }, rate=(int){ 48000, 96000 }, channels=(int)[ 1, 8 ], dynamic_range=(int)[ 0, 255 ], emphasis=(boolean){ false, true }, mute=(boolean){ false, true }; audio/x-ac3; audio/x-dts
-
- - current_subpicture - source - always -
video/x-dvd-subpicture
-
- - current_video - source - always -
video/mpeg, mpegversion=(int){ 1, 2 }, systemstream=(boolean)false
-
- - audio_%02d - source - sometimes -
audio/mpeg, mpegversion=(int)1
-
- - dvd_audio_%02d - source - sometimes -
audio/mpeg, mpegversion=(int)1; audio/x-lpcm, width=(int){ 16, 20, 24 }, rate=(int){ 48000, 96000 }, channels=(int)[ 1, 8 ], dynamic_range=(int)[ 0, 255 ], emphasis=(boolean){ false, true }, mute=(boolean){ false, true }; audio/x-ac3; audio/x-dts
-
- - private_%d - source - sometimes -
ANY
-
- - subpicture_%d - source - sometimes -
video/x-dvd-subpicture
-
- - video_%02d - source - sometimes -
video/mpeg, mpegversion=(int){ 1, 2 }, systemstream=(boolean)false
-
-
-
- - mpegdemux - MPEG Demuxer - Codec/Demuxer - Demultiplexes MPEG1 and MPEG2 System Streams - Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim.taymans@chello.be> - - - sink - sink - always -
video/mpeg, mpegversion=(int){ 1, 2 }, systemstream=(boolean)true
-
- - audio_%02d - source - sometimes -
audio/mpeg, mpegversion=(int)1
-
- - private_%d - source - sometimes -
ANY
-
- - video_%02d - source - sometimes -
video/mpeg, mpegversion=(int){ 1, 2 }, systemstream=(boolean)false
-
-
-
- - mpegparse - MPEG System Parser - Codec/Parser - Parses MPEG1 and MPEG2 System Streams - Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim.taymans@chello.be> - - - sink - sink - always -
video/mpeg, mpegversion=(int)[ 1, 2 ], systemstream=(boolean)true
-
- - src - source - always -
video/mpeg, mpegversion=(int)[ 1, 2 ], systemstream=(boolean)true
-
-
-
-
-
\ No newline at end of file diff --git a/gst-plugins-ugly.spec.in b/gst-plugins-ugly.spec.in index 39b33cb13a..5015c5cf2c 100644 --- a/gst-plugins-ugly.spec.in +++ b/gst-plugins-ugly.spec.in @@ -95,7 +95,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/gstreamer-%{majorminor}/libgstasf.so %{_libdir}/gstreamer-%{majorminor}/libgstdvdlpcmdec.so # %{_libdir}/gstreamer-%{majorminor}/libgstxingmux.so -# %{_libdir}/gstreamer-%{majorminor}/libgstmpegstream.so # %{_libdir}/gstreamer-%{majorminor}/libgstrmdemux.so %{_libdir}/gstreamer-%{majorminor}/libgstdvdsub.so diff --git a/gst/mpegstream/Makefile.am b/gst/mpegstream/Makefile.am deleted file mode 100644 index 7f7166f80b..0000000000 --- a/gst/mpegstream/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -plugin_LTLIBRARIES = libgstmpegstream.la - -libgstmpegstream_la_SOURCES = gstmpegstream.c \ - gstmpegparse.c \ - gstmpegdemux.c \ - gstdvddemux.c \ - gstmpegpacketize.c \ - gstmpegclock.c -# gstrfc2250enc.c -libgstmpegstream_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -libgstmpegstream_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-@GST_MAJORMINOR@ -libgstmpegstream_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstmpegstream_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = gstmpegparse.h \ - gstmpegdemux.h \ - gstdvddemux.h \ - gstmpegpacketize.h \ - gstmpegclock.h \ - gstrfc2250enc.h - -EXTRA_DIST = README notes - -Android.mk: Makefile.am $(BUILT_SOURCES) - androgenizer \ - -:PROJECT libgstmpegstream -:SHARED libgstmpegstream \ - -:TAGS eng debug \ - -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ - -:SOURCES $(libgstmpegstream_la_SOURCES) \ - -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegstream_la_CFLAGS) \ - -:LDFLAGS $(libgstmpegstream_la_LDFLAGS) \ - $(libgstmpegstream_la_LIBADD) \ - -ldl \ - -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ - LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ - > $@ diff --git a/gst/mpegstream/README b/gst/mpegstream/README deleted file mode 100644 index db2b5c0e33..0000000000 --- a/gst/mpegstream/README +++ /dev/null @@ -1,6 +0,0 @@ -MPEG-2 System Stream Parser -=========================== - -This element will parse MPEG-2 Program Streams (and eventually Transport -Streams, though likely as a second element) into its elemental streams. - diff --git a/gst/mpegstream/gstdvddemux.c b/gst/mpegstream/gstdvddemux.c deleted file mode 100644 index 6f9a38a13e..0000000000 --- a/gst/mpegstream/gstdvddemux.c +++ /dev/null @@ -1,1278 +0,0 @@ -/* GStreamer - * Copyright (C) 2005 Martin Soto - * - * 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 - -#include "gstdvddemux.h" - -/* - * Move PTM discont back by 0.3 seconds to allow for strange audio - * timestamps when audio crosses a VOBU - */ -#define PTM_DISCONT_ADJUST (0.3 * GST_SECOND) -#define INITIAL_END_PTM (-1) -#define MAX_GAP ( 3 * GST_SECOND / 2 ) -#define MAX_GAP_TOLERANCE ( GST_SECOND / 20 ) - -GST_DEBUG_CATEGORY_STATIC (gstdvddemux_debug); -#define GST_CAT_DEFAULT (gstdvddemux_debug) - - -#define PARSE_CLASS(o) GST_MPEG_PARSE_CLASS (G_OBJECT_GET_CLASS (o)) -#define DEMUX_CLASS(o) GST_MPEG_DEMUX_CLASS (G_OBJECT_GET_CLASS (o)) -#define CLASS(o) GST_DVD_DEMUX_CLASS (G_OBJECT_GET_CLASS (o)) - -/* DVDDemux signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0 - /* FILL ME */ -}; - - -/* Define the capabilities separately, to be able to reuse them. */ - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) 2, " "systemstream = (boolean) TRUE") - ); - -#define VIDEO_CAPS \ - GST_STATIC_CAPS ("video/mpeg, " \ - "mpegversion = (int) { 1, 2 }, " \ - "systemstream = (boolean) FALSE" \ - ) - -#define AUDIO_CAPS \ - GST_STATIC_CAPS ( \ - "audio/mpeg, " \ - "mpegversion = (int) 1;" \ - "audio/x-lpcm, " \ - "width = (int) { 16, 20, 24 }, " \ - "rate = (int) { 48000, 96000 }, " \ - "channels = (int) [ 1, 8 ], " \ - "dynamic_range = (int) [ 0, 255 ], " \ - "emphasis = (boolean) { FALSE, TRUE }, " \ - "mute = (boolean) { FALSE, TRUE }; " \ - "audio/x-ac3;" \ - "audio/x-dts" \ - ) - -#define SUBPICTURE_CAPS \ - GST_STATIC_CAPS ("video/x-dvd-subpicture") - -static GstStaticPadTemplate cur_video_template = -GST_STATIC_PAD_TEMPLATE ("current_video", - GST_PAD_SRC, - GST_PAD_ALWAYS, - VIDEO_CAPS); - -static GstStaticPadTemplate audio_template = -GST_STATIC_PAD_TEMPLATE ("dvd_audio_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - AUDIO_CAPS); - -static GstStaticPadTemplate cur_audio_template = -GST_STATIC_PAD_TEMPLATE ("current_audio", - GST_PAD_SRC, - GST_PAD_ALWAYS, - AUDIO_CAPS); - -static GstStaticPadTemplate subpicture_template = -GST_STATIC_PAD_TEMPLATE ("subpicture_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - SUBPICTURE_CAPS); - -static GstStaticPadTemplate cur_subpicture_template = -GST_STATIC_PAD_TEMPLATE ("current_subpicture", - GST_PAD_SRC, - GST_PAD_ALWAYS, - SUBPICTURE_CAPS); - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gstdvddemux_debug, "dvddemux", 0, \ - "DVD (VOB) demultiplexer element"); - -GST_BOILERPLATE_FULL (GstDVDDemux, gst_dvd_demux, GstMPEGDemux, - GST_TYPE_MPEG_DEMUX, _do_init); - -static gboolean gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, - GstEvent * event); -static gboolean gst_dvd_demux_parse_packhead (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); - -static gboolean gst_dvd_demux_handle_dvd_event - (GstDVDDemux * dvd_demux, GstEvent * event); - -static GstMPEGStream *gst_dvd_demux_get_video_stream - (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info); -static GstMPEGStream *gst_dvd_demux_get_audio_stream - (GstMPEGDemux * dvd_demux, - guint8 stream_nr, gint type, const gpointer info); -static GstMPEGStream *gst_dvd_demux_get_subpicture_stream - (GstMPEGDemux * dvd_demux, - guint8 stream_nr, gint type, const gpointer info); - -static GstFlowReturn gst_dvd_demux_process_private - (GstMPEGDemux * mpeg_demux, - GstBuffer * buffer, - guint stream_nr, GstClockTime timestamp, guint headerlen, guint datalen); - -static GstFlowReturn gst_dvd_demux_send_subbuffer - (GstMPEGDemux * mpeg_demux, - GstMPEGStream * outstream, - GstBuffer * buffer, GstClockTime timestamp, guint offset, guint size); - -static GstFlowReturn gst_dvd_demux_combine_flows (GstMPEGDemux * mpegdemux, - GstMPEGStream * stream, GstFlowReturn flow); - -static void gst_dvd_demux_set_cur_audio - (GstDVDDemux * dvd_demux, gint stream_nr); -static void gst_dvd_demux_set_cur_subpicture - (GstDVDDemux * dvd_demux, gint stream_nr); - -static void gst_dvd_demux_reset (GstDVDDemux * dvd_demux); -static void gst_dvd_demux_synchronise_pads (GstMPEGDemux * mpeg_demux, - GstClockTime threshold, GstClockTime new_ts); -static void gst_dvd_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux, - GstMPEGStream * stream, GstClockTime last_ts); - -static GstStateChangeReturn gst_dvd_demux_change_state (GstElement * element, - GstStateChange transition); - -/*static guint gst_dvd_demux_signals[LAST_SIGNAL] = { 0 };*/ - - -static void -gst_dvd_demux_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstMPEGParseClass *mpeg_parse_class = GST_MPEG_PARSE_CLASS (klass); - GstMPEGDemuxClass *demux_class = GST_MPEG_DEMUX_CLASS (klass); - GstDVDDemuxClass *dvd_demux_class = GST_DVD_DEMUX_CLASS (klass); - - mpeg_parse_class->send_buffer = NULL; - mpeg_parse_class->process_event = gst_dvd_demux_process_event; - mpeg_parse_class->parse_packhead = gst_dvd_demux_parse_packhead; - - /* sink pad */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - - demux_class->audio_template = gst_static_pad_template_get (&audio_template); - - dvd_demux_class->cur_video_template = - gst_static_pad_template_get (&cur_video_template); - dvd_demux_class->cur_audio_template = - gst_static_pad_template_get (&cur_audio_template); - dvd_demux_class->subpicture_template = - gst_static_pad_template_get (&subpicture_template); - dvd_demux_class->cur_subpicture_template = - gst_static_pad_template_get (&cur_subpicture_template); - - gst_element_class_add_pad_template (element_class, - demux_class->audio_template); - - gst_element_class_add_pad_template (element_class, - dvd_demux_class->cur_video_template); - gst_element_class_add_pad_template (element_class, - dvd_demux_class->cur_audio_template); - - gst_element_class_add_pad_template (element_class, - dvd_demux_class->subpicture_template); - gst_element_class_add_pad_template (element_class, - dvd_demux_class->cur_subpicture_template); - - gst_element_class_set_details_simple (element_class, "DVD Demuxer", - "Codec/Demuxer", - "Demultiplexes DVD (VOB) MPEG2 streams", - "Martin Soto "); -} - - -static void -gst_dvd_demux_class_init (GstDVDDemuxClass * klass) -{ - GstElementClass *gstelement_class; - GstMPEGDemuxClass *mpeg_demux_class; - - parent_class = g_type_class_peek_parent (klass); - - gstelement_class = (GstElementClass *) klass; - mpeg_demux_class = (GstMPEGDemuxClass *) klass; - - gstelement_class->change_state = gst_dvd_demux_change_state; - - mpeg_demux_class->get_audio_stream = gst_dvd_demux_get_audio_stream; - mpeg_demux_class->get_video_stream = gst_dvd_demux_get_video_stream; - mpeg_demux_class->send_subbuffer = gst_dvd_demux_send_subbuffer; - mpeg_demux_class->combine_flows = gst_dvd_demux_combine_flows; - mpeg_demux_class->process_private = gst_dvd_demux_process_private; - mpeg_demux_class->synchronise_pads = gst_dvd_demux_synchronise_pads; - mpeg_demux_class->sync_stream_to_time = gst_dvd_demux_sync_stream_to_time; - - klass->get_subpicture_stream = gst_dvd_demux_get_subpicture_stream; -} - - -static void -gst_dvd_demux_init (GstDVDDemux * dvd_demux, GstDVDDemuxClass * klass) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (dvd_demux); - gint i; - - /* Create the pads for the current streams. */ - dvd_demux->cur_video = - DEMUX_CLASS (dvd_demux)->new_output_pad (mpeg_demux, "current_video", - CLASS (dvd_demux)->cur_video_template); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), dvd_demux->cur_video); - dvd_demux->cur_audio = - DEMUX_CLASS (dvd_demux)->new_output_pad (mpeg_demux, "current_audio", - CLASS (dvd_demux)->cur_audio_template); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), dvd_demux->cur_audio); - dvd_demux->cur_subpicture = - DEMUX_CLASS (dvd_demux)->new_output_pad (mpeg_demux, "current_subpicture", - CLASS (dvd_demux)->cur_subpicture_template); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), dvd_demux->cur_subpicture); - - dvd_demux->mpeg_version = 0; - dvd_demux->cur_video_nr = 0; - dvd_demux->cur_audio_nr = 0; - dvd_demux->cur_subpicture_nr = 0; - - for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) { - dvd_demux->subpicture_stream[i] = NULL; - } - - /* Directly after starting we operate as if we had just flushed. */ - dvd_demux->segment_filter = TRUE; - - dvd_demux->langcodes = NULL; -} - -static gboolean -gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_parse); - gboolean ret = TRUE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - - gst_event_parse_new_segment (event, &update, NULL, NULL, - NULL, NULL, NULL); - - if (!update) { - /* This is a discontinuity in the timestamp sequence. which - may mean that we find some audio blocks lying outside the - segment. Filter them. */ - dvd_demux->segment_filter = TRUE; - - /* reset stream synchronization; parent handles other streams */ - gst_mpeg_streams_reset_cur_ts (dvd_demux->subpicture_stream, - GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS, 0); - } - - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - break; - } - case GST_EVENT_FLUSH_STOP: - dvd_demux->segment_filter = TRUE; - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - - /* parent class will have reset the other streams */ - gst_mpeg_streams_reset_last_flow (dvd_demux->subpicture_stream, - GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS); - break; - case GST_EVENT_CUSTOM_DOWNSTREAM: - case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: - if (event->structure != NULL && - gst_structure_has_name (event->structure, "application/x-gst-dvd")) { - ret = gst_dvd_demux_handle_dvd_event (dvd_demux, event); - } else { - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - } - break; - default: - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - break; - } - - return ret; -} - -static gboolean -gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event) -{ - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (dvd_demux); - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (dvd_demux); - const GstStructure *structure = gst_event_get_structure (event); - const char *event_type = gst_structure_get_string (structure, "event"); - - g_return_val_if_fail (event != NULL, FALSE); - - GST_LOG_OBJECT (dvd_demux, "dvd event %" GST_PTR_FORMAT, structure); - - if (strcmp (event_type, "dvd-audio-stream-change") == 0) { - gint stream_nr; - - gst_structure_get_int (structure, "physical", &stream_nr); - if (stream_nr < -1 || stream_nr >= GST_MPEG_DEMUX_NUM_AUDIO_STREAMS) { - GST_ERROR_OBJECT (dvd_demux, - "GstDVDDemux: Invalid audio stream %02d", stream_nr); - return FALSE; - } - gst_dvd_demux_set_cur_audio (dvd_demux, stream_nr); - gst_event_unref (event); - } else if (strcmp (event_type, "dvd-spu-stream-change") == 0) { - gint stream_nr; - - gst_structure_get_int (structure, "physical", &stream_nr); - if (stream_nr < -1 || stream_nr >= GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS) { - GST_ERROR_OBJECT (dvd_demux, - "GstDVDDemux: Invalid subpicture stream %02d", stream_nr); - return FALSE; - } - gst_dvd_demux_set_cur_subpicture (dvd_demux, stream_nr); - gst_event_unref (event); - } else if (!strcmp (event_type, "dvd-lang-codes")) { - gint num_substreams = 0, num_audstreams = 0, n; - gchar *t; - - /* reset */ - if (dvd_demux->langcodes) - gst_event_unref (dvd_demux->langcodes); - - /* see what kind of streams we have */ - dvd_demux->langcodes = event; - - /* now create pads for each; first video */ - n = 2; - DEMUX_CLASS (dvd_demux)->get_video_stream (mpeg_demux, - 0, GST_MPEG_DEMUX_VIDEO_MPEG, &n); - - /* audio */ - for (n = 0;; n++) { - gint fmt, ifo = 0; - - t = g_strdup_printf ("audio-%d-format", num_audstreams); - if (!gst_structure_get_int (structure, t, &fmt)) { - g_free (t); - break; - } - g_free (t); - switch (fmt) { - case 0x0: /* AC-3 */ - fmt = GST_DVD_DEMUX_AUDIO_AC3; - break; - case 0x2: - case 0x3: /* MPEG */ - fmt = GST_MPEG_DEMUX_AUDIO_MPEG; - break; - case 0x4: - fmt = GST_DVD_DEMUX_AUDIO_LPCM; - break; - case 0x6: - fmt = GST_DVD_DEMUX_AUDIO_DTS; - break; - default: - fmt = GST_MPEG_DEMUX_AUDIO_UNKNOWN; - break; - } - DEMUX_CLASS (dvd_demux)->get_audio_stream (mpeg_demux, - num_audstreams++, fmt, &ifo); - } - - /* subtitle */ - for (;;) { - t = g_strdup_printf ("subtitle-%d-language", num_substreams); - if (!gst_structure_get_value (structure, t)) { - g_free (t); - break; - } - g_free (t); - CLASS (dvd_demux)->get_subpicture_stream (mpeg_demux, - num_substreams++, GST_DVD_DEMUX_SUBP_DVD, NULL); - } - GST_DEBUG_OBJECT (dvd_demux, - "Created 1 video stream, %d audio streams and %d subpicture streams " - "based on DVD lang codes event; now signalling no-more-pads", - num_audstreams, num_substreams); - - /* we know this will be all */ - gst_element_no_more_pads (GST_ELEMENT (dvd_demux)); - - /* Keep video/audio/subtitle pads within 1/2 sec of the SCR */ - mpeg_demux->max_gap = MAX_GAP; - mpeg_demux->max_gap_tolerance = MAX_GAP_TOLERANCE; - } else { - GST_DEBUG_OBJECT (dvd_demux, "dvddemux Forwarding DVD event %s to all pads", - event_type); - - PARSE_CLASS (dvd_demux)->send_event (mpeg_parse, event); - } - - return TRUE; -} - -static GstMPEGStream * -gst_dvd_demux_get_video_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - GstMPEGStream *str = - parent_class->get_video_stream (mpeg_demux, stream_nr, type, info); - gint mpeg_version = *((gint *) info); - - if (dvd_demux->mpeg_version != mpeg_version) { - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("video/mpeg", - "mpegversion", G_TYPE_INT, mpeg_version, - "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); - - if (!gst_pad_set_caps (dvd_demux->cur_video, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), ("failed to set caps")); - gst_caps_unref (str->caps); - str->caps = NULL; - return str; - } else { - dvd_demux->mpeg_version = mpeg_version; - } - } - - dvd_demux->mpeg_version = mpeg_version; - return str; -} - -static GstMPEGStream * -gst_dvd_demux_get_audio_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - guint32 sample_info = 0; - GstMPEGStream *str; - GstDVDLPCMStream *lpcm_str = NULL; - gboolean add_pad = FALSE; - const gchar *codec = NULL, *lang_code = NULL; - - g_return_val_if_fail (stream_nr < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS, NULL); - g_return_val_if_fail (type > GST_MPEG_DEMUX_AUDIO_UNKNOWN && - type < GST_DVD_DEMUX_AUDIO_LAST, NULL); - - if (type < GST_MPEG_DEMUX_AUDIO_LAST) { - /* FIXME: language codes on MPEG audio streams */ - return parent_class->get_audio_stream (mpeg_demux, stream_nr, type, info); - } - - if (type == GST_DVD_DEMUX_AUDIO_LPCM) { - sample_info = *((guint32 *) info); - } - - str = mpeg_demux->audio_stream[stream_nr]; - - /* If the stream type is changing, recreate the pad */ - if (str && str->type != type) { - gst_element_remove_pad (GST_ELEMENT (mpeg_demux), str->pad); - g_free (str); - str = mpeg_demux->audio_stream[stream_nr] = NULL; - } - - if (str == NULL) { - gchar *name; - - if (type != GST_DVD_DEMUX_AUDIO_LPCM) { - str = g_new0 (GstMPEGStream, 1); - } else { - lpcm_str = g_new0 (GstDVDLPCMStream, 1); - str = (GstMPEGStream *) lpcm_str; - } - - name = g_strdup_printf ("audio_%u", stream_nr); - DEMUX_CLASS (dvd_demux)->init_stream (mpeg_demux, type, str, stream_nr, - name, DEMUX_CLASS (dvd_demux)->audio_template); - /* update caps */ - str->type = GST_MPEG_DEMUX_AUDIO_UNKNOWN; - g_free (name); - add_pad = TRUE; - } else { - /* Stream size may have changed, reset it. */ - if (type != GST_DVD_DEMUX_AUDIO_LPCM) { - str = g_renew (GstMPEGStream, str, 1); - } else { - lpcm_str = g_renew (GstDVDLPCMStream, str, 1); - str = (GstMPEGStream *) lpcm_str; - } - } - - mpeg_demux->audio_stream[stream_nr] = str; - - if (type != str->type || - (type == GST_DVD_DEMUX_AUDIO_LPCM && - sample_info != lpcm_str->sample_info)) { - gint width, rate, channels, dynamic_range; - gboolean emphasis, mute; - - /* We need to set new caps for this pad. */ - switch (type) { - case GST_DVD_DEMUX_AUDIO_LPCM: - /* Dynamic range in the lower byte */ - dynamic_range = sample_info & 0xff; - - /* Determine the sample width. */ - switch (sample_info & 0xC000) { - case 0x8000: - width = 24; - break; - case 0x4000: - width = 20; - break; - default: - width = 16; - break; - } - - /* Determine the rate. */ - if (sample_info & 0x1000) { - rate = 96000; - } else { - rate = 48000; - } - - mute = ((sample_info & 0x400000) != 0); - emphasis = ((sample_info & 0x800000) != 0); - - /* Determine the number of channels. */ - channels = ((sample_info >> 8) & 0x7) + 1; - - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("audio/x-lpcm", - "width", G_TYPE_INT, width, - "rate", G_TYPE_INT, rate, - "channels", G_TYPE_INT, channels, - "dynamic_range", G_TYPE_INT, dynamic_range, - "emphasis", G_TYPE_BOOLEAN, emphasis, - "mute", G_TYPE_BOOLEAN, mute, NULL); - - lpcm_str->sample_info = sample_info; - lpcm_str->width = width; - lpcm_str->rate = rate; - lpcm_str->channels = channels; - lpcm_str->dynamic_range = dynamic_range; - lpcm_str->mute = mute; - lpcm_str->emphasis = emphasis; - codec = "LPCM audio"; - break; - - case GST_DVD_DEMUX_AUDIO_AC3: - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("audio/x-ac3", NULL); - codec = "AC-3 audio"; - break; - - case GST_DVD_DEMUX_AUDIO_DTS: - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("audio/x-dts", NULL); - codec = "DTS audio"; - break; - - default: - g_return_val_if_reached (NULL); - break; - } - - if (!gst_pad_set_caps (str->pad, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), - ("failed to set caps on pad %s:%s", GST_DEBUG_PAD_NAME (str->pad))); - gst_caps_unref (str->caps); - str->caps = NULL; - return str; - } - - if (str->number == dvd_demux->cur_audio_nr) { - /* This is the current audio stream. Use the same caps. */ - if (!gst_pad_set_caps (dvd_demux->cur_audio, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), ("failed to set caps on pad %s:%s", - GST_DEBUG_PAD_NAME (dvd_demux->cur_audio))); - } - } - - if (add_pad) { - if (dvd_demux->langcodes) { - gchar *t; - - t = g_strdup_printf ("audio-%d-language", stream_nr); - lang_code = - gst_structure_get_string (gst_event_get_structure - (dvd_demux->langcodes), t); - g_free (t); - } - - GST_DEBUG_OBJECT (mpeg_demux, "adding pad %s with language = %s", - GST_PAD_NAME (str->pad), (lang_code) ? lang_code : "(unknown)"); - - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - - if (codec || lang_code) { - GstTagList *list = gst_tag_list_new (); - - if (codec) { - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, codec, NULL); - } - if (lang_code) { - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_LANGUAGE_CODE, lang_code, NULL); - } - str->tags = gst_tag_list_copy (list); - gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), - str->pad, list); - } - } - - str->type = type; - } - - return str; -} - - -static GstMPEGStream * -gst_dvd_demux_get_subpicture_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - GstMPEGStream *str; - gchar *name; - gboolean add_pad = FALSE; - const gchar *lang_code = NULL; - - g_return_val_if_fail (stream_nr < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS, NULL); - g_return_val_if_fail (type > GST_DVD_DEMUX_SUBP_UNKNOWN && - type < GST_DVD_DEMUX_SUBP_LAST, NULL); - - str = dvd_demux->subpicture_stream[stream_nr]; - - if (str == NULL) { - str = g_new0 (GstMPEGStream, 1); - - name = g_strdup_printf ("subpicture_%02d", stream_nr); - DEMUX_CLASS (dvd_demux)->init_stream (mpeg_demux, type, str, stream_nr, - name, CLASS (dvd_demux)->subpicture_template); - str->type = GST_DVD_DEMUX_SUBP_UNKNOWN; - g_free (name); - add_pad = TRUE; - } else { - /* This stream may have been created by a derived class, reset the - size. */ - str = g_renew (GstMPEGStream, str, 1); - } - - dvd_demux->subpicture_stream[stream_nr] = str; - - if (str->type != GST_DVD_DEMUX_SUBP_DVD) { - /* We need to set new caps for this pad. */ - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL); - - if (!gst_pad_set_caps (str->pad, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), - ("failed to set caps on pad %s:%s", GST_DEBUG_PAD_NAME (str->pad))); - gst_caps_unref (str->caps); - str->caps = NULL; - return str; - } - - if (str->number == dvd_demux->cur_subpicture_nr) { - /* This is the current subpicture stream. Use the same caps. */ - if (!gst_pad_set_caps (dvd_demux->cur_subpicture, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), - ("failed to set caps on pad %s:%s", GST_DEBUG_PAD_NAME (str->pad))); - } - } - - if (add_pad) { - if (dvd_demux->langcodes) { - gchar *t; - - t = g_strdup_printf ("subtitle-%d-language", stream_nr); - lang_code = - gst_structure_get_string (gst_event_get_structure - (dvd_demux->langcodes), t); - g_free (t); - } - - GST_DEBUG_OBJECT (mpeg_demux, "adding pad %s with language = %s", - GST_PAD_NAME (str->pad), (lang_code) ? lang_code : "(unknown)"); - - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - - if (lang_code) { - GstTagList *list = gst_tag_list_new (); - - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_LANGUAGE_CODE, lang_code, NULL); - str->tags = gst_tag_list_copy (list); - gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), - str->pad, list); - } - } - str->type = GST_DVD_DEMUX_SUBP_DVD; - } - - return str; -} - -static gboolean -gst_dvd_demux_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_parse); - gboolean pending_tags = mpeg_demux->pending_tags; - - GST_MPEG_PARSE_CLASS (parent_class)->parse_packhead (mpeg_parse, buffer); - - if (pending_tags) { - GstMPEGStream **streams; - guint i, num; - - streams = dvd_demux->subpicture_stream; - num = GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; - for (i = 0; i < num; ++i) { - if (streams[i] != NULL && streams[i]->tags != NULL) - gst_pad_push_event (streams[i]->pad, - gst_event_new_tag (gst_tag_list_copy (streams[i]->tags))); - } - } - - return TRUE; -} - -static GstFlowReturn -gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux, - GstBuffer * buffer, - guint stream_nr, GstClockTime timestamp, guint headerlen, guint datalen) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - GstFlowReturn ret = GST_FLOW_OK; - guint8 *basebuf; - guint8 ps_id_code; - GstMPEGStream *outstream = NULL; - guint first_access = 0; - gint align = 1, len, off; - - basebuf = GST_BUFFER_DATA (buffer); - - /* Determine the substream number. */ - ps_id_code = basebuf[headerlen + 4]; - - /* In the following, the "first access" refers to the location in a - buffer the time stamp is associated to. DVDs include this - information explicitely. */ - switch (stream_nr) { - case 0: - /* Private stream 1. */ - - if (ps_id_code >= 0x80 && ps_id_code <= 0x87) { - GST_LOG_OBJECT (dvd_demux, - "we have an audio (AC3) packet, track %d", ps_id_code - 0x80); - outstream = DEMUX_CLASS (dvd_demux)->get_audio_stream (mpeg_demux, - ps_id_code - 0x80, GST_DVD_DEMUX_AUDIO_AC3, NULL); - - /* Determine the position of the "first access". This - should always be the beginning of an AC3 frame. */ - first_access = (basebuf[headerlen + 6] << 8) | basebuf[headerlen + 7]; - - headerlen += 4; - datalen -= 4; - } else if (ps_id_code >= 0x88 && ps_id_code <= 0x8f) { - GST_LOG_OBJECT (dvd_demux, - "we have an audio (DTS) packet, track %d", ps_id_code - 0x88); - outstream = DEMUX_CLASS (dvd_demux)->get_audio_stream (mpeg_demux, - ps_id_code - 0x88, GST_DVD_DEMUX_AUDIO_DTS, NULL); - - /* Determine the position of the "first access". This - should always be the beginning of a DTS frame. */ - first_access = (basebuf[headerlen + 6] << 8) | basebuf[headerlen + 7]; - - headerlen += 4; - datalen -= 4; - } else if (ps_id_code >= 0xA0 && ps_id_code <= 0xA7) { - GstDVDLPCMStream *lpcm_str; - guint32 lpcm_sample_info; - - GST_LOG_OBJECT (dvd_demux, - "we have an audio (LPCM) packet, track %d", ps_id_code - 0xA0); - - /* Compose the sample info from the LPCM header, masking out the frame_num */ - lpcm_sample_info = - basebuf[headerlen + 10] | (basebuf[headerlen + - 9] << 8) | ((basebuf[headerlen + 8] & 0xc0) << 16); - - outstream = DEMUX_CLASS (dvd_demux)->get_audio_stream (mpeg_demux, - ps_id_code - 0xA0, GST_DVD_DEMUX_AUDIO_LPCM, &lpcm_sample_info); - lpcm_str = (GstDVDLPCMStream *) outstream; - - /* Determine the position of the "first access". */ - first_access = (basebuf[headerlen + 6] << 8) | basebuf[headerlen + 7]; - - /* Get rid of the LPCM header. */ - headerlen += 7; - datalen -= 7; - - /* align by frame round up to nearest byte */ - align = (lpcm_str->width * lpcm_str->channels + 7) / 8; - } else if (ps_id_code >= 0x20 && ps_id_code <= 0x3F) { - GST_LOG_OBJECT (dvd_demux, - "we have a subpicture packet, track %d", ps_id_code - 0x20); - outstream = CLASS (dvd_demux)->get_subpicture_stream (mpeg_demux, - ps_id_code - 0x20, GST_DVD_DEMUX_SUBP_DVD, NULL); - - headerlen += 1; - datalen -= 1; - } else { - GST_WARNING_OBJECT (dvd_demux, - "unknown DVD (private 1) id 0x%02x", ps_id_code); - } - break; - - case 1: - /* Private stream 2 */ - - switch (ps_id_code) { - case 0: - GST_LOG_OBJECT (dvd_demux, "we have a PCI nav packet"); - - outstream = DEMUX_CLASS (mpeg_demux)->get_private_stream (mpeg_demux, - 1, GST_MPEG_DEMUX_PRIVATE_UNKNOWN, NULL); - break; - - case 1: - GST_LOG_OBJECT (dvd_demux, "we have a DSI nav packet"); - - outstream = DEMUX_CLASS (mpeg_demux)->get_private_stream (mpeg_demux, - 1, GST_MPEG_DEMUX_PRIVATE_UNKNOWN, NULL); - break; - - default: - GST_WARNING_OBJECT (dvd_demux, - "unknown DVD (private 2) id 0x%02x", ps_id_code); - break; - } - break; - - default: - g_return_val_if_reached (GST_FLOW_UNEXPECTED); - break; - } - - if (outstream == NULL) { - return GST_FLOW_OK; - } - - if (timestamp != GST_CLOCK_TIME_NONE && first_access > 1) { - /* We have a first access location. Since GStreamer doesn't have - a means to associate a timestamp to the middle of a buffer, we - send two separate buffers and put the timestamp in the second - one. */ - off = headerlen + 4; - len = first_access - 1; - len -= len % align; - if (len > 0) { - ret = DEMUX_CLASS (dvd_demux)->send_subbuffer (mpeg_demux, outstream, - buffer, GST_CLOCK_TIME_NONE, off, len); - } - off += len; - len = datalen - len; - len -= len % align; - if (len > 0) { - ret = DEMUX_CLASS (dvd_demux)->send_subbuffer (mpeg_demux, outstream, - buffer, timestamp, off, len); - } - } else { - off = headerlen + 4; - len = datalen; - len -= len % align; - if (len > 0) { - ret = DEMUX_CLASS (dvd_demux)->send_subbuffer (mpeg_demux, outstream, - buffer, timestamp, off, len); - } - } - - return ret; -} - -/* random magic value */ -#define MIN_BUFS_FOR_NO_MORE_PADS 100 - -static GstFlowReturn -gst_dvd_demux_combine_flows (GstMPEGDemux * mpegdemux, GstMPEGStream * stream, - GstFlowReturn flow) -{ - GstDVDDemux *demux = (GstDVDDemux *) mpegdemux; - gint i; - - /* store the value */ - stream->last_flow = flow; - - /* if it's success we can return the value right away */ - if (flow == GST_FLOW_OK) - goto done; - - /* any other error that is not-linked can be returned right - * away */ - if (flow != GST_FLOW_NOT_LINKED) { - GST_DEBUG_OBJECT (demux, "flow %s on pad %" GST_PTR_FORMAT, - gst_flow_get_name (flow), stream->pad); - goto done; - } - - /* let parent class check for anything non-not-linked for its streams */ - flow = - GST_MPEG_DEMUX_CLASS (parent_class)->combine_flows (mpegdemux, stream, - flow); - if (flow != GST_FLOW_NOT_LINKED) - goto done; - - /* only return NOT_LINKED if all other pads returned NOT_LINKED */ - for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) { - if (demux->subpicture_stream[i] != NULL) { - flow = demux->subpicture_stream[i]->last_flow; - /* some other return value (must be SUCCESS but we can return - * other values as well) */ - if (flow != GST_FLOW_NOT_LINKED) - goto done; - if (demux->subpicture_stream[i]->buffers_sent < MIN_BUFS_FOR_NO_MORE_PADS) { - flow = GST_FLOW_OK; - goto done; - } - } - } - /* if we get here, all other pads were unlinked and we return - * NOT_LINKED then */ - GST_DEBUG_OBJECT (demux, "all pads combined have not-linked flow"); - -done: - return flow; -} - -static GstFlowReturn -gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux, - GstMPEGStream * outstream, GstBuffer * buffer, - GstClockTime timestamp, guint offset, guint size) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - GstFlowReturn ret; - GstPad *outpad; - gint cur_nr; - - if (dvd_demux->segment_filter && - GST_MPEG_DEMUX_STREAM_KIND (outstream->type) == - GST_MPEG_DEMUX_STREAM_AUDIO) { - /* We are in segment_filter mode and have an audio buffer. */ - if (GST_CLOCK_TIME_IS_VALID (timestamp)) { - /* This is the first valid audio buffer after the flush. */ - dvd_demux->segment_filter = FALSE; - } else { - /* Discard the buffer. */ - return GST_FLOW_OK; - } - } - - /* You never know what happens to a buffer when you send it. Just - in case, we keep a reference to the buffer during the execution - of this function. */ - gst_buffer_ref (buffer); - - /* Send the buffer to the standard output pad. */ - ret = parent_class->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, offset, size); - - /* Determine the current output pad and stream number for the given - type of stream. */ - switch (GST_MPEG_DEMUX_STREAM_KIND (outstream->type)) { - case GST_MPEG_DEMUX_STREAM_VIDEO: - outpad = dvd_demux->cur_video; - cur_nr = dvd_demux->cur_video_nr; - break; - case GST_MPEG_DEMUX_STREAM_AUDIO: - outpad = dvd_demux->cur_audio; - cur_nr = dvd_demux->cur_audio_nr; - break; - case GST_MPEG_DEMUX_STREAM_PRIVATE: - outpad = NULL; - cur_nr = 0; - break; - case GST_DVD_DEMUX_STREAM_SUBPICTURE: - outpad = dvd_demux->cur_subpicture; - cur_nr = dvd_demux->cur_subpicture_nr; - break; - default: - g_return_val_if_reached (GST_FLOW_UNEXPECTED); - break; - } - - if (outpad != NULL && cur_nr == outstream->number && size > 0) { - GstBuffer *outbuf; - - /* We have a packet of the current stream. Send it to the - corresponding pad as well. */ - outbuf = gst_buffer_create_sub (buffer, offset, size); - g_return_val_if_fail (outbuf != NULL, GST_FLOW_UNEXPECTED); - - GST_BUFFER_TIMESTAMP (outbuf) = timestamp; - GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer) + offset; - gst_buffer_set_caps (outbuf, outstream->caps); - - ret = gst_pad_push (outpad, outbuf); - - /* this was one of the current_foo pads, which is shadowing one of the - * foo_%02d pads, so since we keep track of the last flow value in the - * stream structure we need to combine the OK/NOT_LINKED flows here - * (because both pads share the same stream structure) */ - if ((ret == GST_FLOW_NOT_LINKED && outstream->last_flow == GST_FLOW_OK) || - (ret == GST_FLOW_OK && outstream->last_flow == GST_FLOW_NOT_LINKED)) { - outstream->last_flow = GST_FLOW_OK; - ret = GST_FLOW_OK; - } - } - - gst_buffer_unref (buffer); - - ret = DEMUX_CLASS (dvd_demux)->combine_flows (mpeg_demux, outstream, ret); - - return ret; -} - -static void -gst_dvd_demux_set_cur_audio (GstDVDDemux * dvd_demux, gint stream_nr) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (dvd_demux); - GstMPEGStream *str; - GstCaps *caps; - - g_return_if_fail (stream_nr >= -1 && - stream_nr < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS); - - GST_DEBUG_OBJECT (dvd_demux, "changing current audio to %02d", stream_nr); - - dvd_demux->cur_audio_nr = stream_nr; - - if (stream_nr == -1) { - return; - } - - str = mpeg_demux->audio_stream[stream_nr]; - if (str != NULL) { - /* (Re)set the caps in the "current" pad. */ - caps = GST_PAD_CAPS (str->pad); - if (caps != NULL) { - gst_pad_set_caps (dvd_demux->cur_audio, caps); - } - } -} - -static void -gst_dvd_demux_set_cur_subpicture (GstDVDDemux * dvd_demux, gint stream_nr) -{ - GstMPEGStream *str; - - g_return_if_fail (stream_nr >= -1 && - stream_nr < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS); - - GST_DEBUG_OBJECT (dvd_demux, "changing current subpicture to %02d", - stream_nr); - - dvd_demux->cur_subpicture_nr = stream_nr; - - if (stream_nr == -1) { - return; - } - - str = dvd_demux->subpicture_stream[stream_nr]; - if (str != NULL) { - GstCaps *caps = NULL; - - /* (Re)set the caps in the "current" pad. */ - caps = GST_PAD_CAPS (str->pad); - gst_pad_set_caps (dvd_demux->cur_subpicture, caps); - } -} - -static void -gst_dvd_demux_reset (GstDVDDemux * dvd_demux) -{ - int i; - - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (dvd_demux); - - GST_INFO ("Resetting the dvd demuxer"); - for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) { - if (dvd_demux->subpicture_stream[i]) { - gst_pad_push_event (dvd_demux->subpicture_stream[i]->pad, - gst_event_new_eos ()); - - gst_element_remove_pad (GST_ELEMENT (dvd_demux), - dvd_demux->subpicture_stream[i]->pad); - if (dvd_demux->subpicture_stream[i]->caps) - gst_caps_unref (dvd_demux->subpicture_stream[i]->caps); - if (dvd_demux->subpicture_stream[i]->tags) - gst_tag_list_free (dvd_demux->subpicture_stream[i]->tags); - g_free (dvd_demux->subpicture_stream[i]); - dvd_demux->subpicture_stream[i] = NULL; - } - } - gst_pad_set_caps (dvd_demux->cur_video, NULL); - gst_pad_set_caps (dvd_demux->cur_audio, NULL); - gst_pad_set_caps (dvd_demux->cur_subpicture, NULL); - - dvd_demux->cur_video_nr = 0; - dvd_demux->cur_audio_nr = 0; - dvd_demux->cur_subpicture_nr = 0; - dvd_demux->mpeg_version = 0; - - /* Reset max_gap handling */ - mpeg_demux->max_gap = MAX_GAP; - mpeg_demux->max_gap_tolerance = MAX_GAP_TOLERANCE; -} - -static void -gst_dvd_demux_synchronise_pads (GstMPEGDemux * mpeg_demux, - GstClockTime threshold, GstClockTime new_ts) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - int i; - - parent_class->synchronise_pads (mpeg_demux, threshold, new_ts); - - for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) { - if (dvd_demux->subpicture_stream[i]) { - GST_LOG_OBJECT (mpeg_demux, "stream: %d, current: %" GST_TIME_FORMAT - ", threshold %" GST_TIME_FORMAT, i, - GST_TIME_ARGS (dvd_demux->subpicture_stream[i]->cur_ts), - GST_TIME_ARGS (threshold)); - if (dvd_demux->subpicture_stream[i]->cur_ts < threshold) { - DEMUX_CLASS (mpeg_demux)->sync_stream_to_time (mpeg_demux, - dvd_demux->subpicture_stream[i], new_ts); - dvd_demux->subpicture_stream[i]->cur_ts = new_ts; - } - } - } -} - -static void -gst_dvd_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux, - GstMPEGStream * stream, GstClockTime last_ts) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_demux); - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (mpeg_demux); - GstPad *outpad; - gint cur_nr; - - parent_class->sync_stream_to_time (mpeg_demux, stream, last_ts); - - switch (GST_MPEG_DEMUX_STREAM_KIND (stream->type)) { - case GST_MPEG_DEMUX_STREAM_VIDEO: - outpad = dvd_demux->cur_video; - cur_nr = dvd_demux->cur_video_nr; - break; - case GST_MPEG_DEMUX_STREAM_AUDIO: - outpad = dvd_demux->cur_audio; - cur_nr = dvd_demux->cur_audio_nr; - break; - case GST_DVD_DEMUX_STREAM_SUBPICTURE: - outpad = dvd_demux->cur_subpicture; - cur_nr = dvd_demux->cur_subpicture_nr; - break; - default: - return; - } - - if (outpad && (cur_nr == stream->number)) { - guint64 update_time; - - update_time = - MIN ((guint64) last_ts, (guint64) mpeg_parse->current_segment.stop); - gst_pad_push_event (outpad, gst_event_new_new_segment (TRUE, - mpeg_parse->current_segment.rate, GST_FORMAT_TIME, - update_time, mpeg_parse->current_segment.stop, update_time)); - } -} - -static GstStateChangeReturn -gst_dvd_demux_change_state (GstElement * element, GstStateChange transition) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (element); - GstStateChangeReturn ret; - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_dvd_demux_reset (dvd_demux); - if (dvd_demux->langcodes) { - gst_event_unref (dvd_demux->langcodes); - dvd_demux->langcodes = NULL; - } - break; - default: - break; - } - return ret; -} - -gboolean -gst_dvd_demux_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "dvddemux", - GST_RANK_SECONDARY + 1, GST_TYPE_DVD_DEMUX); -} diff --git a/gst/mpegstream/gstdvddemux.h b/gst/mpegstream/gstdvddemux.h deleted file mode 100644 index 5f283e6a34..0000000000 --- a/gst/mpegstream/gstdvddemux.h +++ /dev/null @@ -1,138 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Martin Soto - * - * 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 __DVD_DEMUX_H__ -#define __DVD_DEMUX_H__ - - -#include -#include "gstmpegdemux.h" - -G_BEGIN_DECLS - -#define GST_TYPE_DVD_DEMUX \ - (gst_dvd_demux_get_type()) -#define GST_DVD_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVD_DEMUX,GstDVDDemux)) -#define GST_DVD_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DVD_DEMUX,GstDVDDemuxClass)) -#define GST_IS_DVD_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DVD_DEMUX)) -#define GST_IS_DVD_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DVD_DEMUX)) - - -/* Supported kinds of streams in addition to what mpegdemux already - does. */ -enum { - GST_DVD_DEMUX_STREAM_SUBPICTURE = GST_MPEG_DEMUX_STREAM_LAST, - GST_DVD_DEMUX_STREAM_LAST -}; - -/* Supported number of streams. */ -#define GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS 32 -#define GST_DVD_DEMUX_MAX_SUBPICTURE_DELAY 0 - -typedef struct _GstDVDLPCMStream GstDVDLPCMStream ; -typedef struct _GstDVDDemux GstDVDDemux; -typedef struct _GstDVDDemuxClass GstDVDDemuxClass; - - -/* Additional recognized audio types. */ -enum { - GST_DVD_DEMUX_AUDIO_LPCM = GST_MPEG_DEMUX_AUDIO_LAST, - GST_DVD_DEMUX_AUDIO_AC3, - GST_DVD_DEMUX_AUDIO_DTS, - GST_DVD_DEMUX_AUDIO_LAST -}; - - -/* The recognized subpicture types. */ -enum { - GST_DVD_DEMUX_SUBP_UNKNOWN = - GST_MPEG_DEMUX_STREAM_TYPE (GST_DVD_DEMUX_STREAM_SUBPICTURE, 1), - GST_DVD_DEMUX_SUBP_DVD, - GST_DVD_DEMUX_SUBP_LAST -}; - - -/* Extended structure to hold additional information for linear PCM - streams. */ -struct _GstDVDLPCMStream { - GstMPEGStream parent; - guint32 sample_info; /* The type of linear PCM samples - associated to this stream. The - values are bit fields with the same - format of the sample_info field in - the linear PCM header. */ - gint rate, channels, width, - dynamic_range; - gboolean mute, emphasis; -}; - - -struct _GstDVDDemux { - GstMPEGDemux parent; - - GstPad *cur_video; /* Current video stream pad. */ - GstPad *cur_audio; /* Current audio stream pad. */ - GstPad *cur_subpicture; /* Current subpicture stream pad. */ - - gint cur_video_nr; /* Current video stream number. */ - gint cur_audio_nr; /* Current audio stream number. */ - gint cur_subpicture_nr; /* Current subpicture stream number. */ - - gint mpeg_version; /* Version of the MPEG video stream */ - - GstMPEGStream *subpicture_stream[GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS]; - /* Subpicture output streams. */ - - gboolean segment_filter; /* If TRUE, the demuxer refrains from - sending any audio packets until it - sees one with a timestamp lying - inside the current segment. */ - - GstEvent *langcodes; -}; - - -struct _GstDVDDemuxClass { - GstMPEGDemuxClass parent_class; - - GstPadTemplate *cur_video_template; - GstPadTemplate *cur_audio_template; - GstPadTemplate *subpicture_template; - GstPadTemplate *cur_subpicture_template; - - GstMPEGStream * - (*get_subpicture_stream)(GstMPEGDemux *mpeg_demux, - guint8 stream_nr, - gint type, - const gpointer info); -}; - - -GType gst_dvd_demux_get_type (void); - -gboolean gst_dvd_demux_plugin_init (GstPlugin *plugin); - -G_END_DECLS - -#endif /* __DVD_DEMUX_H__ */ diff --git a/gst/mpegstream/gstmpegclock.c b/gst/mpegstream/gstmpegclock.c deleted file mode 100644 index ed627c6eab..0000000000 --- a/gst/mpegstream/gstmpegclock.c +++ /dev/null @@ -1,101 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstclock.c: Clock subsystem for maintaining time sync - * - * 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 "gstmpegclock.h" - -static void gst_mpeg_clock_class_init (GstMPEGClockClass * klass); -static void gst_mpeg_clock_init (GstMPEGClock * clock); - -static GstClockTime gst_mpeg_clock_get_internal_time (GstClock * clock); - -static GstSystemClockClass *parent_class = NULL; - -/* static guint gst_mpeg_clock_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_mpeg_clock_get_type (void) -{ - static GType clock_type = 0; - - if (!clock_type) { - static const GTypeInfo clock_info = { - sizeof (GstMPEGClockClass), - NULL, - NULL, - (GClassInitFunc) gst_mpeg_clock_class_init, - NULL, - NULL, - sizeof (GstMPEGClock), - 4, - (GInstanceInitFunc) gst_mpeg_clock_init, - NULL - }; - - clock_type = g_type_register_static (GST_TYPE_SYSTEM_CLOCK, "GstMPEGClock", - &clock_info, 0); - } - return clock_type; -} - - -static void -gst_mpeg_clock_class_init (GstMPEGClockClass * klass) -{ - GstClockClass *gstclock_class; - - gstclock_class = (GstClockClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gstclock_class->get_internal_time = gst_mpeg_clock_get_internal_time; -} - -static void -gst_mpeg_clock_init (GstMPEGClock * clock) -{ - gst_object_set_name (GST_OBJECT (clock), "GstMPEGClock"); -} - -GstClock * -gst_mpeg_clock_new (gchar * name, GstMPEGClockGetTimeFunc func, - gpointer user_data) -{ - GstMPEGClock *mpeg_clock = - GST_MPEG_CLOCK (g_object_new (GST_TYPE_MPEG_CLOCK, NULL)); - - mpeg_clock->func = func; - mpeg_clock->user_data = user_data; - - return GST_CLOCK (mpeg_clock); -} - -static GstClockTime -gst_mpeg_clock_get_internal_time (GstClock * clock) -{ - GstMPEGClock *mpeg_clock = GST_MPEG_CLOCK (clock); - - return mpeg_clock->func (clock, mpeg_clock->user_data); -} diff --git a/gst/mpegstream/gstmpegclock.h b/gst/mpegstream/gstmpegclock.h deleted file mode 100644 index c0025fd2b8..0000000000 --- a/gst/mpegstream/gstmpegclock.h +++ /dev/null @@ -1,65 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstclock.h: Header for clock subsystem - * - * 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_MPEG_CLOCK_H__ -#define __GST_MPEG_CLOCK_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_MPEG_CLOCK \ - (gst_mpeg_clock_get_type()) -#define GST_MPEG_CLOCK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEG_CLOCK,GstMPEGClock)) -#define GST_MPEG_CLOCK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEG_CLOCK,GstMPEGClockClass)) -#define GST_IS_MPEG_CLOCK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEG_CLOCK)) -#define GST_IS_MPEG_CLOCK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEG_CLOCK)) - -typedef struct _GstMPEGClock GstMPEGClock; -typedef struct _GstMPEGClockClass GstMPEGClockClass; - -typedef GstClockTime (*GstMPEGClockGetTimeFunc) (GstClock *clock, gpointer user_data); - - -struct _GstMPEGClock { - GstSystemClock clock; - - GstMPEGClockGetTimeFunc func; - gpointer user_data; -}; - -struct _GstMPEGClockClass { - GstSystemClockClass parent_class; -}; - -GType gst_mpeg_clock_get_type (void); -GstClock* gst_mpeg_clock_new (gchar *name, GstMPEGClockGetTimeFunc func, - gpointer user_data); - -G_END_DECLS - -#endif /* __GST_MPEG_CLOCK_H__ */ diff --git a/gst/mpegstream/gstmpegdemux.c b/gst/mpegstream/gstmpegdemux.c deleted file mode 100644 index 05a9260dff..0000000000 --- a/gst/mpegstream/gstmpegdemux.c +++ /dev/null @@ -1,1458 +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. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "gstmpegdemux.h" - - -GST_DEBUG_CATEGORY_STATIC (gstmpegdemux_debug); -#define GST_CAT_DEFAULT (gstmpegdemux_debug) - -#define PARSE_CLASS(o) GST_MPEG_PARSE_CLASS (G_OBJECT_GET_CLASS (o)) -#define CLASS(o) GST_MPEG_DEMUX_CLASS (G_OBJECT_GET_CLASS (o)) - -/* MPEG2Demux signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_BIT_RATE, - ARG_MPEG2 - /* FILL ME */ -}; - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) { 1, 2 }, " "systemstream = (boolean) TRUE") - ); - -static GstStaticPadTemplate video_template = -GST_STATIC_PAD_TEMPLATE ("video_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) { 1, 2 }, " "systemstream = (boolean) FALSE") - ); - -static GstStaticPadTemplate audio_template = -GST_STATIC_PAD_TEMPLATE ("audio_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("audio/mpeg, " "mpegversion = (int) 1" - /* FIXME "layer = (int) { 1, 2 }" */ - ) - ); - -static GstStaticPadTemplate private_template = -GST_STATIC_PAD_TEMPLATE ("private_%u", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS_ANY); - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gstmpegdemux_debug, "mpegdemux", 0, \ - "MPEG demuxer element"); - -GST_BOILERPLATE_FULL (GstMPEGDemux, gst_mpeg_demux, GstMPEGParse, - GST_TYPE_MPEG_PARSE, _do_init); - -static gboolean gst_mpeg_demux_process_event (GstMPEGParse * mpeg_parse, - GstEvent * event); - -static GstPad *gst_mpeg_demux_new_output_pad (GstMPEGDemux * mpeg_demux, - const gchar * name, GstPadTemplate * temp); -static void gst_mpeg_demux_init_stream (GstMPEGDemux * mpeg_demux, - gint type, - GstMPEGStream * str, - gint number, const gchar * name, GstPadTemplate * temp); -static GstMPEGStream *gst_mpeg_demux_get_video_stream (GstMPEGDemux * - mpeg_demux, guint8 stream_nr, gint type, const gpointer info); -static GstMPEGStream *gst_mpeg_demux_get_audio_stream (GstMPEGDemux * - mpeg_demux, guint8 stream_nr, gint type, const gpointer info); -static GstMPEGStream *gst_mpeg_demux_get_private_stream (GstMPEGDemux * - mpeg_demux, guint8 stream_nr, gint type, const gpointer info); - -static gboolean gst_mpeg_demux_parse_packhead (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); -static gboolean gst_mpeg_demux_parse_syshead (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); -static GstFlowReturn gst_mpeg_demux_parse_packet (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); -static GstFlowReturn gst_mpeg_demux_parse_pes (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); - -static GstFlowReturn gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux, - GstMPEGStream * outstream, GstBuffer * buffer, - GstClockTime timestamp, guint offset, guint size); -static GstFlowReturn gst_mpeg_demux_combine_flows (GstMPEGDemux * mpeg_demux, - GstMPEGStream * stream, GstFlowReturn flow); -static GstFlowReturn gst_mpeg_demux_process_private (GstMPEGDemux * mpeg_demux, - GstBuffer * buffer, - guint stream_nr, GstClockTime timestamp, guint headerlen, guint datalen); -static void gst_mpeg_demux_synchronise_pads (GstMPEGDemux * mpeg_demux, - GstClockTime threshold, GstClockTime new_ts); -static void gst_mpeg_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux, - GstMPEGStream * stream, GstClockTime last_ts); - -#if 0 -const GstFormat *gst_mpeg_demux_get_src_formats (GstPad * pad); - -static gboolean index_seek (GstPad * pad, GstEvent * event, gint64 * offset); -static gboolean normal_seek (GstPad * pad, GstEvent * event, gint64 * offset); - -static gboolean gst_mpeg_demux_handle_src_event (GstPad * pad, - GstEvent * event); -#endif -static void gst_mpeg_demux_reset (GstMPEGDemux * mpeg_demux); - -#if 0 -static gboolean gst_mpeg_demux_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * format, gint64 * value); -#endif - -static GstStateChangeReturn gst_mpeg_demux_change_state (GstElement * element, - GstStateChange transition); - -static void gst_mpeg_demux_set_index (GstElement * element, GstIndex * index); -static GstIndex *gst_mpeg_demux_get_index (GstElement * element); - - -/*static guint gst_mpeg_demux_signals[LAST_SIGNAL] = { 0 };*/ - -static void -gst_mpeg_demux_base_init (gpointer klass_ptr) -{ - GstMPEGDemuxClass *klass = GST_MPEG_DEMUX_CLASS (klass_ptr); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass_ptr); - - klass->video_template = gst_static_pad_template_get (&video_template); - klass->audio_template = gst_static_pad_template_get (&audio_template); - klass->private_template = gst_static_pad_template_get (&private_template); - - gst_element_class_add_pad_template (element_class, klass->video_template); - gst_element_class_add_pad_template (element_class, klass->audio_template); - gst_element_class_add_pad_template (element_class, klass->private_template); - - gst_element_class_set_details_simple (element_class, "MPEG Demuxer", - "Codec/Demuxer", - "Demultiplexes MPEG1 and MPEG2 System Streams", - "Erik Walthinsen , Wim Taymans "); -} - -static void -gst_mpeg_demux_class_init (GstMPEGDemuxClass * klass) -{ - GstElementClass *gstelement_class; - GstMPEGParseClass *mpeg_parse_class; - - parent_class = g_type_class_peek_parent (klass); - - gstelement_class = (GstElementClass *) klass; - mpeg_parse_class = (GstMPEGParseClass *) klass; - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_mpeg_demux_change_state); - gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_mpeg_demux_set_index); - gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_mpeg_demux_get_index); - - mpeg_parse_class->parse_packhead = gst_mpeg_demux_parse_packhead; - mpeg_parse_class->parse_syshead = gst_mpeg_demux_parse_syshead; - mpeg_parse_class->parse_packet = gst_mpeg_demux_parse_packet; - mpeg_parse_class->parse_pes = gst_mpeg_demux_parse_pes; - mpeg_parse_class->send_buffer = NULL; - mpeg_parse_class->process_event = gst_mpeg_demux_process_event; - - klass->new_output_pad = gst_mpeg_demux_new_output_pad; - klass->init_stream = gst_mpeg_demux_init_stream; - klass->get_video_stream = gst_mpeg_demux_get_video_stream; - klass->get_audio_stream = gst_mpeg_demux_get_audio_stream; - klass->get_private_stream = gst_mpeg_demux_get_private_stream; - klass->send_subbuffer = gst_mpeg_demux_send_subbuffer; - klass->combine_flows = gst_mpeg_demux_combine_flows; - klass->process_private = gst_mpeg_demux_process_private; - klass->synchronise_pads = gst_mpeg_demux_synchronise_pads; - klass->sync_stream_to_time = gst_mpeg_demux_sync_stream_to_time; - - /* we have our own sink pad template, but don't use it in subclasses */ - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sink_template)); -} - -static void -gst_mpeg_demux_init (GstMPEGDemux * mpeg_demux, GstMPEGDemuxClass * klass) -{ - gint i; - - /* i think everything is already zero'd, but oh well */ - for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) { - mpeg_demux->video_stream[i] = NULL; - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) { - mpeg_demux->audio_stream[i] = NULL; - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) { - mpeg_demux->private_stream[i] = NULL; - } - - mpeg_demux->max_gap = GST_CLOCK_TIME_NONE; - mpeg_demux->max_gap_tolerance = GST_CLOCK_TIME_NONE; - - mpeg_demux->last_pts = -1; - mpeg_demux->pending_tags = FALSE; -} - - -static gboolean -gst_mpeg_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event) -{ - GstMPEGDemux *demux = GST_MPEG_DEMUX (mpeg_parse); - gboolean ret; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - - demux->pending_tags = TRUE; - - gst_mpeg_streams_reset_last_flow (demux->video_stream, - GST_MPEG_DEMUX_NUM_VIDEO_STREAMS); - gst_mpeg_streams_reset_last_flow (demux->audio_stream, - GST_MPEG_DEMUX_NUM_AUDIO_STREAMS); - gst_mpeg_streams_reset_last_flow (demux->private_stream, - GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS); - break; - case GST_EVENT_NEWSEGMENT: - /* reset stream synchronization */ - gst_mpeg_streams_reset_cur_ts (demux->video_stream, - GST_MPEG_DEMUX_NUM_VIDEO_STREAMS, 0); - gst_mpeg_streams_reset_cur_ts (demux->audio_stream, - GST_MPEG_DEMUX_NUM_AUDIO_STREAMS, 0); - gst_mpeg_streams_reset_cur_ts (demux->private_stream, - GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS, 0); - /* fallthrough */ - default: - ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, - event); - break; - } - - return ret; -} - -static gint -_demux_get_writer_id (GstIndex * index, GstPad * pad) -{ - gint id; - - if (!gst_index_get_writer_id (index, GST_OBJECT (pad), &id)) { - GST_WARNING_OBJECT (index, - "can't get index id for %s:%s", GST_DEBUG_PAD_NAME (pad)); - return -1; - } else { - GST_LOG_OBJECT (index, - "got index id %d for %s:%s", id, GST_DEBUG_PAD_NAME (pad)); - return id; - } -} - -static GstPad * -gst_mpeg_demux_new_output_pad (GstMPEGDemux * mpeg_demux, - const gchar * name, GstPadTemplate * temp) -{ - GstPad *pad; - - pad = gst_pad_new_from_template (temp, name); - -#if 0 - gst_pad_set_event_function (pad, - GST_DEBUG_FUNCPTR (gst_mpeg_demux_handle_src_event)); -#endif - gst_pad_set_query_type_function (pad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_get_src_query_types)); - gst_pad_set_query_function (pad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_handle_src_query)); - gst_pad_use_fixed_caps (pad); - - return pad; -} - -static void -gst_mpeg_demux_init_stream (GstMPEGDemux * mpeg_demux, - gint type, - GstMPEGStream * str, gint number, const gchar * name, GstPadTemplate * temp) -{ - str->type = type; - str->number = number; - - str->pad = CLASS (mpeg_demux)->new_output_pad (mpeg_demux, name, temp); - gst_pad_set_element_private (str->pad, str); - - if (mpeg_demux->index) { - str->index_id = _demux_get_writer_id (mpeg_demux->index, str->pad); - } - - str->cur_ts = 0; - str->scr_offs = 0; - - str->last_flow = GST_FLOW_OK; - str->buffers_sent = 0; - str->tags = NULL; - str->caps = NULL; -} - -static GstMPEGStream * -gst_mpeg_demux_get_video_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - gint mpeg_version = *((gint *) info); - GstMPEGStream *str; - GstMPEGVideoStream *video_str; - gchar *name; - gboolean set_caps = FALSE; - - g_return_val_if_fail (stream_nr < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS, NULL); - g_return_val_if_fail (type > GST_MPEG_DEMUX_VIDEO_UNKNOWN && - type < GST_MPEG_DEMUX_VIDEO_LAST, NULL); - - str = mpeg_demux->video_stream[stream_nr]; - - if (str == NULL) { - video_str = g_new0 (GstMPEGVideoStream, 1); - str = (GstMPEGStream *) video_str; - - name = g_strdup_printf ("video_%u", stream_nr); - CLASS (mpeg_demux)->init_stream (mpeg_demux, type, str, stream_nr, name, - CLASS (mpeg_demux)->video_template); - g_free (name); - - set_caps = TRUE; - } else { - /* This stream may have been created by a derived class, reset the - size. */ - video_str = g_renew (GstMPEGVideoStream, str, 1); - str = (GstMPEGStream *) video_str; - } - - mpeg_demux->video_stream[stream_nr] = str; - - if (set_caps || video_str->mpeg_version != mpeg_version) { - gchar *codec; - GstTagList *list; - - /* We need to set new caps for this pad. */ - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("video/mpeg", - "mpegversion", G_TYPE_INT, mpeg_version, - "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); - if (!gst_pad_set_caps (str->pad, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), ("failed to set caps")); - gst_caps_unref (str->caps); - str->caps = NULL; - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - return str; - } - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - - /* Store the current values. */ - video_str->mpeg_version = mpeg_version; - - /* set stream metadata */ - codec = g_strdup_printf ("MPEG-%d video", mpeg_version); - list = gst_tag_list_new (); - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_VIDEO_CODEC, codec, NULL); - g_free (codec); - gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), str->pad, list); - } - - return str; -} - -static GstMPEGStream * -gst_mpeg_demux_get_audio_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - GstMPEGStream *str; - gchar *name; - gboolean set_caps = FALSE; - - g_return_val_if_fail (stream_nr < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS, NULL); - g_return_val_if_fail (type > GST_MPEG_DEMUX_AUDIO_UNKNOWN && - type < GST_MPEG_DEMUX_AUDIO_LAST, NULL); - - str = mpeg_demux->audio_stream[stream_nr]; - - if (str && str->type != type) { - gst_element_remove_pad (GST_ELEMENT (mpeg_demux), str->pad); - g_free (str); - str = mpeg_demux->audio_stream[stream_nr] = NULL; - } - - if (str == NULL) { - str = g_new0 (GstMPEGStream, 1); - - name = g_strdup_printf ("audio_%u", stream_nr); - CLASS (mpeg_demux)->init_stream (mpeg_demux, type, str, stream_nr, name, - CLASS (mpeg_demux)->audio_template); - g_free (name); - - /* new pad, set caps */ - set_caps = TRUE; - } else { - /* This stream may have been created by a derived class, reset the - size. */ - str = g_renew (GstMPEGStream, str, 1); - } - - mpeg_demux->audio_stream[stream_nr] = str; - - if (set_caps) { - GstTagList *list; - - /* We need to set new caps for this pad. */ - if (str->caps) - gst_caps_unref (str->caps); - str->caps = gst_caps_new_simple ("audio/mpeg", - "mpegversion", G_TYPE_INT, 1, NULL); - if (!gst_pad_set_caps (str->pad, str->caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_demux), - CORE, NEGOTIATION, (NULL), ("failed to set caps")); - gst_caps_unref (str->caps); - str->caps = NULL; - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - return str; - } - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - - /* stream metadata */ - list = gst_tag_list_new (); - gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, "MPEG-1 audio", NULL); - gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), str->pad, list); - } - - return str; -} - -static GstMPEGStream * -gst_mpeg_demux_get_private_stream (GstMPEGDemux * mpeg_demux, - guint8 stream_nr, gint type, const gpointer info) -{ - GstMPEGStream *str; - gchar *name; - - g_return_val_if_fail (stream_nr < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS, NULL); - - str = mpeg_demux->private_stream[stream_nr]; - - if (str == NULL) { - name = g_strdup_printf ("private_%u", stream_nr + 1); - str = g_new0 (GstMPEGStream, 1); - CLASS (mpeg_demux)->init_stream (mpeg_demux, type, str, stream_nr, name, - CLASS (mpeg_demux)->private_template); - g_free (name); - gst_pad_set_active (str->pad, TRUE); - gst_element_add_pad (GST_ELEMENT (mpeg_demux), str->pad); - - mpeg_demux->private_stream[stream_nr] = str; - } - - return str; -} - -static gboolean -gst_mpeg_demux_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - GstMPEGDemux *demux = GST_MPEG_DEMUX (mpeg_parse); - - parent_class->parse_packhead (mpeg_parse, buffer); - - /* do something useful here */ - - if (demux->pending_tags) { - GstMPEGStream **streams; - guint i, num; - - streams = demux->audio_stream; - num = GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; - for (i = 0; i < num; ++i) { - if (streams[i] != NULL && streams[i]->tags != NULL) - gst_pad_push_event (streams[i]->pad, - gst_event_new_tag (gst_tag_list_copy (streams[i]->tags))); - } - demux->pending_tags = FALSE; - } - - return TRUE; -} - -static gboolean -gst_mpeg_demux_parse_syshead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); - guint16 header_length; - guchar *buf; - - buf = GST_BUFFER_DATA (buffer); - buf += 4; - - header_length = GST_READ_UINT16_BE (buf); - GST_DEBUG_OBJECT (mpeg_demux, "header_length %d", header_length); - buf += 2; - - /* marker:1==1 ! rate_bound:22 | marker:1==1 */ - buf += 3; - - /* audio_bound:6==1 ! fixed:1 | constrained:1 */ - buf += 1; - - /* audio_lock:1 | video_lock:1 | marker:1==1 | video_bound:5 */ - buf += 1; - - /* apacket_rate_restriction:1 | reserved:7==0x7F */ - buf += 1; - - if (!GST_MPEG_PARSE_IS_MPEG2 (mpeg_demux)) { - gint stream_count = (header_length - 6) / 3; - gint i, j = 0; - - /* Reset the total_size_bound before counting it up */ - mpeg_demux->total_size_bound = 0; - - GST_DEBUG_OBJECT (mpeg_demux, "number of streams: %d ", stream_count); - - for (i = 0; i < stream_count; i++) { - guint8 stream_id; - gboolean STD_buffer_bound_scale; - guint16 STD_buffer_size_bound; - guint32 buf_byte_size_bound; - GstMPEGStream *outstream = NULL; - - stream_id = *buf++; - if (!(stream_id & 0x80)) { - GST_DEBUG_OBJECT (mpeg_demux, "error in system header length"); - return FALSE; - } - - /* check marker bits */ - if ((*buf & 0xC0) != 0xC0) { - GST_DEBUG_OBJECT (mpeg_demux, "expecting placeholder bit values" - " '11' after stream id"); - return FALSE; - } - - STD_buffer_bound_scale = *buf & 0x20; - STD_buffer_size_bound = ((guint16) (*buf++ & 0x1F)) << 8; - STD_buffer_size_bound |= *buf++; - - if (STD_buffer_bound_scale == 0) { - buf_byte_size_bound = STD_buffer_size_bound * 128; - } else { - buf_byte_size_bound = STD_buffer_size_bound * 1024; - } - - if (stream_id == 0xBD) { - /* Private stream 1. */ - outstream = CLASS (mpeg_demux)->get_private_stream (mpeg_demux, - 0, GST_MPEG_DEMUX_PRIVATE_UNKNOWN, NULL); - } else if (stream_id == 0xBF) { - /* Private stream 2. */ - outstream = CLASS (mpeg_demux)->get_private_stream (mpeg_demux, - 1, GST_MPEG_DEMUX_PRIVATE_UNKNOWN, NULL); - } else if (stream_id >= 0xC0 && stream_id <= 0xDF) { - /* Audio. */ - outstream = CLASS (mpeg_demux)->get_audio_stream (mpeg_demux, - stream_id - 0xC0, GST_MPEG_DEMUX_AUDIO_MPEG, NULL); - } else if (stream_id >= 0xE0 && stream_id <= 0xEF) { - /* Video. */ - gint mpeg_version = !GST_MPEG_PARSE_IS_MPEG2 (mpeg_demux) ? 1 : 2; - - outstream = CLASS (mpeg_demux)->get_video_stream (mpeg_demux, - stream_id - 0xE0, GST_MPEG_DEMUX_VIDEO_MPEG, &mpeg_version); - } else { - GST_WARNING_OBJECT (mpeg_demux, "unknown stream id 0x%02x", stream_id); - } - - GST_DEBUG_OBJECT (mpeg_demux, "STD_buffer_bound_scale %d", - STD_buffer_bound_scale); - GST_DEBUG_OBJECT (mpeg_demux, "STD_buffer_size_bound %d or %d bytes", - STD_buffer_size_bound, buf_byte_size_bound); - - if (outstream != NULL) { - outstream->size_bound = buf_byte_size_bound; - mpeg_demux->total_size_bound += buf_byte_size_bound; - - if (mpeg_demux->index) { - outstream->index_id = - _demux_get_writer_id (mpeg_demux->index, outstream->pad); - } - } - - j++; - } - } - - return TRUE; -} - -static GstFlowReturn -gst_mpeg_demux_parse_packet (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); - guint8 id; - guint16 headerlen; - - guint16 packet_length; - guint16 STD_buffer_size_bound G_GNUC_UNUSED; - guint64 dts; - gint64 pts = -1; - - guint16 datalen; - - GstMPEGStream *outstream = NULL; - guint8 *buf; - gint64 timestamp; - - GstFlowReturn ret = GST_FLOW_OK; - - buf = GST_BUFFER_DATA (buffer); - id = *(buf + 3); - buf += 4; - - /* start parsing */ - packet_length = GST_READ_UINT16_BE (buf); - - GST_DEBUG_OBJECT (mpeg_demux, "got packet_length %d", packet_length); - headerlen = 2; - buf += 2; - - /* loop through looping for stuffing bits, STD, PTS, DTS, etc */ - do { - guint8 bits = *buf++; - - /* stuffing bytes */ - switch (bits & 0xC0) { - case 0xC0: - if (bits == 0xff) { - GST_DEBUG_OBJECT (mpeg_demux, "have stuffing byte"); - } else { - GST_DEBUG_OBJECT (mpeg_demux, "expected stuffing byte"); - } - headerlen++; - break; - case 0x40: - GST_DEBUG_OBJECT (mpeg_demux, "have STD"); - - /* STD_buffer_bound_scale = ((bits & 0x20) == 0x20); */ - STD_buffer_size_bound = ((guint16) (bits & 0x1F)) << 8; - STD_buffer_size_bound |= *buf++; - - headerlen += 2; - break; - case 0x00: - switch (bits & 0x30) { - case 0x20: - /* pts:3 ! 1 ! pts:15 ! 1 | pts:15 ! 1 */ - pts = ((guint64) (bits & 0x0E)) << 29; - pts |= ((guint64) (*buf++)) << 22; - pts |= ((guint64) (*buf++ & 0xFE)) << 14; - pts |= ((guint64) (*buf++)) << 7; - pts |= ((guint64) (*buf++ & 0xFE)) >> 1; - - GST_DEBUG_OBJECT (mpeg_demux, "PTS = %" G_GUINT64_FORMAT, pts); - headerlen += 5; - goto done; - case 0x30: - /* pts:3 ! 1 ! pts:15 ! 1 | pts:15 ! 1 */ - pts = ((guint64) (bits & 0x0E)) << 29; - pts |= ((guint64) (*buf++)) << 22; - pts |= ((guint64) (*buf++ & 0xFE)) << 14; - pts |= ((guint64) (*buf++)) << 7; - pts |= ((guint64) (*buf++ & 0xFE)) >> 1; - - /* sync:4 ! pts:3 ! 1 ! pts:15 ! 1 | pts:15 ! 1 */ - dts = ((guint64) (*buf++ & 0x0E)) << 29; - dts |= ((guint64) * buf++) << 22; - dts |= ((guint64) (*buf++ & 0xFE)) << 14; - dts |= ((guint64) * buf++) << 7; - dts |= ((guint64) (*buf++ & 0xFE)) >> 1; - - GST_DEBUG_OBJECT (mpeg_demux, "PTS = %" G_GUINT64_FORMAT - ", DTS = %" G_GUINT64_FORMAT, pts, dts); - headerlen += 10; - goto done; - case 0x00: - GST_DEBUG_OBJECT (mpeg_demux, "have no pts/dts"); - GST_DEBUG_OBJECT (mpeg_demux, "got trailer bits %x", (bits & 0x0f)); - if ((bits & 0x0f) != 0xf) { - GST_DEBUG_OBJECT (mpeg_demux, "not a valid packet time sequence"); - return FALSE; - } - headerlen++; - default: - goto done; - } - default: - goto done; - } - } while (1); - GST_DEBUG_OBJECT (mpeg_demux, "done with header loop"); - -done: - - /* calculate the amount of real data in this packet */ - datalen = packet_length - headerlen + 2; - - GST_DEBUG_OBJECT (mpeg_demux, "headerlen is %d, datalen is %d", - headerlen, datalen); - - if (pts != -1) { - /* Check for pts overflow */ - if (mpeg_demux->last_pts != -1) { - gint32 diff = pts - mpeg_demux->last_pts; - - if (diff > -4 * CLOCK_FREQ && diff < 4 * CLOCK_FREQ) - pts = mpeg_demux->last_pts + diff; - } - mpeg_demux->last_pts = pts; - - timestamp = PARSE_CLASS (mpeg_parse)->adjust_ts (mpeg_parse, - MPEGTIME_TO_GSTTIME (pts)); - - /* this apparently happens for some input were headers are - * rewritten to make time start at zero... */ - if ((gint64) timestamp < 0) - timestamp = 0; - } else { - timestamp = GST_CLOCK_TIME_NONE; - } - - if (id == 0xBD) { - /* Private stream 1. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have a private 1 packet"); - ret = CLASS (mpeg_demux)->process_private (mpeg_demux, buffer, 0, timestamp, - headerlen, datalen); - } else if (id == 0xBF) { - /* Private stream 2. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have a private 2 packet"); - ret = CLASS (mpeg_demux)->process_private (mpeg_demux, buffer, 1, timestamp, - headerlen, datalen); - } else if (id >= 0xC0 && id <= 0xDF) { - /* Audio. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have an audio packet"); - outstream = CLASS (mpeg_demux)->get_audio_stream (mpeg_demux, - id - 0xC0, GST_MPEG_DEMUX_AUDIO_MPEG, NULL); - ret = CLASS (mpeg_demux)->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, headerlen + 4, datalen); - } else if (id >= 0xE0 && id <= 0xEF) { - /* Video. */ - gint mpeg_version = !GST_MPEG_PARSE_IS_MPEG2 (mpeg_demux) ? 1 : 2; - - GST_DEBUG_OBJECT (mpeg_demux, "we have a video packet"); - - outstream = CLASS (mpeg_demux)->get_video_stream (mpeg_demux, - id - 0xE0, GST_MPEG_DEMUX_VIDEO_MPEG, &mpeg_version); - ret = CLASS (mpeg_demux)->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, headerlen + 4, datalen); - } else if (id == 0xBE) { - /* padding stream */ - GST_DEBUG_OBJECT (mpeg_demux, "we have a padding packet"); - } else { - GST_WARNING_OBJECT (mpeg_demux, "unknown stream id 0x%02x", id); - } - - return ret; -} - -static GstFlowReturn -gst_mpeg_demux_parse_pes (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); - guint8 id; - - guint16 packet_length; - guint8 header_data_length = 0; - - guint16 datalen; - guint16 headerlen; - GstClockTime timestamp; - - GstFlowReturn ret = GST_FLOW_OK; - - GstMPEGStream *outstream = NULL; - guint8 *buf; - - buf = GST_BUFFER_DATA (buffer); - id = *(buf + 3); - buf += 4; - - /* start parsing */ - packet_length = GST_READ_UINT16_BE (buf); - - GST_DEBUG_OBJECT (mpeg_demux, "packet_length %d", packet_length); - buf += 2; - - /* we don't operate on: program_stream_map, padding_stream, */ - /* private_stream_2, ECM, EMM, or program_stream_directory */ - if ((id != 0xBC) && (id != 0xBE) && (id != 0xBF) && (id != 0xF0) && - (id != 0xF1) && (id != 0xFF)) { - guchar flags1 = *buf++; - guchar flags2 = *buf++; - - if ((flags1 & 0xC0) != 0x80) { - return FALSE; - } - - header_data_length = *buf++; - - GST_DEBUG_OBJECT (mpeg_demux, "header_data_length: %d", header_data_length); - - /* check for PTS */ - if ((flags2 & 0x80)) { - gint64 pts; - - pts = ((guint64) (*buf++ & 0x0E)) << 29; - pts |= ((guint64) * buf++) << 22; - pts |= ((guint64) (*buf++ & 0xFE)) << 14; - pts |= ((guint64) * buf++) << 7; - pts |= ((guint64) (*buf++ & 0xFE)) >> 1; - - /* Check for pts overflow */ - if (mpeg_demux->last_pts != -1) { - gint32 diff = pts - mpeg_demux->last_pts; - - if (diff > -4 * CLOCK_FREQ && diff < 4 * CLOCK_FREQ) - pts = mpeg_demux->last_pts + diff; - } - mpeg_demux->last_pts = pts; - - timestamp = PARSE_CLASS (mpeg_parse)->adjust_ts (mpeg_parse, - MPEGTIME_TO_GSTTIME (pts)); - - GST_DEBUG_OBJECT (mpeg_demux, - "0x%02x (% " G_GINT64_FORMAT ") PTS = %" G_GUINT64_FORMAT, id, pts, - MPEGTIME_TO_GSTTIME (pts)); - } else { - timestamp = GST_CLOCK_TIME_NONE; - } - - if ((flags2 & 0x40)) { - GST_DEBUG_OBJECT (mpeg_demux, "%x DTS found", id); - buf += 5; - } - - if ((flags2 & 0x20)) { - GST_DEBUG_OBJECT (mpeg_demux, "%x ESCR found", id); - buf += 6; - } - - if ((flags2 & 0x10)) { - guint32 es_rate; - - es_rate = ((guint32) (*buf++ & 0x07)) << 14; - es_rate |= ((guint32) (*buf++)) << 7; - es_rate |= ((guint32) (*buf++ & 0xFE)) >> 1; - GST_DEBUG_OBJECT (mpeg_demux, "%x ES Rate found", id); - } - /* FIXME: lots of PES parsing missing here... */ - - /* calculate the amount of real data in this PES packet */ - /* constant is 2 bytes packet_length, 2 bytes of bits, 1 byte header len */ - headerlen = 5 + header_data_length; - /* constant is 2 bytes of bits, 1 byte header len */ - datalen = packet_length - (3 + header_data_length); - } else { - /* Deliver the whole packet. */ - /* constant corresponds to the 2 bytes of the packet length. */ - headerlen = 2; - datalen = packet_length; - - timestamp = GST_CLOCK_TIME_NONE; - } - - GST_DEBUG_OBJECT (mpeg_demux, "headerlen is %d, datalen is %d", - headerlen, datalen); - - if (id == 0xBD) { - /* Private stream 1. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have a private 1 packet"); - ret = CLASS (mpeg_demux)->process_private (mpeg_demux, buffer, 0, - timestamp, headerlen, datalen); - } else if (id == 0xBF) { - /* Private stream 2. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have a private 2 packet"); - ret = CLASS (mpeg_demux)->process_private (mpeg_demux, buffer, 1, - timestamp, headerlen, datalen); - } else if (id >= 0xC0 && id <= 0xDF) { - /* Audio. */ - GST_DEBUG_OBJECT (mpeg_demux, "we have an audio packet"); - outstream = CLASS (mpeg_demux)->get_audio_stream (mpeg_demux, - id - 0xC0, GST_MPEG_DEMUX_AUDIO_MPEG, NULL); - ret = CLASS (mpeg_demux)->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, headerlen + 4, datalen); - } else if (id >= 0xE0 && id <= 0xEF) { - /* Video. */ - gint mpeg_version = !GST_MPEG_PARSE_IS_MPEG2 (mpeg_demux) ? 1 : 2; - - GST_DEBUG_OBJECT (mpeg_demux, "we have a video packet"); - - outstream = CLASS (mpeg_demux)->get_video_stream (mpeg_demux, - id - 0xE0, GST_MPEG_DEMUX_VIDEO_MPEG, &mpeg_version); - ret = CLASS (mpeg_demux)->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, headerlen + 4, datalen); - } else if (id != 0xBE /* Ignore padding stream */ ) { - GST_WARNING_OBJECT (mpeg_demux, "unknown stream id 0x%02x", id); - } - - return ret; -} - -/* random magic value */ -#define MIN_BUFS_FOR_NO_MORE_PADS 100 - -static GstFlowReturn -gst_mpeg_demux_combine_flows (GstMPEGDemux * demux, GstMPEGStream * stream, - GstFlowReturn flow) -{ - gint i; - - /* store the value */ - stream->last_flow = flow; - - /* if it's success we can return the value right away */ - if (flow == GST_FLOW_OK) - goto done; - - /* any other error that is not-linked can be returned right - * away */ - if (flow != GST_FLOW_NOT_LINKED) { - GST_DEBUG_OBJECT (demux, "flow %s on pad %" GST_PTR_FORMAT, - gst_flow_get_name (flow), stream->pad); - goto done; - } - - /* only return NOT_LINKED if all other pads returned NOT_LINKED */ - for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) { - if (demux->video_stream[i] != NULL) { - flow = demux->video_stream[i]->last_flow; - /* some other return value (must be SUCCESS but we can return - * other values as well) */ - if (flow != GST_FLOW_NOT_LINKED) - goto done; - if (demux->video_stream[i]->buffers_sent < MIN_BUFS_FOR_NO_MORE_PADS) { - flow = GST_FLOW_OK; - goto done; - } - } - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) { - if (demux->audio_stream[i] != NULL) { - flow = demux->audio_stream[i]->last_flow; - /* some other return value (must be SUCCESS but we can return - * other values as well) */ - if (flow != GST_FLOW_NOT_LINKED) - goto done; - if (demux->audio_stream[i]->buffers_sent < MIN_BUFS_FOR_NO_MORE_PADS) { - flow = GST_FLOW_OK; - goto done; - } - } - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) { - if (demux->private_stream[i] != NULL) { - flow = demux->private_stream[i]->last_flow; - /* some other return value (must be SUCCESS but we can return - * other values as well) */ - if (flow != GST_FLOW_NOT_LINKED) - goto done; - if (demux->private_stream[i]->buffers_sent < MIN_BUFS_FOR_NO_MORE_PADS) { - flow = GST_FLOW_OK; - goto done; - } - } - } - /* if we get here, all other pads were unlinked and we return - * NOT_LINKED then */ - GST_DEBUG_OBJECT (demux, "all pads combined have not-linked flow"); - -done: - return flow; -} - -static GstFlowReturn -gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux, - GstMPEGStream * outstream, GstBuffer * buffer, - GstClockTime timestamp, guint offset, guint size) -{ - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (mpeg_demux); - GstFlowReturn ret; - GstBuffer *outbuf; - - if (timestamp != GST_CLOCK_TIME_NONE) { - outstream->cur_ts = timestamp; - if (timestamp > mpeg_parse->current_ts) - outstream->scr_offs = timestamp - mpeg_parse->current_ts; - else - outstream->scr_offs = 0; - - if (mpeg_demux->index != NULL) { - /* Register a new index position. - * FIXME: check for keyframes - */ - gst_index_add_association (mpeg_demux->index, - outstream->index_id, GST_ASSOCIATION_FLAG_DELTA_UNIT, - GST_FORMAT_BYTES, - GST_BUFFER_OFFSET (buffer), GST_FORMAT_TIME, timestamp, 0); - } - } else if (mpeg_parse->current_ts != GST_CLOCK_TIME_NONE) - outstream->cur_ts = mpeg_parse->current_ts + outstream->scr_offs; - - if (size == 0) - return GST_FLOW_OK; - - if (timestamp != GST_CLOCK_TIME_NONE) { - GST_DEBUG_OBJECT (mpeg_demux, "Creating subbuffer size %d, time=%" - GST_TIME_FORMAT, size, GST_TIME_ARGS (timestamp)); - } else { - GST_DEBUG_OBJECT (mpeg_demux, "Creating subbuffer size %d", size); - } - - if (G_UNLIKELY (offset + size > GST_BUFFER_SIZE (buffer))) - goto broken_file; - - outbuf = gst_buffer_create_sub (buffer, offset, size); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (outstream->pad)); - - GST_BUFFER_TIMESTAMP (outbuf) = timestamp; - GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer) + offset; - - if (GST_CLOCK_TIME_IS_VALID (timestamp) && - GST_CLOCK_TIME_IS_VALID (mpeg_parse->current_segment.last_stop)) { - GstClockTimeDiff diff; - guint64 update_time; - - update_time = MAX (timestamp, mpeg_parse->current_segment.start); - diff = GST_CLOCK_DIFF (mpeg_parse->current_segment.last_stop, update_time); - if (diff > GST_SECOND * 2) { - GST_DEBUG_OBJECT (mpeg_demux, "Gap of %" GST_TIME_FORMAT " detected in " - "stream %d. Sending updated NEWSEGMENT events", GST_TIME_ARGS (diff), - outstream->number); - PARSE_CLASS (mpeg_parse)->send_event (mpeg_parse, - gst_event_new_new_segment (TRUE, mpeg_parse->current_segment.rate, - GST_FORMAT_TIME, mpeg_parse->current_segment.last_stop, - mpeg_parse->current_segment.last_stop, - mpeg_parse->current_segment.last_stop)); - gst_segment_set_newsegment (&mpeg_parse->current_segment, - FALSE, mpeg_parse->current_segment.rate, GST_FORMAT_TIME, - update_time, mpeg_parse->current_segment.stop, update_time); - PARSE_CLASS (mpeg_parse)->send_event (mpeg_parse, - gst_event_new_new_segment (FALSE, mpeg_parse->current_segment.rate, - GST_FORMAT_TIME, update_time, - mpeg_parse->current_segment.stop, update_time)); - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); - } - gst_segment_set_last_stop (&mpeg_parse->current_segment, - GST_FORMAT_TIME, update_time); - } - - ret = gst_pad_push (outstream->pad, outbuf); - GST_LOG_OBJECT (outstream->pad, "flow: %s", gst_flow_get_name (ret)); - ++outstream->buffers_sent; - - GST_LOG_OBJECT (mpeg_demux, "current: %" GST_TIME_FORMAT - ", gap %" GST_TIME_FORMAT ", tol: %" GST_TIME_FORMAT, - GST_TIME_ARGS (mpeg_parse->current_ts), - GST_TIME_ARGS (mpeg_demux->max_gap), - GST_TIME_ARGS (mpeg_demux->max_gap_tolerance)); - if (GST_CLOCK_TIME_IS_VALID (mpeg_demux->max_gap) && - GST_CLOCK_TIME_IS_VALID (mpeg_parse->current_ts) && - (mpeg_parse->current_ts > mpeg_demux->max_gap)) { - CLASS (mpeg_demux)->synchronise_pads (mpeg_demux, - mpeg_parse->current_ts - mpeg_demux->max_gap, - mpeg_parse->current_ts - mpeg_demux->max_gap_tolerance); - } - - ret = CLASS (mpeg_demux)->combine_flows (mpeg_demux, outstream, ret); - - return ret; - -/* ERRORS */ -broken_file: - { - GST_ELEMENT_ERROR (mpeg_demux, STREAM, DEMUX, (NULL), - ("Either broken file or not an MPEG stream")); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_mpeg_demux_process_private (GstMPEGDemux * mpeg_demux, - GstBuffer * buffer, - guint stream_nr, GstClockTime timestamp, guint headerlen, guint datalen) -{ - GstMPEGStream *outstream; - GstFlowReturn ret; - - outstream = CLASS (mpeg_demux)->get_private_stream (mpeg_demux, - stream_nr, GST_MPEG_DEMUX_PRIVATE_UNKNOWN, NULL); - ret = CLASS (mpeg_demux)->send_subbuffer (mpeg_demux, outstream, buffer, - timestamp, headerlen + 4, datalen); - return ret; -} - -static void -gst_mpeg_demux_synchronise_pads (GstMPEGDemux * mpeg_demux, - GstClockTime threshold, GstClockTime new_ts) -{ - /* - * Send a new-segment event to any pad with cur_ts < threshold to catch it up - */ - gint i; - - for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) - if (mpeg_demux->video_stream[i] - && mpeg_demux->video_stream[i]->cur_ts < threshold) { - CLASS (mpeg_demux)->sync_stream_to_time (mpeg_demux, - mpeg_demux->video_stream[i], new_ts); - mpeg_demux->video_stream[i]->cur_ts = new_ts; - } - - for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) - if (mpeg_demux->audio_stream[i] - && mpeg_demux->audio_stream[i]->cur_ts < threshold) { - CLASS (mpeg_demux)->sync_stream_to_time (mpeg_demux, - mpeg_demux->audio_stream[i], new_ts); - mpeg_demux->audio_stream[i]->cur_ts = new_ts; - } - - for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) - if (mpeg_demux->private_stream[i] - && mpeg_demux->private_stream[i]->cur_ts < threshold) { - CLASS (mpeg_demux)->sync_stream_to_time (mpeg_demux, - mpeg_demux->private_stream[i], new_ts); - mpeg_demux->private_stream[i]->cur_ts = new_ts; - } -} - -/* - * Send a new-segment event on the indicated pad to catch it up to last_ts. - */ -static void -gst_mpeg_demux_sync_stream_to_time (GstMPEGDemux * mpeg_demux, - GstMPEGStream * stream, GstClockTime last_ts) -{ - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (mpeg_demux); - guint64 update_time; - - update_time = - MIN ((guint64) last_ts, (guint64) mpeg_parse->current_segment.stop); - gst_pad_push_event (stream->pad, gst_event_new_new_segment (TRUE, - mpeg_parse->current_segment.rate, GST_FORMAT_TIME, - update_time, mpeg_parse->current_segment.stop, update_time)); -} - -#if 0 -const GstFormat * -gst_mpeg_demux_get_src_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_TIME, /* we prefer seeking on time */ - GST_FORMAT_BYTES, - 0 - }; - - return formats; -} - -static gboolean -index_seek (GstPad * pad, GstEvent * event, gint64 * offset) -{ - GstIndexEntry *entry; - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad)); - GstMPEGStream *stream = gst_pad_get_element_private (pad); - - entry = gst_index_get_assoc_entry (mpeg_demux->index, stream->index_id, - GST_INDEX_LOOKUP_BEFORE, 0, - GST_EVENT_SEEK_FORMAT (event), GST_EVENT_SEEK_OFFSET (event)); - if (!entry) { - GST_CAT_WARNING (GST_CAT_SEEK, "%s:%s index %s %" G_GINT64_FORMAT - " -> failed", - GST_DEBUG_PAD_NAME (pad), - gst_format_get_details (GST_EVENT_SEEK_FORMAT (event))->nick, - GST_EVENT_SEEK_OFFSET (event)); - return FALSE; - } - - if (gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, offset)) { - GST_CAT_DEBUG (GST_CAT_SEEK, "%s:%s index %s %" G_GINT64_FORMAT - " -> %" G_GINT64_FORMAT " bytes", - GST_DEBUG_PAD_NAME (pad), - gst_format_get_details (GST_EVENT_SEEK_FORMAT (event))->nick, - GST_EVENT_SEEK_OFFSET (event), *offset); - return TRUE; - } - return FALSE; -} - -static gboolean -normal_seek (GstPad * pad, GstEvent * event, gint64 * offset) -{ - gboolean res = FALSE; - gint64 adjust; - GstFormat format; - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad)); - - format = GST_EVENT_SEEK_FORMAT (event); - - res = gst_pad_convert (pad, GST_FORMAT_BYTES, mpeg_demux->total_size_bound, - &format, &adjust); - - if (res) { - *offset = MAX (GST_EVENT_SEEK_OFFSET (event) - adjust, 0); - - GST_CAT_DEBUG (GST_CAT_SEEK, "%s:%s guesstimate %" G_GINT64_FORMAT - " %s -> %" G_GINT64_FORMAT - " (total_size_bound = %" G_GINT64_FORMAT ")", - GST_DEBUG_PAD_NAME (pad), - GST_EVENT_SEEK_OFFSET (event), - gst_format_get_details (GST_EVENT_SEEK_FORMAT (event))->nick, - *offset, mpeg_demux->total_size_bound); - } - - return res; -} - -static gboolean -gst_mpeg_demux_handle_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res = FALSE; - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - gint64 desired_offset; - - if (mpeg_demux->index) - res = index_seek (pad, event, &desired_offset); - if (!res) - res = normal_seek (pad, event, &desired_offset); - - if (res) { - GstEvent *new_event; - - new_event = - gst_event_new_seek (GST_EVENT_SEEK_TYPE (event), desired_offset); - res = gst_mpeg_parse_handle_src_event (pad, new_event); - } - gst_event_unref (event); - break; - } - case GST_EVENT_NAVIGATION: - { - res = gst_pad_push_event (GST_MPEG_PARSE (mpeg_demux)->sinkpad, event); - break; - } - default: - gst_event_unref (event); - break; - } - return res; -} - -static gboolean -gst_mpeg_demux_handle_src_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value) -{ - gboolean res; - - res = gst_mpeg_parse_handle_src_query (pad, type, format, value); - - if (res && (type == GST_QUERY_POSITION) && (format) - && (*format == GST_FORMAT_TIME)) { - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad)); - - *value += mpeg_demux->adjust; - } - - return res; -} -#endif - -static void -gst_mpeg_demux_reset (GstMPEGDemux * mpeg_demux) -{ - int i; - - /* Reset the element */ - - GST_INFO ("Resetting the MPEG Demuxer"); - - /* free the streams , remove the pads */ - /* filled in init_stream */ - /* check get_audio/video_stream because it can be derivated */ - for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) - if (mpeg_demux->video_stream[i]) { - gst_pad_push_event (mpeg_demux->video_stream[i]->pad, - gst_event_new_eos ()); - gst_element_remove_pad (GST_ELEMENT (mpeg_demux), - mpeg_demux->video_stream[i]->pad); - if (mpeg_demux->video_stream[i]->caps) - gst_caps_unref (mpeg_demux->video_stream[i]->caps); - g_free (mpeg_demux->video_stream[i]); - mpeg_demux->video_stream[i] = NULL; - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) - if (mpeg_demux->audio_stream[i]) { - gst_pad_push_event (mpeg_demux->audio_stream[i]->pad, - gst_event_new_eos ()); - gst_element_remove_pad (GST_ELEMENT (mpeg_demux), - mpeg_demux->audio_stream[i]->pad); - if (mpeg_demux->audio_stream[i]->tags) - gst_tag_list_free (mpeg_demux->audio_stream[i]->tags); - if (mpeg_demux->audio_stream[i]->caps) - gst_caps_unref (mpeg_demux->audio_stream[i]->caps); - g_free (mpeg_demux->audio_stream[i]); - mpeg_demux->audio_stream[i] = NULL; - } - for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) - if (mpeg_demux->private_stream[i]) { - gst_pad_push_event (mpeg_demux->private_stream[i]->pad, - gst_event_new_eos ()); - gst_element_remove_pad (GST_ELEMENT (mpeg_demux), - mpeg_demux->private_stream[i]->pad); - if (mpeg_demux->private_stream[i]->caps) - gst_caps_unref (mpeg_demux->private_stream[i]->caps); - g_free (mpeg_demux->private_stream[i]); - mpeg_demux->private_stream[i] = NULL; - } - - mpeg_demux->in_flush = FALSE; - mpeg_demux->header_length = 0; - mpeg_demux->rate_bound = 0; - mpeg_demux->audio_bound = 0; - mpeg_demux->video_bound = 0; - mpeg_demux->fixed = FALSE; - mpeg_demux->constrained = FALSE; - mpeg_demux->audio_lock = FALSE; - mpeg_demux->video_lock = FALSE; - - mpeg_demux->packet_rate_restriction = FALSE; - mpeg_demux->total_size_bound = G_GINT64_CONSTANT (0); - - mpeg_demux->index = NULL; - mpeg_demux->last_pts = -1; - mpeg_demux->pending_tags = FALSE; - - /* - * Don't adjust things that are only for subclass use - * - if they changed it, they can reset it. - * - * mpeg_demux->adjust = 0; - * mpeg_demux->max_gap = GST_CLOCK_TIME_NONE; - * mpeg_demux->max_gap_tolerance = GST_CLOCK_TIME_NONE; - */ -} - -static GstStateChangeReturn -gst_mpeg_demux_change_state (GstElement * element, GstStateChange transition) -{ - GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (element); - GstStateChangeReturn ret; - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_mpeg_demux_reset (mpeg_demux); - break; - default: - break; - } - return ret; -} - -static void -gst_mpeg_demux_set_index (GstElement * element, GstIndex * index) -{ - GstMPEGDemux *mpeg_demux; - - GST_ELEMENT_CLASS (parent_class)->set_index (element, index); - - mpeg_demux = GST_MPEG_DEMUX (element); - - mpeg_demux->index = index; -} - -static GstIndex * -gst_mpeg_demux_get_index (GstElement * element) -{ - GstMPEGDemux *mpeg_demux; - - mpeg_demux = GST_MPEG_DEMUX (element); - - return mpeg_demux->index; -} - -void -gst_mpeg_streams_reset_last_flow (GstMPEGStream * streams[], guint num) -{ - guint i; - - for (i = 0; i < num; ++i) { - if (streams[i] != NULL) - streams[i]->last_flow = GST_FLOW_OK; - } -} - -void -gst_mpeg_streams_reset_cur_ts (GstMPEGStream * streams[], guint num, - GstClockTime cur_ts) -{ - guint i; - - for (i = 0; i < num; ++i) { - if (streams[i] != NULL) - streams[i]->cur_ts = cur_ts; - } -} - -gboolean -gst_mpeg_demux_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "mpegdemux", - GST_RANK_SECONDARY, GST_TYPE_MPEG_DEMUX); -} diff --git a/gst/mpegstream/gstmpegdemux.h b/gst/mpegstream/gstmpegdemux.h deleted file mode 100644 index 583de0d2f4..0000000000 --- a/gst/mpegstream/gstmpegdemux.h +++ /dev/null @@ -1,221 +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 __MPEG_DEMUX_H__ -#define __MPEG_DEMUX_H__ - - -#include -#include "gstmpegparse.h" - -G_BEGIN_DECLS - -#define GST_TYPE_MPEG_DEMUX \ - (gst_mpeg_demux_get_type()) -#define GST_MPEG_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEG_DEMUX,GstMPEGDemux)) -#define GST_MPEG_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEG_DEMUX,GstMPEGDemuxClass)) -#define GST_IS_MPEG_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEG_DEMUX)) -#define GST_IS_MPEG_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEG_DEMUX)) - -/* Supported kinds of streams. */ -enum { - GST_MPEG_DEMUX_STREAM_VIDEO = 1, - GST_MPEG_DEMUX_STREAM_AUDIO, - GST_MPEG_DEMUX_STREAM_PRIVATE, - GST_MPEG_DEMUX_STREAM_LAST -}; - -/* Supported number of streams. */ -#define GST_MPEG_DEMUX_NUM_VIDEO_STREAMS 16 -#define GST_MPEG_DEMUX_NUM_AUDIO_STREAMS 32 -#define GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS 2 - -/* How to make stream type values. */ -#define GST_MPEG_DEMUX_STREAM_TYPE(kind, serial) \ - (((kind) << 16) + (serial)) - -/* How to retrieve the stream kind back from a type. */ -#define GST_MPEG_DEMUX_STREAM_KIND(type) ((type) >> 16) - -/* The recognized video types. */ -enum { - GST_MPEG_DEMUX_VIDEO_UNKNOWN = - GST_MPEG_DEMUX_STREAM_TYPE (GST_MPEG_DEMUX_STREAM_VIDEO, 1), - GST_MPEG_DEMUX_VIDEO_MPEG, - GST_MPEG_DEMUX_VIDEO_LAST -}; - -/* The recognized audio types. */ -enum { - GST_MPEG_DEMUX_AUDIO_UNKNOWN = - GST_MPEG_DEMUX_STREAM_TYPE (GST_MPEG_DEMUX_STREAM_AUDIO, 1), - GST_MPEG_DEMUX_AUDIO_MPEG, - GST_MPEG_DEMUX_AUDIO_LAST -}; - -/* The recognized private stream types. */ -enum { - GST_MPEG_DEMUX_PRIVATE_UNKNOWN = - GST_MPEG_DEMUX_STREAM_TYPE (GST_MPEG_DEMUX_STREAM_PRIVATE, 1), - GST_MPEG_DEMUX_PRIVATE_LAST -}; - -typedef struct _GstMPEGStream GstMPEGStream; -typedef struct _GstMPEGVideoStream GstMPEGVideoStream; -typedef struct _GstMPEGDemux GstMPEGDemux; -typedef struct _GstMPEGDemuxClass GstMPEGDemuxClass; - -/* Information associated to a single MPEG stream. */ -struct _GstMPEGStream { - gint type; - gint number; - GstPad *pad; - GstCaps *caps; - gint index_id; - gint size_bound; - GstClockTime cur_ts; - GstClockTimeDiff scr_offs; - GstFlowReturn last_flow; - guint buffers_sent; - GstTagList *tags; -}; - -/* Extended structure to hold additional information for video - streams. */ -struct _GstMPEGVideoStream { - GstMPEGStream parent; - gint mpeg_version; -}; - -struct _GstMPEGDemux { - GstMPEGParse parent; - - /* previous partial chunk and bytes remaining in it */ - gboolean in_flush; - - /* program stream header values */ - guint16 header_length; - guint32 rate_bound; - guint8 audio_bound; - gboolean fixed; - gboolean constrained; - gboolean audio_lock; - gboolean video_lock; - guint8 video_bound; - gboolean packet_rate_restriction; - gint64 total_size_bound; - - gint64 last_pts; - gboolean pending_tags; - GstIndex *index; - - /* stream output */ - GstMPEGStream *video_stream[GST_MPEG_DEMUX_NUM_VIDEO_STREAMS]; - GstMPEGStream *audio_stream[GST_MPEG_DEMUX_NUM_AUDIO_STREAMS]; - GstMPEGStream *private_stream[GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS]; - - GstClockTime max_gap; /* Maximum timestamp difference to - allow between pads before using a - filler to catch up. */ - GstClockTime max_gap_tolerance; - /* When catching a pad up, how far - behind to make it. */ - - GstClockTime max_ts; /* Highest timestamp of all pads. */ - GstPad *max_pad; /* Pad with highest timestamp. */ -}; - -struct _GstMPEGDemuxClass { - GstMPEGParseClass parent_class; - - GstPadTemplate *video_template; - GstPadTemplate *audio_template; - GstPadTemplate *private_template; - - GstPad * (*new_output_pad) (GstMPEGDemux *mpeg_demux, - const gchar *name, - GstPadTemplate *temp); - void (*init_stream) (GstMPEGDemux *mpeg_demux, - gint type, - GstMPEGStream *str, - gint number, - const gchar *name, - GstPadTemplate *temp); - - GstMPEGStream * - (*get_video_stream) (GstMPEGDemux *mpeg_demux, - guint8 stream_nr, - gint type, - const gpointer info); - GstMPEGStream * - (*get_audio_stream) (GstMPEGDemux *mpeg_demux, - guint8 stream_nr, - gint type, - const gpointer info); - GstMPEGStream * - (*get_private_stream) (GstMPEGDemux *mpeg_demux, - guint8 stream_nr, - gint type, - const gpointer info); - - GstFlowReturn (*send_subbuffer) (GstMPEGDemux *mpeg_demux, - GstMPEGStream *outstream, - GstBuffer *buffer, - GstClockTime timestamp, - guint offset, - guint size); - - - GstFlowReturn (*combine_flows) (GstMPEGDemux *mpeg_demux, - GstMPEGStream *stream, - GstFlowReturn flow); - - GstFlowReturn (*process_private) (GstMPEGDemux *mpeg_demux, - GstBuffer *buffer, - guint stream_nr, - GstClockTime timestamp, - guint headerlen, guint datalen); - - void (*synchronise_pads) (GstMPEGDemux *mpeg_demux, - GstClockTime threshold, - GstClockTime new_ts); - - void (*sync_stream_to_time) (GstMPEGDemux *mpeg_demux, - GstMPEGStream *stream, - GstClockTime last_ts); -}; - -void gst_mpeg_streams_reset_last_flow (GstMPEGStream *streams[], - guint num); -void gst_mpeg_streams_reset_cur_ts (GstMPEGStream *streams[], - guint num, - GstClockTime cur_ts); - -GType gst_mpeg_demux_get_type (void); - -gboolean gst_mpeg_demux_plugin_init (GstPlugin *plugin); - -G_END_DECLS - -#endif /* __MPEG_DEMUX_H__ */ diff --git a/gst/mpegstream/gstmpegpacketize.c b/gst/mpegstream/gstmpegpacketize.c deleted file mode 100644 index 609e23ecec..0000000000 --- a/gst/mpegstream/gstmpegpacketize.c +++ /dev/null @@ -1,360 +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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstmpegpacketize.h" - -GST_DEBUG_CATEGORY_STATIC (gstmpegpacketize_debug); -#define GST_CAT_DEFAULT (gstmpegpacketize_debug) - -GstMPEGPacketize * -gst_mpeg_packetize_new (GstMPEGPacketizeType type) -{ - GstMPEGPacketize *new; - - new = g_new0 (GstMPEGPacketize, 1); - new->resync = TRUE; - new->id = 0; - new->cache_head = 0; - new->cache_tail = 0; - new->cache_size = 0x4000; - new->cache = g_malloc (new->cache_size); - new->cache_byte_pos = 0; - new->MPEG2 = FALSE; - new->type = type; - -#ifndef GST_DISABLE_GST_DEBUG - if (gstmpegpacketize_debug == NULL) { - GST_DEBUG_CATEGORY_INIT (gstmpegpacketize_debug, "mpegpacketize", 0, - "MPEG parser element packetizer"); - } -#endif - - return new; -} - -void -gst_mpeg_packetize_flush_cache (GstMPEGPacketize * packetize) -{ - g_return_if_fail (packetize != NULL); - - packetize->cache_byte_pos += packetize->cache_tail; - - packetize->resync = TRUE; - packetize->cache_head = 0; - packetize->cache_tail = 0; - - GST_DEBUG ("flushed packetize cache"); -} - -void -gst_mpeg_packetize_destroy (GstMPEGPacketize * packetize) -{ - g_return_if_fail (packetize != NULL); - - g_free (packetize->cache); - g_free (packetize); -} - -guint64 -gst_mpeg_packetize_tell (GstMPEGPacketize * packetize) -{ - return packetize->cache_byte_pos + packetize->cache_head; -} - -void -gst_mpeg_packetize_put (GstMPEGPacketize * packetize, GstBuffer * buf) -{ - int cache_len = packetize->cache_tail - packetize->cache_head; - - if (packetize->cache_head == 0 && cache_len == 0 && - GST_BUFFER_OFFSET_IS_VALID (buf)) { - packetize->cache_byte_pos = GST_BUFFER_OFFSET (buf); - GST_DEBUG ("cache byte position now %" G_GINT64_FORMAT, - packetize->cache_byte_pos); - } - - if (cache_len + GST_BUFFER_SIZE (buf) > packetize->cache_size) { - /* the buffer does not fit into the cache so grow the cache */ - - guint8 *new_cache; - - /* get the new size of the cache */ - do { - packetize->cache_size *= 2; - } while (cache_len + GST_BUFFER_SIZE (buf) > packetize->cache_size); - - /* allocate new cache - do not realloc to avoid copying data twice */ - new_cache = g_malloc (packetize->cache_size); - - /* copy the data to the beginning of the new cache and update the cache info */ - memcpy (new_cache, packetize->cache + packetize->cache_head, cache_len); - g_free (packetize->cache); - packetize->cache = new_cache; - packetize->cache_byte_pos += packetize->cache_head; - packetize->cache_head = 0; - packetize->cache_tail = cache_len; - } else if (packetize->cache_tail + GST_BUFFER_SIZE (buf) > - packetize->cache_size) { - /* the buffer does not fit into the end of the cache so move the cache data - to the beginning of the cache */ - - memmove (packetize->cache, packetize->cache + packetize->cache_head, - packetize->cache_tail - packetize->cache_head); - packetize->cache_byte_pos += packetize->cache_head; - packetize->cache_tail -= packetize->cache_head; - packetize->cache_head = 0; - } - - /* copy the buffer to the cache */ - memcpy (packetize->cache + packetize->cache_tail, GST_BUFFER_DATA (buf), - GST_BUFFER_SIZE (buf)); - packetize->cache_tail += GST_BUFFER_SIZE (buf); - - gst_buffer_unref (buf); -} - -static guint -peek_cache (GstMPEGPacketize * packetize, guint length, guint8 ** buf) -{ - *buf = packetize->cache + packetize->cache_head; - - if (packetize->cache_tail - packetize->cache_head < length) - return packetize->cache_tail - packetize->cache_head; - - return length; -} - -static void -skip_cache (GstMPEGPacketize * packetize, guint length) -{ - g_assert (packetize->cache_tail - packetize->cache_head >= length); - - packetize->cache_head += length; -} - -static GstFlowReturn -read_cache (GstMPEGPacketize * packetize, guint length, GstBuffer ** outbuf) -{ - if (packetize->cache_tail - packetize->cache_head < length) - return GST_FLOW_RESEND; - if (length == 0) - return GST_FLOW_RESEND; - - *outbuf = gst_buffer_new_and_alloc (length); - - memcpy (GST_BUFFER_DATA (*outbuf), packetize->cache + packetize->cache_head, - length); - packetize->cache_head += length; - - return GST_FLOW_OK; -} - -static GstFlowReturn -parse_packhead (GstMPEGPacketize * packetize, GstBuffer ** outbuf) -{ - guint length = 8 + 4; - guint8 *buf; - guint got_bytes; - - GST_DEBUG ("packetize: in parse_packhead"); - - *outbuf = NULL; - - got_bytes = peek_cache (packetize, length, &buf); - if (got_bytes < length) - return GST_FLOW_RESEND; - - buf += 4; - - GST_DEBUG ("code %02x", *buf); - - /* start parsing the stream */ - if ((*buf & 0xc0) == 0x40) { - GST_DEBUG ("packetize::parse_packhead setting mpeg2"); - packetize->MPEG2 = TRUE; - length += 2; - got_bytes = peek_cache (packetize, length, &buf); - if (got_bytes < length) - return GST_FLOW_RESEND; - } else { - GST_DEBUG ("packetize::parse_packhead setting mpeg1"); - packetize->MPEG2 = FALSE; - } - - return read_cache (packetize, length, outbuf); -} - -static GstFlowReturn -parse_end (GstMPEGPacketize * packetize, GstBuffer ** outbuf) -{ - return read_cache (packetize, 4, outbuf); -} - -static GstFlowReturn -parse_generic (GstMPEGPacketize * packetize, GstBuffer ** outbuf) -{ - guchar *buf; - guint length = 6; - guint got_bytes; - - GST_DEBUG ("packetize: in parse_generic"); - - got_bytes = peek_cache (packetize, length, &buf); - if (got_bytes < length) - return GST_FLOW_RESEND; - - buf += 4; - - length += GST_READ_UINT16_BE (buf); - GST_DEBUG ("packetize: header_length %d", length); - - return read_cache (packetize, length, outbuf); -} - -static GstFlowReturn -parse_chunk (GstMPEGPacketize * packetize, GstBuffer ** outbuf) -{ - guchar *buf; - gint offset; - guint32 code; - guint chunksize; - - chunksize = peek_cache (packetize, 4096, &buf); - if (chunksize == 0) - return GST_FLOW_RESEND; - - offset = 4; - - code = GST_READ_UINT32_BE (buf + offset); - - GST_DEBUG ("code = %08x", code); - - while ((code & 0xffffff00) != 0x100L) { - code = (code << 8) | buf[offset++]; - - GST_DEBUG (" code = %08x", code); - - if (offset == chunksize) { - chunksize = peek_cache (packetize, offset + 4096, &buf); - if (chunksize == 0) - return GST_FLOW_RESEND; - chunksize += offset; - } - } - if (offset > 4) { - return read_cache (packetize, offset - 4, outbuf); - } - return GST_FLOW_RESEND; -} - - -/* FIXME mmx-ify me */ -static gboolean -find_start_code (GstMPEGPacketize * packetize) -{ - guint8 *buf; - gint offset; - guint32 code; - gint chunksize; - - chunksize = peek_cache (packetize, 4096, &buf); - if (chunksize < 5) - return FALSE; - - offset = 4; - - code = GST_READ_UINT32_BE (buf); - - GST_DEBUG ("code = %08x %p %08x", code, buf, chunksize); - - while ((code & 0xffffff00) != 0x100L) { - code = (code << 8) | buf[offset++]; - - GST_DEBUG (" code = %08x %p %08x", code, buf, chunksize); - - if (offset == chunksize) { - skip_cache (packetize, offset); - - chunksize = peek_cache (packetize, 4096, &buf); - if (chunksize == 0) - return FALSE; - - offset = 0; - } - } - packetize->id = code & 0xff; - if (offset > 4) { - skip_cache (packetize, offset - 4); - } - return TRUE; -} - -GstFlowReturn -gst_mpeg_packetize_read (GstMPEGPacketize * packetize, GstBuffer ** outbuf) -{ - g_return_val_if_fail (packetize != NULL, GST_FLOW_ERROR); - - *outbuf = NULL; - - while (*outbuf == NULL) { - if (!find_start_code (packetize)) - return GST_FLOW_RESEND; - - GST_DEBUG ("packetize: have chunk 0x%02X", packetize->id); - if (packetize->type == GST_MPEG_PACKETIZE_SYSTEM) { - if (packetize->resync) { - if (packetize->id != PACK_START_CODE) { - skip_cache (packetize, 4); - continue; - } - - packetize->resync = FALSE; - } - switch (packetize->id) { - case PACK_START_CODE: - return parse_packhead (packetize, outbuf); - case SYS_HEADER_START_CODE: - return parse_generic (packetize, outbuf); - case ISO11172_END_START_CODE: - return parse_end (packetize, outbuf); - default: - if (packetize->MPEG2 && ((packetize->id < 0xBD) - || (packetize->id > 0xFE))) { - skip_cache (packetize, 4); - g_warning ("packetize: ******** unknown id 0x%02X", packetize->id); - } else { - return parse_generic (packetize, outbuf); - } - } - } else if (packetize->type == GST_MPEG_PACKETIZE_VIDEO) { - return parse_chunk (packetize, outbuf); - } else { - g_assert_not_reached (); - } - } - - g_assert_not_reached (); - return GST_FLOW_ERROR; -} diff --git a/gst/mpegstream/gstmpegpacketize.h b/gst/mpegstream/gstmpegpacketize.h deleted file mode 100644 index 1511217097..0000000000 --- a/gst/mpegstream/gstmpegpacketize.h +++ /dev/null @@ -1,80 +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 __MPEGPACKETIZE_H__ -#define __MPEGPACKETIZE_H__ - - -#include - -G_BEGIN_DECLS - -#define PICTURE_START_CODE 0x00 -#define SLICE_MIN_START_CODE 0x01 -#define SLICE_MAX_START_CODE 0xaf -#define USER_START_CODE 0xb2 -#define SEQUENCE_START_CODE 0xb3 -#define SEQUENCE_ERROR_START_CODE 0xb4 -#define EXT_START_CODE 0xb5 -#define SEQUENCE_END_START_CODE 0xb7 -#define GOP_START_CODE 0xb8 - -#define ISO11172_END_START_CODE 0xb9 -#define PACK_START_CODE 0xba -#define SYS_HEADER_START_CODE 0xbb - -typedef struct _GstMPEGPacketize GstMPEGPacketize; - -#define GST_MPEG_PACKETIZE_ID(pack) ((pack)->id) -#define GST_MPEG_PACKETIZE_IS_MPEG2(pack) ((pack)->MPEG2) - -typedef enum { - GST_MPEG_PACKETIZE_SYSTEM, - GST_MPEG_PACKETIZE_VIDEO, -} GstMPEGPacketizeType; - -struct _GstMPEGPacketize { - /* current parse state */ - guchar id; - - GstMPEGPacketizeType type; - - guint8 *cache; /* cache for incoming data */ - guint cache_size; /* allocated size of the cache */ - guint cache_head; /* position of the beginning of the data */ - guint cache_tail; /* position of the end of the data in the cache */ - guint64 cache_byte_pos; /* byte position of the cache in the MPEG stream */ - - gboolean MPEG2; - gboolean resync; -}; - -GstMPEGPacketize* gst_mpeg_packetize_new (GstMPEGPacketizeType type); -void gst_mpeg_packetize_destroy (GstMPEGPacketize *packetize); - -void gst_mpeg_packetize_flush_cache (GstMPEGPacketize *packetize); - -guint64 gst_mpeg_packetize_tell (GstMPEGPacketize *packetize); -void gst_mpeg_packetize_put (GstMPEGPacketize *packetize, GstBuffer * buf); -GstFlowReturn gst_mpeg_packetize_read (GstMPEGPacketize *packetize, GstBuffer ** outbuf); - -G_END_DECLS - -#endif /* __MPEGPACKETIZE_H__ */ diff --git a/gst/mpegstream/gstmpegparse.c b/gst/mpegstream/gstmpegparse.c deleted file mode 100644 index 1033ff56b8..0000000000 --- a/gst/mpegstream/gstmpegparse.c +++ /dev/null @@ -1,1361 +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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstmpegparse.h" -#include "gstmpegclock.h" - -static GstFormat scr_format; - -GST_DEBUG_CATEGORY_STATIC (gstmpegparse_debug); -#define GST_CAT_DEFAULT (gstmpegparse_debug) - -GST_DEBUG_CATEGORY_EXTERN (GST_CAT_SEEK); - -#define MP_INVALID_SCR ((guint64)(-1)) -#define MP_MUX_RATE_MULT 50 -#define MP_MIN_VALID_BSS 8192 -#define MP_MAX_VALID_BSS 16384 -/* - * Hysteresis value to limit the - * total predicted time skipping about - */ -#define MP_SCR_RATE_HYST 0.08 - -#define CLASS(o) GST_MPEG_PARSE_CLASS (G_OBJECT_GET_CLASS (o)) - -#define DEFAULT_MAX_SCR_GAP 120000 - -/* GstMPEGParse signals and args */ -enum -{ - SIGNAL_REACHED_OFFSET, - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_MAX_SCR_GAP, - ARG_BYTE_OFFSET, - ARG_TIME_OFFSET - /* FILL ME */ -}; - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) TRUE") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) TRUE") - ); - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gstmpegparse_debug, "mpegparse", 0, \ - "MPEG parser element"); - -GST_BOILERPLATE_FULL (GstMPEGParse, gst_mpeg_parse, GstElement, - GST_TYPE_ELEMENT, _do_init); - -static GstStateChangeReturn gst_mpeg_parse_change_state (GstElement * element, - GstStateChange transition); - -static gboolean gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, - GstBuffer * buffer); - -static void gst_mpeg_parse_reset (GstMPEGParse * mpeg_parse); - -static GstClockTime gst_mpeg_parse_adjust_ts (GstMPEGParse * mpeg_parse, - GstClockTime ts); - -static GstFlowReturn gst_mpeg_parse_send_buffer (GstMPEGParse * mpeg_parse, - GstBuffer * buffer, GstClockTime time); -static gboolean gst_mpeg_parse_process_event (GstMPEGParse * mpeg_parse, - GstEvent * event); -static gboolean gst_mpeg_parse_send_event (GstMPEGParse * mpeg_parse, - GstEvent * event); - -static void gst_mpeg_parse_pad_added (GstElement * element, GstPad * pad); - -static gboolean gst_mpeg_parse_event (GstPad * pad, GstEvent * event); -static GstFlowReturn gst_mpeg_parse_chain (GstPad * pad, GstBuffer * buf); - -static void gst_mpeg_parse_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void gst_mpeg_parse_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_mpeg_parse_set_index (GstElement * element, GstIndex * index); -static GstIndex *gst_mpeg_parse_get_index (GstElement * element); - -static guint gst_mpeg_parse_signals[LAST_SIGNAL] = { 0 }; - -static void -gst_mpeg_parse_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, "MPEG System Parser", - "Codec/Parser", - "Parses MPEG1 and MPEG2 System Streams", - "Erik Walthinsen , Wim Taymans "); -} - -static void -gst_mpeg_parse_class_init (GstMPEGParseClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gst_mpeg_parse_signals[SIGNAL_REACHED_OFFSET] = - g_signal_new ("reached-offset", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstMPEGParseClass, reached_offset), - NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0); - - gobject_class->get_property = gst_mpeg_parse_get_property; - gobject_class->set_property = gst_mpeg_parse_set_property; - - gstelement_class->pad_added = gst_mpeg_parse_pad_added; - gstelement_class->change_state = gst_mpeg_parse_change_state; - gstelement_class->get_index = gst_mpeg_parse_get_index; - gstelement_class->set_index = gst_mpeg_parse_set_index; - - klass->parse_packhead = gst_mpeg_parse_parse_packhead; - klass->parse_syshead = NULL; - klass->parse_packet = NULL; - klass->parse_pes = NULL; - klass->adjust_ts = gst_mpeg_parse_adjust_ts; - klass->send_buffer = gst_mpeg_parse_send_buffer; - klass->process_event = gst_mpeg_parse_process_event; - klass->send_event = gst_mpeg_parse_send_event; - - /* FIXME: this is a hack. We add the pad templates here instead - * in the base_init function, since the derived class (mpegdemux) - * uses different pads. IMO, this is wrong. */ - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sink_factory)); - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_SCR_GAP, - g_param_spec_int ("max-scr-gap", "Max SCR gap", - "Maximum allowed gap between expected and actual " - "SCR values. -1 means never adjust.", -1, G_MAXINT, - DEFAULT_MAX_SCR_GAP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTE_OFFSET, - g_param_spec_uint64 ("byte-offset", "Byte Offset", - "Emit reached-offset signal when the byte offset is reached.", - 0, G_MAXUINT64, G_MAXUINT64, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TIME_OFFSET, - g_param_spec_uint64 ("time-offset", "Time Offset", - "Time offset in the stream.", - 0, G_MAXUINT64, G_MAXUINT64, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -} - -static void -gst_mpeg_parse_init (GstMPEGParse * mpeg_parse, GstMPEGParseClass * klass) -{ - GstElementClass *gstelement_class; - GstPadTemplate *templ; - - gstelement_class = GST_ELEMENT_GET_CLASS (mpeg_parse); - - mpeg_parse->packetize = NULL; - - mpeg_parse->max_scr_gap = DEFAULT_MAX_SCR_GAP; - - mpeg_parse->byte_offset = G_MAXUINT64; - - gst_mpeg_parse_reset (mpeg_parse); - - templ = gst_element_class_get_pad_template (gstelement_class, "sink"); - mpeg_parse->sinkpad = gst_pad_new_from_template (templ, "sink"); - gst_element_add_pad (GST_ELEMENT (mpeg_parse), mpeg_parse->sinkpad); - - if ((templ = gst_element_class_get_pad_template (gstelement_class, "src"))) { - mpeg_parse->srcpad = gst_pad_new_from_template (templ, "src"); - gst_element_add_pad (GST_ELEMENT (mpeg_parse), mpeg_parse->srcpad); - gst_pad_set_event_function (mpeg_parse->srcpad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_handle_src_event)); - gst_pad_set_query_type_function (mpeg_parse->srcpad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_get_src_query_types)); - gst_pad_set_query_function (mpeg_parse->srcpad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_handle_src_query)); - gst_pad_use_fixed_caps (mpeg_parse->srcpad); - } - - gst_pad_set_event_function (mpeg_parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_event)); - gst_pad_set_chain_function (mpeg_parse->sinkpad, - GST_DEBUG_FUNCPTR (gst_mpeg_parse_chain)); -} - -#ifdef FIXME -static void -gst_mpeg_parse_update_streaminfo (GstMPEGParse * mpeg_parse) -{ - GstProps *props; - GstPropsEntry *entry; - gboolean mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize); - GstCaps *caps; - - props = gst_props_empty_new (); - - entry = gst_props_entry_new ("mpegversion", G_TYPE_INT (mpeg2 ? 2 : 1)); - gst_props_add_entry (props, (GstPropsEntry *) entry); - - entry = - gst_props_entry_new ("bitrate", G_TYPE_INT (mpeg_parse->mux_rate * 8)); - gst_props_add_entry (props, (GstPropsEntry *) entry); - - caps = gst_caps_new ("mpeg_streaminfo", - "application/x-gst-streaminfo", props); - - gst_caps_replace_sink (&mpeg_parse->streaminfo, caps); - g_object_notify (G_OBJECT (mpeg_parse), "streaminfo"); -} -#endif - -static void -gst_mpeg_parse_reset (GstMPEGParse * mpeg_parse) -{ - GST_DEBUG_OBJECT (mpeg_parse, "Resetting mpeg_parse"); - - mpeg_parse->first_scr = MP_INVALID_SCR; - mpeg_parse->first_scr_pos = 0; - mpeg_parse->last_scr = MP_INVALID_SCR; - mpeg_parse->last_scr_pos = 0; - mpeg_parse->scr_rate = 0; - - mpeg_parse->avg_bitrate_time = 0; - mpeg_parse->avg_bitrate_bytes = 0; - - mpeg_parse->mux_rate = 0; - mpeg_parse->current_scr = MP_INVALID_SCR; - mpeg_parse->next_scr = 0; - mpeg_parse->bytes_since_scr = 0; - - mpeg_parse->current_ts = 0; - - mpeg_parse->do_adjust = TRUE; - mpeg_parse->pending_newsegment = TRUE; - mpeg_parse->adjust = 0; - - /* Initialize the current segment. */ - GST_DEBUG_OBJECT (mpeg_parse, "Resetting current segment"); - gst_segment_init (&mpeg_parse->current_segment, GST_FORMAT_TIME); -} - -static GstClockTime -gst_mpeg_parse_adjust_ts (GstMPEGParse * mpeg_parse, GstClockTime ts) -{ - if (!GST_CLOCK_TIME_IS_VALID (ts)) { - return GST_CLOCK_TIME_NONE; - } - - if (mpeg_parse->do_adjust) { - /* Close the SCR gaps. */ - return ts + MPEGTIME_TO_GSTTIME (mpeg_parse->adjust); - } else { - if (ts >= mpeg_parse->current_segment.start) { - return ts; - } else { - /* The timestamp lies outside the current segment. Return an - invalid timestamp instead. */ - return GST_CLOCK_TIME_NONE; - } - } -} - -static GstFlowReturn -gst_mpeg_parse_send_buffer (GstMPEGParse * mpeg_parse, GstBuffer * buffer, - GstClockTime time) -{ - GstFlowReturn result = GST_FLOW_OK; - - if (!GST_PAD_CAPS (mpeg_parse->srcpad)) { - gboolean mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize); - GstCaps *caps; - - caps = gst_caps_new_simple ("video/mpeg", - "mpegversion", G_TYPE_INT, (mpeg2 ? 2 : 1), - "systemstream", G_TYPE_BOOLEAN, TRUE, - "parsed", G_TYPE_BOOLEAN, TRUE, NULL); - - if (!gst_pad_set_caps (mpeg_parse->srcpad, caps)) { - GST_ELEMENT_ERROR (GST_ELEMENT (mpeg_parse), - CORE, NEGOTIATION, (NULL), ("failed to set caps")); - gst_caps_unref (caps); - gst_buffer_unref (buffer); - return GST_FLOW_ERROR; - } - gst_caps_unref (caps); - } - - GST_BUFFER_TIMESTAMP (buffer) = time; - GST_DEBUG_OBJECT (mpeg_parse, "current buffer time: %" GST_TIME_FORMAT, - GST_TIME_ARGS (time)); - - gst_buffer_set_caps (buffer, GST_PAD_CAPS (mpeg_parse->srcpad)); - result = gst_pad_push (mpeg_parse->srcpad, buffer); - - return result; -} - -static gboolean -gst_mpeg_parse_process_event (GstMPEGParse * mpeg_parse, GstEvent * event) -{ - gboolean ret = FALSE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - gdouble rate; - GstFormat format; - gint64 start, stop, time; - - gst_event_parse_new_segment (event, &update, &rate, &format, - &start, &stop, &time); - - if (format == GST_FORMAT_TIME && (GST_CLOCK_TIME_IS_VALID (time))) { - /* We are receiving segments from upstream. Don't try to adjust - SCR values. */ - mpeg_parse->do_adjust = FALSE; - mpeg_parse->adjust = 0; - - if (!update && mpeg_parse->current_segment.stop != -1) { - /* Close the current segment. */ - if (CLASS (mpeg_parse)->send_event) { - CLASS (mpeg_parse)->send_event (mpeg_parse, - gst_event_new_new_segment (TRUE, - mpeg_parse->current_segment.rate, - GST_FORMAT_TIME, - mpeg_parse->current_segment.start, - mpeg_parse->current_segment.stop, - mpeg_parse->current_segment.time)); - } - } - - /* Update the current segment. */ - GST_DEBUG_OBJECT (mpeg_parse, - "Updating current segment with newsegment"); - gst_segment_set_newsegment (&mpeg_parse->current_segment, - update, rate, format, start, stop, time); - - if (!update) { - /* Send a newsegment event for the new current segment. */ - if (CLASS (mpeg_parse)->send_event) { - CLASS (mpeg_parse)->send_event (mpeg_parse, - gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME, - start, stop, time)); - mpeg_parse->pending_newsegment = FALSE; - } - } - } else if (format != GST_FORMAT_TIME && !update) { - GST_DEBUG_OBJECT (mpeg_parse, - "Received non-time newsegment from stream"); - mpeg_parse->do_adjust = TRUE; - mpeg_parse->adjust = 0; - mpeg_parse->pending_newsegment = TRUE; - } - mpeg_parse->packetize->resync = TRUE; - - gst_event_unref (event); - - ret = TRUE; - break; - } - case GST_EVENT_FLUSH_STOP:{ - /* Forward the event. */ - if (CLASS (mpeg_parse)->send_event) { - ret = CLASS (mpeg_parse)->send_event (mpeg_parse, event); - } else { - gst_event_unref (event); - } - - /* Reset the internal fields. */ - gst_mpeg_parse_reset (mpeg_parse); - gst_mpeg_packetize_flush_cache (mpeg_parse->packetize); - break; - } - case GST_EVENT_EOS:{ - GST_DEBUG_OBJECT (mpeg_parse, "EOS"); - - if (CLASS (mpeg_parse)->send_event) { - ret = CLASS (mpeg_parse)->send_event (mpeg_parse, event); - } else { - gst_event_unref (event); - } - if (!ret) { - GST_ELEMENT_ERROR (mpeg_parse, STREAM, DEMUX, (NULL), - ("Pushing EOS event didn't work on any of the source pads")); - } - break; - } - default: - if (CLASS (mpeg_parse)->send_event) { - ret = CLASS (mpeg_parse)->send_event (mpeg_parse, event); - } else { - gst_event_unref (event); - } - break; - } - - return ret; -} - -/* returns TRUE if pushing the event worked on at least one pad */ -static gboolean -gst_mpeg_parse_send_event (GstMPEGParse * mpeg_parse, GstEvent * event) -{ - GstIterator *it; - gpointer pad; - gboolean ret = FALSE; - - /* Send event to all source pads of this element. */ - it = gst_element_iterate_src_pads (GST_ELEMENT (mpeg_parse)); - while (TRUE) { - switch (gst_iterator_next (it, &pad)) { - case GST_ITERATOR_OK: - gst_event_ref (event); - if (gst_pad_push_event (GST_PAD (pad), event)) - ret = TRUE; - gst_object_unref (GST_OBJECT (pad)); - break; - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - case GST_ITERATOR_DONE: - goto done; - case GST_ITERATOR_ERROR: - ret = FALSE; - goto done; - } - } - -done: - gst_iterator_free (it); - gst_event_unref (event); - - return ret; -} - -static void -gst_mpeg_parse_pad_added (GstElement * element, GstPad * pad) -{ - GstMPEGParse *mpeg_parse; - GstEvent *event; - - if (GST_PAD_IS_SINK (pad)) { - return; - } - - mpeg_parse = GST_MPEG_PARSE (element); - - /* For each new added pad, send a newsegment event so it knows about - * the current time. This is required because MPEG allows any sort - * of order of packets, and new substreams can be found at any - * time. */ - event = gst_event_new_new_segment (FALSE, - mpeg_parse->current_segment.rate, - GST_FORMAT_TIME, mpeg_parse->current_segment.start, - mpeg_parse->current_segment.stop, mpeg_parse->current_segment.start); - - gst_pad_push_event (pad, event); -} - -static gboolean -gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) -{ - guint8 *buf; - guint64 prev_scr, scr, diff; - guint32 scr1, scr2; - guint32 new_rate; - guint64 offset; - - buf = GST_BUFFER_DATA (buffer); - buf += 4; - - scr1 = GST_READ_UINT32_BE (buf); - scr2 = GST_READ_UINT32_BE (buf + 4); - - /* Extract the SCR and rate values from the header. */ - if (GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize)) { - guint32 scr_ext; - - /* :2=01 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 */ - scr = ((guint64) scr1 & 0x38000000) << 3; - scr |= ((guint64) scr1 & 0x03fff800) << 4; - scr |= ((guint64) scr1 & 0x000003ff) << 5; - scr |= ((guint64) scr2 & 0xf8000000) >> 27; - - scr_ext = (scr2 & 0x03fe0000) >> 17; - - scr = (scr * 300 + scr_ext % 300) / 300; - - GST_LOG_OBJECT (mpeg_parse, "%" G_GINT64_FORMAT " %d, %08x %08x %" - G_GINT64_FORMAT " diff: %" G_GINT64_FORMAT, - scr, scr_ext, scr1, scr2, mpeg_parse->bytes_since_scr, - scr - mpeg_parse->current_scr); - - buf += 6; - new_rate = (GST_READ_UINT32_BE (buf) & 0xfffffc00) >> 10; - } else { - scr = ((guint64) scr1 & 0x0e000000) << 5; - scr |= ((guint64) scr1 & 0x00fffe00) << 6; - scr |= ((guint64) scr1 & 0x000000ff) << 7; - scr |= ((guint64) scr2 & 0xfe000000) >> 25; - - buf += 5; - /* we do this byte by byte because buf[3] might be outside of buf's - * memory space */ - new_rate = ((gint32) buf[0] & 0x7f) << 15; - new_rate |= ((gint32) buf[1]) << 7; - new_rate |= buf[2] >> 1; - } - new_rate *= MP_MUX_RATE_MULT; - - /* Deal with SCR overflow */ - if (mpeg_parse->current_scr != MP_INVALID_SCR) { - guint32 diff; - - diff = scr - mpeg_parse->current_scr; - if (diff < 4 * CLOCK_FREQ) - scr = mpeg_parse->current_scr + diff; - } - - - prev_scr = mpeg_parse->current_scr; - mpeg_parse->current_scr = scr; - - if (mpeg_parse->do_adjust && mpeg_parse->pending_newsegment) { - /* Open a new segment. */ - gst_segment_set_newsegment (&mpeg_parse->current_segment, - FALSE, 1.0, GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (scr), -1, - MPEGTIME_TO_GSTTIME (scr)); - CLASS (mpeg_parse)->send_event (mpeg_parse, - gst_event_new_new_segment (FALSE, mpeg_parse->current_segment.rate, - GST_FORMAT_TIME, mpeg_parse->current_segment.start, -1, - mpeg_parse->current_segment.time)); - - mpeg_parse->pending_newsegment = FALSE; - - /* The first SCR seen should not lead to timestamp adjustment. */ - mpeg_parse->next_scr = scr; - } - - if (mpeg_parse->next_scr == MP_INVALID_SCR) { - mpeg_parse->next_scr = mpeg_parse->current_scr; - } - - /* Update the first SCR. */ - if ((mpeg_parse->first_scr == MP_INVALID_SCR) || - (mpeg_parse->current_scr < mpeg_parse->first_scr)) { - mpeg_parse->first_scr = mpeg_parse->current_scr; - mpeg_parse->first_scr_pos = gst_mpeg_packetize_tell (mpeg_parse->packetize); - } - - /* Update the last SCR. */ - if ((mpeg_parse->last_scr == MP_INVALID_SCR) || - (mpeg_parse->current_scr > mpeg_parse->last_scr)) { - mpeg_parse->last_scr = mpeg_parse->current_scr; - mpeg_parse->last_scr_pos = gst_mpeg_packetize_tell (mpeg_parse->packetize); - } - - GST_LOG_OBJECT (mpeg_parse, - "SCR is %" G_GUINT64_FORMAT - " (%" G_GUINT64_FORMAT ") next: %" - G_GINT64_FORMAT " (%" G_GINT64_FORMAT - ") diff: %" G_GINT64_FORMAT " (%" - G_GINT64_FORMAT ")", - mpeg_parse->current_scr, - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr), - mpeg_parse->next_scr, - MPEGTIME_TO_GSTTIME (mpeg_parse->next_scr), - mpeg_parse->current_scr - mpeg_parse->next_scr, - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr) - - MPEGTIME_TO_GSTTIME (mpeg_parse->next_scr)); - - /* Watch out for integer overflows... */ - if (mpeg_parse->next_scr > scr) { - diff = mpeg_parse->next_scr - scr; - } else { - diff = scr - mpeg_parse->next_scr; - } - - if (mpeg_parse->do_adjust && diff > mpeg_parse->max_scr_gap) { - /* SCR gap found, fix the adjust value. */ - GST_DEBUG_OBJECT (mpeg_parse, "SCR gap detected; expected: %" - G_GUINT64_FORMAT " got: %" G_GUINT64_FORMAT, - mpeg_parse->next_scr, mpeg_parse->current_scr); - - mpeg_parse->adjust += - (gint64) mpeg_parse->next_scr - (gint64) mpeg_parse->current_scr; - GST_DEBUG_OBJECT (mpeg_parse, "new adjust: %" G_GINT64_FORMAT, - mpeg_parse->adjust); - } - - /* Update the current timestamp. */ - mpeg_parse->current_ts = CLASS (mpeg_parse)->adjust_ts (mpeg_parse, - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr)); - - /* Check for the reached offset signal. */ - offset = gst_mpeg_packetize_tell (mpeg_parse->packetize); - if (offset > mpeg_parse->byte_offset) { - /* we have reached the wanted offset so emit the signal. */ - g_signal_emit (G_OBJECT (mpeg_parse), - gst_mpeg_parse_signals[SIGNAL_REACHED_OFFSET], 0); - } - - /* Update index if any. */ - if (mpeg_parse->index && GST_INDEX_IS_WRITABLE (mpeg_parse->index)) { - gst_index_add_association (mpeg_parse->index, mpeg_parse->index_id, - GST_ASSOCIATION_FLAG_KEY_UNIT, - GST_FORMAT_BYTES, GST_BUFFER_OFFSET (buffer), - GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr), 0); - } - - /* Update the calculated average bitrate. */ - if ((mpeg_parse->current_scr > prev_scr) && (diff < mpeg_parse->max_scr_gap)) { - mpeg_parse->avg_bitrate_time += - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr - prev_scr); - mpeg_parse->avg_bitrate_bytes += mpeg_parse->bytes_since_scr; - } - - /* Update the bitrate. */ - if (mpeg_parse->mux_rate != new_rate) { - if (GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize)) { - mpeg_parse->mux_rate = new_rate; - } else if (mpeg_parse->avg_bitrate_bytes > MP_MIN_VALID_BSS) { - mpeg_parse->mux_rate = - GST_SECOND * mpeg_parse->avg_bitrate_bytes / - mpeg_parse->avg_bitrate_time; - } - //gst_mpeg_parse_update_streaminfo (mpeg_parse); - GST_LOG_OBJECT (mpeg_parse, - "stream current is %1.3fMbs, calculated over %1.3fkB", - (mpeg_parse->mux_rate * 8) / 1048576.0, - gst_guint64_to_gdouble (mpeg_parse->bytes_since_scr) / 1024.0); - } - - if (mpeg_parse->avg_bitrate_bytes) { - GST_LOG_OBJECT (mpeg_parse, - "stream avg is %1.3fMbs, calculated over %1.3fkB", - gst_guint64_to_gdouble (mpeg_parse->avg_bitrate_bytes) * 8 * GST_SECOND - / gst_guint64_to_gdouble (mpeg_parse->avg_bitrate_time) / 1048576.0, - gst_guint64_to_gdouble (mpeg_parse->avg_bitrate_bytes) / 1024.0); - } - - /* Range-check the calculated average bitrate. */ - if (mpeg_parse->avg_bitrate_bytes > MP_MAX_VALID_BSS) { - mpeg_parse->avg_bitrate_bytes = 0; - mpeg_parse->avg_bitrate_time = 0; - } - mpeg_parse->bytes_since_scr = 0; - - return TRUE; -} - -static gboolean -gst_mpeg_parse_event (GstPad * pad, GstEvent * event) -{ - gboolean ret; - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad)); - - ret = CLASS (mpeg_parse)->process_event (mpeg_parse, event); - - gst_object_unref (mpeg_parse); - return ret; -} - -static GstFlowReturn -gst_mpeg_parse_chain (GstPad * pad, GstBuffer * buffer) -{ - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (GST_PAD_PARENT (pad)); - GstFlowReturn result; - guint id; - gboolean mpeg2; - GstClockTime time; - guint64 size; - - if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { - GST_DEBUG_OBJECT (mpeg_parse, "buffer with DISCONT flag set"); - gst_mpeg_packetize_flush_cache (mpeg_parse->packetize); - } - - gst_mpeg_packetize_put (mpeg_parse->packetize, buffer); - buffer = NULL; - - do { - result = gst_mpeg_packetize_read (mpeg_parse->packetize, &buffer); - if (result == GST_FLOW_RESEND) { - /* there was not enough data in packetizer cache */ - result = GST_FLOW_OK; - break; - } - if (result != GST_FLOW_OK) - break; - - id = GST_MPEG_PACKETIZE_ID (mpeg_parse->packetize); - mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize); - - GST_LOG_OBJECT (mpeg_parse, "have chunk 0x%02X", id); - - switch (id) { - case ISO11172_END_START_CODE: - break; - case PACK_START_CODE: - if (CLASS (mpeg_parse)->parse_packhead) { - CLASS (mpeg_parse)->parse_packhead (mpeg_parse, buffer); - } - break; - case SYS_HEADER_START_CODE: - if (CLASS (mpeg_parse)->parse_syshead) { - CLASS (mpeg_parse)->parse_syshead (mpeg_parse, buffer); - } - break; - default: - if (mpeg2 && ((id < 0xBD) || (id > 0xFE))) { - GST_ELEMENT_WARNING (GST_ELEMENT (mpeg_parse), - STREAM, DEMUX, (NULL), ("Unknown stream id 0x%02X", id)); - } else { - if (mpeg2) { - if (CLASS (mpeg_parse)->parse_pes) { - result = CLASS (mpeg_parse)->parse_pes (mpeg_parse, buffer); - } - } else { - if (CLASS (mpeg_parse)->parse_packet) { - result = CLASS (mpeg_parse)->parse_packet (mpeg_parse, buffer); - } - } - } - } - - /* Don't send data as long as no new SCR is found. */ - if (mpeg_parse->current_scr == MP_INVALID_SCR) { - GST_DEBUG_OBJECT (mpeg_parse, "waiting for SCR"); - gst_buffer_unref (buffer); - result = GST_FLOW_OK; - break; - } - - /* Update the byte count. */ - size = GST_BUFFER_SIZE (buffer); - mpeg_parse->bytes_since_scr += size; - - /* Make sure the output pad has proper capabilities. */ - if (!GST_PAD_CAPS (mpeg_parse->sinkpad)) { - gboolean mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize); - GstCaps *caps = gst_caps_new_simple ("video/mpeg", - "mpegversion", G_TYPE_INT, (mpeg2 ? 2 : 1), - "systemstream", G_TYPE_BOOLEAN, TRUE, - "parsed", G_TYPE_BOOLEAN, TRUE, NULL); - if (!gst_pad_set_caps (mpeg_parse->sinkpad, caps) < 0) { - GST_ELEMENT_ERROR (mpeg_parse, CORE, NEGOTIATION, (NULL), (NULL)); - gst_buffer_unref (buffer); - result = GST_FLOW_ERROR; - gst_caps_unref (caps); - break; - } - gst_caps_unref (caps); - } - - /* Send the buffer. */ - g_return_val_if_fail (mpeg_parse->current_scr != MP_INVALID_SCR, - GST_FLOW_OK); - time = CLASS (mpeg_parse)->adjust_ts (mpeg_parse, - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr)); - - if (CLASS (mpeg_parse)->send_buffer) - result = CLASS (mpeg_parse)->send_buffer (mpeg_parse, buffer, time); - else - gst_buffer_unref (buffer); - - buffer = NULL; - - /* Calculate the expected next SCR. */ - if (mpeg_parse->current_scr != MP_INVALID_SCR) { - guint64 scr, bss, br; - - scr = mpeg_parse->current_scr; - bss = mpeg_parse->bytes_since_scr; - if (mpeg_parse->scr_rate != 0) - br = mpeg_parse->scr_rate; - else - br = mpeg_parse->mux_rate; - - if (br) { - if (GST_MPEG_PACKETIZE_IS_MPEG2 (mpeg_parse->packetize)) { - /* - * The mpeg spec says something like this, but that doesn't - * really work: - * - * mpeg_parse->next_scr = (scr * br + bss * CLOCK_FREQ) / (CLOCK_FREQ + br); - */ - - mpeg_parse->next_scr = scr + (bss * CLOCK_FREQ) / br; - } else { - /* we are interpolating the scr here */ - mpeg_parse->next_scr = scr + (bss * CLOCK_FREQ) / br; - } - } else { - /* no bitrate known */ - mpeg_parse->next_scr = scr; - } - - GST_LOG_OBJECT (mpeg_parse, "size: %" G_GINT64_FORMAT - ", total since SCR: %" G_GINT64_FORMAT ", br: %" G_GINT64_FORMAT - ", next SCR: %" G_GINT64_FORMAT, size, bss, br, mpeg_parse->next_scr); - } - } while (result == GST_FLOW_OK); - - if (result != GST_FLOW_OK) { - GST_DEBUG_OBJECT (mpeg_parse, "flow: %s", gst_flow_get_name (result)); - } - - return result; -} - -const GstFormat * -gst_mpeg_parse_get_src_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - GST_FORMAT_TIME, - 0 - }; - - return formats; -} - -/* - * Return the bitrate to the nearest byte/sec - */ -static gboolean -gst_mpeg_parse_get_rate (GstMPEGParse * mpeg_parse, gint64 * rate) -{ - GstFormat time_format = GST_FORMAT_TIME; - GstFormat bytes_format = GST_FORMAT_BYTES; - gint64 total_time = 0; - gint64 total_bytes = 0; - - /* If upstream knows the total time and the total bytes, - * use those to compute an average byterate - */ - if (gst_pad_query_duration (GST_PAD_PEER (mpeg_parse->sinkpad), - &time_format, &total_time) - && - gst_pad_query_duration (GST_PAD_PEER (mpeg_parse->sinkpad), - &bytes_format, &total_bytes) - && total_time != 0 && total_bytes != 0) { - /* Use the funny calculation to avoid overflow of 64 bits */ - *rate = ((total_bytes * GST_USECOND) / total_time) * - (GST_SECOND / GST_USECOND); - - if (*rate > 0) { - return TRUE; - } - } - - *rate = 0; - - if ((mpeg_parse->first_scr != MP_INVALID_SCR) && - (mpeg_parse->last_scr != MP_INVALID_SCR) && - (mpeg_parse->last_scr_pos - mpeg_parse->first_scr_pos > MP_MIN_VALID_BSS) - && (mpeg_parse->last_scr != mpeg_parse->first_scr)) { - *rate = - GST_SECOND * (mpeg_parse->last_scr_pos - - mpeg_parse->first_scr_pos) / MPEGTIME_TO_GSTTIME (mpeg_parse->last_scr - - mpeg_parse->first_scr); - } - - if (*rate == 0 && mpeg_parse->avg_bitrate_time != 0 - && mpeg_parse->avg_bitrate_bytes > MP_MIN_VALID_BSS) { - *rate = - GST_SECOND * mpeg_parse->avg_bitrate_bytes / - mpeg_parse->avg_bitrate_time; - } - - if (*rate != 0) { - /* - * check if we need to update scr_rate - */ - if ((mpeg_parse->scr_rate == 0) || - ((gst_guint64_to_gdouble (ABS (mpeg_parse->scr_rate - - *rate)) / gst_guint64_to_gdouble (mpeg_parse->scr_rate)) - >= MP_SCR_RATE_HYST)) { - mpeg_parse->scr_rate = *rate; - return TRUE; - } - } - - if (mpeg_parse->scr_rate != 0) { - *rate = mpeg_parse->scr_rate; - return TRUE; - } - - if (mpeg_parse->mux_rate != 0) { - *rate = mpeg_parse->mux_rate; - return TRUE; - } - - return FALSE; -} - -static gboolean -gst_mpeg_parse_convert (GstMPEGParse * mpeg_parse, GstFormat src_format, - gint64 src_value, GstFormat * dest_format, gint64 * dest_value) -{ - gboolean res = TRUE; - gint64 rate; - - if (src_format == *dest_format) { - *dest_value = src_value; - return TRUE; - } - - switch (src_format) { - case GST_FORMAT_BYTES: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - *dest_format = GST_FORMAT_TIME; - case GST_FORMAT_TIME: - if (!gst_mpeg_parse_get_rate (mpeg_parse, &rate)) { - res = FALSE; - } else { - *dest_value = GST_SECOND * src_value / rate; - } - break; - default: - res = FALSE; - break; - } - break; - case GST_FORMAT_TIME: - switch (*dest_format) { - case GST_FORMAT_DEFAULT: - *dest_format = GST_FORMAT_BYTES; - case GST_FORMAT_BYTES: - if (!gst_mpeg_parse_get_rate (mpeg_parse, &rate)) { - res = FALSE; - } else { - *dest_value = src_value * rate / GST_SECOND; - } - break; - case GST_FORMAT_TIME: - break; - default: - res = FALSE; - break; - } - break; - default: - res = FALSE; - break; - } - - return res; -} - -const GstQueryType * -gst_mpeg_parse_get_src_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_DURATION, - GST_QUERY_POSITION, - GST_QUERY_CONVERT, - 0 - }; - - return types; -} - -gboolean -gst_mpeg_parse_handle_src_query (GstPad * pad, GstQuery * query) -{ - gboolean res = TRUE; - GstMPEGParse *mpeg_parse; - GstFormat src_format = GST_FORMAT_UNDEFINED, format; - gint64 src_value = 0, value = -1; - - mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_DURATION:{ - gst_query_parse_duration (query, &format, NULL); - - switch (format) { - case GST_FORMAT_DEFAULT: - format = GST_FORMAT_TIME; - /* fallthrough */ - case GST_FORMAT_TIME: - /* Try asking upstream if it knows the time - a DVD might - know */ - src_format = GST_FORMAT_TIME; - if (gst_pad_query_peer_duration (mpeg_parse->sinkpad, - &src_format, &src_value)) { - break; - } - /* Otherwise fallthrough */ - default: - src_format = GST_FORMAT_BYTES; - if (!gst_pad_query_peer_duration (mpeg_parse->sinkpad, - &src_format, &src_value)) { - res = FALSE; - goto done; - } - break; - } - - /* Convert the value to the desired format. */ - if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value, - &format, &value)) || - (res = gst_pad_query_peer_duration (mpeg_parse->sinkpad, - &format, &value))) { - gst_query_set_duration (query, format, value); - } - break; - } - case GST_QUERY_POSITION:{ - gint64 cur; - - gst_query_parse_position (query, &format, NULL); - - switch (format) { - case GST_FORMAT_DEFAULT: - format = GST_FORMAT_TIME; - /* Fallthrough. */ - default: - src_format = GST_FORMAT_TIME; - if ((mpeg_parse->current_scr == MP_INVALID_SCR) || - (mpeg_parse->first_scr == MP_INVALID_SCR)) { - res = FALSE; - goto done; - } - - cur = (gint64) (mpeg_parse->current_scr) - mpeg_parse->first_scr; - src_value = MPEGTIME_TO_GSTTIME (MAX (0, cur)); - break; - } - - /* Convert the value to the desired format. */ - if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value, - &format, &value)) || - (res = gst_pad_query_peer_position (mpeg_parse->sinkpad, - &format, &value))) { - gst_query_set_position (query, format, value); - } - break; - } - case GST_QUERY_CONVERT:{ - gst_query_parse_convert (query, &src_format, &src_value, &format, NULL); - - if ((res = gst_mpeg_parse_convert (mpeg_parse, src_format, src_value, - &format, &value)) || - (res = gst_pad_query_peer_convert (mpeg_parse->sinkpad, - src_format, src_value, &format, &value))) { - gst_query_set_convert (query, src_format, src_value, format, value); - } - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - -done: - gst_object_unref (mpeg_parse); - return res; -} - -#ifdef FIXME -static gboolean -index_seek (GstPad * pad, GstEvent * event, gint64 * offset, gint64 * scr) -{ - GstIndexEntry *entry; - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad)); - - entry = gst_index_get_assoc_entry (mpeg_parse->index, mpeg_parse->index_id, - GST_INDEX_LOOKUP_BEFORE, 0, - GST_EVENT_SEEK_FORMAT (event), GST_EVENT_SEEK_OFFSET (event)); - if (!entry) - return FALSE; - - if (gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, offset)) { - gint64 time; - - if (gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time)) { - *scr = GSTTIME_TO_MPEGTIME (time); - } - GST_CAT_DEBUG (GST_CAT_SEEK, "%s:%s index %s %" G_GINT64_FORMAT - " -> %" G_GINT64_FORMAT " bytes, scr=%" G_GINT64_FORMAT, - GST_DEBUG_PAD_NAME (pad), - gst_format_get_details (GST_EVENT_SEEK_FORMAT (event))->nick, - GST_EVENT_SEEK_OFFSET (event), *offset, *scr); - return TRUE; - } - - return FALSE; -} -#endif - -static GstEvent * -normal_seek (GstMPEGParse * mpeg_parse, GstPad * pad, GstEvent * event) -{ - GstEvent *upstream = NULL; - gint64 offset; - GstFormat format, conv; - gint64 cur, stop; - gdouble rate; - GstSeekType cur_type, stop_type; - GstSeekFlags flags; - gint64 start_position, end_position; - - gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, - &cur, &stop_type, &stop); - - offset = cur; - if (offset != -1) { - GST_LOG_OBJECT (mpeg_parse, "starting conversion of cur"); - /* Bring the format to time on srcpad. */ - conv = GST_FORMAT_TIME; - if (!gst_pad_query_convert (pad, format, offset, &conv, &start_position)) { - goto done; - } - /* And convert to bytes on sinkpad. */ - conv = GST_FORMAT_BYTES; - if (!gst_pad_query_convert (mpeg_parse->sinkpad, GST_FORMAT_TIME, - start_position, &conv, &start_position)) { - goto done; - } - GST_INFO_OBJECT (mpeg_parse, - "Finished conversion of cur, BYTES cur : %" G_GINT64_FORMAT, - start_position); - } else { - start_position = -1; - } - - offset = stop; - if (offset != -1) { - GST_INFO_OBJECT (mpeg_parse, "starting conversion of stop"); - /* Bring the format to time on srcpad. */ - conv = GST_FORMAT_TIME; - if (!gst_pad_query_convert (pad, format, offset, &conv, &end_position)) { - goto done; - } - /* And convert to bytes on sinkpad. */ - conv = GST_FORMAT_BYTES; - if (!gst_pad_query_convert (mpeg_parse->sinkpad, GST_FORMAT_TIME, - end_position, &conv, &end_position)) { - goto done; - } - GST_INFO_OBJECT (mpeg_parse, - "Finished conversion of stop, BYTES stop : %" G_GINT64_FORMAT, - end_position); - } else { - end_position = -1; - } - - upstream = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, - cur_type, start_position, stop_type, end_position); - -done: - return upstream; -} - -gboolean -gst_mpeg_parse_handle_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - GstEvent *upstream = NULL; - - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad)); - - GST_LOG_OBJECT (mpeg_parse, "got %s event", GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { -#ifdef FIXME - /* First try to use the index if we have one. */ - if (mpeg_parse->index) { - res = index_seek (pad, event, &desired_offset, &expected_scr); - } -#endif - - if (upstream == NULL) { - /* Nothing found, try fuzzy seek. */ - upstream = normal_seek (mpeg_parse, pad, event); - } - - if (!upstream) { - gst_event_unref (event); - res = FALSE; - goto done; - } - - res = gst_pad_event_default (pad, upstream); - break; - } - case GST_EVENT_NAVIGATION: - /* Forward navigation events unchanged. */ - res = gst_pad_push_event (mpeg_parse->sinkpad, event); - break; - default: - res = gst_pad_event_default (pad, event); - break; - } - -done: - gst_object_unref (mpeg_parse); - - return res; -} - -static GstStateChangeReturn -gst_mpeg_parse_change_state (GstElement * element, GstStateChange transition) -{ - GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (element); - GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - if (!mpeg_parse->packetize) { - mpeg_parse->packetize = - gst_mpeg_packetize_new (GST_MPEG_PACKETIZE_SYSTEM); - } - - /* Initialize parser state */ - gst_mpeg_parse_reset (mpeg_parse); - break; - default: - break; - } - - result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (mpeg_parse->packetize) { - gst_mpeg_packetize_destroy (mpeg_parse->packetize); - mpeg_parse->packetize = NULL; - } - //gst_caps_replace (&mpeg_parse->streaminfo, NULL); - break; - default: - break; - } - - return result; -} - -static void -gst_mpeg_parse_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstMPEGParse *mpeg_parse; - - mpeg_parse = GST_MPEG_PARSE (object); - - switch (prop_id) { - case ARG_MAX_SCR_GAP: - g_value_set_int (value, mpeg_parse->max_scr_gap); - break; - case ARG_BYTE_OFFSET: - g_value_set_uint64 (value, mpeg_parse->byte_offset); - break; - case ARG_TIME_OFFSET: - g_value_set_uint64 (value, mpeg_parse->current_ts); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_mpeg_parse_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstMPEGParse *mpeg_parse; - - mpeg_parse = GST_MPEG_PARSE (object); - - switch (prop_id) { - case ARG_MAX_SCR_GAP: - mpeg_parse->max_scr_gap = g_value_get_int (value); - break; - case ARG_BYTE_OFFSET: - mpeg_parse->byte_offset = g_value_get_uint64 (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_mpeg_parse_set_index (GstElement * element, GstIndex * index) -{ - GstMPEGParse *mpeg_parse; - - mpeg_parse = GST_MPEG_PARSE (element); - - mpeg_parse->index = index; - - gst_index_get_writer_id (index, GST_OBJECT (mpeg_parse->sinkpad), - &mpeg_parse->index_id); - gst_index_add_format (index, mpeg_parse->index_id, scr_format); -} - -static GstIndex * -gst_mpeg_parse_get_index (GstElement * element) -{ - GstMPEGParse *mpeg_parse; - - mpeg_parse = GST_MPEG_PARSE (element); - - return mpeg_parse->index; -} - -gboolean -gst_mpeg_parse_plugin_init (GstPlugin * plugin) -{ - scr_format = - gst_format_register ("scr", "The MPEG system clock reference time"); - - return gst_element_register (plugin, "mpegparse", - GST_RANK_NONE, GST_TYPE_MPEG_PARSE); -} diff --git a/gst/mpegstream/gstmpegparse.h b/gst/mpegstream/gstmpegparse.h deleted file mode 100644 index cfeaa2bcff..0000000000 --- a/gst/mpegstream/gstmpegparse.h +++ /dev/null @@ -1,142 +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 __MPEG_PARSE_H__ -#define __MPEG_PARSE_H__ - -#include -#include "gstmpegpacketize.h" - -G_BEGIN_DECLS - -#define GST_TYPE_MPEG_PARSE \ - (gst_mpeg_parse_get_type()) -#define GST_MPEG_PARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEG_PARSE,GstMPEGParse)) -#define GST_MPEG_PARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEG_PARSE,GstMPEGParseClass)) -#define GST_IS_MPEG_PARSE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEG_PARSE)) -#define GST_IS_MPEG_PARSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEG_PARSE)) - -#define GST_MPEG_PARSE_IS_MPEG2(parse) (GST_MPEG_PACKETIZE_IS_MPEG2 (GST_MPEG_PARSE (parse)->packetize)) - -#define CLOCK_BASE G_GINT64_CONSTANT (9) -#define CLOCK_FREQ CLOCK_BASE * 10000 - -#define MPEGTIME_TO_GSTTIME(time) (((time) * (GST_MSECOND/10)) / CLOCK_BASE) -#define GSTTIME_TO_MPEGTIME(time) (((time) * CLOCK_BASE) / (GST_MSECOND/10)) - -typedef struct _GstMPEGParse GstMPEGParse; -typedef struct _GstMPEGParseClass GstMPEGParseClass; - -struct _GstMPEGParse -{ - GstElement element; - - GstPad *sinkpad, *srcpad; - - GstMPEGPacketize *packetize; - - /* Keep track of total rate using SCR and use hysteresis */ - guint64 first_scr; /* Earliest SCR value for reference */ - guint64 first_scr_pos; /* Byte position of reference SCR */ - guint64 last_scr; /* Latest SCR value for reference */ - guint64 last_scr_pos; /* Byte position of reference SCR */ - guint64 scr_rate; /* Remember the last rate for hysteresis */ - - /* Compute a rolling average for SCR interpolation (for MPEG1) */ - guint64 avg_bitrate_time; /* Time total for local average bitrate */ - guint64 avg_bitrate_bytes; /* Bytes total for local average bitrate */ - - /* Pack header values */ - guint32 mux_rate; /* Mux rate in bytes/sec derived from Pack - header */ - guint64 current_scr; /* Current SCR from the stream */ - guint64 next_scr; /* Expected next SCR */ - guint64 bytes_since_scr; /* Bytes since current_scr */ - - GstClockTime current_ts; /* Current timestamp (i.e., SCR - adjusted with the value of - 'adjust') */ - - /* Timestamp handling. */ - gboolean do_adjust; /* If true, adjust SCR values using - the 'adjust' attribute. */ - gint64 adjust; /* Value added to SCR values to - produce buffer timestamps */ - gboolean pending_newsegment; /* The element should send a - newsegment event as soon as it sees - the next SCR. This option is only - meaningful in do_adjust mode. */ - gint max_scr_gap; /* The maximum allowed SCR gap without - making a timestamp adjustment */ - GstSegment current_segment; /* Segment currently being played. */ - - GstIndex *index; - gint index_id; - - guint64 byte_offset; -}; - -struct _GstMPEGParseClass -{ - GstElementClass parent_class; - - /* Process packets of different types */ - gboolean (*parse_packhead) (GstMPEGParse * parse, GstBuffer * buffer); - gboolean (*parse_syshead) (GstMPEGParse * parse, GstBuffer * buffer); - GstFlowReturn (*parse_packet) (GstMPEGParse * parse, GstBuffer * buffer); - GstFlowReturn (*parse_pes) (GstMPEGParse * parse, GstBuffer * buffer); - - /* Optional method to send out the data */ - GstFlowReturn (*send_buffer) (GstMPEGParse * parse, - GstBuffer * buffer, GstClockTime time); - - /* Process an event */ - gboolean (*process_event) (GstMPEGParse * parse, - GstEvent * event); - - /* Send an event */ - gboolean (*send_event) (GstMPEGParse * parse, GstEvent *event); - - /* Adjust a timestamp */ - GstClockTime (*adjust_ts) (GstMPEGParse * parse, GstClockTime ts); - - /* Signals */ - void (*reached_offset) (GstMPEGParse *parse, - GstClockTime timeval); -}; - -GType gst_mpeg_parse_get_type (void); - -gboolean gst_mpeg_parse_plugin_init (GstPlugin * plugin); - -const GstFormat *gst_mpeg_parse_get_src_formats (GstPad * pad); - -gboolean gst_mpeg_parse_handle_src_event (GstPad * pad, GstEvent * event); - -const GstQueryType *gst_mpeg_parse_get_src_query_types (GstPad * pad); -gboolean gst_mpeg_parse_handle_src_query (GstPad * pad, GstQuery * query); - -G_END_DECLS - -#endif /* __MPEG_PARSE_H__ */ diff --git a/gst/mpegstream/gstmpegstream.c b/gst/mpegstream/gstmpegstream.c deleted file mode 100644 index 19a938ecde..0000000000 --- a/gst/mpegstream/gstmpegstream.c +++ /dev/null @@ -1,48 +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. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "gstmpegparse.h" -#include "gstmpegdemux.h" -#include "gstdvddemux.h" -#include "gstrfc2250enc.h" - -static gboolean -plugin_init (GstPlugin * plugin) -{ - /* short-circuit here; this is potentially dangerous since if the second - * or third init fails then the whole plug-in will be placed on the register - * stack again and the first _init will be called more than once - * and wtay wants to use dlclose at some point in the future */ - - if (!gst_mpeg_parse_plugin_init (plugin) || !gst_mpeg_demux_plugin_init (plugin) || !gst_dvd_demux_plugin_init (plugin) /*|| - !gst_rfc2250_enc_plugin_init (plugin) */ ) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "mpegstream", - "MPEG system stream parser", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/gst/mpegstream/gstrfc2250enc.c b/gst/mpegstream/gstrfc2250enc.c deleted file mode 100644 index e5fcb78dd0..0000000000 --- a/gst/mpegstream/gstrfc2250enc.c +++ /dev/null @@ -1,352 +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. - */ - - -/*#define GST_DEBUG_ENABLED*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "gstrfc2250enc.h" - -#define CLASS(o) GST_RFC2250_ENC_CLASS (G_OBJECT_GET_CLASS (o)) - -/* GstRFC2250Enc signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_BIT_RATE, - ARG_MPEG2 - /* FILL ME */ -}; - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) FALSE") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, " - "mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) FALSE") - ); - -static void gst_rfc2250_enc_class_init (GstRFC2250EncClass * klass); -static void gst_rfc2250_enc_base_init (GstRFC2250EncClass * klass); -static void gst_rfc2250_enc_init (GstRFC2250Enc * rfc2250_enc); -static GstStateChangeReturn -gst_rfc2250_enc_change_state (GstElement * element, GstStateChange transition); - -static void gst_rfc2250_enc_loop (GstElement * element); - -static void gst_rfc2250_enc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstElementClass *parent_class = NULL; - -/*static guint gst_rfc2250_enc_signals[LAST_SIGNAL] = { 0 };*/ - -GType -gst_rfc2250_enc_get_type (void) -{ - static GType rfc2250_enc_type = 0; - - if (!rfc2250_enc_type) { - static const GTypeInfo rfc2250_enc_info = { - sizeof (GstRFC2250EncClass), - (GBaseInitFunc) gst_rfc2250_enc_base_init, - NULL, - (GClassInitFunc) gst_rfc2250_enc_class_init, - NULL, - NULL, - sizeof (GstRFC2250Enc), - 0, - (GInstanceInitFunc) gst_rfc2250_enc_init, - }; - - rfc2250_enc_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstRFC2250Enc", - &rfc2250_enc_info, 0); - } - return rfc2250_enc_type; -} - -static void -gst_rfc2250_enc_base_init (GstRFC2250EncClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details_simple (element_class, - "RFC 2250 packet encoder", "Codec/Parser", - "transforms MPEG1/2 video to an RFC 2250 compliant format", - "Wim Taymans "); -} - -static void -gst_rfc2250_enc_class_init (GstRFC2250EncClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BIT_RATE, - g_param_spec_uint ("bit_rate", "bit_rate", "bit_rate", - 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MPEG2, - g_param_spec_boolean ("mpeg2", "mpeg2", "is this an mpeg2 stream", - FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - gobject_class->get_property = gst_rfc2250_enc_get_property; - - gstelement_class->change_state = gst_rfc2250_enc_change_state; -} - -static void -gst_rfc2250_enc_init (GstRFC2250Enc * rfc2250_enc) -{ - rfc2250_enc->sinkpad = - gst_pad_new_from_static_template (&sink_factory, "sink"); - gst_element_add_pad (GST_ELEMENT (rfc2250_enc), rfc2250_enc->sinkpad); - gst_element_set_loop_function (GST_ELEMENT (rfc2250_enc), - gst_rfc2250_enc_loop); - rfc2250_enc->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); - gst_element_add_pad (GST_ELEMENT (rfc2250_enc), rfc2250_enc->srcpad); - - /* initialize parser state */ - rfc2250_enc->packetize = NULL; - rfc2250_enc->next_ts = 0; - rfc2250_enc->packet = 0; - - /* zero counters (should be done at RUNNING?) */ - rfc2250_enc->bit_rate = 0; - rfc2250_enc->MTU = 3048; -} - -static void -gst_rfc2250_enc_new_buffer (GstRFC2250Enc * enc) -{ - if (enc->packet) { - gst_pad_push (enc->srcpad, GST_DATA (enc->packet)); - } - enc->packet = gst_buffer_new (); - enc->flags = 0; - enc->remaining = enc->MTU; -} - -static void -gst_rfc2250_enc_add_slice (GstRFC2250Enc * enc, GstBuffer * buffer) -{ - gint slice_length = GST_BUFFER_SIZE (buffer); - - /* see if the slice fits in the current buffer */ - if (slice_length <= enc->remaining) { - GstBuffer *newbuf; - - newbuf = gst_buffer_merge (enc->packet, buffer); - gst_buffer_unref (buffer); - gst_buffer_unref (enc->packet); - enc->packet = newbuf; - enc->remaining -= slice_length; - } - /* it doesn't fit */ - else { - /* do we need to start a new packet? */ - if (slice_length <= enc->MTU) { - GstBuffer *newbuf; - - gst_rfc2250_enc_new_buffer (enc); - newbuf = gst_buffer_merge (enc->packet, buffer); - gst_buffer_unref (buffer); - gst_buffer_unref (enc->packet); - enc->packet = newbuf; - enc->remaining -= slice_length; - } - /* else we have to fragment */ - else { - gint offset = 0; - - while (slice_length > 0) { - GstBuffer *outbuf; - GstBuffer *newbuf; - - outbuf = - gst_buffer_create_sub (buffer, offset, MIN (enc->remaining, - slice_length)); - newbuf = gst_buffer_merge (enc->packet, outbuf); - slice_length -= GST_BUFFER_SIZE (outbuf); - offset += GST_BUFFER_SIZE (outbuf); - gst_buffer_unref (outbuf); - gst_buffer_unref (newbuf); - enc->packet = newbuf; - gst_rfc2250_enc_new_buffer (enc); - } - gst_buffer_unref (buffer); - } - } -} - -static void -gst_rfc2250_enc_loop (GstElement * element) -{ - GstRFC2250Enc *enc = GST_RFC2250_ENC (element); - GstData *data; - guint id; - gboolean mpeg2; - - data = gst_mpeg_packetize_read (enc->packetize); - - id = GST_MPEG_PACKETIZE_ID (enc->packetize); - mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (enc->packetize); - - if (GST_IS_BUFFER (data)) { - GstBuffer *buffer = GST_BUFFER (data); - - GST_DEBUG ("rfc2250enc: have chunk 0x%02X", id); - - switch (id) { - case SEQUENCE_START_CODE: - gst_rfc2250_enc_new_buffer (enc); - enc->flags |= ENC_HAVE_SEQ; - break; - case GOP_START_CODE: - if (enc->flags & ENC_HAVE_DATA) { - gst_rfc2250_enc_new_buffer (enc); - } - enc->flags |= ENC_HAVE_GOP; - break; - case PICTURE_START_CODE: - if (enc->flags & ENC_HAVE_DATA) { - gst_rfc2250_enc_new_buffer (enc); - } - enc->flags |= ENC_HAVE_PIC; - break; - case EXT_START_CODE: - case USER_START_CODE: - case SEQUENCE_ERROR_START_CODE: - case SEQUENCE_END_START_CODE: - break; - default: - /* do this here because of the long range */ - if (id >= SLICE_MIN_START_CODE && id <= SLICE_MAX_START_CODE) { - enc->flags |= ENC_HAVE_DATA; - gst_rfc2250_enc_add_slice (enc, buffer); - buffer = NULL; - break; - } - break; - - } - if (buffer) { - gst_buffer_merge (enc->packet, buffer); - enc->remaining -= GST_BUFFER_SIZE (buffer); - gst_buffer_unref (buffer); - } - } else { - if (enc->packet) { - gst_pad_push (enc->srcpad, GST_DATA (enc->packet)); - enc->packet = NULL; - enc->flags = 0; - enc->remaining = enc->MTU; - } - gst_pad_event_default (enc->sinkpad, GST_EVENT (data)); - } -} - -static GstStateChangeReturn -gst_rfc2250_enc_change_state (GstElement * element, GstStateChange transition) -{ - GstRFC2250Enc *rfc2250_enc = GST_RFC2250_ENC (element); - GstStateChangeReturn ret; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - if (!rfc2250_enc->packetize) { - rfc2250_enc->packetize = - gst_mpeg_packetize_new (rfc2250_enc->sinkpad, - GST_MPEG_PACKETIZE_VIDEO); - } - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - if (rfc2250_enc->packetize) { - gst_mpeg_packetize_destroy (rfc2250_enc->packetize); - rfc2250_enc->packetize = NULL; - } - break; - default: - break; - } - return ret; -} - -static void -gst_rfc2250_enc_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstRFC2250Enc *rfc2250_enc; - - /* it's not null if we got it, but it might not be ours */ - rfc2250_enc = GST_RFC2250_ENC (object); - - switch (prop_id) { - case ARG_BIT_RATE: - g_value_set_uint (value, rfc2250_enc->bit_rate); - break; - case ARG_MPEG2: - if (rfc2250_enc->packetize) - g_value_set_boolean (value, - GST_MPEG_PACKETIZE_IS_MPEG2 (rfc2250_enc->packetize)); - else - g_value_set_boolean (value, FALSE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -gboolean -gst_rfc2250_enc_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "rfc2250enc", - GST_RANK_NONE, GST_TYPE_RFC2250_ENC); -} diff --git a/gst/mpegstream/gstrfc2250enc.h b/gst/mpegstream/gstrfc2250enc.h deleted file mode 100644 index 3b97e2d059..0000000000 --- a/gst/mpegstream/gstrfc2250enc.h +++ /dev/null @@ -1,79 +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 __RFC2250_ENC_H__ -#define __RFC2250_ENC_H__ - - -#include -#include "gstmpegpacketize.h" - -G_BEGIN_DECLS - -#define GST_TYPE_RFC2250_ENC \ - (gst_rfc2250_enc_get_type()) -#define GST_RFC2250_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RFC2250_ENC,GstRFC2250Enc)) -#define GST_RFC2250_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RFC2250_ENC,GstRFC2250EncClass)) -#define GST_IS_RFC2250_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RFC2250_ENC)) -#define GST_IS_RFC2250_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RFC2250_ENC)) - -#define GST_RFC2250_ENC_IS_MPEG2(parse) (GST_MPEG_PACKETIZE_IS_MPEG2 (GST_RFC2250_ENC (parse)->packetize)) - -typedef enum { - ENC_HAVE_SEQ = (1 << 0), - ENC_HAVE_GOP = (1 << 1), - ENC_HAVE_PIC = (1 << 2), - ENC_HAVE_DATA = (1 << 3), -} GstEncFlags; - -typedef struct _GstRFC2250Enc GstRFC2250Enc; -typedef struct _GstRFC2250EncClass GstRFC2250EncClass; - -struct _GstRFC2250Enc { - GstElement element; - - GstPad *sinkpad, *srcpad; - - GstMPEGPacketize *packetize; - - /* pack header values */ - guint32 bit_rate; - guint64 next_ts; - GstBuffer *packet; - GstEncFlags flags; - gint MTU; - gint remaining; -}; - -struct _GstRFC2250EncClass { - GstElementClass parent_class; -}; - -GType gst_rfc2250_enc_get_type(void); - -gboolean gst_rfc2250_enc_plugin_init (GstPlugin *plugin); - -G_END_DECLS - -#endif /* __RFC2250_ENC_H__ */ diff --git a/gst/mpegstream/mpegstream.vcproj b/gst/mpegstream/mpegstream.vcproj deleted file mode 100644 index ca9c9d4a0d..0000000000 --- a/gst/mpegstream/mpegstream.vcproj +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gst/mpegstream/notes b/gst/mpegstream/notes deleted file mode 100644 index 8c275ffbc4..0000000000 --- a/gst/mpegstream/notes +++ /dev/null @@ -1,40 +0,0 @@ -Basic parsing method -==================== - -In an MPEG-2 Program Stream, every chunk of data starts with at least 23 -zeros and a one. This is followed by a byte of ID. At any given point I -can search for the next 3-byte string equal to 1 to find the next chunk. -I assume these start codes are aligned on byte boundaries. I might be -wrong, in which case this thing has to be rewritten at some point in the -future. - -This means there are two basic modes of operation. The first is the -simple search for the next start code. The second is a continuation mode, -where data from the previous buffer is available to attempt to complete a -chunk. Hopefully the majority of time will be spent in the first mode, as -that is where the most efficiency is, since there's no copying of partial -chunks. - -The parsing is done as a state machine, as long as there's data left in -the buffer, something is attempted. What is attempted is based on the -state of the parser (gee, so that's why they call it a state machine ). -The stages are: - -1) looking for sync (have_sync == FALSE) - a) have some zeros (zeros > 0) -2) getting ID (have_sync == TRUE, id == 0) -3) decoding the chunk contents (have_sync == TRUE, id != 0) - -Mechanism for handling cross-buffer chunks of data -================================================== - -The problem: if data were to come to the parser in 64-byte chunks, the -pack head would be split across at least two buffers, possibly three. Up -front I will make the assumption that no one will be sending buffers of -less size than the largest chunk (header, PES packet), such that no chunk -will be split across more than two buffers. - -If we take the pack header as an example, when the stream starts out, we -can assume that the it starts at the beginning of the buffer and doesn't -exceed the bounds of it. However, if we're mid-stream and starting -another pack, it can be split across two buffers. diff --git a/win32/MANIFEST b/win32/MANIFEST index 8e37b135d3..42c53a19a3 100644 --- a/win32/MANIFEST +++ b/win32/MANIFEST @@ -1,13 +1,10 @@ win32/MANIFEST win32/common/config.h win32/vs6/gst_plugins_ugly.dsw -win32/vs6/libgstac3parse.dsp win32/vs6/libgstasfdemux.dsp win32/vs6/libgstdvdlpcmdec.dsp win32/vs6/libgstdvdsub.dsp win32/vs6/libgstlame.dsp win32/vs6/libgstmad.dsp -win32/vs6/libgstmpegaudioparse.dsp -win32/vs6/libgstmpegstream.dsp win32/vs6/libgstrealmedia.dsp win32/vs6/libgstsynaesthesia.dsp diff --git a/win32/vs6/gst_plugins_ugly.dsw b/win32/vs6/gst_plugins_ugly.dsw index ee6e9cce78..32d2fd3a86 100644 --- a/win32/vs6/gst_plugins_ugly.dsw +++ b/win32/vs6/gst_plugins_ugly.dsw @@ -3,18 +3,6 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "libgstac3parse"=".\libgstac3parse.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Project: "libgstasfdemux"=".\libgstasfdemux.dsp" - Package Owner=<4> Package=<5> @@ -51,18 +39,6 @@ Package=<4> ############################################################################### -Project: "libgstiec958"=".\libgstiec958.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Project: "libgstlame"=".\libgstlame.dsp" - Package Owner=<4> Package=<5> @@ -87,30 +63,6 @@ Package=<4> ############################################################################### -Project: "libgstmpegaudioparse"=".\libgstmpegaudioparse.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "libgstmpegstream"=".\libgstmpegstream.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Project: "libgstrealmedia"=".\libgstrealmedia.dsp" - Package Owner=<4> Package=<5> diff --git a/win32/vs6/libgstac3parse.dsp b/win32/vs6/libgstac3parse.dsp deleted file mode 100644 index e89aa9325f..0000000000 --- a/win32/vs6/libgstac3parse.dsp +++ /dev/null @@ -1,123 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgstac3parse" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=libgstac3parse - 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 "libgstac3parse.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 "libgstac3parse.mak" CFG="libgstac3parse - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgstac3parse - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "libgstac3parse - 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)" == "libgstac3parse - 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 "LIBGSTAC3PARSE_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "./" /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTAC3PARSE_EXPORTS" /D "HAVE_CONFIG_H" /FD /c -# SUBTRACT CPP /YX -# 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 ibgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0.lib gobject-2.0.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"./release" /libpath:"../../../gst-plugins-base/win32/vs6/release" -# Begin Special Build Tool -TargetPath=.\Release\libgstac3parse.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\lib\gstreamer-0.10 -# End Special Build Tool - -!ELSEIF "$(CFG)" == "libgstac3parse - 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 "LIBGSTAC3PARSE_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTAC3PARSE_EXPORTS" /D "HAVE_CONFIG_H" /FD /GZ /c -# SUBTRACT CPP /YX -# 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 ibgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0D.lib gobject-2.0D.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"./debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" -# Begin Special Build Tool -TargetPath=.\Debug\libgstac3parse.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\debug\lib\gstreamer-0.10 -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "libgstac3parse - Win32 Release" -# Name "libgstac3parse - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\gst\ac3parse\gstac3parse.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\gst\ac3parse\gstac3parse.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 diff --git a/win32/vs6/libgstmpegaudioparse.dsp b/win32/vs6/libgstmpegaudioparse.dsp deleted file mode 100644 index eba8d4874b..0000000000 --- a/win32/vs6/libgstmpegaudioparse.dsp +++ /dev/null @@ -1,131 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgstmpegaudioparse" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=libgstmpegaudioparse - 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 "libgstmpegaudioparse.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 "libgstmpegaudioparse.mak" CFG="libgstmpegaudioparse - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgstmpegaudioparse - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "libgstmpegaudioparse - 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)" == "libgstmpegaudioparse - 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 "LIBGSTMPEGAUDIOPARSE_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "./" /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTMPEGAUDIOPARSE_EXPORTS" /D "HAVE_CONFIG_H" /FD /c -# SUBTRACT CPP /YX -# 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 libgstriff-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0.lib gobject-2.0.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"./release" /libpath:"../../../gst-plugins-base/win32/vs6/release" -# Begin Special Build Tool -TargetPath=.\Release\libgstmpegaudioparse.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\lib\gstreamer-0.10 -# End Special Build Tool - -!ELSEIF "$(CFG)" == "libgstmpegaudioparse - 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 "LIBGSTMPEGAUDIOPARSE_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTMPEGAUDIOPARSE_EXPORTS" /D "HAVE_CONFIG_H" /FD /GZ /c -# SUBTRACT CPP /YX -# 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 libgstriff-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0D.lib gobject-2.0D.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"./debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" -# Begin Special Build Tool -TargetPath=.\Debug\libgstmpegaudioparse.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\debug\lib\gstreamer-0.10 -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "libgstmpegaudioparse - Win32 Release" -# Name "libgstmpegaudioparse - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\gst\mpegaudioparse\gstmpegaudioparse.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegaudioparse\gstxingmux.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegaudioparse\plugin.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\gst\mpegaudioparse\gstmpegaudioparse.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 diff --git a/win32/vs6/libgstmpegstream.dsp b/win32/vs6/libgstmpegstream.dsp deleted file mode 100644 index 0633b6b74c..0000000000 --- a/win32/vs6/libgstmpegstream.dsp +++ /dev/null @@ -1,159 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgstmpegstream" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=libgstmpegstream - 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 "libgstmpegstream.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 "libgstmpegstream.mak" CFG="libgstmpegstream - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgstmpegstream - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "libgstmpegstream - 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)" == "libgstmpegstream - 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 "LIBGSTMPEGSTREAM_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "./" /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTMPEGSTREAM_EXPORTS" /D "HAVE_CONFIG_H" /FD /c -# SUBTRACT CPP /YX -# 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 libgstriff-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0.lib gobject-2.0.lib /nologo /dll /machine:I386 /libpath:"../../../gstreamer/win32/vs6/release" /libpath:"./release" /libpath:"../../../gst-plugins-base/win32/vs6/release" -# Begin Special Build Tool -TargetPath=.\Release\libgstmpegstream.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\lib\gstreamer-0.10 -# End Special Build Tool - -!ELSEIF "$(CFG)" == "libgstmpegstream - 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 "LIBGSTMPEGSTREAM_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../gst-libs" /I "../../../gstreamer" /I "../common" /I "../../../gstreamer/libs" /I "../../../gst-plugins-base/gst-libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGSTMPEGSTREAM_EXPORTS" /D "HAVE_CONFIG_H" /FD /GZ /c -# SUBTRACT CPP /YX -# 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 libgstriff-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0D.lib gobject-2.0D.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"./debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" -# Begin Special Build Tool -TargetPath=.\Debug\libgstmpegstream.dll -SOURCE="$(InputPath)" -PostBuild_Cmds=copy /Y $(TargetPath) c:\gstreamer\debug\lib\gstreamer-0.10 -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "libgstmpegstream - Win32 Release" -# Name "libgstmpegstream - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstdvddemux.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegclock.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegdemux.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegpacketize.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegparse.c -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegstream.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstdvddemux.h -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegclock.h -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegdemux.h -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegpacketize.h -# End Source File -# Begin Source File - -SOURCE=..\..\gst\mpegstream\gstmpegparse.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