From: <wt...@fr...> - 2005-05-05 10:08:07
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu May 05 2005 19:39:47 EST Log message: * ext/ogg/Makefile.am: * ext/ogg/README: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind), (gst_ogg_pad_submit_packet), (gst_ogg_demux_sink_activate), (gst_ogg_print): * ext/ogg/gstoggmux.c: (gst_ogg_mux_init), (gst_ogg_mux_request_new_pad), (gst_ogg_mux_next_buffer), (gst_ogg_mux_push_page), (gst_ogg_mux_queue_pads), (gst_ogg_mux_get_headers), (gst_ogg_mux_set_header_on_caps), (gst_ogg_mux_send_headers), (gst_ogg_mux_collected), (gst_ogg_mux_change_state): Ported ogg muxer. Modified files: . : ChangeLog ext/ogg : Makefile.am README gstoggdemux.c gstoggmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1669&r2=1.1670 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/Makefile.am.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/README.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.70&r2=1.71 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c.diff?r1=1.23&r2=1.24 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1669 retrieving revision 1.1670 diff -u -d -r1.1669 -r1.1670 --- ChangeLog 5 May 2005 09:37:45 -0000 1.1669 +++ ChangeLog 5 May 2005 09:39:35 -0000 1.1670 @@ -1,5 +1,20 @@ 2005-05-05 Wim Taymans <wi...@fl...> + * ext/ogg/Makefile.am: + * ext/ogg/README: + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind), + (gst_ogg_pad_submit_packet), (gst_ogg_demux_sink_activate), + (gst_ogg_print): + * ext/ogg/gstoggmux.c: (gst_ogg_mux_init), + (gst_ogg_mux_request_new_pad), (gst_ogg_mux_next_buffer), + (gst_ogg_mux_push_page), (gst_ogg_mux_queue_pads), + (gst_ogg_mux_get_headers), (gst_ogg_mux_set_header_on_caps), + (gst_ogg_mux_send_headers), (gst_ogg_mux_collected), + (gst_ogg_mux_change_state): + Ported ogg muxer. + +2005-05-05 Wim Taymans <wi...@fl...> * docs/design-audiosinks.txt: * gst-libs/gst/audio/TODO: * gst-libs/gst/audio/gstaudiosink.c: Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/Makefile.am,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- Makefile.am 25 Apr 2005 00:23:01 -0000 1.7 +++ Makefile.am 5 May 2005 09:39:35 -0000 1.8 @@ -10,6 +10,6 @@ libgstogg_la_CFLAGS = $(GST_CFLAGS) $(OGG_CFLAGS) libgstogg_la_LIBADD = $(OGG_LIBS) \ - $(top_builddir)/gst-libs/gst/riff/libgstriff-@GST_MAJORMINOR@.la + $(top_builddir)/gst-libs/gst/riff/libgstriff-@GST_MAJORMINOR@.la $(GST_BASE_LIBS) libgstogg_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) Index: README RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/README,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- README 31 Mar 2005 09:43:43 -0000 1.2 +++ README 5 May 2005 09:39:35 -0000 1.3 @@ -125,6 +125,8 @@ in a raw theroa stream we use the granulepos as the offset field. +The granulepos of an ogg page is the framenumber of the last frame in the page. vorbis and granulepos --------------------- @@ -134,6 +136,8 @@ in a raw vorbis stream we use the granulepos as the offset field. +The granulepos of an ogg page is the sample number of the next page in the ogg stream. What can ogg do? ---------------- @@ -183,4 +187,3 @@ - use the OFFSET field in the GstBuffer to store/read the granulepos as opposed to the OFFSET_END field. -- Seeking should be implemented with a binary search. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.70 retrieving revision 1.71 diff -u -d -r1.70 -r1.71 --- gstoggdemux.c 28 Apr 2005 17:13:47 -0000 1.70 +++ gstoggdemux.c 5 May 2005 09:39:35 -0000 1.71 @@ -703,6 +703,9 @@ ret = GST_RPAD_CHAINFUNC (pad->elem_pad) (pad->elem_pad, buf); } +#if 0 +done: +#endif pad->packetno++; return ret; @@ -1975,7 +1978,7 @@ ogg->seekable = FALSE; result = TRUE; break; - case GST_ACTIVATE_PULL: + case GST_ACTIVATE_PULL_RANGE: /* if we have a scheduler we can start the task */ if (GST_ELEMENT_SCHEDULER (ogg)) { gst_pad_peer_set_active (sinkpad, mode); @@ -2007,6 +2010,9 @@ + case GST_ACTIVATE_PULL: + result = FALSE; + break; return result; } @@ -2142,7 +2148,7 @@ { guint j, i; - GST_INFO_OBJECT (ogg, "%u chains, total time %" GST_TIME_FORMAT ":", + GST_INFO_OBJECT (ogg, "%u chains, total time: %" GST_TIME_FORMAT, ogg->chains->len, GST_TIME_ARGS (ogg->total_time)); for (i = 0; i < ogg->chains->len; i++) { @@ -2158,17 +2164,17 @@ GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, j); GST_INFO_OBJECT (ogg, " stream %08lx:", stream->serialno); - GST_INFO_OBJECT (ogg, " start time %" GST_TIME_FORMAT ":", + GST_INFO_OBJECT (ogg, " start time: %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->start_time)); - GST_INFO_OBJECT (ogg, " first granulepos %" G_GINT64_FORMAT ":", + GST_INFO_OBJECT (ogg, " first granulepos: %" G_GINT64_FORMAT, stream->first_granule); - GST_INFO_OBJECT (ogg, " first time %" GST_TIME_FORMAT ":", + GST_INFO_OBJECT (ogg, " first time: %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->first_time)); - GST_INFO_OBJECT (ogg, " last granulepos %" G_GINT64_FORMAT ":", + GST_INFO_OBJECT (ogg, " last granulepos: %" G_GINT64_FORMAT, stream->last_granule); - GST_INFO_OBJECT (ogg, " last time %" GST_TIME_FORMAT ":", + GST_INFO_OBJECT (ogg, " last time: %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->last_time)); - GST_INFO_OBJECT (ogg, " total time %" GST_TIME_FORMAT ":", + GST_INFO_OBJECT (ogg, " total time: %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->total_time)); } Index: gstoggmux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstoggmux.c 31 Mar 2005 09:43:43 -0000 1.23 +++ gstoggmux.c 5 May 2005 09:39:35 -0000 1.24 @@ -22,6 +22,8 @@ #endif #include <gst/gst.h> +#include <gst/base/gstcollectpads.h> #include <ogg/ogg.h> /* memcpy - if someone knows a way to get rid of it, please speak up * note: the ogg docs even say you need this... */ @@ -40,10 +42,17 @@ typedef struct _GstOggMux GstOggMux; typedef struct _GstOggMuxClass GstOggMuxClass; +typedef enum +{ + GST_OGG_PAD_STATE_CONTROL = 0, + GST_OGG_PAD_STATE_DATA = 1 +} +GstOggPadState; /* all information needed for one ogg stream */ typedef struct - GstPad *pad; /* reference for this pad is held by element we belong to */ + GstCollectData collect; /* we extend the CollectData */ GstBuffer *buffer; /* the queued buffer for this pad */ @@ -55,7 +64,7 @@ gboolean eos; gint64 offset; - guint state; /* state of the pad */ + GstOggPadState state; /* state of the pad */ GList *headers; @@ -65,24 +74,17 @@ GstOggPad; -typedef enum -{ - GST_OGG_PAD_STATE_CONTROL = 0, - GST_OGG_PAD_STATE_DATA = 1 -} -GstOggPadState; - struct _GstOggMux GstElement element; - /* pad */ + /* source pad */ GstPad *srcpad; - /* sinkpads, a GSList of GstOggPads */ - GSList *sinkpads; + /* sinkpads */ + GstCollectPads *collect; - /* the pad we are currently pulling from to fill a page */ + /* the pad we are currently using to fill a page */ GstOggPad *pulling; /* next timestamp for the page */ @@ -128,9 +130,9 @@ LAST_SIGNAL }; -/* set to 5 seconds by default */ -#define DEFAULT_MAX_DELAY 5000000000LL -#define DEFAULT_MAX_PAGE_DELAY 5000000000LL +/* set to 0.5 seconds by default */ +#define DEFAULT_MAX_DELAY 500000000LL +#define DEFAULT_MAX_PAGE_DELAY 500000000LL enum ARG_0, @@ -156,7 +158,8 @@ static void gst_ogg_mux_class_init (GstOggMuxClass * klass); static void gst_ogg_mux_init (GstOggMux * ogg_mux); -static void gst_ogg_mux_loop (GstElement * element); +static GstFlowReturn +gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux); static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event); static GstPad *gst_ogg_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); @@ -265,16 +268,15 @@ /* seed random number generator for creation of serial numbers */ srand (time (NULL)); - ogg_mux->sinkpads = NULL; + ogg_mux->collect = gst_collectpads_new (); + gst_collectpads_set_function (ogg_mux->collect, + (GstCollectPadsFunction) gst_ogg_mux_collected, ogg_mux); ogg_mux->pulling = NULL; ogg_mux->need_headers = TRUE; ogg_mux->max_delay = DEFAULT_MAX_DELAY; ogg_mux->max_page_delay = DEFAULT_MAX_PAGE_DELAY; ogg_mux->delta_pad = NULL; - //gst_element_set_loop_function (GST_ELEMENT (ogg_mux), gst_ogg_mux_loop); - gst_ogg_mux_loop (GST_ELEMENT (ogg_mux)); static GstPadLinkReturn @@ -290,42 +292,28 @@ return GST_PAD_LINK_OK; -static void -gst_ogg_mux_pad_link (GstPad * pad, GstPad * peer, gpointer data) - GstOggMux *ogg_mux = ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad)); - GST_DEBUG_OBJECT (ogg_mux, "pad '%s' connected", gst_pad_get_name (pad)); -gst_ogg_mux_pad_unlink (GstPad * pad, GstPad * peer, gpointer data) - GST_DEBUG_OBJECT (ogg_mux, "pad '%s' unlinked", gst_pad_get_name (pad)); static GstPad * gst_ogg_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * req_name) GstOggMux *ogg_mux; GstPad *newpad; - GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstElementClass *klass; g_return_val_if_fail (templ != NULL, NULL); - if (templ->direction != GST_PAD_SINK) { - g_warning ("ogg_mux: request pad that is not a SINK pad\n"); - return NULL; - } + if (templ->direction != GST_PAD_SINK) + goto wrong_direction; g_return_val_if_fail (GST_IS_OGG_MUX (element), NULL); ogg_mux = GST_OGG_MUX (element); - if (templ == gst_element_class_get_pad_template (klass, "sink_%d")) { + klass = GST_ELEMENT_GET_CLASS (element); + if (templ != gst_element_class_get_pad_template (klass, "sink_%d")) + goto wrong_template; + { gint serial; gchar *name; @@ -344,9 +332,12 @@ /* construct our own wrapper data structure for the pad to * keep track of its status */ { - GstOggPad *oggpad = g_new0 (GstOggPad, 1); + GstOggPad *oggpad; + oggpad = (GstOggPad *) + gst_collectpads_add_pad (ogg_mux->collect, newpad, + sizeof (GstOggPad)); - oggpad->pad = newpad; oggpad->serial = serial; ogg_stream_init (&oggpad->stream, serial); oggpad->packetno = 0; @@ -357,22 +348,9 @@ oggpad->new_page = TRUE; oggpad->first_delta = FALSE; oggpad->prev_delta = FALSE; - /* save a pointer to our data in the pad */ - gst_pad_set_element_private (newpad, oggpad); - /* store our data for the pad */ - ogg_mux->sinkpads = g_slist_prepend (ogg_mux->sinkpads, oggpad); - } else { - g_warning ("ogg_mux: this is not our template!\n"); - g_signal_connect (newpad, "linked", - G_CALLBACK (gst_ogg_mux_pad_link), (gpointer) ogg_mux); - g_signal_connect (newpad, "unlinked", - G_CALLBACK (gst_ogg_mux_pad_unlink), (gpointer) ogg_mux); /* setup some pad functions */ gst_pad_set_link_function (newpad, gst_ogg_mux_sinkconnect); gst_pad_set_event_mask_function (newpad, gst_ogg_mux_get_sink_event_masks); @@ -380,6 +358,18 @@ gst_element_add_pad (element, newpad); return newpad; + /* ERRORS */ +wrong_direction: + g_warning ("ogg_mux: request pad that is not a SINK pad\n"); + return NULL; + } +wrong_template: + g_warning ("ogg_mux: this is not our template!\n"); /* handle events */ @@ -404,6 +394,7 @@ return gst_pad_event_default (pad, event); static GstBuffer * gst_ogg_mux_next_buffer (GstOggPad * pad, gboolean * interrupt) @@ -473,6 +464,7 @@ return GST_BUFFER (data); gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta) @@ -497,14 +489,17 @@ return buffer; gst_ogg_mux_push_page (GstOggMux * mux, ogg_page * page, gboolean delta) - if (GST_PAD_IS_USABLE (mux->srcpad)) { - GstBuffer *buffer = gst_ogg_mux_buffer_from_page (mux, page, delta); + GstBuffer *buffer; + GstFlowReturn ret; - gst_pad_push (mux->srcpad, buffer); + buffer = gst_ogg_mux_buffer_from_page (mux, page, delta); + ret = gst_pad_push (mux->srcpad, buffer); + return ret; /* @@ -555,34 +550,50 @@ /* make sure a buffer is queued on all pads, returns a pointer to an oggpad * that holds the best buffer or NULL when no pad was usable */ static GstOggPad * -gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * interrupt) +gst_ogg_mux_queue_pads (GstOggMux * ogg_mux) GstOggPad *bestpad = NULL; GSList *walk; /* try to make sure we have a buffer from each usable pad first */ - walk = ogg_mux->sinkpads; + walk = ogg_mux->collect->data; while (walk) { - GstOggPad *pad = (GstOggPad *) walk->data; + GstOggPad *pad; + GstCollectData *data; - walk = walk->next; + data = (GstCollectData *) walk->data; + pad = (GstOggPad *) data; - if (pad->eos) + walk = g_slist_next (walk); + if (data->eos) continue; /* try to get a new buffer for this pad if needed and possible */ - if (pad->buffer == NULL && GST_PAD_IS_USABLE (pad->pad)) { - pad->buffer = gst_ogg_mux_next_buffer (pad, interrupt); - if (*interrupt) - return NULL; - /* no next buffer, try another pad */ - if (pad->buffer == NULL) - continue; - } + if (pad->buffer == NULL) { + GstBuffer *buf; + gboolean incaps; - /* skip unusable pads */ - if (!GST_PAD_IS_USABLE (pad->pad)) - continue; + buf = gst_collectpads_pop (ogg_mux->collect, data); + incaps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_IN_CAPS); + /* if we need headers */ + if (pad->state == GST_OGG_PAD_STATE_CONTROL) { + /* and we have one */ + if (incaps) { + GST_DEBUG ("muxer: got incaps buffer in control state, ignoring"); + /* just ignore */ + gst_buffer_unref (buf); + buf = NULL; + } else { + GST_DEBUG + ("muxer: got data buffer in control state, switching to data mode"); + /* this is a data buffer so switch to data state */ + pad->state = GST_OGG_PAD_STATE_DATA; + } + } + pad->buffer = buf; + } /* we should have a buffer now, see if it is the best pad to * pull on */ @@ -602,45 +613,64 @@ GstStructure *structure; const GstCaps *caps; + GstPad *thepad; - ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad->pad)); + thepad = pad->collect.pad; - GST_LOG ("getting headers from pad %s:%s", GST_DEBUG_PAD_NAME (pad->pad)); + ogg_mux = GST_OGG_MUX (GST_PAD_PARENT (thepad)); - caps = gst_pad_get_negotiated_caps (pad->pad); + GST_LOG ("getting headers from pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); + caps = gst_pad_get_negotiated_caps (thepad); if (caps != NULL) { const GValue *streamheader; structure = gst_caps_get_structure (caps, 0); streamheader = gst_structure_get_value (structure, "streamheader"); if (streamheader != NULL) { + GST_LOG ("got header"); if (G_VALUE_TYPE (streamheader) == GST_TYPE_FIXED_LIST) { GArray *bufarr = g_value_peek_pointer (streamheader); gint i; + GST_LOG ("got fixed list"); for (i = 0; i < bufarr->len; i++) { GValue *bufval = &g_array_index (bufarr, GValue, i); + GST_LOG ("item %d", i); if (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER) { GstBuffer *buf = g_value_peek_pointer (bufval); + GST_LOG ("adding item %d to header list", i); gst_buffer_ref (buf); res = g_list_append (res, buf); } } + } else { + GST_LOG ("streamheader is not fixed list"); } + } else { + GST_LOG ("caps done have streamheader"); + } else { + GST_LOG ("got empty caps as negotiated format"); return res; +static GstCaps * gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers) - GstStructure *structure = gst_caps_get_structure (caps, 0); + GstStructure *structure; GValue list = { 0 }; GList *walk = buffers; + caps = gst_caps_make_writable (caps); + structure = gst_caps_get_structure (caps, 0); /* put buffers in a fixed list */ g_value_init (&list, GST_TYPE_FIXED_LIST); @@ -660,6 +690,8 @@ gst_structure_set_value (structure, "streamheader", &list); g_value_unset (&list); + return caps; /** @@ -670,24 +702,30 @@ * find that info in the streamcaps. * After writing the headers we must start a new page for the data. */ gst_ogg_mux_send_headers (GstOggMux * mux) GList *hbufs, *hwalk; GstCaps *caps; hbufs = NULL; + ret = GST_FLOW_OK; GST_LOG ("collecting headers"); - walk = mux->sinkpads; + walk = mux->collect->data; + GstPad *thepad; + pad = (GstOggPad *) walk->data; + thepad = pad->collect.pad; - GST_LOG ("looking at pad %s:%s", GST_DEBUG_PAD_NAME (pad->pad)); + GST_LOG ("looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); /* if the pad has no buffer, we don't care */ if (pad->buffer == NULL) @@ -698,19 +736,22 @@ GST_LOG ("creating first headers"); GstBuffer *buf; ogg_packet packet; ogg_page page; walk = walk->next; pad->packetno = 0; - GST_LOG ("looping over headers for pad %s:%s", - GST_DEBUG_PAD_NAME (pad->pad)); + GST_LOG ("looping over headers for pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); if (pad->headers) { buf = GST_BUFFER (pad->headers->data); @@ -746,14 +787,17 @@ GST_LOG ("creating next headers"); hwalk = pad->headers; while (hwalk) { @@ -808,8 +852,8 @@ /* create caps with the buffers */ caps = gst_pad_get_caps (mux->srcpad); if (caps) { - gst_ogg_mux_set_header_on_caps (caps, hbufs); - //gst_pad_try_set_caps (mux->srcpad, caps); + caps = gst_ogg_mux_set_header_on_caps (caps, hbufs); + gst_pad_set_caps (mux->srcpad, caps); /* and send the buffers */ hwalk = hbufs; @@ -818,19 +862,20 @@ hwalk = hwalk->next; - if (GST_PAD_IS_USABLE (mux->srcpad)) { - gst_pad_push (mux->srcpad, buf); - } else { - gst_buffer_unref (buf); + if ((ret = gst_pad_push (mux->srcpad, buf)) != GST_FLOW_OK) g_list_free (hbufs); -/* basic idea: +/* this function is called when there is data on all pads. * - * 1) find a pad to pull on, this is done by pulling on all pads and - * looking at the buffers to decide which one should be muxed first. + * basic idea: + * + * 1) find a pad to pull on, this is done by looking at the buffers + * to decide which one should be muxed first. * 2) store the selected pad and keep on pulling until we fill a * complete ogg page or the ogg page is filled above the max-delay * threshold. This is needed because the ogg spec says that @@ -841,19 +886,20 @@ * spec mandates that the last packet should have the EOS flag set before * sending it to ogg. -gst_ogg_mux_loop (GstElement * element) +gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux) - GstOggMux *ogg_mux; GstOggPad *best; gboolean delta_unit; - gboolean interrupt = FALSE; - ogg_mux = GST_OGG_MUX (element); + GST_DEBUG ("collected"); - best = gst_ogg_mux_queue_pads (ogg_mux, &interrupt); - if (interrupt) - return; + best = gst_ogg_mux_queue_pads (ogg_mux); + if (best == NULL) + return GST_FLOW_OK; + GST_DEBUG ("best pad %p", best); /* we're pulling a pad and there is a better one, see if we need * to flush the current page */ @@ -863,13 +909,14 @@ GstClockTime last_ts = GST_BUFFER_TIMESTAMP (pad->buffer) + GST_BUFFER_DURATION (pad->buffer); /* if the next packet in the current page is going to make the page * too long, we need to flush */ if (last_ts > ogg_mux->next_ts + ogg_mux->max_delay) { ogg_page page; while (ogg_stream_flush (&pad->stream, &page)) { - gst_ogg_mux_push_page (ogg_mux, &page, pad->first_delta); + ret = gst_ogg_mux_push_page (ogg_mux, &page, pad->first_delta); /* increment the page number counter */ pad->pageno++; /* mark other pages as delta */ @@ -888,15 +935,13 @@ ogg_mux->next_ts = GST_BUFFER_TIMESTAMP (ogg_mux->pulling->buffer); } else { /* no pad to pull on, send EOS */ - if (GST_PAD_IS_USABLE (ogg_mux->srcpad)) - gst_pad_push_event (ogg_mux->srcpad, gst_event_new (GST_EVENT_EOS)); - //gst_element_set_eos (element); - return; + gst_pad_push_event (ogg_mux->srcpad, gst_event_new (GST_EVENT_EOS)); + return GST_FLOW_WRONG_STATE; if (ogg_mux->need_headers) { - gst_ogg_mux_send_headers (ogg_mux); + ret = gst_ogg_mux_send_headers (ogg_mux); ogg_mux->need_headers = FALSE; @@ -912,18 +957,6 @@ /* now see if we have a buffer */ buf = pad->buffer; - if (buf == NULL) { - /* no buffer, get one, and store in the pad so we free it later on */ - buf = pad->buffer = gst_ogg_mux_next_buffer (pad, &interrupt); - if (interrupt) - return; - /* data exhausted on this pad (EOS) */ - if (buf == NULL) { - /* stop pulling from the pad */ - ogg_mux->pulling = NULL; - } delta_unit = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_DELTA_UNIT); duration = GST_BUFFER_DURATION (buf); @@ -938,6 +971,7 @@ packet.b_o_s = (pad->packetno == 0); packet.packetno = pad->packetno++; /* read ahead one more buffer to find EOS */ tmpbuf = gst_ogg_mux_next_buffer (pad, &interrupt); if (interrupt) @@ -949,6 +983,10 @@ /* mark EOS */ packet.e_o_s = (tmpbuf == NULL ? 1 : 0); +#else + packet.e_o_s = 0; + tmpbuf = NULL; /* we flush when we see a new keyframe */ force_flush = (pad->prev_delta && !delta_unit); @@ -964,7 +1002,7 @@ /* force flush */ if (force_flush) { @@ -1004,6 +1042,11 @@ pad->prev_delta = delta_unit; /* swap the packet in */ + if (packet.e_o_s == 1) + GST_DEBUG_OBJECT (pad, "swapping in EOS packet"); + if (packet.b_o_s == 1) + GST_DEBUG_OBJECT (pad, "swapping in BOS packet"); ogg_stream_packetin (&pad->stream, &packet); /* don't need the old buffer anymore */ @@ -1015,7 +1058,7 @@ * up in more than one page so we need to write them all */ if (ogg_stream_pageout (&pad->stream, &page) > 0) { /* push the page */ - gst_ogg_mux_push_page (ogg_mux, &page, pad->first_delta); + ret = gst_ogg_mux_push_page (ogg_mux, &page, pad->first_delta); pad->pageno++; /* mark next pages as delta */ pad->first_delta = TRUE; @@ -1025,7 +1068,7 @@ while (ogg_stream_pageout (&pad->stream, &page) > 0) { /* we have a complete page now, we can push the page * and make sure to pull on a new pad the next time around */ @@ -1037,6 +1080,8 @@ ogg_mux->pulling = NULL; + return GST_FLOW_OK; static void @@ -1085,10 +1130,10 @@ gst_ogg_mux_change_state (GstElement * element) - gint transition = GST_STATE_TRANSITION (element); - g_return_val_if_fail (GST_IS_OGG_MUX (element), GST_STATE_FAILURE); + gint transition; + GstElementStateReturn ret; + transition = GST_STATE_TRANSITION (element); switch (transition) { @@ -1097,18 +1142,28 @@ ogg_mux->next_ts = 0; ogg_mux->offset = 0; + gst_collectpads_start (ogg_mux->collect); case GST_STATE_PAUSED_TO_PLAYING: + default: + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); + switch (transition) { case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PAUSED_TO_READY: + gst_collectpads_stop (ogg_mux->collect); case GST_STATE_READY_TO_NULL: - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - return GST_STATE_SUCCESS; gboolean |
From: <wt...@fr...> - 2005-05-06 08:26:54
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Fri May 06 2005 18:26:47 EST Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind), (gst_ogg_demux_sink_activate): And revert after wingo's revert.. sigh.. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1676&r2=1.1677 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.71&r2=1.72 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1676 retrieving revision 1.1677 diff -u -d -r1.1676 -r1.1677 --- ChangeLog 6 May 2005 03:32:50 -0000 1.1676 +++ ChangeLog 6 May 2005 08:26:35 -0000 1.1677 @@ -1,3 +1,9 @@ +2005-05-06 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind), + (gst_ogg_demux_sink_activate): + And revert after wingo's revert.. sigh.. 2005-05-05 Andy Wingo <wi...@po...> * gst/audiorate/gstaudiorate.c (gst_audiorate_class_init): Pacify Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.71 retrieving revision 1.72 diff -u -d -r1.71 -r1.72 --- gstoggdemux.c 5 May 2005 09:39:35 -0000 1.71 +++ gstoggdemux.c 6 May 2005 08:26:35 -0000 1.72 @@ -1978,7 +1978,7 @@ ogg->seekable = FALSE; result = TRUE; break; - case GST_ACTIVATE_PULL_RANGE: + case GST_ACTIVATE_PULL: /* if we have a scheduler we can start the task */ if (GST_ELEMENT_SCHEDULER (ogg)) { gst_pad_peer_set_active (sinkpad, mode); @@ -2010,9 +2010,6 @@ - case GST_ACTIVATE_PULL: - result = FALSE; - break; } return result; } |
From: <wt...@fr...> - 2005-05-26 12:09:25
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu May 26 2005 05:09:07 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet), (gst_ogg_demux_activate_chain), (gst_ogg_demux_chain), (gst_ogg_demux_clear_chains), (gst_ogg_demux_change_state): Clear chains in READY Queue packets until the chain is activated. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1717&r2=1.1718 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.79&r2=1.80 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1717 retrieving revision 1.1718 diff -u -d -r1.1717 -r1.1718 --- ChangeLog 25 May 2005 19:52:14 -0000 1.1717 +++ ChangeLog 26 May 2005 12:08:55 -0000 1.1718 @@ -1,3 +1,11 @@ +2005-05-26 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet), + (gst_ogg_demux_activate_chain), (gst_ogg_demux_chain), + (gst_ogg_demux_clear_chains), (gst_ogg_demux_change_state): + Clear chains in READY + Queue packets until the chain is activated. 2005-05-25 Wim Taymans <wi...@fl...> * gst-libs/gst/audio/gstaudiosink.c: Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -r1.79 -r1.80 --- gstoggdemux.c 25 May 2005 16:08:01 -0000 1.79 +++ gstoggdemux.c 26 May 2005 12:08:55 -0000 1.80 @@ -664,12 +664,17 @@ GST_DEBUG_OBJECT (ogg, "%p could not get buffer from peer %08lx, packetno %lld", pad, pad->serialno, pad->packetno); - buf = gst_buffer_new_and_alloc (packet->bytes); - memcpy (buf->data, packet->packet, packet->bytes); - pad->offset = packet->granulepos; - GST_BUFFER_OFFSET (buf) = -1; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos; - pad->headers = g_list_append (pad->headers, buf); + /* if we are still building a chain, we have to queue this buffer and + * push it when we activate the chain */ + if (ogg->building_chain) { + buf = gst_buffer_new_and_alloc (packet->bytes); + memcpy (buf->data, packet->packet, packet->bytes); + pad->offset = packet->granulepos; + GST_BUFFER_OFFSET (buf) = -1; + GST_BUFFER_OFFSET_END (buf) = packet->granulepos; + pad->headers = g_list_append (pad->headers, buf); + } } } else { /* initialize our internal decoder with packets */ @@ -1159,6 +1164,7 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain) { gint i; + GstFlowReturn ret; if (chain == ogg->current_chain) return TRUE; @@ -1176,7 +1182,9 @@ for (headers = pad->headers; headers; headers = g_list_next (headers)) { GstBuffer *buffer = GST_BUFFER (headers->data); - gst_pad_push (GST_PAD_CAST (pad), buffer); + ret = gst_pad_push (GST_PAD_CAST (pad), buffer); + if (ret != GST_FLOW_OK) + goto flow_error; } gst_element_no_more_pads (GST_ELEMENT (ogg)); @@ -1184,6 +1192,11 @@ ogg->current_chain = chain; return TRUE; +flow_error: + { + return FALSE; + } } static gboolean @@ -1838,7 +1851,7 @@ /* see if we know about the chain already */ chain = gst_ogg_demux_find_chain (ogg, serialno); if (chain) { - /* we do, activate it */ + /* we do, activate it as it means we have a non-header */ gst_ogg_demux_activate_chain (ogg, chain); pad = gst_ogg_demux_find_pad (ogg, serialno); } else { @@ -1952,6 +1965,23 @@ return; +static void +gst_ogg_demux_clear_chains (GstOggDemux * ogg) +{ + gint i; + gst_ogg_demux_deactivate_current_chain (ogg); + GST_CHAIN_LOCK (ogg); + for (i = 0; i < ogg->chains->len; i++) { + GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); + gst_ogg_chain_free (chain); + ogg->chains = g_array_set_size (ogg->chains, 0); + GST_CHAIN_UNLOCK (ogg); +} gst_ogg_demux_sink_activate (GstPad * sinkpad, GstActivateMode mode) @@ -2009,6 +2039,7 @@ case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: + gst_ogg_demux_clear_chains (ogg); case GST_STATE_READY_TO_NULL: ogg_sync_clear (&ogg->sync); |
From: <wt...@fr...> - 2005-06-23 15:09:50
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Jun 23 2005 08:09:43 PDT Log message: * ext/ogg/README: * ext/ogg/gstoggmux.c: (gst_ogg_mux_set_header_on_caps): Buffer on caps is not boxed anymore. Modified files: . : ChangeLog ext/ogg : Makefile.am README gstoggmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1731&r2=1.1732 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/Makefile.am.diff?r1=1.8&r2=1.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/README.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c.diff?r1=1.27&r2=1.28 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1731 retrieving revision 1.1732 diff -u -d -r1.1731 -r1.1732 --- ChangeLog 22 Jun 2005 09:57:58 -0000 1.1731 +++ ChangeLog 23 Jun 2005 15:09:31 -0000 1.1732 @@ -1,3 +1,9 @@ +2005-06-23 Wim Taymans <wi...@fl...> + + * ext/ogg/README: + * ext/ogg/gstoggmux.c: (gst_ogg_mux_set_header_on_caps): + Buffer on caps is not boxed anymore. 2005-06-22 Wim Taymans <wi...@fl...> * ext/theora/theoraenc.c: (theora_set_header_on_caps): Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/Makefile.am,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Makefile.am 5 May 2005 09:39:35 -0000 1.8 +++ Makefile.am 23 Jun 2005 15:09:31 -0000 1.9 @@ -8,8 +8,9 @@ gstoggmux.c \ gstogmparse.c -libgstogg_la_CFLAGS = $(GST_CFLAGS) $(OGG_CFLAGS) +libgstogg_la_CFLAGS = $(GST_CFLAGS) $(OGG_CFLAGS) $(GST_PLUGINS_LIBS_CFLAGS) libgstogg_la_LIBADD = $(OGG_LIBS) \ - $(top_builddir)/gst-libs/gst/riff/libgstriff-@GST_MAJORMINOR@.la $(GST_BASE_LIBS) -libgstogg_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + $(top_builddir)/gst-libs/gst/riff/libgstriff-@GST_MAJORMINOR@.la $(GST_BASE_LIBS) \ + $(top_builddir)/gst-libs/gst/oggmapper/libgstoggmapper-@GST_MAJORMINOR@.la +libgstogg_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_PLUGINS_LIBS_LIBS) Index: README RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/README,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- README 2 Jun 2005 09:46:39 -0000 1.4 +++ README 23 Jun 2005 15:09:31 -0000 1.5 @@ -200,7 +200,8 @@ - 1 page with 1 packet header identification - N pages with 2 packets comments and codebooks - granulepos is samplenumber of next page - - one packet can contain a variable number of samples + - one packet can contain a variable number of samples but one frame + that should be handed to the vorbis decoder. For Theora @@ -211,7 +212,6 @@ is a combination of keyframe number and p frames since keyframe. - one packet contains 1 frame - Index: gstoggmux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- gstoggmux.c 2 Jun 2005 09:46:39 -0000 1.27 +++ gstoggmux.c 23 Jun 2005 15:09:31 -0000 1.28 @@ -684,7 +684,7 @@ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS); g_value_init (&value, GST_TYPE_BUFFER); - g_value_set_boxed (&value, buf); + gst_value_set_buffer (&value, buf); gst_value_list_append_value (&list, &value); g_value_unset (&value); } |
From: <wt...@fr...> - 2005-06-28 11:00:22
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Jun 28 2005 04:00:15 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet): If we're building a chain we are not in an error case when we queue a buffer. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1740&r2=1.1741 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.85&r2=1.86 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1740 retrieving revision 1.1741 diff -u -d -r1.1740 -r1.1741 --- ChangeLog 28 Jun 2005 10:16:11 -0000 1.1740 +++ ChangeLog 28 Jun 2005 11:00:03 -0000 1.1741 @@ -1,3 +1,9 @@ +2005-06-28 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet): + If we're building a chain we are not in an error case + when we queue a buffer. 2005-06-28 Andy Wingo <wi...@po...> * *.c: Don't cast to GstObject before reffing/unreffing. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.85 retrieving revision 1.86 diff -u -d -r1.85 -r1.86 --- gstoggdemux.c 28 Jun 2005 10:16:12 -0000 1.85 +++ gstoggdemux.c 28 Jun 2005 11:00:03 -0000 1.86 @@ -661,6 +661,8 @@ GST_BUFFER_OFFSET (buf) = -1; GST_BUFFER_OFFSET_END (buf) = packet->granulepos; pad->headers = g_list_append (pad->headers, buf); + /* we are ok now */ + ret = GST_FLOW_OK; } } } else { |
From: <wt...@fr...> - 2005-06-28 11:41:01
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Jun 28 2005 04:40:59 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet), (gst_ogg_demux_init): Removed pad loop function. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1741&r2=1.1742 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.86&r2=1.87 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1741 retrieving revision 1.1742 diff -u -d -r1.1741 -r1.1742 --- ChangeLog 28 Jun 2005 11:00:03 -0000 1.1741 +++ ChangeLog 28 Jun 2005 11:40:46 -0000 1.1742 @@ -1,5 +1,11 @@ 2005-06-28 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet), + (gst_ogg_demux_init): + Removed pad loop function. + +2005-06-28 Wim Taymans <wi...@fl...> * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet): If we're building a chain we are not in an error case when we queue a buffer. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.86 retrieving revision 1.87 diff -u -d -r1.86 -r1.87 --- gstoggdemux.c 28 Jun 2005 11:00:03 -0000 1.86 +++ gstoggdemux.c 28 Jun 2005 11:40:46 -0000 1.87 @@ -926,8 +926,6 @@ ogg->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&ogg_demux_sink_template_factory), "sink"); - gst_pad_set_loop_function (ogg->sinkpad, - (GstPadLoopFunction) gst_ogg_demux_loop); gst_pad_set_event_function (ogg->sinkpad, gst_ogg_demux_handle_event); gst_pad_set_chain_function (ogg->sinkpad, gst_ogg_demux_chain); gst_pad_set_activate_function (ogg->sinkpad, gst_ogg_demux_sink_activate); |
From: <wt...@fr...> - 2005-07-14 18:13:21
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Jul 14 2005 11:13:20 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_dispose), (gst_ogg_pad_submit_packet), (gst_ogg_pad_submit_page), (gst_ogg_demux_activate_chain), (gst_ogg_demux_loop): Better error recovery, ignore unconnected pads and non-fatal errors. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1780&r2=1.1781 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.90&r2=1.91 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1780 retrieving revision 1.1781 diff -u -d -r1.1780 -r1.1781 --- ChangeLog 14 Jul 2005 09:35:08 -0000 1.1780 +++ ChangeLog 14 Jul 2005 18:13:08 -0000 1.1781 @@ -1,3 +1,11 @@ +2005-07-14 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_dispose), + (gst_ogg_pad_submit_packet), (gst_ogg_pad_submit_page), + (gst_ogg_demux_activate_chain), (gst_ogg_demux_loop): + Better error recovery, ignore unconnected pads and + non-fatal errors. 2005-07-14 Thomas Vander Stichele <thomas at apestaart dot org> * docs/libs/tmpl/gstaudio.sgml: Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.90 retrieving revision 1.91 diff -u -d -r1.90 -r1.91 --- gstoggdemux.c 8 Jul 2005 13:35:04 -0000 1.90 +++ gstoggdemux.c 14 Jul 2005 18:13:08 -0000 1.91 @@ -268,8 +268,6 @@ { GstOggPad *pad = GST_OGG_PAD (object); - gst_element_set_state (pad->element, GST_STATE_NULL); - gst_object_replace ((GstObject **) (&pad->elem_pad), NULL); gst_object_replace ((GstObject **) (&pad->element), NULL); gst_object_replace ((GstObject **) (&pad->elem_out), NULL); @@ -662,6 +660,9 @@ ret = GST_FLOW_OK; } } + /* we just ignore unlinked pads */ + if (ret == GST_FLOW_NOT_LINKED) + ret = GST_FLOW_OK; } else { /* initialize our internal decoder with packets */ if (!pad->elem_pad) @@ -678,6 +679,8 @@ GST_BUFFER_OFFSET_END (buf) = packet->granulepos; ret = gst_pad_chain (pad->elem_pad, buf); + if (GST_FLOW_IS_FATAL (ret)) + goto decoder_error; } pad->packetno++; @@ -687,7 +690,12 @@ { GST_WARNING_OBJECT (ogg, "pad %08lx does not have elem_pad, no decoder ?", pad); - return GST_FLOW_OK; + return GST_FLOW_ERROR; + } +decoder_error: + { + GST_WARNING_OBJECT (ogg, "internal decoder error"); } @@ -705,13 +713,8 @@ ogg = GST_OGG_DEMUX (GST_PAD_PARENT (pad)); - if (ogg_stream_pagein (&pad->stream, page) != 0) { - GST_WARNING_OBJECT (ogg, - "ogg stream choked on page (serial %08lx), resetting stream", - pad->serialno); - gst_ogg_pad_reset (pad); - } + if (ogg_stream_pagein (&pad->stream, page) != 0) + goto choked; while (!done) { ret = ogg_stream_packetout (&pad->stream, &packet); @@ -726,12 +729,8 @@ break; case 1: result = gst_ogg_pad_submit_packet (pad, &packet); - if (result != GST_FLOW_OK) { - GST_WARNING_OBJECT (ogg, "could not submit packet, error: %d", - result); - gst_ogg_pad_reset (pad); - done = TRUE; - } + if (GST_FLOW_IS_FATAL (result)) + goto could_not_submit; default: GST_WARNING_OBJECT (ogg, @@ -742,6 +741,22 @@ return result; +choked: + GST_WARNING_OBJECT (ogg, + "ogg stream choked on page (serial %08lx), resetting stream", + pad->serialno); + gst_ogg_pad_reset (pad); + /* we continue to recover */ + return GST_FLOW_OK; +could_not_submit: + GST_WARNING_OBJECT (ogg, "could not submit packet, error: %d", result); + return result; @@ -1156,39 +1171,38 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain) gint i; - GstFlowReturn ret; + GList *headers; + GstOggPad *pad; if (chain == ogg->current_chain) return TRUE; gst_ogg_demux_deactivate_current_chain (ogg); + /* first add the pads */ for (i = 0; i < chain->streams->len; i++) { - GstOggPad *pad; - GList *headers; pad = g_array_index (chain->streams, GstOggPad *, i); gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD (pad)); + gst_element_no_more_pads (GST_ELEMENT (ogg)); + ogg->current_chain = chain; + /* then send out the buffers */ + for (i = 0; i < chain->streams->len; i++) { + pad = g_array_index (chain->streams, GstOggPad *, i); for (headers = pad->headers; headers; headers = g_list_next (headers)) { GstBuffer *buffer = GST_BUFFER (headers->data); - ret = gst_pad_push (GST_PAD_CAST (pad), buffer); - if (ret != GST_FLOW_OK) - goto flow_error; + /* we don't care about the return value here */ + gst_pad_push (GST_PAD_CAST (pad), buffer); + /* and free the headers */ + g_list_free (pad->headers); + pad->headers = NULL; - gst_element_no_more_pads (GST_ELEMENT (ogg)); - ogg->current_chain = chain; return TRUE; -flow_error: - { - return FALSE; static gboolean @@ -1930,39 +1944,51 @@ GST_CHAIN_LOCK (ogg); got_chains = gst_ogg_demux_find_chains (ogg); GST_CHAIN_UNLOCK (ogg); - if (!got_chains) { - GST_LOG_OBJECT (ogg, "could not read chains"); - goto pause; - } + if (!got_chains) + goto chain_read_failed; ogg->need_chains = FALSE; ogg->offset = 0; GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); if (ogg->offset == ogg->length) { + ret = GST_FLOW_OK; gst_ogg_demux_send_eos (ogg); goto pause; ret = gst_pad_pull_range (ogg->sinkpad, ogg->offset, CHUNKSIZE, &buffer); - if (ret != GST_FLOW_OK) { - GST_LOG_OBJECT (ogg, "got unexpected %d", ret); + if (ret != GST_FLOW_OK) ogg->offset += GST_BUFFER_SIZE (buffer); ret = gst_ogg_demux_chain (ogg->sinkpad, buffer); - GST_LOG_OBJECT (ogg, "got unexpected %d, pausing", ret); return; + /* ERRORS */ +chain_read_failed: + GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, + ("could not read chains"), ("could not read chains")); + ret = GST_FLOW_ERROR; + goto pause; pause: - GST_LOG_OBJECT (ogg, "pausing task"); - gst_pad_pause_task (ogg->sinkpad); - return; + GST_LOG_OBJECT (ogg, "pausing task, reason %d", ret); + gst_pad_pause_task (ogg->sinkpad); + if (GST_FLOW_IS_FATAL (ret)) { + gst_ogg_demux_send_eos (ogg); + GST_ELEMENT_ERROR (ogg, STREAM, STOPPED, + ("stream stopped, reason %d", ret), + ("stream stopped, reason %d", ret)); + } + return; static void |
From: <wt...@fr...> - 2005-07-21 12:17:54
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Jul 21 2005 05:17:50 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_init), (gst_ogg_pad_event), (gst_ogg_pad_internal_chain), (gst_ogg_pad_typefind), (gst_ogg_demux_chain_elem_pad), (gst_ogg_demux_queue_data), (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), (gst_ogg_pad_submit_page), (gst_ogg_chain_new), (gst_ogg_demux_init), (gst_ogg_demux_deactivate_current_chain), (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek), (gst_ogg_demux_read_chain), (gst_ogg_demux_find_pad), (gst_ogg_demux_collect_chain_info), (gst_ogg_demux_collect_info), (gst_ogg_demux_find_chains), (gst_ogg_demux_chain), (gst_ogg_demux_send_event), (gst_ogg_demux_loop), (gst_ogg_demux_change_state), (gst_ogg_print): Reorganize code to send the right disconts when in streaming mode. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1799&r2=1.1800 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.92&r2=1.93 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1799 retrieving revision 1.1800 diff -u -d -r1.1799 -r1.1800 --- ChangeLog 20 Jul 2005 17:30:45 -0000 1.1799 +++ ChangeLog 21 Jul 2005 12:17:37 -0000 1.1800 @@ -1,3 +1,20 @@ +2005-07-21 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_init), (gst_ogg_pad_event), + (gst_ogg_pad_internal_chain), (gst_ogg_pad_typefind), + (gst_ogg_demux_chain_elem_pad), (gst_ogg_demux_queue_data), + (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), + (gst_ogg_pad_submit_page), (gst_ogg_chain_new), + (gst_ogg_demux_init), (gst_ogg_demux_deactivate_current_chain), + (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek), + (gst_ogg_demux_read_chain), (gst_ogg_demux_find_pad), + (gst_ogg_demux_collect_chain_info), (gst_ogg_demux_collect_info), + (gst_ogg_demux_find_chains), (gst_ogg_demux_chain), + (gst_ogg_demux_send_event), (gst_ogg_demux_loop), + (gst_ogg_demux_change_state), (gst_ogg_print): + Reorganize code to send the right disconts when in streaming + mode. 2005-07-20 Andy Wingo <wi...@po...> * gst/videoscale/vs_image.c (vs_image_scale_nearest_YUYV): Typo Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.92 retrieving revision 1.93 diff -u -d -r1.92 -r1.93 --- gstoggdemux.c 16 Jul 2005 14:47:26 -0000 1.92 +++ gstoggdemux.c 21 Jul 2005 12:17:37 -0000 1.93 @@ -75,11 +75,11 @@ GstClockTime total_time; /* the total time of this chain, this is the MAX of the totals of all streams */ - GstClockTime start_time; /* the timestamp of the first sample */ - GstClockTime last_time; /* the timestamp of the last page == last sample */ - + GstClockTime start_time; /* the timestamp of the first sample, this is the MIN of + the start times of all streams. */ + GstClockTime last_time; /* the timestamp of the last page, this is the MAX of the + streams. */ GstClockTime begin_time; /* when this chain starts in the stream */ } GstOggChain; /* different modes for the pad */ @@ -97,6 +97,7 @@ { PARENT pad; /* subclass GstPad */ + gboolean have_type; GstOggPadMode mode; GstPad *elem_pad; /* sinkpad of internal element */ @@ -110,11 +111,6 @@ gint serialno; gint64 packetno; - gint64 offset; - gint64 start; - gint64 stop; gint64 current_granule; GstClockTime start_time; /* the timestamp of the first sample */ @@ -155,18 +151,24 @@ OggState state; gboolean seekable; + gboolean running; gboolean need_chains; /* state */ GMutex *chain_lock; /* we need the lock to protect the chains */ GArray *chains; /* list of chains we know */ + GstClockTime start_time; /* the start time of the first chain */ GstClockTime total_time; /* the total time of this ogg, this is the sum of the totals of all chains */ GstOggChain *current_chain; GstOggChain *building_chain; + /* playback start/stop positions */ + GstClockTime segment_start; + GstClockTime segment_stop; + gboolean segment_play; /* ogg stuff */ ogg_sync_state sync; }; @@ -182,7 +184,12 @@ GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); -static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg, gint64 pos); +static gboolean gst_ogg_demux_collect_chain_info (GstOggDemux * ogg, + GstOggChain * chain); +static gboolean gst_ogg_demux_activate_chain (GstOggDemux * ogg, + GstOggChain * chain, GstEvent * event); +static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg, gboolean flush); static void gst_ogg_pad_class_init (GstOggPadClass * klass); static void gst_ogg_pad_init (GstOggPad * pad); @@ -256,10 +263,12 @@ pad->last_granule = -1; pad->current_granule = -1; - pad->start_time = -1; - pad->first_time = -1; - pad->last_time = -1; + pad->start_time = GST_CLOCK_TIME_NONE; + pad->first_time = GST_CLOCK_TIME_NONE; + pad->last_time = GST_CLOCK_TIME_NONE; + pad->total_time = GST_CLOCK_TIME_NONE; + pad->have_type = FALSE; pad->headers = NULL; } @@ -382,23 +391,44 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { - gint64 offset; + gboolean running; + gboolean flush; - /* can't seek if we are not seekable */ + /* can't seek if we are not seekable, FIXME could pass the + * seek query upstream after converting it to bytes using + * the average bitrate of the stream. */ if (!ogg->seekable) { res = FALSE; + GST_DEBUG ("seek on non seekable stream"); goto done_unref; } /* we can only seek on time */ if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_TIME) { + GST_DEBUG ("can only seek on TIME"); - offset = GST_EVENT_SEEK_OFFSET (event); + ogg->segment_start = GST_EVENT_SEEK_OFFSET (event); + ogg->segment_stop = GST_EVENT_SEEK_ENDOFFSET (event); + ogg->segment_play = + !!(GST_EVENT_SEEK_TYPE (event) & GST_SEEK_FLAG_SEGMENT_LOOP); + flush = !!(GST_EVENT_SEEK_TYPE (event) & GST_SEEK_FLAG_FLUSH); gst_event_unref (event); + GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" + GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment_start), + GST_TIME_ARGS (ogg->segment_stop)); + /* check if we can do the seek now */ + GST_LOCK (ogg); + running = ogg->running; + GST_UNLOCK (ogg); /* now do the seek */ - res = gst_ogg_demux_perform_seek (ogg, offset); + if (running) { + res = gst_ogg_demux_perform_seek (ogg, flush); + } else + res = TRUE; break; } default: @@ -409,6 +439,7 @@ return res; done_unref: + GST_DEBUG ("error handling event"); gst_event_unref (event); @@ -506,7 +537,7 @@ GST_DEBUG_OBJECT (oggpad, "received buffer from iternal pad, TS=%lld", timestamp); - if (oggpad->start_time == -1) + if (oggpad->start_time == GST_CLOCK_TIME_NONE) oggpad->start_time = timestamp; gst_buffer_unref (buffer); @@ -539,53 +570,48 @@ caps = gst_caps_new_simple ("application/octet-stream", NULL); } else { /* ogg requires you to use a decoder element to define the - * meaning of granulepos etc so we make one. We only do this if - * we are in the seeking mode. */ - if (ogg->seekable) { - GList *factories; + * meaning of granulepos etc so we make one. We also do this if + * we are in the streaming mode to calculate the first timestamp. */ + GList *factories; - /* first filter out the interesting element factories */ - factories = gst_registry_pool_feature_filter ( - (GstPluginFeatureFilter) gst_ogg_demux_factory_filter, FALSE, caps); + /* first filter out the interesting element factories */ + factories = gst_registry_pool_feature_filter ( + (GstPluginFeatureFilter) gst_ogg_demux_factory_filter, FALSE, caps); - /* sort them according to their ranks */ - factories = g_list_sort (factories, (GCompareFunc) compare_ranks); + /* sort them according to their ranks */ + factories = g_list_sort (factories, (GCompareFunc) compare_ranks); - /* then pick the first factory to create an element */ - if (factories) { - element = - gst_element_factory_create (GST_ELEMENT_FACTORY (factories->data), - NULL); - if (element) { - /* this is ours */ - gst_object_ref (element); - gst_object_sink (GST_OBJECT (element)); + /* then pick the first factory to create an element */ + if (factories) { + element = + gst_element_factory_create (GST_ELEMENT_FACTORY (factories->data), + NULL); + if (element) { + /* this is ours */ + gst_object_ref (element); + gst_object_sink (GST_OBJECT (element)); - /* FIXME, it might not be named "sink" */ - pad->elem_pad = gst_element_get_pad (element, "sink"); - gst_element_set_state (element, GST_STATE_PAUSED); - pad->elem_out = - gst_pad_new_from_template (gst_static_pad_template_get - (&internaltemplate), "internal"); - gst_pad_set_chain_function (pad->elem_out, - gst_ogg_pad_internal_chain); - gst_pad_set_element_private (pad->elem_out, pad); - gst_pad_set_active (pad->elem_out, TRUE); + /* FIXME, it might not be named "sink" */ + pad->elem_pad = gst_element_get_pad (element, "sink"); + gst_element_set_state (element, GST_STATE_PAUSED); + pad->elem_out = + gst_pad_new_from_template (gst_static_pad_template_get + (&internaltemplate), "internal"); + gst_pad_set_chain_function (pad->elem_out, gst_ogg_pad_internal_chain); + gst_pad_set_element_private (pad->elem_out, pad); + gst_pad_set_active (pad->elem_out, TRUE); - /* and this pad may not be named src.. */ - { - GstPad *p; + /* and this pad may not be named src.. */ + { + GstPad *p; - p = gst_element_get_pad (element, "src"); - gst_pad_link (p, pad->elem_out); - gst_object_unref (p); - } + p = gst_element_get_pad (element, "src"); + gst_pad_link (p, pad->elem_out); + gst_object_unref (p); } - g_list_free (factories); - } else { - pad->mode = GST_OGG_PAD_MODE_STREAMING; + g_list_free (factories); } pad->element = element; @@ -595,6 +621,96 @@ return TRUE; +/* send packet to internal element */ +static GstFlowReturn +gst_ogg_demux_chain_elem_pad (GstOggPad * pad, ogg_packet * packet) +{ + GstBuffer *buf; + GstFlowReturn ret; + GstOggDemux *ogg = pad->ogg; + /* initialize our internal decoder with packets */ + if (!pad->elem_pad) + goto no_decoder; + GST_DEBUG_OBJECT (ogg, "%p init decoder serial %08lx", pad, pad->serialno); + buf = gst_buffer_new_and_alloc (packet->bytes); + memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes); + gst_buffer_set_caps (buf, GST_PAD_CAPS (pad)); + GST_BUFFER_OFFSET (buf) = -1; + GST_BUFFER_OFFSET_END (buf) = packet->granulepos; + ret = gst_pad_chain (pad->elem_pad, buf); + if (GST_FLOW_IS_FATAL (ret)) + goto decoder_error; + return ret; +no_decoder: + { + GST_WARNING_OBJECT (ogg, + "pad %08lx does not have elem_pad, no decoder ?", pad); + return GST_FLOW_ERROR; + } +decoder_error: + GST_WARNING_OBJECT (ogg, "internal decoder error"); +} +/* queue data */ +gst_ogg_demux_queue_data (GstOggPad * pad, ogg_packet * packet) + GST_DEBUG_OBJECT (ogg, "%p queueing data serial %08lx", pad, pad->serialno); + memcpy (buf->data, packet->packet, packet->bytes); + pad->headers = g_list_append (pad->headers, buf); + /* we are ok now */ + return GST_FLOW_OK; +gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet) + ret = gst_pad_alloc_buffer (GST_PAD (pad), GST_BUFFER_OFFSET_NONE, + packet->bytes, GST_PAD_CAPS (pad), &buf); + GST_DEBUG_OBJECT (ogg, + "%p streaming to peer serial %08lx", pad, pad->serialno); + if (ret == GST_FLOW_OK) { + memcpy (buf->data, packet->packet, packet->bytes); + GST_BUFFER_OFFSET (buf) = -1; + GST_BUFFER_OFFSET_END (buf) = packet->granulepos; + ret = gst_pad_push (GST_PAD (pad), buf); + } else { + GST_DEBUG_OBJECT (ogg, + "%p could not get buffer from peer %08lx", pad, pad->serialno); + if (ret == GST_FLOW_NOT_LINKED) + ret = GST_FLOW_OK; /* submit a packet to the oggpad, this function will run the * typefind code for the pad if this is the first packet for this * stream @@ -602,15 +718,12 @@ static GstFlowReturn gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet) - GstBuffer *buf; gint64 granule; - GstFlowReturn ret = GST_FLOW_OK; GstOggDemux *ogg = pad->ogg; - GST_DEBUG_OBJECT (ogg, - "%p submit packet serial %08lx, packetno %lld", pad, pad->serialno, - pad->packetno); + GST_DEBUG_OBJECT (ogg, "%p submit packet serial %08lx", pad, pad->serialno); granule = packet->granulepos; if (granule != -1) { @@ -619,84 +732,48 @@ pad->first_granule = granule; - /* first packet, FIXME, do this in chain activation */ - if (pad->packetno == 0) { + /* first packet */ + if (!pad->have_type) { gst_ogg_pad_typefind (pad, packet); + pad->have_type = TRUE; - /* stream packet to peer plugin */ - if (pad->mode == GST_OGG_PAD_MODE_STREAMING) { - ret = - gst_pad_alloc_buffer (GST_PAD (pad), GST_BUFFER_OFFSET_NONE, - packet->bytes, GST_PAD_CAPS (pad), &buf); - GST_DEBUG_OBJECT (ogg, - "%p streaming to peer serial %08lx, packetno %lld", pad, pad->serialno, - pad->packetno); - if (ret == GST_FLOW_OK) { - memcpy (buf->data, packet->packet, packet->bytes); + /* no start time known, stream to internal plugin to + * get time */ + if (pad->start_time == GST_CLOCK_TIME_NONE) { + ret = gst_ogg_demux_chain_elem_pad (pad, packet); + /* we know the start_time of the pad data, see if we + * can activate the complete chain if this is a dynamic + * chain. */ + if (pad->start_time != GST_CLOCK_TIME_NONE) { + /* check if complete chain has start time */ + if (pad->chain == ogg->building_chain) { + if (gst_ogg_demux_collect_chain_info (ogg, pad->chain)) { + GstEvent *event; - pad->offset = packet->granulepos; - GST_BUFFER_OFFSET (buf) = -1; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos; + /* create the discont event we are going to send out */ + event = gst_event_new_discontinuous (1.0, + GST_FORMAT_TIME, (gint64) pad->chain->start_time, + (gint64) pad->chain->last_time, NULL); - ret = gst_pad_push (GST_PAD (pad), buf); - GST_DEBUG_OBJECT (ogg, - "%p could not get buffer from peer %08lx, packetno %lld", pad, - pad->serialno, pad->packetno); + gst_ogg_demux_activate_chain (ogg, pad->chain, event); - /* if we are still building a chain, we have to queue this buffer and - * push it when we activate the chain */ - if (ogg->building_chain) { - buf = gst_buffer_new_and_alloc (packet->bytes); - memcpy (buf->data, packet->packet, packet->bytes); - pad->offset = packet->granulepos; - GST_BUFFER_OFFSET (buf) = -1; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos; - pad->headers = g_list_append (pad->headers, buf); - /* we are ok now */ - ret = GST_FLOW_OK; + ogg->building_chain = NULL; - /* we just ignore unlinked pads */ - if (ret == GST_FLOW_NOT_LINKED) - ret = GST_FLOW_OK; - } else { - /* initialize our internal decoder with packets */ - if (!pad->elem_pad) - goto no_decoder; - "%p init decoder serial %08lx, packetno %lld", pad, pad->serialno, - buf = gst_buffer_new_and_alloc (packet->bytes); - memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes); - gst_buffer_set_caps (buf, GST_PAD_CAPS (pad)); - GST_BUFFER_OFFSET (buf) = -1; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos; - ret = gst_pad_chain (pad->elem_pad, buf); - if (GST_FLOW_IS_FATAL (ret)) - goto decoder_error; - pad->packetno++; - return ret; -no_decoder: - { - GST_WARNING_OBJECT (ogg, - "pad %08lx does not have elem_pad, no decoder ?", pad); - return GST_FLOW_ERROR; + /* if we are building a chain, store buffer for when we activate + * it. This path is taken if we operate in streaming mode. */ + if (ogg->building_chain) { + ret = gst_ogg_demux_queue_data (pad, packet); -decoder_error: - GST_WARNING_OBJECT (ogg, "internal decoder error"); + /* else we are completely streaming to the peer */ + else { + ret = gst_ogg_demux_chain_peer (pad, packet); /* submit a page to an oggpad, this function will then submit all @@ -771,6 +848,8 @@ chain->bytes = -1; chain->have_bos = FALSE; chain->streams = g_array_new (FALSE, TRUE, sizeof (GstOggPad *)); + chain->start_time = GST_CLOCK_TIME_NONE; + chain->total_time = GST_CLOCK_TIME_NONE; return chain; @@ -951,6 +1030,12 @@ ogg->chain_lock = g_mutex_new (); ogg->chains = g_array_new (FALSE, TRUE, sizeof (GstOggChain *)); ogg->state = OGG_STATE_NEW_CHAIN; + ogg->segment_start = GST_CLOCK_TIME_NONE; + ogg->segment_stop = GST_CLOCK_TIME_NONE; + ogg->segment_play = FALSE; + ogg->running = FALSE; static void @@ -1153,13 +1238,15 @@ if (chain == NULL) return TRUE; + /* send EOS on all the pads */ for (i = 0; i < chain->streams->len; i++) { GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i); gst_pad_push_event (GST_PAD (pad), gst_event_new (GST_EVENT_EOS)); gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD (pad)); - /* if we cannot seek, we can destroy the chain completely */ + /* if we cannot seek back to the chain, we can destroy the chain + * completely */ if (!ogg->seekable) { gst_ogg_chain_free (chain); @@ -1169,20 +1256,25 @@ static gboolean -gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain) +gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, + GstEvent * event) gint i; - GList *headers; - GstOggPad *pad; - GstEvent *event; - if (chain == ogg->current_chain) + if (chain == ogg->current_chain) { + if (event) + gst_event_unref (event); gst_ogg_demux_deactivate_current_chain (ogg); + GST_DEBUG ("activating chain"); /* first add the pads */ + GstOggPad *pad; pad = g_array_index (chain->streams, GstOggPad *, i); gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD (pad)); @@ -1190,15 +1282,19 @@ gst_element_no_more_pads (GST_ELEMENT (ogg)); ogg->current_chain = chain; - /* send the base time */ - event = gst_event_new_discontinuous (1.0, - GST_FORMAT_TIME, (gint64) chain->start_time, (gint64) chain->total_time, - NULL); + if (event) + gst_ogg_demux_send_event (ogg, event); - gst_ogg_demux_send_event (ogg, event); + GST_DEBUG ("starting chain"); - /* then send out the buffers */ + /* we are streaming now */ + ogg->state = OGG_STATE_STREAMING; + /* then send out any queued buffers */ + GList *headers; for (headers = pad->headers; headers; headers = g_list_next (headers)) { @@ -1215,7 +1311,7 @@ -gst_ogg_demux_perform_seek (GstOggDemux * ogg, gint64 pos) +gst_ogg_demux_perform_seek (GstOggDemux * ogg, gboolean flush) GstOggChain *chain = NULL; gint64 begin, end; @@ -1226,18 +1322,22 @@ gint64 result = 0; - total = ogg->total_time; + /* nothing configured, play complete file */ + if (ogg->segment_start == GST_CLOCK_TIME_NONE) + ogg->segment_start = ogg->start_time; + if (ogg->segment_stop == GST_CLOCK_TIME_NONE) + ogg->segment_stop = ogg->total_time; - /* can't seek past start or end */ - if (pos < 0 || pos > total) { - return FALSE; - } + ogg->segment_start = + CLAMP (ogg->segment_start, ogg->start_time, ogg->total_time); + ogg->segment_stop = + CLAMP (ogg->segment_stop, ogg->start_time, ogg->total_time); /* first step is to unlock the streaming thread if it is * blocked in a chain call, we do this by starting the flush. because * we cannot yet hold any streaming lock, we have to protect the chains * with their own lock. */ + if (flush) { gint i; gst_pad_push_event (ogg->sinkpad, gst_event_new_flush (FALSE)); @@ -1247,7 +1347,6 @@ GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); gint j; for (j = 0; j < chain->streams->len; j++) { GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j); @@ -1255,16 +1354,19 @@ GST_CHAIN_UNLOCK (ogg); + gst_pad_pause_task (ogg->sinkpad); - /* now grab the stream lock so that streaming cannot continue */ + /* now grab the stream lock so that streaming cannot continue, for + * non flushing seeks when the element is in PAUSED this could block + * forever. */ GST_STREAM_LOCK (ogg->sinkpad); - /* we need to stop flushing on the srcpad as w're going to use it + /* we need to stop flushing on the srcpad as we're going to use it * next. We can do this as we have the STREAM lock now. */ gst_pad_push_event (ogg->sinkpad, gst_event_new_flush (TRUE)); { @@ -1283,10 +1385,11 @@ /* first find the chain to search in */ + total = ogg->total_time; for (i = ogg->chains->len - 1; i >= 0; i--) { chain = g_array_index (ogg->chains, GstOggChain *, i); total -= chain->total_time; - if (pos >= total) + if (ogg->segment_start >= total) @@ -1294,11 +1397,13 @@ end = chain->end_offset; begintime = chain->begin_time; endtime = chain->begin_time + chain->total_time; - target = pos - total + begintime; + target = ogg->segment_start - total + begintime; best = begin; - GST_DEBUG_OBJECT (ogg, "seeking to %" GST_TIME_FORMAT " in chain %p", - GST_TIME_ARGS (pos), chain); + "seeking to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT " in chain %p", + GST_TIME_ARGS (ogg->segment_start), GST_TIME_ARGS (ogg->segment_stop), + chain); GST_DEBUG_OBJECT (ogg, "chain offset %" G_GINT64_FORMAT ", end offset %" G_GINT64_FORMAT, begin, end); @@ -1407,6 +1512,10 @@ ogg->offset = best; + /* switch to different chain */ + if (chain != ogg->current_chain) { + gst_ogg_demux_activate_chain (ogg, chain, NULL); /* now we have a new position, prepare for streaming again */ @@ -1414,7 +1523,8 @@ /* create the discont event we are going to send out */ event = gst_event_new_discontinuous (1.0, - GST_FORMAT_TIME, (gint64) pos, (gint64) ogg->total_time, NULL); + GST_FORMAT_TIME, (gint64) ogg->segment_start, + (gint64) ogg->segment_stop, NULL); for (i = 0; i < ogg->chains->len; i++) { @@ -1423,7 +1533,8 @@ - gst_pad_push_event (GST_PAD (pad), gst_event_new_flush (TRUE)); + if (flush) + gst_pad_push_event (GST_PAD (pad), gst_event_new_flush (TRUE)); /* and the discont */ gst_event_ref (event); @@ -1431,17 +1542,18 @@ gst_event_unref (event); + /* notify start of new segment */ + if (ogg->segment_play) { + gst_element_post_message (GST_ELEMENT (ogg), + gst_message_new_segment_start (GST_OBJECT (ogg), ogg->segment_start)); + } /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop, ogg->sinkpad); - /* switch to different chain */ - if (chain != ogg->current_chain) { - gst_ogg_demux_activate_chain (ogg, chain); /* streaming can continue now */ GST_STREAM_UNLOCK (ogg->sinkpad); @@ -1593,7 +1705,7 @@ gst_ogg_pad_submit_page (pad, &op); /* the timestamp will be filled in when we submit the pages */ - done &= (pad->start_time != -1); + done &= (pad->start_time != GST_CLOCK_TIME_NONE); GST_LOG_OBJECT (ogg, "done %08lx now %d", serial, done); @@ -1617,7 +1729,6 @@ pad->mode = GST_OGG_PAD_MODE_STREAMING; - pad->packetno = 0; @@ -1692,7 +1803,14 @@ GstOggPad *pad; - /* first look in current chain if any */ + /* first look in building chain if any */ + pad = gst_ogg_chain_get_stream (ogg->building_chain, serialno); + if (pad) + return pad; + /* then look in current chain if any */ if (ogg->current_chain) { pad = gst_ogg_chain_get_stream (ogg->current_chain, serialno); if (pad) @@ -1723,6 +1841,67 @@ return NULL; +static gboolean +gst_ogg_demux_collect_chain_info (GstOggDemux * ogg, GstOggChain * chain) + gint i; + chain->total_time = 0; + chain->start_time = G_MAXINT64; + chain->last_time = 0; + for (i = 0; i < chain->streams->len; i++) { + GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i); + /* can do this if the pad start time is not defined */ + if (pad->start_time == GST_CLOCK_TIME_NONE) + goto no_start_time; + if (pad->last_time != GST_CLOCK_TIME_NONE) { + pad->total_time = pad->last_time - pad->start_time; + chain->total_time = MAX (chain->total_time, pad->total_time); + chain->last_time = MAX (chain->last_time, pad->last_time); + } else { + pad->total_time = GST_CLOCK_TIME_NONE; + chain->total_time = GST_CLOCK_TIME_NONE; + chain->last_time = GST_CLOCK_TIME_NONE; + chain->start_time = MIN (chain->start_time, pad->start_time); + return TRUE; + /* ERROR */ +no_start_time: + chain->total_time = GST_CLOCK_TIME_NONE; + chain->start_time = GST_CLOCK_TIME_NONE; + chain->last_time = GST_CLOCK_TIME_NONE; + chain->begin_time = GST_CLOCK_TIME_NONE; + return FALSE; +static void +gst_ogg_demux_collect_info (GstOggDemux * ogg) + /* collect all info */ + ogg->start_time = G_MAXINT64; + ogg->total_time = 0; + for (i = 0; i < ogg->chains->len; i++) { + GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); + chain->begin_time = ogg->total_time; + gst_ogg_demux_collect_chain_info (ogg, chain); + ogg->start_time = MIN (ogg->start_time, chain->start_time); + ogg->total_time += chain->total_time; /* find all the chains in the ogg file, this reads the first and * last page of the ogg stream, if they match then the ogg file has * just one chain, else we do a binary search for all chains. @@ -1774,44 +1953,11 @@ gst_ogg_demux_bisect_forward_serialno (ogg, 0, ogg->length, ogg->length, chain, 0); - /* collect all info */ - gint i, j; - ogg->total_time = 0; - for (i = 0; i < ogg->chains->len; i++) { - GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); - chain->total_time = 0; - chain->start_time = G_MAXINT64; - chain->last_time = 0; - chain->begin_time = ogg->total_time; - for (j = 0; j < chain->streams->len; j++) { - GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j); - pad->total_time = pad->last_time - pad->start_time; - chain->total_time = MAX (chain->total_time, pad->total_time); - chain->start_time = MIN (chain->start_time, pad->start_time); - chain->last_time = MAX (chain->last_time, pad->last_time); - } - ogg->total_time += chain->total_time; - } + gst_ogg_demux_collect_info (ogg); /* dump our chains and streams */ gst_ogg_print (ogg); - /* activate first chain */ - if (ogg->chains->len > 0) { - GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, 0); - /* and we are streaming now */ - ogg->state = OGG_STATE_STREAMING; /*** error cases ***/ @@ -1875,7 +2021,7 @@ chain = gst_ogg_demux_find_chain (ogg, serialno); if (chain) { /* we do, activate it as it means we have a non-header */ - gst_ogg_demux_activate_chain (ogg, chain); + gst_ogg_demux_activate_chain (ogg, chain, NULL); pad = gst_ogg_demux_find_pad (ogg, serialno); } else { /* chain is unknown */ @@ -1892,13 +2038,6 @@ pad = gst_ogg_chain_new_stream (ogg->building_chain, serialno); } else { - /* no more bos pages, see if we need to activate the chain we were - * building */ - if (ogg->building_chain) { - gst_ogg_demux_activate_chain (ogg, ogg->building_chain); - ogg->building_chain = NULL; - ogg->state = OGG_STATE_STREAMING; - } pad = gst_ogg_demux_find_pad (ogg, serialno); if (pad) { @@ -1959,13 +2098,28 @@ goto chain_read_failed; ogg->need_chains = FALSE; - ogg->offset = 0; + GST_LOCK (ogg); + ogg->running = TRUE; + GST_UNLOCK (ogg); + /* and seek to configured positions without FLUSH */ + gst_ogg_demux_perform_seek (ogg, FALSE); GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); if (ogg->offset == ogg->length) { ret = GST_FLOW_OK; - gst_ogg_demux_send_event (ogg, gst_event_new (GST_EVENT_EOS)); + /* segment playback just posts a segment end message instead of + * pushing out EOS. */ + /* FIXME, need to be done somewhere else where we + * can check against segment_stop time. */ + gst_message_new_segment_done (GST_OBJECT (ogg), ogg->total_time)); + gst_ogg_demux_send_event (ogg, gst_event_new (GST_EVENT_EOS)); goto pause; @@ -2020,6 +2174,12 @@ GST_CHAIN_UNLOCK (ogg); +/* this function is called when the pad is activated and should start + * processing data. + * + * We check if we can do random access to decide if we work push or + * pull based. + */ gst_ogg_demux_sink_activate (GstPad * sinkpad) @@ -2030,6 +2190,8 @@ +/* this function gets called when we activate ourselves in push mode. + * We cannot seek (ourselves) in the stream */ gst_ogg_demux_sink_activate_push (GstPad * sinkpad, gboolean active) @@ -2042,6 +2204,9 @@ +/* this function gets called when we activate ourselves in pull mode. + * We can perform random access to the resource and we start a task + * to start reading */ gst_ogg_demux_sink_activate_pull (GstPad * sinkpad, gboolean active) @@ -2086,6 +2251,9 @@ case GST_STATE_PAUSED_TO_READY: gst_ogg_demux_clear_chains (ogg); + ogg->running = FALSE; case GST_STATE_READY_TO_NULL: ogg_sync_clear (&ogg->sync); @@ -2192,7 +2360,9 @@ guint j, i; - GST_INFO_OBJECT (ogg, "%u chains, total time: %" GST_TIME_FORMAT, + GST_INFO_OBJECT (ogg, "%u chains, start time: %" GST_TIME_FORMAT, + ogg->chains->len, GST_TIME_ARGS (ogg->start_time)); + GST_INFO_OBJECT (ogg, " total time: %" GST_TIME_FORMAT, ogg->chains->len, GST_TIME_ARGS (ogg->total_time)); for (i = 0; i < ogg->chains->len; i++) { @@ -2201,8 +2371,12 @@ GST_INFO_OBJECT (ogg, " chain %d (%u streams):", i, chain->streams->len); GST_INFO_OBJECT (ogg, " offset: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT, chain->offset, chain->end_offset); + GST_INFO_OBJECT (ogg, " start time: %" GST_TIME_FORMAT, + GST_TIME_ARGS (chain->start_time)); GST_INFO_OBJECT (ogg, " total time: %" GST_TIME_FORMAT, GST_TIME_ARGS (chain->total_time)); + GST_INFO_OBJECT (ogg, " begin time: %" GST_TIME_FORMAT, + GST_TIME_ARGS (chain->begin_time)); for (j = 0; j < chain->streams->len; j++) { GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, j); |
From: <wt...@fr...> - 2005-10-18 13:20:49
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Oct 18 2005 06:20:45 PDT Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_chain_peer), (gst_ogg_demux_perform_seek), (gst_ogg_demux_loop): Fix for segment-start/stop API change. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2000&r2=1.2001 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.106&r2=1.107 ====Begin Diffs==== Index: gstoggdemux.c =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.106 retrieving revision 1.107 diff -u -d -r1.106 -r1.107 --- gstoggdemux.c 11 Oct 2005 16:30:54 -0000 1.106 +++ gstoggdemux.c 18 Oct 2005 13:20:29 -0000 1.107 @@ -749,7 +749,7 @@ if (ret == GST_FLOW_NOT_LINKED) ret = GST_FLOW_OK; - if (packet->granulepos != -1) { + if (packet->granulepos >= 0) { GstFormat format; ogg->current_granule = packet->granulepos; @@ -1472,6 +1472,9 @@ /* first find the chain to search in */ total = ogg->total_time; + if (ogg->chains->len == 0) + goto no_chains; + for (i = ogg->chains->len - 1; i >= 0; i--) { chain = g_array_index (ogg->chains, GstOggChain *, i); total -= chain->total_time; @@ -1633,7 +1636,8 @@ /* notify start of new segment */ if (ogg->segment_play) { gst_element_post_message (GST_ELEMENT (ogg), - gst_message_new_segment_start (GST_OBJECT (ogg), ogg->segment_start)); + gst_message_new_segment_start (GST_OBJECT (ogg), GST_FORMAT_TIME, + ogg->segment_start)); } /* restart our task since it might have been stopped when we did the * flush. */ @@ -1646,11 +1650,20 @@ return TRUE; +no_chains: + { + GST_DEBUG_OBJECT (ogg, "no chains"); + GST_STREAM_UNLOCK (ogg->sinkpad); + return FALSE; + } seek_error: - GST_DEBUG_OBJECT (ogg, "got a seek error"); - GST_STREAM_UNLOCK (ogg->sinkpad); + GST_DEBUG_OBJECT (ogg, "got a seek error"); - return FALSE; } /* finds each bitstream link one at a time using a bisection search @@ -2243,7 +2256,8 @@ * can check against segment_stop time. */ - gst_message_new_segment_done (GST_OBJECT (ogg), ogg->total_time)); + gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME, + ogg->total_time)); } else { gst_ogg_demux_send_event (ogg, gst_event_new_eos ()); Index: ChangeLog RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2000 retrieving revision 1.2001 diff -u -d -r1.2000 -r1.2001 --- ChangeLog 18 Oct 2005 11:13:33 -0000 1.2000 +++ ChangeLog 18 Oct 2005 13:20:29 -0000 1.2001 @@ -1,5 +1,11 @@ 2005-10-18 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_demux_chain_peer), + (gst_ogg_demux_perform_seek), (gst_ogg_demux_loop): + Fix for segment-start/stop API change. +2005-10-18 Wim Taymans <wi...@fl...> * check/Makefile.am: * check/clocks/selection.c: (GST_START_TEST), (volume_suite), (main): |
From: <wt...@fr...> - 2005-11-10 18:01:49
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Nov 10 2005 10:01:40 PST Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_event), (gst_ogg_demux_init), (gst_ogg_demux_configure_segment), (gst_ogg_demux_perform_seek), (gst_ogg_demux_loop), (gst_ogg_demux_change_state): Modernise the seek code. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2058&r2=1.2059 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.112&r2=1.113 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2058 retrieving revision 1.2059 diff -u -d -r1.2058 -r1.2059 --- ChangeLog 10 Nov 2005 17:29:48 -0000 1.2058 +++ ChangeLog 10 Nov 2005 18:01:28 -0000 1.2059 @@ -1,3 +1,10 @@ +2005-11-10 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_event), (gst_ogg_demux_init), + (gst_ogg_demux_configure_segment), (gst_ogg_demux_perform_seek), + (gst_ogg_demux_loop), (gst_ogg_demux_change_state): + Modernise the seek code. 2005-11-10 Michael Smith <ms...@fl...> * gst/playback/gstplaybasebin.c: (group_commit), (new_decoded_pad), Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.112 retrieving revision 1.113 diff -u -d -r1.112 -r1.113 --- gstoggdemux.c 8 Nov 2005 12:12:55 -0000 1.112 +++ gstoggdemux.c 10 Nov 2005 18:01:28 -0000 1.113 @@ -154,10 +154,10 @@ GstOggChain *building_chain; /* playback start/stop positions */ + gdouble segment_rate; + GstSeekFlags segment_flags; GstClockTime segment_start; GstClockTime segment_stop; - gboolean segment_play; - gdouble segment_rate; gint64 current_granule; GstClockTime current_time; @@ -182,8 +182,9 @@ static gboolean gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, GstEvent * event); -static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg, - gboolean accurate, gboolean flush); +static gboolean gst_ogg_demux_configure_segment (GstOggDemux * ogg, + GstEvent * event, gboolean * running); +static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg); static void gst_ogg_pad_class_init (GstOggPadClass * klass); static void gst_ogg_pad_init (GstOggPad * pad); @@ -398,12 +399,6 @@ case GST_EVENT_SEEK: { gboolean running; - gboolean flush, accurate; - GstFormat format; - gdouble rate; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; /* can't seek if we are not seekable, FIXME could pass the * seek query upstream after converting it to bytes using @@ -413,49 +408,14 @@ goto error; } - gst_event_parse_seek (event, &rate, &format, &flags, - &cur_type, &cur, &stop_type, &stop); - - /* we can only seek on time */ - if (format != GST_FORMAT_TIME) { - GST_DEBUG ("can only seek on TIME"); - goto error; - } - /* cannot yet do backwards playback */ - if (rate <= 0.0) { - GST_DEBUG ("can only seek with positive rate"); + if (!gst_ogg_demux_configure_segment (ogg, event, &running)) { + GST_DEBUG ("configure segment failed"); - /* store start and stop values */ - GST_LOCK (ogg); - if (cur_type == GST_SEEK_TYPE_SET) - ogg->segment_start = cur; - else if (cur_type == GST_SEEK_TYPE_CUR) - ogg->segment_start += cur; - if (stop_type != GST_SEEK_TYPE_NONE) - ogg->segment_stop = stop; - else if (stop_type == GST_SEEK_TYPE_CUR) - ogg->segment_stop += cur; - ogg->segment_rate = rate; - ogg->segment_play = !!(flags & GST_SEEK_FLAG_SEGMENT); - flush = (flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH; - accurate = (flags & GST_SEEK_FLAG_ACCURATE) == GST_SEEK_FLAG_ACCURATE; - gst_event_unref (event); - GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" - GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment_start), - GST_TIME_ARGS (ogg->segment_stop)); - /* check if we can do the seek now */ - running = ogg->running; - GST_UNLOCK (ogg); /* now do the seek */ if (running) { - res = gst_ogg_demux_perform_seek (ogg, accurate, flush); + res = gst_ogg_demux_perform_seek (ogg); } else res = TRUE; break; @@ -1135,16 +1095,6 @@ ogg->chain_lock = g_mutex_new (); ogg->chains = g_array_new (FALSE, TRUE, sizeof (GstOggChain *)); - ogg->current_granule = -1; - ogg->current_time = 0; - ogg->segment_rate = 1.0; - ogg->segment_start = GST_CLOCK_TIME_NONE; - ogg->segment_stop = GST_CLOCK_TIME_NONE; - ogg->segment_play = FALSE; - ogg->total_time = GST_CLOCK_TIME_NONE; - ogg->running = FALSE; } static void @@ -1417,10 +1367,120 @@ static gboolean -gst_ogg_demux_perform_seek (GstOggDemux * ogg, gboolean accurate, - gboolean flush) +gst_ogg_demux_configure_segment (GstOggDemux * ogg, GstEvent * event, + gboolean * running) +{ + GstFormat format; + gdouble rate; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gboolean update_start, update_stop; + gst_event_parse_seek (event, &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + /* we can only seek on time */ + if (format != GST_FORMAT_TIME) { + GST_DEBUG ("can only seek on TIME"); + goto error; + } + /* cannot yet do backwards playback */ + if (rate <= 0.0) { + GST_DEBUG ("can only seek with positive rate, not %lf", rate); + /* assume we'll update both start and stop values */ + update_start = TRUE; + update_stop = TRUE; + /* perform the seek, segment_start is never invalid */ + switch (cur_type) { + case GST_SEEK_TYPE_NONE: + /* no update to segment */ + cur = ogg->segment_start; + update_start = FALSE; + break; + case GST_SEEK_TYPE_SET: + /* cur holds desired position */ + case GST_SEEK_TYPE_CUR: + /* add cur to currently configure segment */ + cur = ogg->segment_start + cur; + case GST_SEEK_TYPE_END: + /* add cur to total length */ + cur = ogg->total_time + cur; + /* bring in sane range */ + if (ogg->total_time != -1) + cur = CLAMP (cur, 0, ogg->total_time); + else + cur = MAX (cur, 0); + /* segment_end can be -1 if we have not configured a stop. */ + switch (stop_type) { + stop = ogg->segment_stop; + update_stop = FALSE; + /* stop folds required value */ + if (ogg->segment_stop != -1) + stop = ogg->segment_stop + stop; + else + stop = -1; + if (ogg->total_time != -1) + stop = ogg->total_time + stop; + /* if we have a valid stop time, make sure it is clipped */ + if (stop != -1) { + if (ogg->total_time != -1) + stop = CLAMP (stop, 0, ogg->total_time); + else + stop = MAX (stop, 0); + /* store start and stop values */ + GST_LOCK (ogg); + ogg->segment_rate = rate; + ogg->segment_flags = flags; + ogg->segment_start = cur; + ogg->segment_stop = stop; + GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" + GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment_start), + GST_TIME_ARGS (ogg->segment_stop)); + /* check if we can do the seek now */ + if (running) + *running = ogg->running; + GST_UNLOCK (ogg); + return TRUE; + /* ERRORS */ +error: + { + return FALSE; +} +static gboolean +gst_ogg_demux_perform_seek (GstOggDemux * ogg) { GstOggChain *chain = NULL; + gboolean flush, accurate; gint64 begin, end; gint64 begintime, endtime; gint64 target; @@ -1430,6 +1490,9 @@ gint64 start, stop; gint i; + flush = ogg->segment_flags & GST_SEEK_FLAG_FLUSH; + accurate = ogg->segment_flags & GST_SEEK_FLAG_ACCURATE; /* first step is to unlock the streaming thread if it is * blocked in a chain call, we do this by starting the flush. because * we cannot yet hold any streaming lock, we have to protect the chains @@ -1463,16 +1526,14 @@ GST_LOCK (ogg); /* nothing configured, play complete file */ if (ogg->segment_start == GST_CLOCK_TIME_NONE) - ogg->segment_start = 0; - if (ogg->segment_stop == GST_CLOCK_TIME_NONE) - ogg->segment_stop = ogg->total_time; - ogg->segment_start = CLAMP (ogg->segment_start, 0, ogg->total_time); - if (ogg->segment_stop != GST_CLOCK_TIME_NONE) - ogg->segment_stop = CLAMP (ogg->segment_stop, 0, ogg->total_time); + start = 0; + start = CLAMP (ogg->segment_start, 0, ogg->total_time); - start = ogg->segment_start; - stop = ogg->segment_stop; + if (ogg->segment_stop == GST_CLOCK_TIME_NONE) + stop = ogg->total_time; + stop = CLAMP (ogg->segment_stop, 0, ogg->total_time); GST_UNLOCK (ogg); /* we need to stop flushing on the srcpad as we're going to use it @@ -1660,7 +1721,7 @@ } /* notify start of new segment */ - if (ogg->segment_play) { + if (ogg->segment_flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT (ogg), gst_message_new_segment_start (GST_OBJECT (ogg), GST_FORMAT_TIME, ogg->segment_start)); @@ -2291,7 +2352,7 @@ GST_UNLOCK (ogg); /* and seek to configured positions without FLUSH */ - gst_ogg_demux_perform_seek (ogg, TRUE, FALSE); + gst_ogg_demux_perform_seek (ogg); } GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); @@ -2301,7 +2362,7 @@ * pushing out EOS. */ /* FIXME, need to be done somewhere else where we * can check against segment_stop time. */ gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME, ogg->total_time)); @@ -2422,10 +2483,18 @@ switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + ogg->segment_rate = 1.0; + ogg->segment_flags = GST_SEEK_FLAG_NONE; + ogg->segment_start = GST_CLOCK_TIME_NONE; + ogg->segment_stop = GST_CLOCK_TIME_NONE; + ogg->total_time = GST_CLOCK_TIME_NONE; + ogg->running = FALSE; ogg_sync_init (&ogg->sync); case GST_STATE_CHANGE_READY_TO_PAUSED: ogg_sync_reset (&ogg->sync); + ogg->current_granule = -1; + ogg->current_time = 0; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -2442,6 +2511,10 @@ gst_ogg_demux_clear_chains (ogg); GST_LOCK (ogg); ogg->running = FALSE; GST_UNLOCK (ogg); case GST_STATE_CHANGE_READY_TO_NULL: |
From: <wt...@fr...> - 2005-11-16 18:43:50
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Nov 16 2005 10:43:48 PST Log message: * ext/ogg/gstogmparse.c: (gst_ogm_audio_parse_init): Fix compile again. Modified files: . : ChangeLog ext/ogg : gstogmparse.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2089&r2=1.2090 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstogmparse.c.diff?r1=1.14&r2=1.15 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2089 retrieving revision 1.2090 diff -u -d -r1.2089 -r1.2090 --- ChangeLog 16 Nov 2005 18:21:44 -0000 1.2089 +++ ChangeLog 16 Nov 2005 18:43:35 -0000 1.2090 @@ -1,3 +1,8 @@ +2005-11-16 Wim Taymans <wi...@fl...> + + * ext/ogg/gstogmparse.c: (gst_ogm_audio_parse_init): + Fix compile again. 2005-11-16 Thomas Vander Stichele <thomas at apestaart dot org> * ext/libvisual/visual.c: (gst_visual_init): Index: gstogmparse.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstogmparse.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- gstogmparse.c 16 Nov 2005 18:21:45 -0000 1.14 +++ gstogmparse.c 16 Nov 2005 18:43:35 -0000 1.15 @@ -341,11 +341,9 @@ static void gst_ogm_audio_parse_init (GstOgmParse * ogm) { - GstPadTemplate *templ; - /* create the pads */ ogm->sinkpad = - gst_pad_new_from_template (&ogm_audio_parse_sink_template_factory, + gst_pad_new_from_static_template (&ogm_audio_parse_sink_template_factory, "sink"); gst_pad_set_query_function (ogm->sinkpad, gst_ogm_parse_sink_query); gst_pad_set_chain_function (ogm->sinkpad, gst_ogm_parse_chain); |
From: <wt...@fr...> - 2005-11-16 19:33:06
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Nov 16 2005 11:33:02 PST Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_configure_segment), (gst_ogg_demux_perform_seek): Segment done must include stream time. * ext/ogg/gstoggmux.c: (gst_ogg_mux_class_init), (gst_ogg_mux_clear), (gst_ogg_mux_init), (gst_ogg_mux_finalize), (gst_ogg_mux_change_state): Fix ogg muxer again. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c gstoggmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2090&r2=1.2091 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.119&r2=1.120 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c.diff?r1=1.43&r2=1.44 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2090 retrieving revision 1.2091 diff -u -d -r1.2090 -r1.2091 --- ChangeLog 16 Nov 2005 18:43:35 -0000 1.2090 +++ ChangeLog 16 Nov 2005 19:32:50 -0000 1.2091 @@ -1,5 +1,16 @@ 2005-11-16 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_demux_configure_segment), + (gst_ogg_demux_perform_seek): + Segment done must include stream time. + + * ext/ogg/gstoggmux.c: (gst_ogg_mux_class_init), + (gst_ogg_mux_clear), (gst_ogg_mux_init), (gst_ogg_mux_finalize), + (gst_ogg_mux_change_state): + Fix ogg muxer again. +2005-11-16 Wim Taymans <wi...@fl...> * ext/ogg/gstogmparse.c: (gst_ogm_audio_parse_init): Fix compile again. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.119 retrieving revision 1.120 diff -u -d -r1.119 -r1.120 --- gstoggdemux.c 16 Nov 2005 18:21:45 -0000 1.119 +++ gstoggdemux.c 16 Nov 2005 19:32:50 -0000 1.120 @@ -1777,7 +1777,7 @@ if (ogg->segment_flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT (ogg), gst_message_new_segment_start (GST_OBJECT (ogg), GST_FORMAT_TIME, - ogg->segment_start)); + start)); } /* restart our task since it might have been stopped when we did the * flush. */ Index: gstoggmux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- gstoggmux.c 16 Nov 2005 18:09:15 -0000 1.43 +++ gstoggmux.c 16 Nov 2005 19:32:50 -0000 1.44 @@ -163,6 +163,7 @@ static void gst_ogg_mux_base_init (gpointer g_class); static void gst_ogg_mux_class_init (GstOggMuxClass * klass); static void gst_ogg_mux_init (GstOggMux * ogg_mux); +static void gst_ogg_mux_finalize (GObject * object); static GstFlowReturn gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux); @@ -229,6 +230,7 @@ parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + gobject_class->finalize = gst_ogg_mux_finalize; gobject_class->get_property = gst_ogg_mux_get_property; gobject_class->set_property = gst_ogg_mux_set_property; @@ -269,21 +271,6 @@ ogg_mux->max_delay = DEFAULT_MAX_DELAY; ogg_mux->max_page_delay = DEFAULT_MAX_PAGE_DELAY; ogg_mux->delta_pad = NULL; - - if (ogg_mux->collect) { - gst_object_unref (ogg_mux->collect); - ogg_mux->collect = NULL; - } -} -static void -gst_ogg_mux_reset (GstOggMux * ogg_mux) -{ - gst_ogg_mux_clear (ogg_mux); - ogg_mux->collect = gst_collectpads_new (); - gst_collectpads_set_function (ogg_mux->collect, - (GstCollectPadsFunction) gst_ogg_mux_collected, ogg_mux); } static void @@ -302,11 +289,28 @@ /* seed random number generator for creation of serial numbers */ srand (time (NULL)); - ogg_mux->collect = NULL; + ogg_mux->collect = gst_collectpads_new (); + gst_collectpads_set_function (ogg_mux->collect, + (GstCollectPadsFunction) gst_ogg_mux_collected, ogg_mux); gst_ogg_mux_clear (ogg_mux); +static void +gst_ogg_mux_finalize (GObject * object) +{ + GstOggMux *ogg_mux; + ogg_mux = GST_OGG_MUX (object); + if (ogg_mux->collect) { + gst_object_unref (ogg_mux->collect); + ogg_mux->collect = NULL; + } + G_OBJECT_CLASS (parent_class)->finalize (object); +} static GstPadLinkReturn gst_ogg_mux_sinkconnect (GstPad * pad, GstPad * peer) { @@ -1382,13 +1386,13 @@ switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - gst_ogg_mux_reset (ogg_mux); break; case GST_STATE_CHANGE_READY_TO_PAUSED: ogg_mux->next_ts = 0; ogg_mux->offset = 0; ogg_mux->pulling = NULL; gst_collectpads_start (ogg_mux->collect); + gst_ogg_mux_clear (ogg_mux); case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -1403,10 +1407,9 @@ case GST_STATE_CHANGE_PAUSED_TO_READY: gst_collectpads_stop (ogg_mux->collect); - gst_ogg_mux_clear_collectpads (ogg_mux->collect); case GST_STATE_CHANGE_READY_TO_NULL: - gst_ogg_mux_clear (ogg_mux); + gst_ogg_mux_clear_collectpads (ogg_mux->collect); default: |
From: <wt...@fr...> - 2005-11-17 10:56:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Nov 17 2005 02:56:26 PST Log message: * ext/ogg/gstoggmux.c: (gst_ogg_mux_queue_pads), (gst_ogg_mux_get_headers), (gst_ogg_mux_send_headers), (gst_ogg_mux_collected), (gst_ogg_mux_change_state): Fix EOS on multiple streams. More debugging. Modified files: . : ChangeLog ext/ogg : gstoggmux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2091&r2=1.2092 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c.diff?r1=1.44&r2=1.45 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2091 retrieving revision 1.2092 diff -u -d -r1.2091 -r1.2092 --- ChangeLog 16 Nov 2005 19:32:50 -0000 1.2091 +++ ChangeLog 17 Nov 2005 10:56:13 -0000 1.2092 @@ -1,3 +1,11 @@ +2005-11-17 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggmux.c: (gst_ogg_mux_queue_pads), + (gst_ogg_mux_get_headers), (gst_ogg_mux_send_headers), + (gst_ogg_mux_collected), (gst_ogg_mux_change_state): + Fix EOS on multiple streams. + More debugging. 2005-11-16 Wim Taymans <wi...@fl...> * ext/ogg/gstoggdemux.c: (gst_ogg_demux_configure_segment), Index: gstoggmux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggmux.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- gstoggmux.c 16 Nov 2005 19:32:50 -0000 1.44 +++ gstoggmux.c 17 Nov 2005 10:56:14 -0000 1.45 @@ -434,78 +434,6 @@ return gst_pad_event_default (pad, event); } -#if 0 -static GstBuffer * -gst_ogg_mux_next_buffer (GstOggPad * pad, gboolean * interrupt) -{ - GstData *data = NULL; - GstBuffer *buffer = NULL; - - while (buffer == NULL) { - //gst_pad_pull (pad->pad, &buffer); - GST_DEBUG ("muxer: pulled %s:%s %p", GST_DEBUG_PAD_NAME (pad->pad), data); - /* if it's an event, handle it */ - if (GST_IS_EVENT (data)) { - GstEventType type; - GstOggMux *ogg_mux; - GstEvent *event = GST_EVENT (data); - ogg_mux = GST_OGG_MUX (gst_pad_get_parent (pad->pad)); - type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN; - switch (type) { - case GST_EVENT_EOS: - pad->eos = TRUE; - gst_event_unref (event); - return NULL; - case GST_EVENT_DISCONTINUOUS: - { - guint64 start_value, end_value; - if (gst_event_discont_get_value (event, GST_FORMAT_TIME, - &start_value, &end_value)) { - GST_DEBUG_OBJECT (ogg_mux, - "got discont of %" G_GUINT64_FORMAT " and %" G_GUINT64_FORMAT - " on pad %s:%s", start_value, end_value, - GST_DEBUG_PAD_NAME (pad->pad)); - } - pad->offset = start_value; - } - break; - default: - gst_pad_event_default (pad->pad, event); - } - data = NULL; - } else { - GstBuffer *buf = GST_BUFFER (data); - gboolean incaps; - incaps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_IN_CAPS); - /* if we need headers */ - if (pad->state == GST_OGG_PAD_STATE_CONTROL) { - /* and we have one */ - if (incaps) { - GST_DEBUG ("muxer: got incaps buffer in control state, ignoring"); - /* just ignore */ - gst_buffer_unref (buf); - /* pull next one in next iteration */ - data = NULL; - } else { - GST_DEBUG - ("muxer: got data buffer in control state, switching to data mode"); - /* this is a data buffer so switch to data state */ - pad->state = GST_OGG_PAD_STATE_DATA; - } - } - return GST_BUFFER (data); -} -#endif static GstBuffer * gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta) { @@ -725,12 +653,15 @@ walk = g_slist_next (walk); + GST_DEBUG_OBJECT (ogg_mux, "looking at pad %p", pad); /* try to get a new buffer for this pad if needed and possible */ if (pad->buffer == NULL) { GstBuffer *buf; gboolean incaps; buf = gst_collectpads_pop (ogg_mux->collect, data); + GST_DEBUG_OBJECT (ogg_mux, "popping buffer %p", buf); /* On EOS we get a NULL buffer */ if (buf != NULL) { @@ -739,19 +670,20 @@ if (pad->state == GST_OGG_PAD_STATE_CONTROL) { /* and we have one */ if (incaps) { - GST_DEBUG ("muxer: got incaps buffer in control state, ignoring"); + GST_DEBUG_OBJECT (ogg_mux, + "got incaps buffer in control state, ignoring"); /* just ignore */ gst_buffer_unref (buf); buf = NULL; } else { - GST_DEBUG ("muxer: got data buffer in control state, switching " - "to data mode"); + "got data buffer in control state, switching " "to data mode"); /* this is a data buffer so switch to data state */ pad->state = GST_OGG_PAD_STATE_DATA; } } } else { - GST_DEBUG ("EOS on pad"); + GST_DEBUG_OBJECT (ogg_mux, "EOS on pad"); pad->eos = TRUE; } @@ -761,9 +693,12 @@ /* we should have a buffer now, see if it is the best pad to * pull on */ if (pad->buffer) { - if (gst_ogg_mux_compare_pads (ogg_mux, bestpad, pad) > 0) + if (gst_ogg_mux_compare_pads (ogg_mux, bestpad, pad) > 0) { + GST_DEBUG_OBJECT (ogg_mux, "best pad now %p", pad); bestpad = pad; + } } else if (!pad->eos) { + GST_DEBUG_OBJECT (ogg_mux, "hungry pad %p", pad); still_hungry = pad; } } @@ -788,7 +723,7 @@ ogg_mux = GST_OGG_MUX (GST_PAD_PARENT (thepad)); - GST_LOG ("getting headers from pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); + GST_LOG_OBJECT (thepad, "getting headers"); caps = gst_pad_get_negotiated_caps (thepad); if (caps != NULL) { @@ -797,34 +732,34 @@ structure = gst_caps_get_structure (caps, 0); streamheader = gst_structure_get_value (structure, "streamheader"); if (streamheader != NULL) { - GST_LOG ("got header"); + GST_LOG_OBJECT (thepad, "got header"); if (G_VALUE_TYPE (streamheader) == GST_TYPE_ARRAY) { GArray *bufarr = g_value_peek_pointer (streamheader); gint i; - GST_LOG ("got fixed list"); + GST_LOG_OBJECT (thepad, "got fixed list"); for (i = 0; i < bufarr->len; i++) { GValue *bufval = &g_array_index (bufarr, GValue, i); - GST_LOG ("item %d", i); + GST_LOG_OBJECT (thepad, "item %d", i); if (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER) { GstBuffer *buf = g_value_peek_pointer (bufval); - GST_LOG ("adding item %d to header list", i); + GST_LOG_OBJECT (thepad, "adding item %d to header list", i); gst_buffer_ref (buf); res = g_list_append (res, buf); - GST_LOG ("streamheader is not fixed list"); + GST_LOG_OBJECT (thepad, "streamheader is not fixed list"); } else { - GST_LOG ("caps done have streamheader"); + GST_LOG_OBJECT (thepad, "caps done have streamheader"); } else { - GST_LOG ("got empty caps as negotiated format"); + GST_LOG_OBJECT (thepad, "got empty caps as negotiated format"); return res; @@ -883,7 +818,7 @@ hbufs = NULL; ret = GST_FLOW_OK; - GST_LOG ("collecting headers"); + GST_LOG_OBJECT (mux, "collecting headers"); walk = mux->collect->data; while (walk) { @@ -895,7 +830,7 @@ - GST_LOG ("looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); + GST_LOG_OBJECT (mux, "looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); /* if the pad has no buffer, we don't care */ if (pad->buffer == NULL) @@ -905,7 +840,7 @@ pad->headers = gst_ogg_mux_get_headers (pad); - GST_LOG ("creating first headers"); + GST_LOG_OBJECT (mux, "creating first headers"); GstOggPad *pad; @@ -921,7 +856,8 @@ pad->packetno = 0; - GST_LOG ("looping over headers for pad %s:%s", GST_DEBUG_PAD_NAME (thepad)); + GST_LOG_OBJECT (mux, "looping over headers for pad %s:%s", + GST_DEBUG_PAD_NAME (thepad)); if (pad->headers) { buf = GST_BUFFER (pad->headers->data); @@ -954,16 +890,16 @@ ogg_stream_packetin (&pad->stream, &packet); gst_buffer_unref (buf); - GST_LOG ("flushing page with first packet"); + GST_LOG_OBJECT (mux, "flushing page with first packet"); while (ogg_stream_flush (&pad->stream, &page)) { GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); - GST_LOG ("swapped out page"); + GST_LOG_OBJECT (mux, "swapped out page"); hbufs = g_list_append (hbufs, hbuf); - GST_LOG ("creating next headers"); + GST_LOG_OBJECT (mux, "creating next headers"); @@ -974,7 +910,8 @@ walk = walk->next; hwalk = pad->headers; while (hwalk) { @@ -1002,21 +939,22 @@ /* if last header, flush page */ if (hwalk == NULL) { - GST_LOG ("flushing page as packet %d is first or last packet", + GST_LOG_OBJECT (mux, + "flushing page as packet %d is first or last packet", pad->packetno); while (ogg_stream_flush (&pad->stream, &page)) { GstBuffer *hbuf = gst_ogg_mux_buffer_from_page (mux, &page, FALSE); - GST_LOG ("swapped out page"); + GST_LOG_OBJECT (mux, "swapped out page"); hbufs = g_list_append (hbufs, hbuf); - GST_LOG ("try to swap out page"); + GST_LOG_OBJECT (mux, "try to swap out page"); /* just try to swap out a page then */ while (ogg_stream_pageout (&pad->stream, &page) > 0) { @@ -1079,18 +1017,18 @@ gint64 granulepos = 0; GstClockTime timestamp; - GST_DEBUG ("collected"); + GST_DEBUG_OBJECT (ogg_mux, "collected"); /* queue buffers on all pads; find a buffer with the lowest timestamp */ best = gst_ogg_mux_queue_pads (ogg_mux); if (best && !best->buffer) return GST_FLOW_OK; - GST_DEBUG ("best pad %p", best); + GST_DEBUG_OBJECT (ogg_mux, "best pad %p, pulling %p", best, ogg_mux->pulling); if (!best) { /* EOS : FIXME !! We need to handle EOS correctly, and set EOS flags on the ogg pages. */ - GST_DEBUG ("Pushing EOS"); + GST_DEBUG_OBJECT (ogg_mux, "Pushing EOS"); gst_pad_push_event (ogg_mux->srcpad, gst_event_new_eos ()); return GST_FLOW_WRONG_STATE; @@ -1132,6 +1070,7 @@ /* if we don't know which pad to pull on, use the best one */ if (ogg_mux->pulling == NULL) { ogg_mux->pulling = best; + GST_DEBUG_OBJECT (ogg_mux, "pulling now %p", ogg_mux->pulling); /* remember timestamp of first buffer for this new pad */ if (ogg_mux->pulling != NULL) { ogg_mux->next_ts = GST_BUFFER_TIMESTAMP (ogg_mux->pulling->buffer); @@ -1152,8 +1091,15 @@ gint64 duration; gboolean force_flush; /* now see if we have a buffer */ buf = pad->buffer; + if (buf == NULL) { + GST_DEBUG_OBJECT (ogg_mux, "pad was EOS"); + ogg_mux->pulling = NULL; + return GST_FLOW_OK; + } delta_unit = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); duration = GST_BUFFER_DURATION (buf); @@ -1168,22 +1114,8 @@ packet.b_o_s = (pad->packetno == 0); packet.packetno = pad->packetno++; - /* read ahead one more buffer to find EOS */ - tmpbuf = gst_ogg_mux_next_buffer (pad, &interrupt); - if (interrupt) - return; - /* data exhausted on this pad */ - if (tmpbuf == NULL) { - /* stop pulling from the pad */ - ogg_mux->pulling = NULL; - /* mark EOS */ - packet.e_o_s = (tmpbuf == NULL ? 1 : 0); -#else packet.e_o_s = 0; tmpbuf = NULL; /* we flush when we see a new keyframe */ force_flush = (pad->prev_delta && !delta_unit); @@ -1396,6 +1328,9 @@ break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_collectpads_stop (ogg_mux->collect); + break; default: @@ -1405,9 +1340,6 @@ switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_collectpads_stop (ogg_mux->collect); - break; case GST_STATE_CHANGE_READY_TO_NULL: gst_ogg_mux_clear_collectpads (ogg_mux->collect); |
From: <wt...@ke...> - 2006-02-28 11:05:03
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Feb 28 2006 11:04:59 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_receive_event), (gst_ogg_pad_event), (gst_ogg_pad_internal_chain), (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), (gst_ogg_demux_deactivate_current_chain), (gst_ogg_demux_activate_chain), (gst_ogg_demux_do_seek), (gst_ogg_demux_perform_seek), (gst_ogg_demux_collect_info), (gst_ogg_demux_find_chains), (gst_ogg_demux_chain), (gst_ogg_demux_loop), (gst_ogg_demux_change_state): Use GstSegment infrastructure to remove duplicated code and handle more seek cases correctly. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2424&r2=1.2425 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.136&r2=1.137 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2424 retrieving revision 1.2425 diff -u -d -r1.2424 -r1.2425 --- ChangeLog 28 Feb 2006 10:39:19 -0000 1.2424 +++ ChangeLog 28 Feb 2006 11:04:47 -0000 1.2425 @@ -1,5 +1,18 @@ 2006-02-28 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_demux_receive_event), + (gst_ogg_pad_event), (gst_ogg_pad_internal_chain), + (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), + (gst_ogg_demux_deactivate_current_chain), + (gst_ogg_demux_activate_chain), (gst_ogg_demux_do_seek), + (gst_ogg_demux_perform_seek), (gst_ogg_demux_collect_info), + (gst_ogg_demux_find_chains), (gst_ogg_demux_chain), + (gst_ogg_demux_loop), (gst_ogg_demux_change_state): + Use GstSegment infrastructure to remove duplicated code + and handle more seek cases correctly. + +2006-02-28 Wim Taymans <wi...@fl...> * gst/ffmpegcolorspace/gstffmpegcolorspace.c: (gst_ffmpegcsp_transform): Don't ignore return code from ffmpeg convert function. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.136 retrieving revision 1.137 diff -u -d -r1.136 -r1.137 --- gstoggdemux.c 24 Feb 2006 17:31:53 -0000 1.136 +++ gstoggdemux.c 28 Feb 2006 11:04:47 -0000 1.137 @@ -160,19 +160,18 @@ /* state */ GMutex *chain_lock; /* we need the lock to protect the chains */ GArray *chains; /* list of chains we know */ - GstClockTime total_time; /* the total time of this ogg, this is the sum of - the totals of all chains */ + GstClockTime total_time; GstOggChain *current_chain; GstOggChain *building_chain; /* playback start/stop positions */ - gdouble segment_rate; - GstSeekFlags segment_flags; - GstClockTime segment_start; - GstClockTime segment_stop; + GstSegment segment; + gboolean segment_running; + GstEvent *event; gint64 current_granule; - GstClockTime current_time; /* annodex stuff */ gboolean have_fishead; @@ -198,9 +197,8 @@ static gboolean gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain, GstEvent * event); -static gboolean gst_ogg_demux_configure_segment (GstOggDemux * ogg, - GstEvent * event, gboolean * running); -static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg); +static gboolean gst_ogg_demux_perform_seek (GstOggDemux * ogg, + GstEvent * event); static gboolean gst_ogg_demux_receive_event (GstElement * element, GstEvent * event); @@ -419,8 +417,6 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { - gboolean running; - /* can't seek if we are not seekable, FIXME could pass the * seek query upstream after converting it to bytes using * the average bitrate of the stream. */ @@ -429,16 +425,8 @@ goto error; } - if (!gst_ogg_demux_configure_segment (ogg, event, &running)) { - GST_DEBUG ("configure segment failed"); - goto error; - } /* now do the seek */ - if (running) { - res = gst_ogg_demux_perform_seek (ogg); - } else - res = TRUE; + res = gst_ogg_demux_perform_seek (ogg, event); break; } @@ -469,8 +457,6 @@ @@ -479,16 +465,8 @@ default: @@ -497,10 +475,13 @@ } return res; + /* ERRORS */ error: - GST_DEBUG ("error handling event"); - gst_event_unref (event); - return FALSE; + { + GST_DEBUG ("error handling event"); + gst_event_unref (event); + return FALSE; + } } static void @@ -744,7 +725,6 @@ if (oggpad->start_time == GST_CLOCK_TIME_NONE) { oggpad->start_time = timestamp; - ogg->current_time = timestamp; gst_buffer_unref (buffer); @@ -945,17 +925,20 @@ if (packet->granulepos >= 0) { GstFormat format; + gint64 current_time; ogg->current_granule = packet->granulepos; format = GST_FORMAT_TIME; if (!pad->is_skeleton) { if (!gst_ogg_pad_query_convert (pad, GST_FORMAT_DEFAULT, packet->granulepos, &format, - (gint64 *) & ogg->current_time)) { + (gint64 *) & current_time)) { GST_WARNING_OBJECT (ogg, "could not convert granulepos to time"); } else { + gst_segment_set_last_stop (&ogg->segment, GST_FORMAT_TIME, + current_time); GST_DEBUG ("ogg current time %" GST_TIME_FORMAT, - GST_TIME_ARGS (ogg->current_time)); + GST_TIME_ARGS (current_time)); } @@ -1050,8 +1033,8 @@ GST_DEBUG ("segment_stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (segment_stop)); - /* create the discont event we are going to send out */ - event = gst_event_new_new_segment (FALSE, ogg->segment_rate, + /* create the newsegment event we are going to send out */ + event = gst_event_new_new_segment (FALSE, ogg->segment.rate, GST_FORMAT_TIME, segment_start, segment_stop, 0); gst_ogg_demux_activate_chain (ogg, chain, event); @@ -1541,10 +1524,14 @@ for (i = 0; i < chain->streams->len; i++) { GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i); - gst_pad_push_event (GST_PAD (pad), gst_event_new_eos ()); + gst_pad_push_event (GST_PAD_CAST (pad), gst_event_new_eos ()); GST_DEBUG_OBJECT (ogg, "removing pad %" GST_PTR_FORMAT, pad); - gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD (pad)); + /* deactivate first */ + gst_pad_set_active (GST_PAD_CAST (pad), FALSE); + gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad)); /* if we cannot seek back to the chain, we can destroy the chain * completely */ @@ -1579,7 +1566,10 @@ pad = g_array_index (chain->streams, GstOggPad *, i); GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad); - gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD (pad)); + /* activate first */ + gst_pad_set_active (GST_PAD_CAST (pad), TRUE); + gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD_CAST (pad)); gst_element_no_more_pads (GST_ELEMENT (ogg)); @@ -1610,197 +1600,22 @@ return TRUE; +/* + * do seek to time @position, return FALSE or chain and TRUE + */ static gboolean -gst_ogg_demux_configure_segment (GstOggDemux * ogg, GstEvent * event, - gboolean * running) -{ - GstFormat format; - gdouble rate; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gboolean update_start, update_stop; - gst_event_parse_seek (event, &rate, &format, &flags, - &cur_type, &cur, &stop_type, &stop); - /* we can only seek on time */ - if (format != GST_FORMAT_TIME) { - GST_DEBUG ("can only seek on TIME"); - goto error; - } - /* cannot yet do backwards playback */ - if (rate <= 0.0) { - GST_DEBUG ("can only seek with positive rate, not %lf", rate); - /* assume we'll update both start and stop values */ - update_start = TRUE; - update_stop = TRUE; - /* perform the seek, segment_start is never invalid */ - switch (cur_type) { - case GST_SEEK_TYPE_NONE: - /* no update to segment */ - cur = ogg->segment_start; - update_start = FALSE; - break; - case GST_SEEK_TYPE_SET: - /* cur holds desired position */ - case GST_SEEK_TYPE_CUR: - /* add cur to currently configure segment */ - cur = ogg->segment_start + cur; - case GST_SEEK_TYPE_END: - /* add cur to total length */ - cur = ogg->total_time + cur; - /* bring in sane range */ - if (ogg->total_time != -1) - cur = CLAMP (cur, 0, ogg->total_time); - else - cur = MAX (cur, 0); - /* segment_end can be -1 if we have not configured a stop. */ - switch (stop_type) { - stop = ogg->segment_stop; - update_stop = FALSE; - /* stop folds required value */ - if (ogg->segment_stop != -1) - stop = ogg->segment_stop + stop; - else - stop = -1; - if (ogg->total_time != -1) - stop = ogg->total_time + stop; - /* if we have a valid stop time, make sure it is clipped */ - if (stop != -1) { - if (ogg->total_time != -1) - stop = CLAMP (stop, 0, ogg->total_time); - else - stop = MAX (stop, 0); - /* store start and stop values */ - GST_OBJECT_LOCK (ogg); - ogg->segment_rate = rate; - ogg->segment_flags = flags; - ogg->segment_start = cur; - ogg->segment_stop = stop; - GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" - GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment_start), - GST_TIME_ARGS (ogg->segment_stop)); - /* check if we can do the seek now */ - if (running) - *running = ogg->running; - GST_OBJECT_UNLOCK (ogg); - return TRUE; - /* ERRORS */ -error: - { - return FALSE; -} -static gboolean -gst_ogg_demux_perform_seek (GstOggDemux * ogg) +gst_ogg_demux_do_seek (GstOggDemux * ogg, gint64 position, gboolean accurate, + GstOggChain ** rchain) { GstOggChain *chain = NULL; - gboolean flush, accurate; gint64 begin, end; gint64 begintime, endtime; gint64 target; gint64 best; gint64 total; gint64 result = 0; - gint64 start, stop; gint i; - flush = ogg->segment_flags & GST_SEEK_FLAG_FLUSH; - accurate = ogg->segment_flags & GST_SEEK_FLAG_ACCURATE; - /* first step is to unlock the streaming thread if it is - * blocked in a chain call, we do this by starting the flush. because - * we cannot yet hold any streaming lock, we have to protect the chains - * with their own lock. */ - if (flush) { - gint i; - gst_pad_push_event (ogg->sinkpad, gst_event_new_flush_start ()); - GST_CHAIN_LOCK (ogg); - for (i = 0; i < ogg->chains->len; i++) { - GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); - gint j; - for (j = 0; j < chain->streams->len; j++) { - GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j); - gst_pad_push_event (GST_PAD (pad), gst_event_new_flush_start ()); - } - GST_CHAIN_UNLOCK (ogg); - } else { - gst_pad_pause_task (ogg->sinkpad); - /* now grab the stream lock so that streaming cannot continue, for - * non flushing seeks when the element is in PAUSED this could block - * forever. */ - GST_PAD_STREAM_LOCK (ogg->sinkpad); - /* nothing configured, play complete file */ - if (ogg->segment_start == GST_CLOCK_TIME_NONE) - start = 0; - start = CLAMP (ogg->segment_start, 0, ogg->total_time); - if (ogg->segment_stop == GST_CLOCK_TIME_NONE) - stop = ogg->total_time; - stop = CLAMP (ogg->segment_stop, 0, ogg->total_time); - /* we need to stop flushing on the srcpad as we're going to use it - * next. We can do this as we have the STREAM lock now. */ - gst_pad_push_event (ogg->sinkpad, gst_event_new_flush_stop ()); - /* reset all ogg streams now, need to do this from within the lock to - * make sure the streaming thread is not messing with the stream */ - ogg_stream_reset (&pad->stream); /* first find the chain to search in */ total = ogg->total_time; if (ogg->chains->len == 0) @@ -1809,7 +1624,7 @@ for (i = ogg->chains->len - 1; i >= 0; i--) { chain = g_array_index (ogg->chains, GstOggChain *, i); total -= chain->total_time; - if (start >= total) + if (position >= total) @@ -1817,7 +1632,7 @@ end = chain->end_offset; begintime = chain->begin_time; endtime = chain->begin_time + chain->total_time; - target = start - total + begintime; + target = position - total + begintime; if (accurate) { /* FIXME, seek 4 seconds early to catch keyframes, better implement * keyframe detection. */ @@ -1827,8 +1642,8 @@ best = begin; GST_DEBUG_OBJECT (ogg, - "seeking to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT " in chain %p", - GST_TIME_ARGS (start), GST_TIME_ARGS (stop), chain); + "seeking to %" GST_TIME_FORMAT " in chain %p", + GST_TIME_ARGS (position), chain); "chain offset %" G_GINT64_FORMAT ", end offset %" G_GINT64_FORMAT, begin, end); @@ -1941,31 +1756,147 @@ ogg->offset = best; + *rchain = chain; - /* current time starts from 0 again after a flush */ - if (flush) - ogg->current_time = 0; + return TRUE; +no_chains: + GST_DEBUG_OBJECT (ogg, "no chains"); +seek_error: + GST_DEBUG_OBJECT (ogg, "got a seek error"); +} +static gboolean +gst_ogg_demux_perform_seek (GstOggDemux * ogg, GstEvent * event) +{ + GstOggChain *chain = NULL; + gboolean res; + gboolean flush, accurate; + GstFormat format; + gdouble rate; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gboolean update; + if (event) { + gst_event_parse_seek (event, &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + /* we can only seek on time */ + if (format != GST_FORMAT_TIME) { + GST_DEBUG_OBJECT (ogg, "can only seek on TIME"); + goto error; + } + /* cannot yet do backwards playback */ + if (rate <= 0.0) { + GST_DEBUG_OBJECT (ogg, "can only seek with positive rate, not %lf", rate); + } else { + flags = 0; + GST_DEBUG_OBJECT (ogg, "seek, rate %g", rate); + flush = flags & GST_SEEK_FLAG_FLUSH; + accurate = flags & GST_SEEK_FLAG_ACCURATE; + /* first step is to unlock the streaming thread if it is + * blocked in a chain call, we do this by starting the flush. because + * we cannot yet hold any streaming lock, we have to protect the chains + * with their own lock. */ + if (flush) { + gint i; + gst_pad_push_event (ogg->sinkpad, gst_event_new_flush_start ()); + GST_CHAIN_LOCK (ogg); + for (i = 0; i < ogg->chains->len; i++) { + GstOggChain *chain = g_array_index (ogg->chains, GstOggChain *, i); + gint j; + for (j = 0; j < chain->streams->len; j++) { + GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j); + gst_pad_push_event (GST_PAD (pad), gst_event_new_flush_start ()); + } + GST_CHAIN_UNLOCK (ogg); + gst_pad_pause_task (ogg->sinkpad); + /* now grab the stream lock so that streaming cannot continue, for + * non flushing seeks when the element is in PAUSED this could block + * forever. */ + GST_PAD_STREAM_LOCK (ogg->sinkpad); + if (ogg->segment_running && !flush) { + GstEvent *newseg; + /* create the discont event to close the current segment */ + newseg = gst_event_new_new_segment (TRUE, ogg->segment.rate, + GST_FORMAT_TIME, ogg->segment.start, ogg->segment.last_stop, + ogg->segment.start); + /* send discont on old chain */ + gst_ogg_demux_send_event (ogg, newseg); + gst_segment_set_seek (&ogg->segment, rate, format, flags, + cur_type, cur, stop_type, stop, &update); + GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" + GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment.start), + GST_TIME_ARGS (ogg->segment.stop)); + /* we need to stop flushing on the srcpad as we're going to use it + * next. We can do this as we have the STREAM lock now. */ + gst_pad_push_event (ogg->sinkpad, gst_event_new_flush_stop ()); + /* reset all ogg streams now, need to do this from within the lock to + * make sure the streaming thread is not messing with the stream */ + ogg_stream_reset (&pad->stream); + res = gst_ogg_demux_do_seek (ogg, ogg->segment.last_stop, accurate, &chain); /* now we have a new position, prepare for streaming again */ { GstEvent *event; - gint64 start_value = start + chain->segment_start; - gint64 stop_value; - if (start_value == GST_CLOCK_TIME_NONE) - start_value = 0; - if (chain->segment_start == GST_CLOCK_TIME_NONE) - stop_value = GST_CLOCK_TIME_NONE; - stop_value = stop + chain->segment_start; + gint64 stop; /* we have to send the flush to the old chain, not the new one */ if (flush) gst_ogg_demux_send_event (ogg, gst_event_new_flush_stop ()); + if ((stop = ogg->segment.stop) == -1) + stop = ogg->segment.duration; /* create the discont event we are going to send out */ - event = gst_event_new_new_segment (FALSE, 1.0, - GST_FORMAT_TIME, start_value, stop_value, start); + event = gst_event_new_new_segment (FALSE, ogg->segment.rate, + ogg->segment.format, ogg->segment.last_stop, stop, ogg->segment.time); if (chain != ogg->current_chain) { /* switch to different chain, send discont on new chain */ @@ -1976,11 +1907,13 @@ /* notify start of new segment */ - if (ogg->segment_flags & GST_SEEK_FLAG_SEGMENT) { + if (ogg->segment.flags & GST_SEEK_FLAG_SEGMENT) { gst_element_post_message (GST_ELEMENT (ogg), - gst_message_new_segment_start (GST_OBJECT (ogg), GST_FORMAT_TIME, - start)); + gst_message_new_segment_start (GST_OBJECT (ogg), + GST_FORMAT_TIME, ogg->segment.last_stop)); + ogg->segment_running = TRUE; /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop, @@ -1992,18 +1925,9 @@ -no_chains: - GST_DEBUG_OBJECT (ogg, "no chains"); - GST_PAD_STREAM_UNLOCK (ogg->sinkpad); -seek_error: +error: - GST_DEBUG_OBJECT (ogg, "got a seek error"); + GST_DEBUG_OBJECT (ogg, "seek failed"); return FALSE; @@ -2370,6 +2294,7 @@ ogg->total_time += chain->total_time; + gst_segment_set_duration (&ogg->segment, GST_FORMAT_TIME, ogg->total_time); /* find all the chains in the ogg file, this reads the first and @@ -2394,7 +2319,7 @@ format = GST_FORMAT_BYTES; res = gst_pad_query_duration (peer, &format, &ogg->length); gst_object_unref (peer); - if (!res) + if (!res || ogg->length <= 0) goto no_length; GST_DEBUG ("file length %lld", ogg->length); @@ -2497,17 +2422,20 @@ GstClockTime chain_time; GstOggChain *current_chain; + gint64 current_time; /* this can only happen in non-seekabe mode */ if (ogg->seekable) goto unknown_chain; current_chain = ogg->current_chain; + current_time = ogg->segment.last_stop; if (current_chain) { GstClockTime duration; /* this was the duration of the previous chain */ - duration = ogg->current_time - current_chain->segment_start; + duration = current_time - current_chain->segment_start; /* the new chain time starts at duration + begin_time */ chain_time = duration + current_chain->begin_time; @@ -2515,7 +2443,7 @@ gst_ogg_demux_deactivate_current_chain (ogg); } else { /* non previous chain, start at configured current time */ - chain_time = ogg->current_time; + chain_time = current_time; } if (ogg->building_chain == NULL) { GstOggChain *newchain; @@ -2597,6 +2525,7 @@ GstOggDemux *ogg; GstFlowReturn ret; GstBuffer *buffer; ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad)); @@ -2614,10 +2543,12 @@ GST_OBJECT_LOCK (ogg); ogg->running = TRUE; + event = ogg->event; + ogg->event = NULL; GST_OBJECT_UNLOCK (ogg); /* and seek to configured positions without FLUSH */ - gst_ogg_demux_perform_seek (ogg); + gst_ogg_demux_perform_seek (ogg, event); GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); @@ -2627,7 +2558,8 @@ * pushing out EOS. */ /* FIXME, need to be done somewhere else where we * can check against segment_stop time. */ + ogg->segment_running = FALSE; GST_LOG_OBJECT (ogg, "Sending segment done, at end of segment"); gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME, @@ -2754,20 +2686,16 @@ switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - ogg->segment_rate = 1.0; - ogg->segment_flags = GST_SEEK_FLAG_NONE; - ogg->segment_start = GST_CLOCK_TIME_NONE; - ogg->segment_stop = GST_CLOCK_TIME_NONE; - ogg->total_time = GST_CLOCK_TIME_NONE; ogg->basetime = 0; ogg->have_fishead = FALSE; - ogg->running = FALSE; ogg_sync_init (&ogg->sync); case GST_STATE_CHANGE_READY_TO_PAUSED: ogg_sync_reset (&ogg->sync); ogg->current_granule = -1; - ogg->current_time = 0; + ogg->running = FALSE; + ogg->segment_running = FALSE; + gst_segment_init (&ogg->segment, GST_FORMAT_TIME); case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -2784,11 +2712,8 @@ gst_ogg_demux_clear_chains (ogg); GST_OBJECT_LOCK (ogg); ogg->running = FALSE; GST_OBJECT_UNLOCK (ogg); case GST_STATE_CHANGE_READY_TO_NULL: |
From: <wt...@ke...> - 2006-03-09 17:45:53
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Mar 09 2006 17:45:51 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_demux_activate_chain): Don't try to activate NULL chains. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2468&r2=1.2469 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.137&r2=1.138 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2468 retrieving revision 1.2469 diff -u -d -r1.2468 -r1.2469 --- ChangeLog 9 Mar 2006 16:30:41 -0000 1.2468 +++ ChangeLog 9 Mar 2006 17:45:39 -0000 1.2469 @@ -1,3 +1,8 @@ +2006-03-09 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_demux_activate_chain): + Don't try to activate NULL chains. 2006-03-09 Tim-Philipp Müller <tim at centricular dot net> * gst/typefind/gsttypefindfunctions.c: (mp3_type_find_at_offset): Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.137 retrieving revision 1.138 diff -u -d -r1.137 -r1.138 --- gstoggdemux.c 28 Feb 2006 11:04:47 -0000 1.137 +++ gstoggdemux.c 9 Mar 2006 17:45:39 -0000 1.138 @@ -1557,6 +1557,12 @@ gst_ogg_demux_deactivate_current_chain (ogg); + /* FIXME, should not be called with NULL */ + if (chain == NULL) { + ogg->current_chain = chain; + return TRUE; + } GST_DEBUG ("activating chain %p", chain); /* first add the pads */ |
From: <wt...@ke...> - 2006-04-10 15:17:38
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon Apr 10 2006 15:17:36 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), (gst_ogg_demux_receive_event), (gst_ogg_pad_event), (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), (gst_ogg_demux_submit_buffer), (gst_ogg_demux_get_data), (gst_ogg_demux_deactivate_current_chain), (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek), (gst_ogg_demux_bisect_forward_serialno), (gst_ogg_demux_find_chains), (gst_ogg_demux_chain): Add some more debugging. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2545&r2=1.2546 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.142&r2=1.143 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2545 retrieving revision 1.2546 diff -u -d -r1.2545 -r1.2546 --- ChangeLog 10 Apr 2006 10:29:21 -0000 1.2545 +++ ChangeLog 10 Apr 2006 15:17:24 -0000 1.2546 @@ -1,5 +1,17 @@ 2006-04-10 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), + (gst_ogg_demux_receive_event), (gst_ogg_pad_event), + (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), + (gst_ogg_demux_submit_buffer), (gst_ogg_demux_get_data), + (gst_ogg_demux_deactivate_current_chain), + (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek), + (gst_ogg_demux_bisect_forward_serialno), + (gst_ogg_demux_find_chains), (gst_ogg_demux_chain): + Add some more debugging. + +2006-04-10 Wim Taymans <wi...@fl...> * ext/theora/theoradec.c: (theora_dec_src_event), (theora_handle_data_packet): Some more debug info. Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.142 retrieving revision 1.143 diff -u -d -r1.142 -r1.143 --- gstoggdemux.c 8 Apr 2006 21:02:49 -0000 1.142 +++ gstoggdemux.c 10 Apr 2006 15:17:24 -0000 1.143 @@ -402,7 +402,7 @@ gst_query_parse_duration (query, &format, NULL); /* can only get position in time */ if (format != GST_FORMAT_TIME) { - GST_DEBUG ("only query duration on TIME is supported"); + GST_DEBUG_OBJECT (ogg, "only query duration on TIME is supported"); res = FALSE; goto done; } @@ -433,7 +433,7 @@ * seek query upstream after converting it to bytes using * the average bitrate of the stream. */ if (!ogg->seekable) { - GST_DEBUG ("seek on non seekable stream"); + GST_DEBUG_OBJECT (ogg, "seek on non seekable stream"); goto error; @@ -443,17 +443,20 @@ } default: - GST_DEBUG ("We only handle seek events here"); + GST_DEBUG_OBJECT (ogg, "We only handle seek events here"); goto error; break; } return res; + /* ERRORS */ error: - GST_DEBUG ("error handling event"); - gst_event_unref (event); - return FALSE; + { + GST_DEBUG_OBJECT (ogg, "error handling event"); + gst_event_unref (event); + return FALSE; + } } static gboolean @@ -473,7 +476,7 @@ @@ -490,7 +493,7 @@ /* ERRORS */ { - GST_DEBUG ("error handling event"); gst_event_unref (event); return FALSE; @@ -949,7 +952,7 @@ } else { gst_segment_set_last_stop (&ogg->segment, GST_FORMAT_TIME, current_time); - GST_DEBUG ("ogg current time %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT, GST_TIME_ARGS (current_time)); } @@ -1021,11 +1024,11 @@ GstEvent *event; GstClockTime segment_start, segment_stop; - GST_DEBUG ("chain->begin_time: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "chain->begin_time: %" GST_TIME_FORMAT, GST_TIME_ARGS (chain->begin_time)); - GST_DEBUG ("chain->segment_start: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "chain->segment_start: %" GST_TIME_FORMAT, GST_TIME_ARGS (chain->segment_start)); - GST_DEBUG ("chain->segment_stop: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "chain->segment_stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (chain->segment_stop)); if (chain->begin_time != GST_CLOCK_TIME_NONE) { @@ -1040,9 +1043,9 @@ segment_stop = chain->segment_stop; - GST_DEBUG ("segment_start: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "segment_start: %" GST_TIME_FORMAT, GST_TIME_ARGS (segment_start)); - GST_DEBUG ("segment_stop: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "segment_stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (segment_stop)); /* create the newsegment event we are going to send out */ @@ -1363,7 +1366,7 @@ static gint gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer) { - guint size; + gint size; guint8 *data; gchar *oggbuffer; @@ -1394,7 +1397,7 @@ /* read more data from the current offset and submit to * the ogg sync layer. * - * Return number of bytes written. + * Return number of bytes written or 0 on EOS or -1 on error. */ gst_ogg_demux_get_data (GstOggDemux * ogg) @@ -1405,15 +1408,28 @@ GST_LOG_OBJECT (ogg, "get data %lld %lld", ogg->offset, ogg->length); if (ogg->offset == ogg->length) - return 0; + goto eos; ret = gst_pad_pull_range (ogg->sinkpad, ogg->offset, CHUNKSIZE, &buffer); if (ret != GST_FLOW_OK) - return -1; + goto error; size = gst_ogg_demux_submit_buffer (ogg, buffer); return size; + /* ERROR */ +eos: + GST_LOG_OBJECT (ogg, "reached EOS"); + return 0; +error: + GST_WARNING_OBJECT (ogg, "got %d (%s) from pull range", ret, + gst_flow_get_name (ret)); + return -1; /* Read the next page from the current offset. @@ -1525,7 +1541,7 @@ if (chain == NULL) return TRUE; - GST_DEBUG ("deactivating chain %p", chain); + GST_DEBUG_OBJECT (ogg, "deactivating chain %p", chain); /* send EOS on all the pads */ for (i = 0; i < chain->streams->len; i++) { @@ -1570,7 +1586,7 @@ - GST_DEBUG ("activating chain %p", chain); + GST_DEBUG_OBJECT (ogg, "activating chain %p", chain); /* first add the pads */ @@ -1591,7 +1607,7 @@ if (event) gst_ogg_demux_send_event (ogg, event); - GST_DEBUG ("starting chain"); + GST_DEBUG_OBJECT (ogg, "starting chain"); /* then send out any queued buffers */ @@ -1799,6 +1815,8 @@ gboolean update; if (event) { + GST_DEBUG_OBJECT (ogg, "seek with event"); gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop); @@ -1813,7 +1831,10 @@ } else { + GST_DEBUG_OBJECT (ogg, "seek without event"); flags = 0; + rate = 1.0; GST_DEBUG_OBJECT (ogg, "seek, rate %g", rate); @@ -1868,7 +1889,7 @@ cur_type, cur, stop_type, stop, &update); - GST_DEBUG ("segment positions set to %" GST_TIME_FORMAT "-%" + GST_DEBUG_OBJECT (ogg, "segment positions set to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, GST_TIME_ARGS (ogg->segment.start), GST_TIME_ARGS (ogg->segment.stop)); @@ -1978,7 +1999,7 @@ gst_ogg_demux_seek (ogg, bisect); ret = gst_ogg_demux_get_next_page (ogg, &og, -1); if (ret == OV_EREAD) { - GST_LOG_OBJECT (ogg, "OV_READ"); + GST_LOG_OBJECT (ogg, "OV_EREAD"); return OV_EREAD; @@ -2335,7 +2356,7 @@ if (!res || ogg->length <= 0) goto no_length; - GST_DEBUG ("file length %lld", ogg->length); + GST_DEBUG_OBJECT (ogg, "file length %lld", ogg->length); /* read chain from offset 0, this is the first chain of the * ogg file. */ @@ -2371,17 +2392,17 @@ /*** error cases ***/ no_peer: - GST_DEBUG ("we don't have a peer"); + GST_DEBUG_OBJECT (ogg, "we don't have a peer"); no_length: - GST_DEBUG ("can't get file length"); + GST_DEBUG_OBJECT (ogg, "can't get file length"); no_first_chain: - GST_DEBUG ("can't get first chain"); + GST_DEBUG_OBJECT (ogg, "can't get first chain"); @@ -2399,7 +2420,7 @@ ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad)); - GST_DEBUG ("chain"); + GST_DEBUG_OBJECT (ogg, "chain"); gst_ogg_demux_submit_buffer (ogg, buffer); while (ret != 0 && result == GST_FLOW_OK) { @@ -2465,7 +2486,7 @@ newchain->offset = 0; /* set new chain begin time aligned with end time of old chain */ newchain->begin_time = chain_time; - GST_DEBUG ("new chain, begin time %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (ogg, "new chain, begin time %" GST_TIME_FORMAT, GST_TIME_ARGS (chain_time)); /* and this is the one we are building now */ |
From: <wt...@ke...> - 2006-04-10 19:13:43
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon Apr 10 2006 19:13:42 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), (gst_ogg_demux_receive_event), (gst_ogg_pad_event), (gst_ogg_demux_init), (gst_ogg_demux_finalize), (gst_ogg_demux_sink_event), (gst_ogg_demux_get_data), (gst_ogg_demux_loop): Don't leak events. Remember what error we got when finding chains, if we were shutdown, that would not be an error. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2547&r2=1.2548 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.143&r2=1.144 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2547 retrieving revision 1.2548 diff -u -d -r1.2547 -r1.2548 --- ChangeLog 10 Apr 2006 17:05:46 -0000 1.2547 +++ ChangeLog 10 Apr 2006 19:13:29 -0000 1.2548 @@ -1,5 +1,16 @@ 2006-04-10 Wim Taymans <wi...@fl...> + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), + (gst_ogg_demux_receive_event), (gst_ogg_pad_event), + (gst_ogg_demux_init), (gst_ogg_demux_finalize), + (gst_ogg_demux_sink_event), (gst_ogg_demux_get_data), + (gst_ogg_demux_loop): + Don't leak events. + Remember what error we got when finding chains, if we + were shutdown, that would not be an error. + +2006-04-10 Wim Taymans <wi...@fl...> * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event): Starting the ringbuffer when we did not acquire it can cause Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.143 retrieving revision 1.144 diff -u -d -r1.143 -r1.144 --- gstoggdemux.c 10 Apr 2006 15:17:24 -0000 1.143 +++ gstoggdemux.c 10 Apr 2006 19:13:30 -0000 1.144 @@ -167,6 +167,7 @@ GMutex *chain_lock; /* we need the lock to protect the chains */ GArray *chains; /* list of chains we know */ GstClockTime total_time; + GstFlowReturn chain_error; /* error we received while finding chains */ GstOggChain *current_chain; GstOggChain *building_chain; @@ -391,7 +392,7 @@ GstOggDemux *ogg; GstOggPad *cur; - ogg = GST_OGG_DEMUX (GST_PAD_PARENT (pad)); + ogg = GST_OGG_DEMUX (gst_pad_get_parent (pad)); cur = GST_OGG_PAD (pad); switch (GST_QUERY_TYPE (query)) { @@ -401,12 +402,11 @@ gst_query_parse_duration (query, &format, NULL); /* can only get position in time */ - if (format != GST_FORMAT_TIME) { - GST_DEBUG_OBJECT (ogg, "only query duration on TIME is supported"); - res = FALSE; - goto done; - } + if (format != GST_FORMAT_TIME) + goto wrong_format; /* can only return the total time position */ + /* FIXME, return time for this specific stream */ gst_query_set_duration (query, GST_FORMAT_TIME, ogg->total_time); break; } @@ -415,7 +415,17 @@ } done: + gst_object_unref (ogg); return res; + /* ERRORS */ +wrong_format: + { + GST_DEBUG_OBJECT (ogg, "only query duration on TIME is supported"); + res = FALSE; + goto done; + } } static gboolean @@ -428,7 +438,6 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: - { /* can't seek if we are not seekable, FIXME could pass the * seek query upstream after converting it to bytes using * the average bitrate of the stream. */ @@ -439,13 +448,11 @@ /* now do the seek */ res = gst_ogg_demux_perform_seek (ogg, event); + gst_event_unref (event); - - } default: GST_DEBUG_OBJECT (ogg, "We only handle seek events here"); goto error; - break; @@ -466,12 +473,11 @@ @@ -482,12 +488,15 @@ res = gst_pad_event_default (pad, event); +done: /* ERRORS */ @@ -495,7 +504,8 @@ { GST_DEBUG_OBJECT (ogg, "error handling event"); gst_event_unref (event); - return FALSE; @@ -1266,7 +1276,7 @@ static gint gst_ogg_demux_read_end_chain (GstOggDemux * ogg, GstOggChain * chain); -static gboolean gst_ogg_demux_handle_event (GstPad * pad, GstEvent * event); +static gboolean gst_ogg_demux_sink_event (GstPad * pad, GstEvent * event); static void gst_ogg_demux_loop (GstOggPad * pad); static GstFlowReturn gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer); static gboolean gst_ogg_demux_sink_activate (GstPad * sinkpad); @@ -1314,7 +1324,7 @@ gst_pad_new_from_static_template (&ogg_demux_sink_template_factory, "sink"); - gst_pad_set_event_function (ogg->sinkpad, gst_ogg_demux_handle_event); + gst_pad_set_event_function (ogg->sinkpad, gst_ogg_demux_sink_event); gst_pad_set_chain_function (ogg->sinkpad, gst_ogg_demux_chain); gst_pad_set_activate_function (ogg->sinkpad, gst_ogg_demux_sink_activate); gst_pad_set_activatepull_function (ogg->sinkpad, @@ -1338,25 +1348,33 @@ g_mutex_free (ogg->chain_lock); ogg_sync_clear (&ogg->sync); - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (parent_class)->finalize (object); -gst_ogg_demux_handle_event (GstPad * pad, GstEvent * event) +gst_ogg_demux_sink_event (GstPad * pad, GstEvent * event) { - GstOggDemux *ogg = GST_OGG_DEMUX (GST_PAD_PARENT (pad)); + gboolean res; + GstOggDemux *ogg; case GST_EVENT_NEWSEGMENT: + /* FIXME */ GST_DEBUG_OBJECT (ogg, "got a new segment event"); ogg_sync_reset (&ogg->sync); gst_event_unref (event); + res = TRUE; + case GST_EVENT_EOS: - return gst_pad_event_default (pad, event); + res = gst_pad_event_default (pad, event); + break; - return TRUE; + return res; /* submit the given buffer to the ogg sync. @@ -1428,6 +1446,7 @@ GST_WARNING_OBJECT (ogg, "got %d (%s) from pull range", ret, gst_flow_get_name (ret)); + ogg->chain_error = ret; return -1; @@ -1801,6 +1820,7 @@ +/* does not take ownership of the event */ gst_ogg_demux_perform_seek (GstOggDemux * ogg, GstEvent * event) @@ -2568,6 +2588,7 @@ /* this is the only place where we write chains */ GST_CHAIN_LOCK (ogg); + ogg->chain_error = GST_FLOW_OK; got_chains = gst_ogg_demux_find_chains (ogg); GST_CHAIN_UNLOCK (ogg); if (!got_chains) @@ -2583,6 +2604,8 @@ /* and seek to configured positions without FLUSH */ gst_ogg_demux_perform_seek (ogg, event); + if (event) GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); @@ -2625,7 +2648,7 @@ chain_read_failed: GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL), ("could not read chains")); - ret = GST_FLOW_ERROR; + ret = ogg->chain_error; goto pause; pause: |
From: <wt...@ke...> - 2006-04-11 14:42:48
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Apr 11 2006 14:42:45 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), (gst_ogg_chain_free), (gst_ogg_demux_sink_event), (gst_ogg_demux_loop): More cleanups. Respect segment stop when emiting EOS or SEGMENT_DONE. Fixes (#337945). Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2551&r2=1.2552 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.144&r2=1.145 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2551 retrieving revision 1.2552 diff -u -d -r1.2551 -r1.2552 --- ChangeLog 11 Apr 2006 10:45:32 -0000 1.2551 +++ ChangeLog 11 Apr 2006 14:42:33 -0000 1.2552 @@ -1,3 +1,13 @@ +2006-04-11 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_src_query), + (gst_ogg_demux_chain_peer), (gst_ogg_pad_submit_packet), + (gst_ogg_chain_free), (gst_ogg_demux_sink_event), + (gst_ogg_demux_loop): + More cleanups. + Respect segment stop when emiting EOS or SEGMENT_DONE. + Fixes (#337945). 2006-04-11 Tim-Philipp Müller <tim at centricular dot net> * gst/playback/gststreamselector.c: Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.144 retrieving revision 1.145 diff -u -d -r1.144 -r1.145 --- gstoggdemux.c 10 Apr 2006 19:13:30 -0000 1.144 +++ gstoggdemux.c 11 Apr 2006 14:42:33 -0000 1.145 @@ -930,51 +930,77 @@ GstBuffer *buf; GstFlowReturn ret; GstOggDemux *ogg = pad->ogg; + GstFormat format; + gint64 current_time; + GstOggChain *chain; + GST_DEBUG_OBJECT (ogg, + "%p streaming to peer serial %08lx", pad, pad->serialno); ret = gst_pad_alloc_buffer_and_set_caps (GST_PAD (pad), GST_BUFFER_OFFSET_NONE, packet->bytes, GST_PAD_CAPS (pad), &buf); + if (ret != GST_FLOW_OK) + goto no_buffer; - GST_DEBUG_OBJECT (ogg, - "%p streaming to peer serial %08lx", pad, pad->serialno); + /* copy packet in buffer */ + memcpy (buf->data, packet->packet, packet->bytes); - if (ret == GST_FLOW_OK) { - memcpy (buf->data, packet->packet, packet->bytes); + GST_BUFFER_OFFSET (buf) = -1; + GST_BUFFER_OFFSET_END (buf) = packet->granulepos; - GST_BUFFER_OFFSET (buf) = -1; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos; + ret = gst_pad_push (GST_PAD (pad), buf); + /* ignore not linked */ + if (ret == GST_FLOW_NOT_LINKED) + ret = GST_FLOW_OK; - ret = gst_pad_push (GST_PAD (pad), buf); - if (ret == GST_FLOW_NOT_LINKED) - ret = GST_FLOW_OK; + /* we're done with skeleton stuff */ + if (pad->is_skeleton) + goto done; - if (packet->granulepos >= 0) { - GstFormat format; - gint64 current_time; + /* check if valid granulepos, then we can calculate the current + * position */ + if (packet->granulepos < 0) - ogg->current_granule = packet->granulepos; - format = GST_FORMAT_TIME; - if (!pad->is_skeleton) { - if (!gst_ogg_pad_query_convert (pad, - GST_FORMAT_DEFAULT, packet->granulepos, &format, - (gint64 *) & current_time)) { - GST_WARNING_OBJECT (ogg, "could not convert granulepos to time"); - } else { - gst_segment_set_last_stop (&ogg->segment, GST_FORMAT_TIME, - current_time); - GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT, - GST_TIME_ARGS (current_time)); - } - } - } - } else { - GST_DEBUG_OBJECT (ogg, - "%p could not get buffer from peer %08lx", pad, pad->serialno); + /* store current granule pos */ + ogg->current_granule = packet->granulepos; + /* convert to time */ + format = GST_FORMAT_TIME; + if (!gst_ogg_pad_query_convert (pad, + GST_FORMAT_DEFAULT, packet->granulepos, &format, + (gint64 *) & current_time)) + goto convert_failed; + /* convert to stream time */ + if ((chain = pad->chain)) + current_time = current_time - chain->segment_start + chain->begin_time; + /* and store as the current position */ + gst_segment_set_last_stop (&ogg->segment, GST_FORMAT_TIME, current_time); + GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT, + GST_TIME_ARGS (current_time)); +done: + return ret; + /* special cases */ +no_buffer: + { + GST_DEBUG_OBJECT (ogg, + "%p could not get buffer from peer %08lx, %d (%s)", pad, + pad->serialno, ret, gst_flow_get_name (ret)); if (ret == GST_FLOW_NOT_LINKED) ret = GST_FLOW_OK; + return ret; + } +convert_failed: + GST_WARNING_OBJECT (ogg, "could not convert granulepos to time"); } - return ret; } /* submit a packet to the oggpad, this function will run the @@ -996,7 +1022,6 @@ !memcmp (packet->packet, "fishead\0", 8)) { gst_ogg_pad_parse_skeleton_fishead (pad, packet); } - gst_ogg_pad_typefind (pad, packet); pad->have_type = TRUE; @@ -1172,7 +1197,7 @@ gst_object_unref (pad); g_array_free (chain->streams, TRUE); - chain->streams = NULL; + g_free (chain); static GstOggPad * @@ -2609,24 +2634,8 @@ GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset); - if (ogg->offset == ogg->length) { - ret = GST_FLOW_OK; - /* segment playback just posts a segment end message instead of - * pushing out EOS. */ - /* FIXME, need to be done somewhere else where we - * can check against segment_stop time. */ - ogg->segment_running = FALSE; - if (ogg->segment.flags & GST_SEEK_FLAG_SEGMENT) { - GST_LOG_OBJECT (ogg, "Sending segment done, at end of segment"); - gst_element_post_message (GST_ELEMENT (ogg), - gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME, - ogg->total_time)); - } else { - GST_LOG_OBJECT (ogg, "Sending EOS, at end of stream"); - gst_ogg_demux_send_event (ogg, gst_event_new_eos ()); - goto pause; - } + if (ogg->offset == ogg->length) + goto eos; ret = gst_pad_pull_range (ogg->sinkpad, ogg->offset, CHUNKSIZE, &buffer); if (ret != GST_FLOW_OK) { @@ -2642,6 +2651,11 @@ goto pause; + /* check for the end of the segment */ + if (ogg->segment.stop != -1 && ogg->segment.last_stop != -1) + if (ogg->segment.last_stop > ogg->segment.stop) + goto eos; return; /* ERRORS */ @@ -2651,6 +2665,28 @@ ret = ogg->chain_error; +eos: + /* segment playback just posts a segment end message instead of + * pushing out EOS. */ + ogg->segment_running = FALSE; + if (ogg->segment.flags & GST_SEEK_FLAG_SEGMENT) { + gint64 stop; + if ((stop = ogg->segment.stop) == -1) + stop = ogg->segment.duration; + GST_LOG_OBJECT (ogg, "Sending segment done, at end of segment"); + gst_element_post_message (GST_ELEMENT (ogg), + gst_message_new_segment_done (GST_OBJECT (ogg), GST_FORMAT_TIME, + stop)); + } else { + GST_LOG_OBJECT (ogg, "Sending EOS, at end of stream"); + gst_ogg_demux_send_event (ogg, gst_event_new_eos ()); + } + goto pause; pause: { GST_LOG_OBJECT (ogg, "pausing task, reason %s", gst_flow_get_name (ret)); |
From: <wt...@ke...> - 2006-05-15 15:01:22
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon May 15 2006 15:01:20 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet): Fix seeking performance in the case where a non-header packet has a 0 granulepos (busted theora case). Fixes #341719 Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2635&r2=1.2636 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.148&r2=1.149 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2635 retrieving revision 1.2636 diff -u -d -r1.2635 -r1.2636 --- ChangeLog 15 May 2006 14:19:35 -0000 1.2635 +++ ChangeLog 15 May 2006 15:01:08 -0000 1.2636 @@ -1,3 +1,10 @@ +2006-05-15 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet): + Fix seeking performance in the case where a non-header + packet has a 0 granulepos (busted theora case). + Fixes #341719 2006-05-15 Tim-Philipp Müller <tim at centricular dot net> * gst/subparse/gstsubparse.c: Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.148 retrieving revision 1.149 diff -u -d -r1.148 -r1.149 --- gstoggdemux.c 3 May 2006 15:34:48 -0000 1.148 +++ gstoggdemux.c 15 May 2006 15:01:08 -0000 1.149 @@ -1041,9 +1041,16 @@ granule = packet->granulepos; if (granule != -1) { + GST_DEBUG_OBJECT (ogg, "%p has granulepos %lld", pad, granule); ogg->current_granule = granule; pad->current_granule = granule; + /* granulepos 0 and -1 are considered header packets. + * Note that since theora is busted, it can create non-header + * packets with 0 granulepos. We will correct for this when our + * internal decoder produced a frame and we don't have a + * granulepos because in that case the granulpos must have been 0 */ if (pad->first_granule == -1 && granule != 0) { + GST_DEBUG_OBJECT (ogg, "%p found first granulepos %lld", pad, granule); pad->first_granule = granule; } } @@ -1059,6 +1066,15 @@ if (pad->start_time != GST_CLOCK_TIME_NONE) { GstOggChain *chain = pad->chain; + /* correction for busted ogg, if the internal decoder outputed + * a timestamp but we did not get a granulepos, it must have + * been 0 and the time is therefore also 0 */ + if (pad->first_time == -1) { + GST_DEBUG_OBJECT (ogg, "%p found start time without granulepos", pad); + pad->first_granule = 0; + pad->first_time = 0; + } /* check if complete chain has start time */ if (chain == ogg->building_chain) { |
From: <wt...@ke...> - 2006-05-30 16:04:42
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue May 30 2006 16:04:26 UTC Log message: * ext/ogg/gstoggdemux.c: (gst_ogg_chain_new_stream): Fix build again. Modified files: . : ChangeLog ext/ogg : gstoggdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2680&r2=1.2681 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c.diff?r1=1.151&r2=1.152 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2680 retrieving revision 1.2681 diff -u -d -r1.2680 -r1.2681 --- ChangeLog 30 May 2006 14:59:24 -0000 1.2680 +++ ChangeLog 30 May 2006 16:04:14 -0000 1.2681 @@ -1,3 +1,8 @@ +2006-05-30 Wim Taymans <wi...@fl...> + + * ext/ogg/gstoggdemux.c: (gst_ogg_chain_new_stream): + Fix build again. 2006-05-30 Thomas Vander Stichele <thomas at apestaart dot org> * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind), Index: gstoggdemux.c RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v retrieving revision 1.151 retrieving revision 1.152 diff -u -d -r1.151 -r1.152 --- gstoggdemux.c 30 May 2006 14:59:24 -0000 1.151 +++ gstoggdemux.c 30 May 2006 16:04:14 -0000 1.152 @@ -1270,7 +1270,7 @@ gst_object_sink (GST_OBJECT (ret)); list = gst_tag_list_new (); - name = g_strdup_printf ("serial_%08x", serialno); + name = g_strdup_printf ("serial_%08lx", serialno); GST_PAD_DIRECTION (ret) = GST_PAD_SRC; ret->chain = chain; |