[gst-devel] event handling for mpeg2 plugins
vishnu at pobox.com
vishnu at pobox.com
Mon Oct 22 15:36:02 CEST 2001
The attached patch allows me to seek around an mpeg2 program stream. It
seems to work pretty well.
--
Victory to the Divine Mother!! ... after all,
http://sahajayoga.org http://why-compete.org
-------------- next part --------------
? stamp-h1
Index: gst/gstpad.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/gst/gstpad.c,v
retrieving revision 1.118
diff -u -p -r1.118 gstpad.c
--- gst/gstpad.c 2001/10/21 18:00:31 1.118
+++ gst/gstpad.c 2001/10/22 22:32:50
@@ -1982,13 +1982,15 @@ gst_pad_event_default(GstPad *pad, GstEv
*
* Send the event to the pad.
*
- * Returns: TRUe if the event was handled.
+ * Returns: TRUE if the event was handled.
*/
gboolean
gst_pad_send_event (GstPad *pad, GstEvent *event)
{
gboolean handled = FALSE;
+ g_return_val_if_fail (event, FALSE);
+
GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
@@ -2002,5 +2004,7 @@ gst_pad_send_event (GstPad *pad, GstEven
GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n");
//gst_pad_event_default (pad, event);
}
+
+ return handled;
}
Index: libs/bytestream/gstbytestream.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/libs/bytestream/gstbytestream.c,v
retrieving revision 1.4
diff -u -p -r1.4 gstbytestream.c
--- libs/bytestream/gstbytestream.c 2001/10/22 19:00:52 1.4
+++ libs/bytestream/gstbytestream.c 2001/10/22 22:32:51
@@ -407,6 +407,21 @@ gst_bytestream_read (GstByteStream * bs,
return buf;
}
+
+/**
+ * gst_bytestream_get_status
+ * @bs: a bytestream
+ * @avail_out: total number of bytes buffered
+ * @event_out: an event
+ *
+ * When an event occurs, the bytestream will return NULL. You must
+ * retrieve the event using this API before reading more bytes from
+ * the stream.
+ *
+ * It is possible for the bytestream to return NULL due to running
+ * out of buffers, however, this indicates a bug because an EOS
+ * event should have been sent.
+ */
void
gst_bytestream_get_status (GstByteStream *bs,
guint32 *avail_out,
Index: plugins/a52dec/gsta52dec.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/plugins/a52dec/gsta52dec.c,v
retrieving revision 1.8
diff -u -p -r1.8 gsta52dec.c
--- plugins/a52dec/gsta52dec.c 2001/10/17 10:21:25 1.8
+++ plugins/a52dec/gsta52dec.c 2001/10/22 22:32:51
@@ -356,6 +356,7 @@ gst_a52dec_loop (GstElement *element)
int stream_channels;
a52_state_t *state;
GstBuffer *buf;
+ gboolean got_event = FALSE;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_A52DEC (element));
@@ -370,17 +371,50 @@ gst_a52dec_loop (GstElement *element)
state = g_new(a52_state_t, 1);
do {
+ if (got_event)
+ {
+ guint32 remaining;
+ GstEvent *event;
+
+ got_event = FALSE;
+ gst_bytestream_get_status (a52dec->bs, &remaining, &event);
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_DISCONTINUOUS:
+ gst_bytestream_flush_fast (a52dec->bs, remaining);
+ break;
+
+ case GST_EVENT_EOS:
+ gst_element_set_state (GST_ELEMENT (a52dec), GST_STATE_PAUSED);
+ break;
+
+ default:
+ g_warning ("Don't know how to cope with event type %d",
+ GST_EVENT_TYPE (event));
+ break;
+ }
+
+ gst_event_free (event);
+ }
+
// find and read header
- do {
+ while (1) {
data = gst_bytestream_peek_bytes(a52dec->bs, 7);
if (!data)
- continue;
+ {
+ got_event = TRUE;
+ break;
+ }
length = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
if (length == 0) {
// slide window to next 7 bytes
- gst_bytestream_flush(a52dec->bs, 1);
+ gst_bytestream_flush_fast (a52dec->bs, 1);
}
- } while (length == 0);
+ else
+ break;
+ }
+ if (got_event)
+ continue;
//fprintf(stderr, "sync sr:%d->%d br:%d->%d f:%d->%d\n", a52dec->sample_rate, sample_rate, a52dec->bit_rate, bit_rate, a52dec->flags, flags);
// check if params have changed since last call
@@ -404,7 +438,10 @@ gst_a52dec_loop (GstElement *element)
// read the header + rest of frame
buf = gst_bytestream_read(a52dec->bs, length);
if (!buf)
- continue;
+ {
+ got_event = TRUE;
+ continue;
+ }
data = GST_BUFFER_DATA(buf);
// process
Index: plugins/mpeg2/mpeg2dec/gstmpeg2dec.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/plugins/mpeg2/mpeg2dec/gstmpeg2dec.c,v
retrieving revision 1.24
diff -u -p -r1.24 gstmpeg2dec.c
--- plugins/mpeg2/mpeg2dec/gstmpeg2dec.c 2001/10/17 10:21:25 1.24
+++ plugins/mpeg2/mpeg2dec/gstmpeg2dec.c 2001/10/22 22:32:51
@@ -396,6 +396,11 @@ gst_mpeg2dec_loop (GstElement *element)
restart = 1;
break;
+ case GST_EVENT_EOS:
+ gst_element_set_state (GST_ELEMENT (mpeg2dec), GST_STATE_PAUSED);
+ restart = 1; // we should get stuck in gst_pad_pull
+ break;
+
default:
g_warning ("Ignoring unknown event %d", ev->type);
break;
Index: plugins/mpeg2/parse/mpeg2parse.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/plugins/mpeg2/parse/mpeg2parse.c,v
retrieving revision 1.36
diff -u -p -r1.36 mpeg2parse.c
--- plugins/mpeg2/parse/mpeg2parse.c 2001/10/17 10:21:25 1.36
+++ plugins/mpeg2/parse/mpeg2parse.c 2001/10/22 22:32:51
@@ -826,6 +826,13 @@ _queue_discontinuous (GstPad *pad, gpoin
}
static void
+_queue_eos (GstPad *pad, gpointer ign)
+{
+ // ugh, GstBuffer cast is wrong here
+ gst_pad_push (pad, (GstBuffer*) gst_event_new (GST_EVENT_EOS));
+}
+
+static void
_forall_pads (Mpeg2Parse *mpeg2parse, GFunc fun, gpointer user_data)
{
GstPad *pad;
@@ -874,21 +881,21 @@ gst_mpeg2parse_loop (GstElement *element
}
do {
- gboolean discont = FALSE;
+ gboolean got_event = FALSE;
if (!find_start_code (mpeg2parse))
- discont = TRUE;
+ got_event = TRUE;
else {
GST_DEBUG (0, "mpeg2parse: have chunk 0x%02X\n",mpeg2parse->id);
switch (mpeg2parse->id) {
case 0xBA:
if (!parse_packhead (mpeg2parse))
- discont = TRUE;
+ got_event = TRUE;
break;
case 0xBB:
if (!parse_syshead (mpeg2parse))
- discont = TRUE;
+ got_event = TRUE;
break;
default:
@@ -899,22 +906,48 @@ gst_mpeg2parse_loop (GstElement *element
if (mpeg2parse->MPEG2)
{
if (!parse_pes (mpeg2parse))
- discont = TRUE;
+ got_event = TRUE;
}
else
{
if (!parse_packet (mpeg2parse))
- discont = TRUE;
+ got_event = TRUE;
}
}
}
}
- if (discont)
- _forall_pads (mpeg2parse, (GFunc) _queue_discontinuous, NULL);
+ if (got_event)
+ {
+ guint32 remaining;
+ GstEvent *event;
+ gint etype;
+
+ gst_bytestream_get_status (mpeg2parse->bs, &remaining, &event);
+ etype = event? GST_EVENT_TYPE (event) : GST_EVENT_EOS;
+
+ switch (etype) {
+
+ case GST_EVENT_DISCONTINUOUS:
+ gst_bytestream_flush_fast (mpeg2parse->bs, remaining);
+ _forall_pads (mpeg2parse, (GFunc) _queue_discontinuous, NULL);
+ break;
+
+ case GST_EVENT_EOS:
+ gst_element_set_state (GST_ELEMENT (mpeg2parse), GST_STATE_PAUSED);
+ _forall_pads (mpeg2parse, (GFunc) _queue_eos, NULL);
+ break;
+
+ default:
+ g_warning ("Don't know how to cope with event type %d",
+ GST_EVENT_TYPE (event));
+ break;
+ }
- } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
+ gst_event_free (event);
+ }
+ } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
}
static void
More information about the gstreamer-devel
mailing list