diff --git a/ChangeLog b/ChangeLog index f3caf32588..b267472623 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-05-15 Wim Taymans + + * ext/theora/theoradec.c: (gst_theora_dec_reset), + (theora_dec_src_query), (theora_dec_src_event), + (theora_dec_sink_event), (theora_handle_comment_packet), + (theora_handle_data_packet), (theora_dec_change_state): + Cleanups, add some G_LIKELY. + Use segment helpers instead of our own wrong code. + Clear queued buffers on seek and READY. + + * ext/vorbis/vorbisdec.c: (gst_vorbis_dec_reset), + (vorbis_dec_convert), (vorbis_dec_src_query), + (vorbis_dec_src_event), (vorbis_dec_sink_event), + (vorbis_handle_comment_packet), (vorbis_dec_push), + (vorbis_handle_data_packet), (vorbis_dec_chain), + (vorbis_dec_change_state): + * ext/vorbis/vorbisdec.h: + Remove old useless packetno variable. + Do position query properly. + Add some G_LIKELY. + Do cleanup of queued buffers in new helper function + and use it. + 2006-05-15 Tim-Philipp Müller * ext/alsa/gstalsasink.c: (gst_alsasink_getcaps): diff --git a/ext/theora/theoradec.c b/ext/theora/theoradec.c index a3f8bb7b3b..77ba63ce23 100644 --- a/ext/theora/theoradec.c +++ b/ext/theora/theoradec.c @@ -169,6 +169,8 @@ gst_theora_dec_init (GstTheoraDec * dec, GstTheoraDecClass * g_class) static void gst_theora_dec_reset (GstTheoraDec * dec) { + GList *walk; + dec->need_keyframe = TRUE; dec->last_timestamp = -1; dec->granulepos = -1; @@ -180,6 +182,12 @@ gst_theora_dec_reset (GstTheoraDec * dec) dec->proportion = 1.0; dec->earliest_time = -1; GST_OBJECT_UNLOCK (dec); + + for (walk = dec->queued; walk; walk = g_list_next (walk)) { + gst_buffer_unref (GST_BUFFER_CAST (walk->data)); + } + g_list_free (dec->queued); + dec->queued = NULL; } static int @@ -466,7 +474,7 @@ theora_dec_src_query (GstPad * pad, GstQuery * query) granulepos, &my_format, &time))) goto error; - time = (time - dec->segment.start) + dec->segment.time; + time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); GST_LOG_OBJECT (dec, "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time)); @@ -483,10 +491,20 @@ theora_dec_src_query (GstPad * pad, GstQuery * query) break; } case GST_QUERY_DURATION: - /* forward to peer for total */ - if (!(res = gst_pad_query (GST_PAD_PEER (dec->sinkpad), query))) + { + GstPad *peer; + + if (!(peer = gst_pad_get_peer (dec->sinkpad))) goto error; + + /* forward to peer for total */ + res = gst_pad_query (peer, query); + gst_object_unref (peer); + if (!res) + goto error; + break; + } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; @@ -587,7 +605,6 @@ theora_dec_src_event (GstPad * pad, GstEvent * event) flags, cur_type, tcur, stop_type, tstop); res = gst_pad_push_event (dec->sinkpad, real_seek); - break; } case GST_EVENT_QOS: @@ -654,11 +671,11 @@ theora_dec_sink_event (GstPad * pad, GstEvent * event) { gboolean update; GstFormat format; - gdouble rate; + gdouble rate, arate; gint64 start, stop, time; - gst_event_parse_new_segment (event, &update, &rate, &format, &start, - &stop, &time); + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, + &start, &stop, &time); /* we need TIME and a positive rate */ if (format != GST_FORMAT_TIME) @@ -668,8 +685,8 @@ theora_dec_sink_event (GstPad * pad, GstEvent * event) goto newseg_wrong_rate; /* now configure the values */ - gst_segment_set_newsegment (&dec->segment, update, - rate, format, start, stop, time); + gst_segment_set_newsegment_full (&dec->segment, update, + rate, arate, format, start, stop, time); /* and forward */ ret = gst_pad_push_event (dec->srcpad, event); @@ -736,7 +753,7 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet) GST_TAG_NOMINAL_BITRATE, dec->info.target_bitrate, NULL); } - gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, list); + gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), dec->srcpad, list); return GST_FLOW_OK; } @@ -918,10 +935,10 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet, /* the second most significant bit of the first data byte is cleared * for keyframes */ keyframe = (packet->packet[0] & 0x40) == 0; - if (keyframe) { + if (G_UNLIKELY (keyframe)) { GST_DEBUG_OBJECT (dec, "we have a keyframe"); dec->need_keyframe = FALSE; - } else if (dec->need_keyframe) { + } else if (G_UNLIKELY (dec->need_keyframe)) { goto dropping; } @@ -1164,7 +1181,6 @@ theora_dec_change_state (GstElement * element, GstStateChange transition) GstTheoraDec *dec = GST_THEORA_DEC (element); GstStateChangeReturn ret; - switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; diff --git a/ext/vorbis/vorbisdec.c b/ext/vorbis/vorbisdec.c index b44c380b9e..ff11dbb96c 100644 --- a/ext/vorbis/vorbisdec.c +++ b/ext/vorbis/vorbisdec.c @@ -182,6 +182,25 @@ vorbis_dec_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +gst_vorbis_dec_reset (GstVorbisDec * dec) +{ + GList *walk; + + dec->cur_timestamp = GST_CLOCK_TIME_NONE; + dec->prev_timestamp = GST_CLOCK_TIME_NONE; + dec->granulepos = -1; + dec->discont = TRUE; + gst_segment_init (&dec->segment, GST_FORMAT_TIME); + + for (walk = dec->queued; walk; walk = g_list_next (walk)) { + gst_buffer_unref (GST_BUFFER_CAST (walk->data)); + } + g_list_free (dec->queued); + dec->queued = NULL; +} + + static gboolean vorbis_dec_convert (GstPad * pad, GstFormat src_format, gint64 src_value, @@ -198,7 +217,7 @@ vorbis_dec_convert (GstPad * pad, dec = GST_VORBIS_DEC (gst_pad_get_parent (pad)); - if (dec->packetno < 1) + if (!dec->initialized) goto no_header; if (dec->sinkpad == pad && @@ -271,7 +290,6 @@ no_format: static gboolean vorbis_dec_src_query (GstPad * pad, GstQuery * query) { - gint64 granulepos; GstVorbisDec *dec; gboolean res = FALSE; @@ -280,29 +298,37 @@ vorbis_dec_src_query (GstPad * pad, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { - GstFormat format; - gint64 value; + gint64 granulepos, value; + GstFormat my_format, format; + gint64 time; /* we start from the last seen granulepos */ granulepos = dec->granulepos; gst_query_parse_position (query, &format, NULL); - /* and convert to the final format */ + /* and convert to the final format in two steps with time as the + * intermediate step */ + my_format = GST_FORMAT_TIME; if (!(res = - vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, &format, - &value))) + vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, + &my_format, &time))) goto error; /* correct for the segment values */ - value = - gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, value); + time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); + + GST_LOG_OBJECT (dec, + "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time)); + + /* and convert to the final format */ + if (!(res = vorbis_dec_convert (pad, my_format, time, &format, &value))) + goto error; gst_query_set_position (query, format, value); GST_LOG_OBJECT (dec, - "query %u: peer returned granulepos: %llu - we return %llu (format %u)", - query, granulepos, value, format); + "query %p: we return %lld (format %u)", query, value, format); break; } @@ -406,6 +432,7 @@ vorbis_dec_src_event (GstPad * pad, GstEvent * event) gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop); + gst_event_unref (event); /* we have to ask our peer to seek to time here as we know * nothing about how to generate a granulepos from the src @@ -415,9 +442,9 @@ vorbis_dec_src_event (GstPad * pad, GstEvent * event) */ tformat = GST_FORMAT_TIME; if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur))) - goto error; + goto convert_error; if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop))) - goto error; + goto convert_error; /* then seek with time on the peer */ real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, @@ -425,11 +452,10 @@ vorbis_dec_src_event (GstPad * pad, GstEvent * event) res = gst_pad_push_event (dec->sinkpad, real_seek); - gst_event_unref (event); break; } default: - res = gst_pad_event_default (pad, event); + res = gst_pad_push_event (dec->sinkpad, event); break; } done: @@ -438,10 +464,9 @@ done: return res; /* ERRORS */ -error: +convert_error: { GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek"); - gst_event_unref (event); goto done; } } @@ -463,9 +488,11 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event) ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_FLUSH_STOP: - /* here we are supposed to clean any state in the - * decoder */ - gst_segment_init (&dec->segment, GST_FORMAT_TIME); + /* here we must clean any state in the decoder */ +#ifdef HAVE_VORBIS_SYNTHESIS_RESTART + vorbis_synthesis_restart (&dec->vd); +#endif + gst_vorbis_dec_reset (dec); ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_NEWSEGMENT: @@ -647,7 +674,7 @@ vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet) GST_TAG_BITRATE, (guint) bitrate, NULL); } - gst_element_found_tags_for_pad (GST_ELEMENT (vd), vd->srcpad, list); + gst_element_found_tags_for_pad (GST_ELEMENT_CAST (vd), vd->srcpad, list); return GST_FLOW_OK; } @@ -725,18 +752,6 @@ copy_samples (float *out, float **in, guint samples, gint channels) #endif } -static void -vorbis_dec_clean_queued (GstVorbisDec * dec) -{ - GList *walk; - - for (walk = dec->queued; walk; walk = g_list_next (walk)) { - gst_buffer_unref (GST_BUFFER_CAST (walk->data)); - } - g_list_free (dec->queued); - dec->queued = NULL; -} - static GstFlowReturn vorbis_dec_push (GstVorbisDec * dec, GstBuffer * buf) { @@ -805,10 +820,10 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet) goto not_initialized; /* normal data packet */ - if (vorbis_synthesis (&vd->vb, packet)) + if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet))) goto could_not_read; - if (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0) + if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0)) goto not_accepted; /* assume all goes well here */ @@ -824,11 +839,11 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet) result = gst_pad_alloc_buffer_and_set_caps (vd->srcpad, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (vd->srcpad), &out); - if (result != GST_FLOW_OK) + if (G_UNLIKELY (result != GST_FLOW_OK)) goto done; /* get samples ready for reading now, should be sample_count */ - if ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count) + if (G_UNLIKELY ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count)) goto wrong_samples; /* copy samples in buffer */ @@ -878,7 +893,7 @@ done: not_initialized: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, - (NULL), ("no header sent yet (packet no is %d)", packet->packetno)); + (NULL), ("no header sent yet")); return GST_FLOW_ERROR; } could_not_read: @@ -941,7 +956,7 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) packet.packet = GST_BUFFER_DATA (buffer); packet.bytes = GST_BUFFER_SIZE (buffer); packet.granulepos = GST_BUFFER_OFFSET_END (buffer); - packet.packetno = vd->packetno++; + packet.packetno = 0; /* we don't care */ /* * FIXME. Is there anyway to know that this is the last packet and * set e_o_s?? @@ -950,7 +965,7 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) */ packet.e_o_s = 0; - if (packet.bytes < 1) + if (G_UNLIKELY (packet.bytes < 1)) goto wrong_size; GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT, @@ -1000,12 +1015,7 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition) vorbis_info_init (&vd->vi); vorbis_comment_init (&vd->vc); vd->initialized = FALSE; - vd->cur_timestamp = GST_CLOCK_TIME_NONE; - vd->prev_timestamp = GST_CLOCK_TIME_NONE; - vd->granulepos = -1; - vd->packetno = 0; - vd->discont = TRUE; - gst_segment_init (&vd->segment, GST_FORMAT_TIME); + gst_vorbis_dec_reset (vd); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; @@ -1024,7 +1034,7 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition) vorbis_dsp_clear (&vd->vd); vorbis_comment_clear (&vd->vc); vorbis_info_clear (&vd->vi); - vorbis_dec_clean_queued (vd); + gst_vorbis_dec_reset (vd); break; case GST_STATE_CHANGE_READY_TO_NULL: break; diff --git a/ext/vorbis/vorbisdec.h b/ext/vorbis/vorbisdec.h index ec904e4f04..9319ae349f 100644 --- a/ext/vorbis/vorbisdec.h +++ b/ext/vorbis/vorbisdec.h @@ -57,7 +57,6 @@ struct _GstVorbisDec { vorbis_info vi; vorbis_comment vc; vorbis_block vb; - guint packetno; guint64 granulepos; gboolean initialized;