From 2bed7c60aa6070629c924174780af9cccf102b1a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 May 2005 12:04:37 +0000 Subject: [PATCH] ext/: Remove STREAM locks as they are taken in core now. Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_dispose), (gst_ogg_pad_typefind), (gst_ogg_pad_submit_packet), (gst_ogg_chain_new_stream), (gst_ogg_demux_perform_seek), (gst_ogg_demux_chain), (gst_ogg_demux_loop), (gst_ogg_demux_sink_activate): * ext/theora/theoradec.c: (theora_dec_src_event), (theora_handle_comment_packet), (theora_dec_chain), (theora_dec_change_state): * ext/vorbis/vorbisdec.c: (vorbis_dec_sink_event), (vorbis_handle_data_packet), (vorbis_dec_chain), (vorbis_dec_change_state): Remove STREAM locks as they are taken in core now. Never set bogus granulepos on vorbis/theora. Fix leaks in theoradec tag parsing. --- ChangeLog | 17 ++++++++ ext/ogg/gstoggdemux.c | 93 ++++++++++++++---------------------------- ext/theora/theoradec.c | 16 +++----- ext/vorbis/vorbisdec.c | 48 ++++++++++++++-------- 4 files changed, 85 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0b7f06b7b..7e2c0c191e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-05-25 Wim Taymans + + * ext/ogg/gstoggdemux.c: (gst_ogg_pad_dispose), + (gst_ogg_pad_typefind), (gst_ogg_pad_submit_packet), + (gst_ogg_chain_new_stream), (gst_ogg_demux_perform_seek), + (gst_ogg_demux_chain), (gst_ogg_demux_loop), + (gst_ogg_demux_sink_activate): + * ext/theora/theoradec.c: (theora_dec_src_event), + (theora_handle_comment_packet), (theora_dec_chain), + (theora_dec_change_state): + * ext/vorbis/vorbisdec.c: (vorbis_dec_sink_event), + (vorbis_handle_data_packet), (vorbis_dec_chain), + (vorbis_dec_change_state): + Remove STREAM locks as they are taken in core now. + Never set bogus granulepos on vorbis/theora. + Fix leaks in theoradec tag parsing. + 2005-05-25 Wim Taymans * ext/gnomevfs/gstgnomevfssrc.c: (gst_gnomevfssrc_create): diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 6bcb39018d..281fda7651 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -89,10 +89,15 @@ typedef enum GST_OGG_PAD_MODE_STREAMING, /* we are streaming buffers to the outside */ } GstOggPadMode; +//#define PARENT GstPad +//#define PARENTCLASS GstPadClass +#define PARENT GstRealPad +#define PARENTCLASS GstRealPadClass + /* all information needed for one ogg stream */ struct _GstOggPad { - GstRealPad pad; /* subclass GstRealPad */ + PARENT pad; /* subclass GstPad */ GstOggPadMode mode; @@ -109,7 +114,6 @@ struct _GstOggPad gint64 packetno; gint64 offset; - GstEvent *new_segment; gint64 start; gint64 stop; @@ -130,7 +134,7 @@ struct _GstOggPad struct _GstOggPadClass { - GstRealPadClass parent_class; + PARENTCLASS parent_class; }; typedef enum @@ -197,7 +201,7 @@ static gboolean gst_ogg_pad_event (GstPad * pad, GstEvent * event); static GstCaps *gst_ogg_pad_getcaps (GstPad * pad); static GstCaps *gst_ogg_type_find (ogg_packet * packet); -static GstRealPadClass *ogg_pad_parent_class = NULL; +static GstPadClass *ogg_pad_parent_class = NULL; static GType gst_ogg_pad_get_type (void) @@ -278,10 +282,6 @@ gst_ogg_pad_dispose (GObject * object) g_list_free (pad->headers); pad->headers = NULL; - if (pad->new_segment) { - gst_event_unref (pad->new_segment); - pad->new_segment = NULL; - } ogg_stream_reset (&pad->stream); G_OBJECT_CLASS (ogg_pad_parent_class)->dispose (object); @@ -560,6 +560,8 @@ gst_ogg_pad_typefind (GstOggPad * pad, ogg_packet * packet) gst_element_factory_create (GST_ELEMENT_FACTORY (factories->data), NULL); if (element) { + GstCaps *any; + /* this is ours */ gst_object_ref (GST_OBJECT (element)); gst_object_sink (GST_OBJECT (element)); @@ -573,7 +575,9 @@ gst_ogg_pad_typefind (GstOggPad * pad, ogg_packet * packet) 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_caps (pad->elem_out, gst_caps_new_any ()); + any = gst_caps_new_any (); + gst_pad_set_caps (pad->elem_out, any); + gst_caps_unref (any); gst_pad_set_active (pad->elem_out, TRUE); /* and this pad may not be named src.. */ @@ -648,10 +652,6 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet) "%p streaming to peer serial %08lx, packetno %lld", pad, pad->serialno, pad->packetno); - if (pad->new_segment) { - ret = gst_pad_push_event (GST_PAD (pad), pad->new_segment); - pad->new_segment = NULL; - } if (buf) { memcpy (buf->data, packet->packet, packet->bytes); @@ -683,7 +683,7 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet) GST_BUFFER_OFFSET (buf) = -1; GST_BUFFER_OFFSET_END (buf) = packet->granulepos; - ret = GST_RPAD_CHAINFUNC (pad->elem_pad) (pad->elem_pad, buf); + ret = gst_pad_chain (pad->elem_pad, buf); } #if 0 @@ -795,7 +795,7 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno) list = gst_tag_list_new (); name = g_strdup_printf ("serial_%08lx", serialno); - GST_RPAD_DIRECTION (ret) = GST_PAD_SRC; + GST_PAD_DIRECTION (ret) = GST_PAD_SRC; ret->chain = chain; ret->ogg = chain->ogg; gst_object_set_name (GST_OBJECT (ret), name); @@ -1381,16 +1381,18 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg, gint64 pos) for (j = 0; j < chain->streams->len; j++) { GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, j); - gst_event_ref (event); - /* queue the event for the streaming thread */ - pad->new_segment = event; gst_pad_push_event (GST_PAD (pad), gst_event_new_flush (TRUE)); + + /* and the discont */ + gst_event_ref (event); + gst_pad_push_event (GST_PAD (pad), event); } } gst_event_unref (event); /* restart our task since it might have been stopped when we did the * flush. */ - gst_task_start (GST_RPAD_TASK (ogg->sinkpad)); + gst_pad_start_task (ogg->sinkpad, (GstTaskFunction) gst_ogg_demux_loop, + ogg->sinkpad); } /* switch to different chain */ @@ -1792,7 +1794,7 @@ no_first_chain: * the serialno, submit pages and packets to the oggpads */ static GstFlowReturn -gst_ogg_demux_chain_unlocked (GstPad * pad, GstBuffer * buffer) +gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer) { GstOggDemux *ogg; gint ret = -1; @@ -1868,18 +1870,6 @@ gst_ogg_demux_chain_unlocked (GstPad * pad, GstBuffer * buffer) return result; } -static GstFlowReturn -gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer) -{ - GstFlowReturn ret; - - GST_STREAM_LOCK (pad); - ret = gst_ogg_demux_chain_unlocked (pad, buffer); - GST_STREAM_UNLOCK (pad); - - return ret; -} - static void gst_ogg_demux_send_eos (GstOggDemux * ogg) { @@ -1914,7 +1904,6 @@ gst_ogg_demux_loop (GstOggPad * pad) ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad)); - GST_STREAM_LOCK (pad); if (ogg->need_chains) { gboolean got_chains; @@ -1944,19 +1933,16 @@ gst_ogg_demux_loop (GstOggPad * pad) ogg->offset += GST_BUFFER_SIZE (buffer); - ret = gst_ogg_demux_chain_unlocked (ogg->sinkpad, buffer); + ret = gst_ogg_demux_chain (ogg->sinkpad, buffer); if (ret != GST_FLOW_OK) { GST_LOG_OBJECT (ogg, "got unexpected %d, pausing", ret); goto pause; } - - GST_STREAM_UNLOCK (pad); return; pause: GST_LOG_OBJECT (ogg, "pausing task"); - gst_task_pause (GST_RPAD_TASK (ogg->sinkpad)); - GST_STREAM_UNLOCK (pad); + gst_pad_pause_task (ogg->sinkpad); return; } @@ -1975,35 +1961,18 @@ gst_ogg_demux_sink_activate (GstPad * sinkpad, GstActivateMode mode) break; 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); - GST_STREAM_LOCK (sinkpad); - GST_RPAD_TASK (sinkpad) = - gst_scheduler_create_task (GST_ELEMENT_SCHEDULER (ogg), - (GstTaskFunction) gst_ogg_demux_loop, sinkpad); - - ogg->need_chains = TRUE; - ogg->seekable = TRUE; - gst_task_start (GST_RPAD_TASK (sinkpad)); - GST_STREAM_UNLOCK (sinkpad); - result = TRUE; - } + gst_pad_peer_set_active (sinkpad, mode); + ogg->need_chains = TRUE; + ogg->seekable = TRUE; + result = + gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ogg_demux_loop, + sinkpad); break; case GST_ACTIVATE_NONE: /* step 1, unblock clock sync (if any) */ /* step 2, make sure streaming finishes */ - GST_STREAM_LOCK (sinkpad); - - /* step 3, stop the task */ - if (GST_RPAD_TASK (sinkpad)) { - gst_task_stop (GST_RPAD_TASK (sinkpad)); - gst_object_unref (GST_OBJECT (GST_RPAD_TASK (sinkpad))); - GST_RPAD_TASK (sinkpad) = NULL; - } - GST_STREAM_UNLOCK (sinkpad); - - result = TRUE; + result = gst_pad_stop_task (sinkpad); break; } return result; diff --git a/ext/theora/theoradec.c b/ext/theora/theoradec.c index dedd2a4d62..b95d01c80e 100644 --- a/ext/theora/theoradec.c +++ b/ext/theora/theoradec.c @@ -535,10 +535,7 @@ theora_dec_src_event (GstPad * pad, GstEvent * event) format, value); res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek); - if (!res) - goto error; - error: gst_event_unref (event); break; } @@ -548,6 +545,10 @@ theora_dec_src_event (GstPad * pad, GstEvent * event) } return res; + +error: + gst_event_unref (event); + return res; } static gboolean @@ -633,7 +634,7 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet) GST_DEBUG ("parsing comment packet"); buf = gst_buffer_new_and_alloc (packet->bytes); - GST_BUFFER_DATA (buf) = packet->packet; + memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes); list = gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\201theora", 7, @@ -656,6 +657,7 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet) GST_TAG_VIDEO_CODEC, "Theora", NULL); //gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, 0, list); + gst_tag_list_free (list); return GST_FLOW_OK; } @@ -913,8 +915,6 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf) dec = GST_THEORA_DEC (GST_PAD_PARENT (pad)); - GST_STREAM_LOCK (pad); - if (dec->packetno >= 3) { /* try timestamp first */ outtime = GST_BUFFER_TIMESTAMP (buf); @@ -939,7 +939,6 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf) * offset before we can generate valid timestamps */ dec->queued = g_list_append (dec->queued, buf); GST_DEBUG_OBJECT (dec, "queued buffer"); - GST_STREAM_UNLOCK (pad); return GST_FLOW_OK; } else { /* granulepos to time */ @@ -1013,7 +1012,6 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf) done: dec->packetno++; _inc_granulepos (dec); - GST_STREAM_UNLOCK (pad); gst_buffer_unref (buf); @@ -1040,13 +1038,11 @@ theora_dec_change_state (GstElement * element) case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: - GST_STREAM_LOCK (dec->sinkpad); theora_clear (&dec->state); theora_comment_clear (&dec->comment); theora_info_clear (&dec->info); dec->packetno = 0; dec->granulepos = -1; - GST_STREAM_UNLOCK (dec->sinkpad); break; case GST_STATE_READY_TO_NULL: break; diff --git a/ext/vorbis/vorbisdec.c b/ext/vorbis/vorbisdec.c index cdb096700e..1d1d9173d1 100644 --- a/ext/vorbis/vorbisdec.c +++ b/ext/vorbis/vorbisdec.c @@ -376,6 +376,7 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event) GST_LOG_OBJECT (dec, "handling event"); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_DISCONTINUOUS: + GST_STREAM_LOCK (pad); if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, (gint64 *) & start_value, &end_value)) { dec->granulepos = start_value; @@ -392,18 +393,25 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event) } else { GST_WARNING_OBJECT (dec, "discont event didn't include offset, we might set it wrong now"); + dec->granulepos = -1; } } + GST_DEBUG ("vd: discont %lld", dec->granulepos); + dec->granulepos = -1; if (dec->packetno < 3) { if (dec->granulepos != 0) GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("can't handle discont before parsing first 3 packets")); dec->packetno = 0; +#if 0 gst_pad_push_event (dec->srcpad, gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)); +#endif + gst_event_ref (event); + gst_pad_push_event (dec->srcpad, event); } else { GstFormat time_format, default_format, bytes_format; @@ -417,22 +425,30 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event) dec->granulepos, &time_format, &time) && vorbis_dec_convert (dec->srcpad, GST_FORMAT_DEFAULT, dec->granulepos, &bytes_format, &bytes)) { - gst_pad_push_event (dec->srcpad, - gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, - time, GST_FORMAT_DEFAULT, dec->granulepos, - GST_FORMAT_BYTES, bytes, 0)); + + gst_event_ref (event); + gst_pad_push_event (dec->srcpad, event); + /* + gst_pad_push_event (dec->srcpad, + gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, + time, GST_FORMAT_DEFAULT, dec->granulepos, + GST_FORMAT_BYTES, bytes, 0)); + */ } else { GST_ERROR_OBJECT (dec, "failed to parse data for DISCONT event, not sending any"); + gst_event_ref (event); + gst_pad_push_event (dec->srcpad, event); } #ifdef HAVE_VORBIS_SYNTHESIS_RESTART vorbis_synthesis_restart (&dec->vd); #endif } + GST_STREAM_UNLOCK (pad); gst_event_unref (event); break; default: - ret = gst_pad_event_default (dec->sinkpad, event); + ret = gst_pad_event_default (pad, event); break; } return ret; @@ -657,12 +673,16 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet) GST_BUFFER_OFFSET (out) = vd->granulepos; GST_BUFFER_OFFSET_END (out) = vd->granulepos + sample_count; - GST_BUFFER_TIMESTAMP (out) = vd->granulepos * GST_SECOND / vd->vi.rate; + if (vd->granulepos != -1) + GST_BUFFER_TIMESTAMP (out) = vd->granulepos * GST_SECOND / vd->vi.rate; + else + GST_BUFFER_TIMESTAMP (out) = -1; GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate; result = gst_pad_push (vd->srcpad, out); - vd->granulepos += sample_count; + if (vd->granulepos != -1) + vd->granulepos += sample_count; } else { /* no buffer.. */ result = GST_FLOW_OK; @@ -703,14 +723,12 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) ogg_packet packet; GstFlowReturn result = GST_FLOW_OK; - GST_STREAM_LOCK (pad); - vd = GST_VORBIS_DEC (GST_PAD_PARENT (pad)); /* make ogg_packet out of the buffer */ packet.packet = GST_BUFFER_DATA (buffer); packet.bytes = GST_BUFFER_SIZE (buffer); - packet.granulepos = GST_BUFFER_OFFSET_END (buffer); + packet.granulepos = vd->granulepos; packet.packetno = vd->packetno++; /* * FIXME. Is there anyway to know that this is the last packet and @@ -731,13 +749,13 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) result = vorbis_handle_data_packet (vd, &packet); } + GST_DEBUG ("offset end: %lld", GST_BUFFER_OFFSET_END (buffer)); + /* granulepos is the last sample in the packet */ if (GST_BUFFER_OFFSET_END_IS_VALID (buffer)) vd->granulepos = GST_BUFFER_OFFSET_END (buffer);; done: - GST_STREAM_UNLOCK (pad); - gst_buffer_unref (buffer); return result; @@ -759,7 +777,7 @@ vorbis_dec_change_state (GstElement * element) vorbis_info_init (&vd->vi); vorbis_comment_init (&vd->vc); vd->initialized = FALSE; - vd->granulepos = 0; + vd->granulepos = -1; vd->packetno = 0; break; case GST_STATE_PAUSED_TO_PLAYING: @@ -774,14 +792,10 @@ vorbis_dec_change_state (GstElement * element) case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: - GST_STREAM_LOCK (vd->sinkpad); vorbis_block_clear (&vd->vb); vorbis_dsp_clear (&vd->vd); vorbis_comment_clear (&vd->vc); vorbis_info_clear (&vd->vi); - vd->packetno = 0; - vd->granulepos = 0; - GST_STREAM_UNLOCK (vd->sinkpad); break; case GST_STATE_READY_TO_NULL: break;