From 4d652b147a52075b6a6ef611ce0d964d0d32db06 Mon Sep 17 00:00:00 2001 From: Martin Soto Date: Mon, 28 Nov 2005 19:13:51 +0000 Subject: [PATCH] gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event) Original commit message from CVS: 2005-11-28 Martin Soto * gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event) (gst_dvd_demux_handle_dvd_event): Erase code to prevent mpegparse from making timestamp adjustments. This will have to be re-added in some form in the near future, but in order to do that, some nav packet parsing will be necessary in mpegdemux. * gst/mpegstream/gstmpegparse.h (struct _GstMPEGParse): * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_init) (g_value_set_int, gst_mpeg_parse_set_property) Get rid of do_adjust and use_adjust. Rename max_discont to max_src_gap. (gst_mpeg_parse_parse_packhead): When max_scr_gap has a value of -1, no adjustment is made. * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_class_init): Rename max_discont property to max_scr_gap. Erase "adjust" property. * gst/mpegstream/gstdvddemux.c (gst_dvd_demux_send_event): Don't override send_event anymore, base class does the job. * gst/mpegstream/gstmpegdemux.c (gst_mpeg_demux_send_event): Base class now does most of the work. * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_send_event): Generalize to forwarding the event to all source pads in the element. * gst/mpegstream/gstmpegparse.h: * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_class_init) (gst_mpeg_parse_init, gst_mpeg_parse_set_clock) (gst_mpeg_parse_chain, gst_mpeg_parse_get_property) (gst_mpeg_parse_set_property): Clock synchronization doesn't make sense anymore for a demultiplexer. --- ChangeLog | 34 ++++++++ gst/mpegstream/gstdvddemux.c | 44 ---------- gst/mpegstream/gstmpegdemux.c | 28 ------ gst/mpegstream/gstmpegparse.c | 132 +++++++++++------------------ gst/mpegstream/gstmpegparse.h | 192 ++++++++++++++++++++---------------------- 5 files changed, 177 insertions(+), 253 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b086b1..55daa8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +2005-11-28 Martin Soto + + * gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event) + (gst_dvd_demux_handle_dvd_event): Erase code to prevent mpegparse + from making timestamp adjustments. This will have to be re-added + in some form in the near future, but in order to do that, some nav + packet parsing will be necessary in mpegdemux. + * gst/mpegstream/gstmpegparse.h (struct _GstMPEGParse): + * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_init) + (g_value_set_int, gst_mpeg_parse_set_property) + Get rid of do_adjust and use_adjust. Rename max_discont to + max_src_gap. + (gst_mpeg_parse_parse_packhead): When max_scr_gap has a value of + -1, no adjustment is made. + * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_class_init): + Rename max_discont property to max_scr_gap. Erase "adjust" + property. + + * gst/mpegstream/gstdvddemux.c (gst_dvd_demux_send_event): Don't + override send_event anymore, base class does the job. + * gst/mpegstream/gstmpegdemux.c (gst_mpeg_demux_send_event): + Base class now does most of the work. + * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_send_event): + Generalize to forwarding the event to all source pads in the + element. + + * gst/mpegstream/gstmpegparse.h: + * gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_class_init) + (gst_mpeg_parse_init, gst_mpeg_parse_set_clock) + (gst_mpeg_parse_chain, gst_mpeg_parse_get_property) + (gst_mpeg_parse_set_property): + Clock synchronization doesn't make sense anymore for a + demultiplexer. + 2005-11-28 Michael Smith * gst/realmedia/rmdemux.c: (gst_rmdemux_loop): diff --git a/gst/mpegstream/gstdvddemux.c b/gst/mpegstream/gstdvddemux.c index 1ce91d5..cc45005 100644 --- a/gst/mpegstream/gstdvddemux.c +++ b/gst/mpegstream/gstdvddemux.c @@ -150,8 +150,6 @@ static gboolean gst_dvd_demux_handle_discont static gboolean gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event); #endif -static gboolean gst_dvd_demux_send_event - (GstMPEGParse * mpeg_parse, GstEvent * event, GstClockTime time); static GstMPEGStream *gst_dvd_demux_get_video_stream (GstMPEGDemux * mpeg_demux, @@ -251,7 +249,6 @@ gst_dvd_demux_class_init (GstDVDDemuxClass * klass) gstelement_class->change_state = gst_dvd_demux_change_state; mpeg_parse_class->handle_discont = gst_dvd_demux_handle_discont; - mpeg_parse_class->send_event = gst_dvd_demux_send_event; mpeg_demux_class->get_audio_stream = gst_dvd_demux_get_audio_stream; mpeg_demux_class->get_video_stream = gst_dvd_demux_get_video_stream; @@ -421,11 +418,6 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event) else mpeg_demux->adjust = 0; - /* Try to prevent the mpegparse infrastructure from doing timestamp - adjustment, and enable synchronising filler events. */ - mpeg_parse->use_adjust = FALSE; - mpeg_parse->adjust = 0; - /* Keep video/audio/subtitle pads within 1/2 sec of the SCR */ mpeg_demux->max_gap = 0.5 * GST_SECOND; mpeg_demux->max_gap_tolerance = 0.05 * GST_SECOND; @@ -523,11 +515,6 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event) gst_element_no_more_pads (GST_ELEMENT (dvd_demux)); dvd_demux->ignore_next_newmedia_discont = TRUE; - /* Try to prevent the mpegparse infrastructure from doing timestamp - adjustment, and enable synchronising filler events. */ - mpeg_parse->use_adjust = FALSE; - mpeg_parse->adjust = 0; - /* Keep video/audio/subtitle pads within 1/2 sec of the SCR */ mpeg_demux->max_gap = 0.5 * GST_SECOND; mpeg_demux->max_gap_tolerance = 0.05 * GST_SECOND; @@ -544,37 +531,6 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event) #endif static GstFlowReturn -gst_dvd_demux_send_event (GstMPEGParse * mpeg_parse, GstEvent * event, - GstClockTime ts) -{ - GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_parse); - gint i; - - for (i = 0; i < GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; i++) { - if (dvd_demux->subpicture_stream[i]) { - gst_event_ref (event); - gst_pad_push_event (dvd_demux->subpicture_stream[i]->pad, event); - if (GST_CLOCK_TIME_IS_VALID (ts)) - dvd_demux->subpicture_stream[i]->cur_ts = ts; - } - } - - /* Distribute the event to the "current" pads. */ - gst_event_ref (event); - gst_pad_push_event (dvd_demux->cur_video, event); - - gst_event_ref (event); - gst_pad_push_event (dvd_demux->cur_audio, event); - - gst_event_ref (event); - gst_pad_push_event (dvd_demux->cur_subpicture, event); - - GST_MPEG_PARSE_CLASS (parent_class)->send_event (mpeg_parse, event, ts); - - return GST_FLOW_OK; -} - -static GstFlowReturn gst_dvd_demux_handle_discont (GstMPEGParse * mpeg_parse, GstEvent * event) { #if 0 diff --git a/gst/mpegstream/gstmpegdemux.c b/gst/mpegstream/gstmpegdemux.c index ea80ad8..01629fd 100644 --- a/gst/mpegstream/gstmpegdemux.c +++ b/gst/mpegstream/gstmpegdemux.c @@ -308,7 +308,6 @@ gst_mpeg_demux_send_event (GstMPEGParse * mpeg_parse, GstEvent * event, * Distribute the event to all active pads */ GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); - gint i; GST_DEBUG_OBJECT (mpeg_demux, "Sending %s event", GST_EVENT_TYPE_NAME (event)); @@ -316,33 +315,6 @@ gst_mpeg_demux_send_event (GstMPEGParse * mpeg_parse, GstEvent * event, if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) mpeg_demux->just_flushed = TRUE; - for (i = 0; i < GST_MPEG_DEMUX_NUM_VIDEO_STREAMS; i++) { - if (mpeg_demux->video_stream[i]) { - gst_event_ref (event); - gst_pad_push_event (mpeg_demux->video_stream[i]->pad, event); - if (GST_CLOCK_TIME_IS_VALID (time)) - mpeg_demux->video_stream[i]->cur_ts = time; - } - } - - for (i = 0; i < GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; i++) { - if (mpeg_demux->audio_stream[i]) { - gst_event_ref (event); - gst_pad_push_event (mpeg_demux->audio_stream[i]->pad, event); - if (GST_CLOCK_TIME_IS_VALID (time)) - mpeg_demux->audio_stream[i]->cur_ts = time; - } - } - - for (i = 0; i < GST_MPEG_DEMUX_NUM_PRIVATE_STREAMS; i++) { - if (mpeg_demux->private_stream[i]) { - gst_event_ref (event); - gst_pad_push_event (mpeg_demux->private_stream[i]->pad, event); - if (GST_CLOCK_TIME_IS_VALID (time)) - mpeg_demux->private_stream[i]->cur_ts = time; - } - } - if (parent_class->send_event) return parent_class->send_event (mpeg_parse, event, time); diff --git a/gst/mpegstream/gstmpegparse.c b/gst/mpegstream/gstmpegparse.c index 5418564..351e008 100644 --- a/gst/mpegstream/gstmpegparse.c +++ b/gst/mpegstream/gstmpegparse.c @@ -52,7 +52,7 @@ static GstElementDetails mpeg_parse_details = { #define CLASS(o) GST_MPEG_PARSE_CLASS (G_OBJECT_GET_CLASS (o)) -#define DEFAULT_MAX_DISCONT 120000 +#define DEFAULT_MAX_SCR_GAP 120000 /* GstMPEGParse signals and args */ enum @@ -64,9 +64,7 @@ enum enum { ARG_0, - ARG_SYNC, - ARG_MAX_DISCONT, - ARG_DO_ADJUST, + ARG_MAX_SCR_GAP, ARG_BYTE_OFFSET, ARG_TIME_OFFSET /* FILL ME */ @@ -97,9 +95,6 @@ static void gst_mpeg_parse_class_init (GstMPEGParseClass * klass); static GstStateChangeReturn gst_mpeg_parse_change_state (GstElement * element, GstStateChange transition); -static gboolean gst_mpeg_parse_set_clock (GstElement * element, - GstClock * clock); - static gboolean gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer); @@ -159,7 +154,6 @@ gst_mpeg_parse_class_init (GstMPEGParseClass * klass) gstelement_class->pad_added = gst_mpeg_parse_pad_added; gstelement_class->change_state = gst_mpeg_parse_change_state; - gstelement_class->set_clock = gst_mpeg_parse_set_clock; gstelement_class->get_index = gst_mpeg_parse_get_index; gstelement_class->set_index = gst_mpeg_parse_set_index; @@ -181,18 +175,11 @@ gst_mpeg_parse_class_init (GstMPEGParseClass * klass) 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_SYNC, - g_param_spec_boolean ("sync", "Sync", "Synchronize on the stream SCR", - FALSE, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_DISCONT, - g_param_spec_int ("max_discont", "Max Discont", - "The maximum allowed SCR discontinuity", 0, G_MAXINT, - DEFAULT_MAX_DISCONT, G_PARAM_READWRITE)); - /* FIXME: Default is TRUE to make the behavior backwards compatible. - It probably should be FALSE. */ - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DO_ADJUST, - g_param_spec_boolean ("adjust", "adjust", "Adjust timestamps to " - "smooth discontinuities", TRUE, G_PARAM_READWRITE)); + 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_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.", @@ -235,28 +222,13 @@ gst_mpeg_parse_init (GstMPEGParse * mpeg_parse, GstMPEGParseClass * klass) GST_DEBUG_FUNCPTR (gst_mpeg_parse_chain)); mpeg_parse->packetize = NULL; - mpeg_parse->sync = FALSE; - mpeg_parse->id = NULL; - mpeg_parse->max_discont = DEFAULT_MAX_DISCONT; - - mpeg_parse->do_adjust = TRUE; - mpeg_parse->use_adjust = TRUE; + mpeg_parse->max_scr_gap = DEFAULT_MAX_SCR_GAP; mpeg_parse->byte_offset = G_MAXUINT64; gst_mpeg_parse_reset (mpeg_parse); } -static gboolean -gst_mpeg_parse_set_clock (GstElement * element, GstClock * clock) -{ - GstMPEGParse *parse = GST_MPEG_PARSE (element); - - parse->clock = clock; - - return TRUE; -} - #if 0 static void gst_mpeg_parse_update_streaminfo (GstMPEGParse * mpeg_parse) @@ -302,7 +274,7 @@ gst_mpeg_parse_reset (GstMPEGParse * mpeg_parse) mpeg_parse->next_scr = 0; mpeg_parse->mux_rate = 0; - mpeg_parse->discont_pending = FALSE; + mpeg_parse->newsegment_pending = FALSE; mpeg_parse->scr_pending = FALSE; } @@ -331,7 +303,7 @@ gst_mpeg_parse_handle_discont (GstMPEGParse * mpeg_parse, GstEvent * event) } else { /* Use the next SCR to send a discontinuous event. */ GST_DEBUG_OBJECT (mpeg_parse, "Using next SCR to send discont"); - mpeg_parse->discont_pending = TRUE; + mpeg_parse->newsegment_pending = TRUE; mpeg_parse->scr_pending = TRUE; } mpeg_parse->packetize->resync = TRUE; @@ -399,7 +371,33 @@ static gboolean gst_mpeg_parse_send_event (GstMPEGParse * mpeg_parse, GstEvent * event, GstClockTime time) { - return gst_pad_push_event (mpeg_parse->srcpad, event); + GstIterator *it; + gpointer pad; + gboolean ret = TRUE; + + /* 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_pad_push_event (GST_PAD (pad), event); + 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); + + return ret; } static void @@ -521,20 +519,18 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) diff = scr - mpeg_parse->next_scr; } - if (diff > mpeg_parse->max_discont) { + if (diff > mpeg_parse->max_scr_gap) { GST_DEBUG ("discontinuity detected; expected: %" G_GUINT64_FORMAT " got: %" G_GUINT64_FORMAT " adjusted:%" G_GINT64_FORMAT " adjust:%" G_GINT64_FORMAT, mpeg_parse->next_scr, mpeg_parse->current_scr, mpeg_parse->current_scr + mpeg_parse->adjust, mpeg_parse->adjust); - if (mpeg_parse->do_adjust) { - if (mpeg_parse->use_adjust) { - mpeg_parse->adjust += - (gint64) mpeg_parse->next_scr - (gint64) mpeg_parse->current_scr; - GST_DEBUG ("new adjust: %" G_GINT64_FORMAT, mpeg_parse->adjust); - } + if (mpeg_parse->max_scr_gap >= 0) { + mpeg_parse->adjust += + (gint64) mpeg_parse->next_scr - (gint64) mpeg_parse->current_scr; + GST_DEBUG ("new adjust: %" G_GINT64_FORMAT, mpeg_parse->adjust); } else { - mpeg_parse->discont_pending = TRUE; + mpeg_parse->newsegment_pending = TRUE; } } @@ -555,7 +551,7 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr), 0); } - if ((mpeg_parse->current_scr > prev_scr) && (diff < mpeg_parse->max_discont)) { + 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; @@ -681,20 +677,14 @@ gst_mpeg_parse_chain (GstPad * pad, GstBuffer * buffer) time = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr); /* we're not sending data as long as no new SCR was found */ - if (mpeg_parse->discont_pending) { + if (mpeg_parse->newsegment_pending) { if (!mpeg_parse->scr_pending) { -#if 0 - if (mpeg_parse->clock && mpeg_parse->sync) { - gst_element_set_time (GST_ELEMENT (mpeg_parse), - MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr)); - } -#endif if (CLASS (mpeg_parse)->send_newsegment) { CLASS (mpeg_parse)->send_newsegment (mpeg_parse, 1.0, MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr + mpeg_parse->adjust), GST_CLOCK_TIME_NONE); } - mpeg_parse->discont_pending = FALSE; + mpeg_parse->newsegment_pending = FALSE; } else { GST_DEBUG ("waiting for SCR"); gst_buffer_unref (buffer); @@ -724,13 +714,6 @@ gst_mpeg_parse_chain (GstPad * pad, GstBuffer * buffer) if (CLASS (mpeg_parse)->send_buffer) result = CLASS (mpeg_parse)->send_buffer (mpeg_parse, buffer, time); -#if 0 - if (mpeg_parse->clock && mpeg_parse->sync && !mpeg_parse->discont_pending) { - GST_DEBUG ("syncing mpegparse"); - gst_element_wait (GST_ELEMENT (mpeg_parse), time); - } -#endif - if (mpeg_parse->current_scr != MP_INVALID_SCR) { guint64 scr, bss, br; @@ -1092,7 +1075,7 @@ gst_mpeg_parse_handle_src_event (GstPad * pad, GstEvent * event) if (gst_bytestream_seek (mpeg_parse->packetize->bs, desired_offset, GST_SEEK_METHOD_SET)) { - mpeg_parse->discont_pending = TRUE; + mpeg_parse->newsegment_pending = TRUE; mpeg_parse->scr_pending = TRUE; mpeg_parse->next_scr = expected_scr; mpeg_parse->current_scr = MP_INVALID_SCR; @@ -1156,14 +1139,8 @@ gst_mpeg_parse_get_property (GObject * object, guint prop_id, GValue * value, mpeg_parse = GST_MPEG_PARSE (object); switch (prop_id) { - case ARG_SYNC: - g_value_set_boolean (value, mpeg_parse->sync); - break; - case ARG_MAX_DISCONT: - g_value_set_int (value, mpeg_parse->max_discont); - break; - case ARG_DO_ADJUST: - g_value_set_boolean (value, mpeg_parse->do_adjust); + 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); @@ -1186,15 +1163,8 @@ gst_mpeg_parse_set_property (GObject * object, guint prop_id, mpeg_parse = GST_MPEG_PARSE (object); switch (prop_id) { - case ARG_SYNC: - mpeg_parse->sync = g_value_get_boolean (value); - break; - case ARG_MAX_DISCONT: - mpeg_parse->max_discont = g_value_get_int (value); - break; - case ARG_DO_ADJUST: - mpeg_parse->do_adjust = g_value_get_boolean (value); - mpeg_parse->adjust = 0; + 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); diff --git a/gst/mpegstream/gstmpegparse.h b/gst/mpegstream/gstmpegparse.h index 22fb900..9869a88 100644 --- a/gst/mpegstream/gstmpegparse.h +++ b/gst/mpegstream/gstmpegparse.h @@ -45,106 +45,98 @@ G_BEGIN_DECLS #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 TS corresponding to SCR */ - - gboolean do_adjust; /* If false, send discont events on SCR - * jumps - */ - gboolean use_adjust; /* Collect SCR jumps into 'adjust' in - * order to adjust timestamps to smooth - * discontinuities. */ - gint64 adjust; /* Current timestamp adjust value. */ - - gboolean discont_pending; - gboolean scr_pending; - gint max_discont; - - GstClock *clock; - gboolean sync; - GstClockID id; - - GstIndex *index; - gint index_id; - - guint64 byte_offset; - }; - - struct _GstMPEGParseClass - { - GstElementClass parent_class; - - /* process packet 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); - - /* process events */ - GstFlowReturn (*handle_discont) (GstMPEGParse * parse, GstEvent * event); - - /* optional method to send out the data */ - GstFlowReturn (*send_buffer) (GstMPEGParse * parse, - GstBuffer * buffer, GstClockTime time); - gboolean (*process_event) (GstMPEGParse * parse, - GstEvent * event, GstClockTime time); - gboolean (*send_newsegment)(GstMPEGParse * parse, gdouble rate, - GstClockTime start_time, - GstClockTime stop_time); - gboolean (*send_event) (GstMPEGParse * parse, GstEvent *event, - GstClockTime time); - - /* 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_convert_src (GstPad * pad, GstFormat src_format, - gint64 src_value, GstFormat * dest_format, gint64 * dest_value); - 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, GstQueryType type, - GstFormat * format, gint64 * value); +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') */ + + gint64 adjust; /* Value added to SCR values to + produce buffer timestamps */ + gint max_scr_gap; /* The maximum allowed SCR gap without + making a timestamp adjustment */ + + gboolean newsegment_pending; /* If true, the element should send a + NEWSEGMENT event as soon as there + is SCR information available */ + + gboolean scr_pending; + + GstIndex *index; + gint index_id; + + guint64 byte_offset; +}; + +struct _GstMPEGParseClass +{ + GstElementClass parent_class; + + /* Process packet 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); + + /* Process events */ + GstFlowReturn (*handle_discont) (GstMPEGParse * parse, GstEvent * event); + + /* Optional method to send out the data */ + GstFlowReturn (*send_buffer) (GstMPEGParse * parse, + GstBuffer * buffer, GstClockTime time); + gboolean (*process_event) (GstMPEGParse * parse, + GstEvent * event, GstClockTime time); + gboolean (*send_newsegment)(GstMPEGParse * parse, gdouble rate, + GstClockTime start_time, + GstClockTime stop_time); + gboolean (*send_event) (GstMPEGParse * parse, GstEvent *event, + GstClockTime time); + + /* 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_convert_src (GstPad * pad, GstFormat src_format, + gint64 src_value, GstFormat * dest_format, gint64 * dest_value); +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, GstQueryType type, + GstFormat * format, gint64 * value); G_END_DECLS -- 2.7.4