X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst-libs%2Fgst%2Faudio%2Fgstaudiodecoder.c;h=eec58b9cc55ac77e1a31c8c194cf02fe033badb4;hb=fb6d09055ae90979682fa4b1c6ee4f4abdaafd8f;hp=ced541998165b0b5e26237d8595a936f773336a3;hpb=91bbfbd819f6a347be114ee280dd5bb5b0ab1385;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index ced5419..eec58b9 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -280,25 +280,54 @@ static GstFlowReturn gst_audio_decoder_chain_reverse (GstAudioDecoder * static GstStateChangeReturn gst_audio_decoder_change_state (GstElement * element, GstStateChange transition); -static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event); -static gboolean gst_audio_decoder_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps); -static gboolean gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps); -static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstBuffer * buf); -static gboolean gst_audio_decoder_src_query (GstPad * pad, GstQuery * query); -static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query); -static const GstQueryType *gst_audio_decoder_get_query_types (GstPad * pad); +static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, + GstCaps * caps); +gboolean gst_audio_decoder_src_setcaps (GstAudioDecoder * dec, GstCaps * caps); +static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstObject * parent, + GstBuffer * buf); +static gboolean gst_audio_decoder_src_query (GstPad * pad, GstObject * parent, + GstQuery * query); +static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent, + GstQuery * query); static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full); +static GstElementClass *parent_class = NULL; -GST_BOILERPLATE (GstAudioDecoder, gst_audio_decoder, GstElement, - GST_TYPE_ELEMENT); +static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass); +static void gst_audio_decoder_init (GstAudioDecoder * dec, + GstAudioDecoderClass * klass); -static void -gst_audio_decoder_base_init (gpointer g_class) +GType +gst_audio_decoder_get_type (void) { + static volatile gsize audio_decoder_type = 0; + + if (g_once_init_enter (&audio_decoder_type)) { + GType _type; + static const GTypeInfo audio_decoder_info = { + sizeof (GstAudioDecoderClass), + NULL, + NULL, + (GClassInitFunc) gst_audio_decoder_class_init, + NULL, + NULL, + sizeof (GstAudioDecoder), + 0, + (GInstanceInitFunc) gst_audio_decoder_init, + }; + + _type = g_type_register_static (GST_TYPE_ELEMENT, + "GstAudioDecoder", &audio_decoder_info, G_TYPE_FLAG_ABSTRACT); + g_once_init_leave (&audio_decoder_type, _type); + } + return audio_decoder_type; } + static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass) { @@ -357,8 +386,6 @@ gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass) dec->sinkpad = gst_pad_new_from_template (pad_template, "sink"); gst_pad_set_event_function (dec->sinkpad, GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_event)); - gst_pad_set_setcaps_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_setcaps)); gst_pad_set_chain_function (dec->sinkpad, GST_DEBUG_FUNCPTR (gst_audio_decoder_chain)); gst_pad_set_query_function (dec->sinkpad, @@ -372,14 +399,10 @@ gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass) g_return_if_fail (pad_template != NULL); dec->srcpad = gst_pad_new_from_template (pad_template, "src"); - gst_pad_set_setcaps_function (dec->srcpad, - GST_DEBUG_FUNCPTR (gst_audio_decoder_src_setcaps)); gst_pad_set_event_function (dec->srcpad, GST_DEBUG_FUNCPTR (gst_audio_decoder_src_event)); gst_pad_set_query_function (dec->srcpad, GST_DEBUG_FUNCPTR (gst_audio_decoder_src_query)); - gst_pad_set_query_type_function (dec->srcpad, - GST_DEBUG_FUNCPTR (gst_audio_decoder_get_query_types)); gst_pad_use_fixed_caps (dec->srcpad); gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); GST_DEBUG_OBJECT (dec, "srcpad created"); @@ -415,7 +438,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) dec->priv->error_count = 0; gst_audio_decoder_clear_queues (dec); - gst_audio_info_clear (&dec->priv->ctx.info); + gst_audio_info_init (&dec->priv->ctx.info); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); if (dec->priv->taglist) { @@ -466,17 +489,22 @@ gst_audio_decoder_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } -/* automagically perform sanity checking of src caps; - * also extracts output data format */ -static gboolean -gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps) +/** + * gst_audio_decoder_set_outcaps: + * @dec: a #GstAudioDecoder + * @caps: #GstCaps + * + * Configure output @caps on the srcpad of @dec. Also perform + * sanity checking of @caps and extracts output data format + * + * Returns: %TRUE on success. + * */ +gboolean +gst_audio_decoder_set_outcaps (GstAudioDecoder * dec, GstCaps * caps) { - GstAudioDecoder *dec; gboolean res = TRUE; guint old_rate; - dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); - GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps); GST_AUDIO_DECODER_STREAM_LOCK (dec); @@ -500,7 +528,8 @@ gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps) done: GST_AUDIO_DECODER_STREAM_UNLOCK (dec); - gst_object_unref (dec); + res = gst_pad_set_caps (dec->srcpad, caps); + return res; /* ERRORS */ @@ -513,13 +542,11 @@ refuse_caps: } static gboolean -gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) +gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, GstCaps * caps) { - GstAudioDecoder *dec; GstAudioDecoderClass *klass; gboolean res = TRUE; - dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); klass = GST_AUDIO_DECODER_GET_CLASS (dec); GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps); @@ -527,18 +554,19 @@ gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) GST_AUDIO_DECODER_STREAM_LOCK (dec); /* NOTE pbutils only needed here */ /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */ +#if 0 if (dec->priv->taglist) gst_tag_list_free (dec->priv->taglist); dec->priv->taglist = gst_tag_list_new (); gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist, GST_TAG_AUDIO_CODEC, caps); +#endif if (klass->set_format) res = klass->set_format (dec, caps); GST_AUDIO_DECODER_STREAM_UNLOCK (dec); - g_object_unref (dec); return res; } @@ -580,8 +608,9 @@ gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf) return GST_FLOW_OK; } - GST_LOG_OBJECT (dec, "clipping buffer of size %d with ts %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), + GST_LOG_OBJECT (dec, + "clipping buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT + ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); @@ -594,8 +623,6 @@ gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf) } /* decorate */ - gst_buffer_set_caps (buf, GST_PAD_CAPS (dec->srcpad)); - if (G_UNLIKELY (priv->discont)) { GST_LOG_OBJECT (dec, "marking discont"); GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); @@ -606,7 +633,7 @@ gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf) if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) { /* duration should always be valid for raw audio */ g_assert (GST_BUFFER_DURATION_IS_VALID (buf)); - dec->segment.last_stop = + dec->segment.position = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf); } @@ -622,8 +649,9 @@ gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf) } } - GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), + GST_LOG_OBJECT (dec, + "pushing buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT + ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); @@ -648,8 +676,9 @@ gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf) gst_audio_decoder_setup (dec); if (G_LIKELY (buf)) { - GST_LOG_OBJECT (dec, "output buffer of size %d with ts %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), + GST_LOG_OBJECT (dec, + "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT + ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); } @@ -684,7 +713,7 @@ again: } gst_adapter_push (priv->adapter_out, buf); priv->out_dur += GST_BUFFER_DURATION (buf); - av += GST_BUFFER_SIZE (buf); + av += gst_buffer_get_size (buf); buf = NULL; } if (priv->out_dur > dec->priv->latency) @@ -748,27 +777,30 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, GstAudioDecoderContext *ctx; gint samples = 0; GstClockTime ts, next_ts; + gsize size; GstFlowReturn ret = GST_FLOW_OK; /* subclass should know what it is producing by now */ - g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL, + g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad), GST_FLOW_ERROR); /* subclass should not hand us no data */ - g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0, + g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0, GST_FLOW_ERROR); /* no dummy calls please */ g_return_val_if_fail (frames != 0, GST_FLOW_ERROR); priv = dec->priv; ctx = &dec->priv->ctx; + size = buf ? gst_buffer_get_size (buf) : 0; /* must know the output format by now */ g_return_val_if_fail (buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info), GST_FLOW_ERROR); - GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames", - buf ? GST_BUFFER_SIZE (buf) : -1, - buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames); + GST_LOG_OBJECT (dec, + "accepting %" G_GSIZE_FORMAT " bytes == %" G_GSIZE_FORMAT + " samples for %d frames", buf ? size : -1, + buf ? size / ctx->info.bpf : -1, frames); GST_AUDIO_DECODER_STREAM_LOCK (dec); @@ -786,10 +818,10 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, /* output shoud be whole number of sample frames */ if (G_LIKELY (buf && ctx->info.bpf)) { - if (GST_BUFFER_SIZE (buf) % ctx->info.bpf) + if (size % ctx->info.bpf) goto wrong_buffer; /* per channel least */ - samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf; + samples = size / ctx->info.bpf; } /* frame and ts book-keeping */ @@ -865,12 +897,12 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, if (gst_tag_list_is_empty (priv->taglist)) { gst_tag_list_free (priv->taglist); } else { - gst_element_found_tags (GST_ELEMENT (dec), priv->taglist); + gst_pad_push_event (dec->srcpad, gst_event_new_tag (priv->taglist)); } priv->taglist = NULL; } - buf = gst_buffer_make_metadata_writable (buf); + buf = gst_buffer_make_writable (buf); if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) { GST_BUFFER_TIMESTAMP (buf) = priv->base_ts + @@ -901,7 +933,7 @@ exit: wrong_buffer: { GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL), - ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf), + ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d", size, ctx->info.bpf)); gst_buffer_unref (buf); ret = GST_FLOW_ERROR; @@ -924,13 +956,14 @@ gst_audio_decoder_handle_frame (GstAudioDecoder * dec, GstAudioDecoderClass * klass, GstBuffer * buffer) { if (G_LIKELY (buffer)) { + gsize size = gst_buffer_get_size (buffer); /* keep around for admin */ - GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT, - GST_BUFFER_SIZE (buffer), + GST_LOG_OBJECT (dec, + "tracking frame size %" G_GSIZE_FORMAT ", ts %" GST_TIME_FORMAT, size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); g_queue_push_tail (&dec->priv->frames, buffer); dec->priv->ctx.delay = dec->priv->frames.length; - dec->priv->bytes_in += GST_BUFFER_SIZE (buffer); + dec->priv->bytes_in += size; } else { GST_LOG_OBJECT (dec, "providing subclass with NULL frame"); } @@ -992,7 +1025,7 @@ gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force) goto parse_failed; } - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { GST_LOG_OBJECT (dec, "no frame yet"); ret = GST_FLOW_OK; break; @@ -1015,7 +1048,7 @@ gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force) priv->prev_ts = ts; } buffer = gst_adapter_take_buffer (priv->adapter, len); - buffer = gst_buffer_make_metadata_writable (buffer); + buffer = gst_buffer_make_writable (buffer); GST_BUFFER_TIMESTAMP (buffer) = ts; flush += len; } else { @@ -1113,7 +1146,7 @@ gst_audio_decoder_chain_forward (GstAudioDecoder * dec, GstBuffer * buffer) GstFlowReturn ret = GST_FLOW_OK; /* discard silly case, though maybe ts may be of value ?? */ - if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) == 0)) { + if (G_UNLIKELY (gst_buffer_get_size (buffer) == 0)) { GST_DEBUG_OBJECT (dec, "discarding empty buffer"); gst_buffer_unref (buffer); goto exit; @@ -1278,12 +1311,12 @@ gst_audio_decoder_flush_decode (GstAudioDecoder * dec) } if (G_LIKELY (res == GST_FLOW_OK)) { - GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, " + GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %" G_GSIZE_FORMAT ", " "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf, - GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); /* should be already, but let's be sure */ - buf = gst_buffer_make_metadata_writable (buf); + buf = gst_buffer_make_writable (buf); /* avoid stray DISCONT from forward processing, * which have no meaning in reverse pushing */ GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); @@ -1321,9 +1354,9 @@ gst_audio_decoder_chain_reverse (GstAudioDecoder * dec, GstBuffer * buf) } if (G_LIKELY (buf)) { - GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, " + GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %" G_GSIZE_FORMAT ", " "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf, - GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); /* add buffer to gather queue */ @@ -1334,16 +1367,16 @@ gst_audio_decoder_chain_reverse (GstAudioDecoder * dec, GstBuffer * buf) } static GstFlowReturn -gst_audio_decoder_chain (GstPad * pad, GstBuffer * buffer) +gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) { GstAudioDecoder *dec; GstFlowReturn ret; - dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad)); + dec = GST_AUDIO_DECODER (parent); GST_LOG_OBJECT (dec, - "received buffer of size %d with ts %" GST_TIME_FORMAT - ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), + "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT + ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (GST_BUFFER_DURATION (buffer))); @@ -1395,47 +1428,37 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event) gboolean handled = FALSE; switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: + case GST_EVENT_SEGMENT: { - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - gboolean update; + GstSegment seg; GST_AUDIO_DECODER_STREAM_LOCK (dec); - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); + gst_event_copy_segment (event, &seg); - if (format == GST_FORMAT_TIME) { - GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT - " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT - ", rate %g, applied_rate %g", - GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time), - rate, arate); + if (seg.format == GST_FORMAT_TIME) { + GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_SEGMENT_FORMAT, + &seg); } else { - GstFormat dformat = GST_FORMAT_TIME; - - GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT - " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT - ", rate %g, applied_rate %g", start, stop, time, rate, arate); + gint64 nstart; + GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg); /* handle newsegment resulting from legacy simple seeking */ /* note that we need to convert this whether or not enough data * to handle initial newsegment */ if (dec->priv->ctx.do_byte_time && - gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, start, - &dformat, &start)) { + gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start, + GST_FORMAT_TIME, &nstart)) { /* best attempt convert */ /* as these are only estimates, stop is kept open-ended to avoid * premature cutting */ GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT, - GST_TIME_ARGS (start)); - format = GST_FORMAT_TIME; - time = start; - stop = GST_CLOCK_TIME_NONE; + GST_TIME_ARGS (nstart)); + seg.format = GST_FORMAT_TIME; + seg.start = nstart; + seg.time = nstart; + seg.stop = GST_CLOCK_TIME_NONE; /* replace event */ gst_event_unref (event); - event = gst_event_new_new_segment_full (update, rate, arate, - GST_FORMAT_TIME, start, stop, time); + event = gst_event_new_segment (&seg); } else { GST_DEBUG_OBJECT (dec, "unsupported format; ignoring"); GST_AUDIO_DECODER_STREAM_UNLOCK (dec); @@ -1446,41 +1469,42 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event) /* finish current segment */ gst_audio_decoder_drain (dec); +#if 0 if (update) { /* time progressed without data, see if we can fill the gap with * some concealment data */ GST_DEBUG_OBJECT (dec, - "segment update: plc %d, do_plc %d, last_stop %" GST_TIME_FORMAT, + "segment update: plc %d, do_plc %d, position %" GST_TIME_FORMAT, dec->priv->plc, dec->priv->ctx.do_plc, - GST_TIME_ARGS (dec->segment.last_stop)); + GST_TIME_ARGS (dec->segment.position)); if (dec->priv->plc && dec->priv->ctx.do_plc && - dec->segment.rate > 0.0 && dec->segment.last_stop < start) { + dec->segment.rate > 0.0 && dec->segment.position < start) { GstAudioDecoderClass *klass; GstBuffer *buf; klass = GST_AUDIO_DECODER_GET_CLASS (dec); /* hand subclass empty frame with duration that needs covering */ buf = gst_buffer_new (); - GST_BUFFER_DURATION (buf) = start - dec->segment.last_stop; + GST_BUFFER_DURATION (buf) = start - dec->segment.position; /* best effort, not much error handling */ gst_audio_decoder_handle_frame (dec, klass, buf); } - } else { + } else +#endif + { /* prepare for next one */ gst_audio_decoder_flush (dec, FALSE); /* and that's where we time from, * in case upstream does not come up with anything better * (e.g. upstream BYTE) */ - if (format != GST_FORMAT_TIME) { - dec->priv->base_ts = start; + if (seg.format != GST_FORMAT_TIME) { + dec->priv->base_ts = seg.start; dec->priv->samples = 0; } } /* and follow along with segment */ - gst_segment_set_newsegment_full (&dec->segment, update, rate, arate, - format, start, stop, time); - + dec->segment = seg; dec->priv->pending_events = g_list_append (dec->priv->pending_events, event); handled = TRUE; @@ -1508,6 +1532,16 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event) GST_AUDIO_DECODER_STREAM_UNLOCK (dec); break; + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + gst_audio_decoder_sink_setcaps (dec, caps); + gst_event_unref (event); + handled = TRUE; + break; + } default: break; } @@ -1516,14 +1550,15 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event) } static gboolean -gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event) +gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event) { GstAudioDecoder *dec; GstAudioDecoderClass *klass; gboolean handled = FALSE; gboolean ret = TRUE; - dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); + dec = GST_AUDIO_DECODER (parent); klass = GST_AUDIO_DECODER_GET_CLASS (dec); GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event), @@ -1547,7 +1582,7 @@ gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event) if (!GST_EVENT_IS_SERIALIZED (event) || GST_EVENT_TYPE (event) == GST_EVENT_EOS || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) { - ret = gst_pad_event_default (pad, event); + ret = gst_pad_event_default (pad, parent, event); } else { GST_AUDIO_DECODER_STREAM_LOCK (dec); dec->priv->pending_events = @@ -1559,7 +1594,6 @@ gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event) GST_DEBUG_OBJECT (dec, "event handled"); - gst_object_unref (dec); return ret; } @@ -1600,13 +1634,12 @@ gst_audio_decoder_do_seek (GstAudioDecoder * dec, GstEvent * event) } memcpy (&seek_segment, &dec->segment, sizeof (seek_segment)); - gst_segment_set_seek (&seek_segment, rate, format, flags, start_type, + gst_segment_do_seek (&seek_segment, rate, format, flags, start_type, start_time, end_type, end_time, NULL); - start_time = seek_segment.last_stop; + start_time = seek_segment.position; - format = GST_FORMAT_BYTES; if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time, - &format, &start)) { + GST_FORMAT_BYTES, &start)) { GST_DEBUG_OBJECT (dec, "conversion failed"); return FALSE; } @@ -1623,16 +1656,12 @@ gst_audio_decoder_do_seek (GstAudioDecoder * dec, GstEvent * event) } static gboolean -gst_audio_decoder_src_event (GstPad * pad, GstEvent * event) +gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstAudioDecoder *dec; gboolean res = FALSE; - dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); - if (G_UNLIKELY (dec == NULL)) { - gst_event_unref (event); - return FALSE; - } + dec = GST_AUDIO_DECODER (parent); GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event), GST_EVENT_TYPE_NAME (event)); @@ -1640,7 +1669,7 @@ gst_audio_decoder_src_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { - GstFormat format, tformat; + GstFormat format; gdouble rate; GstSeekFlags flags; GstSeekType cur_type, stop_type; @@ -1665,10 +1694,12 @@ gst_audio_decoder_src_event (GstPad * pad, GstEvent * event) /* ... though a non-time seek can be aided as well */ /* First bring the requested format to time */ - tformat = GST_FORMAT_TIME; - if (!(res = gst_pad_query_convert (pad, format, cur, &tformat, &tcur))) + if (!(res = + gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur))) goto convert_error; - if (!(res = gst_pad_query_convert (pad, format, stop, &tformat, &tstop))) + if (!(res = + gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME, + &tstop))) goto convert_error; /* then seek with time on the peer */ @@ -1684,8 +1715,6 @@ gst_audio_decoder_src_event (GstPad * pad, GstEvent * event) break; } done: - gst_object_unref (dec); - return res; /* ERRORS */ @@ -1768,12 +1797,13 @@ exit: } static gboolean -gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query) +gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent, + GstQuery * query) { - gboolean res = TRUE; + gboolean res = FALSE; GstAudioDecoder *dec; - dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); + dec = GST_AUDIO_DECODER (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_FORMATS: @@ -1796,45 +1826,25 @@ gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query) break; } default: - res = gst_pad_query_default (pad, query); + res = gst_pad_query_default (pad, parent, query); break; } error: - gst_object_unref (dec); return res; } -static const GstQueryType * -gst_audio_decoder_get_query_types (GstPad * pad) -{ - static const GstQueryType gst_audio_decoder_src_query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - GST_QUERY_LATENCY, - 0 - }; - - return gst_audio_decoder_src_query_types; -} - /* FIXME ? are any of these queries (other than latency) a decoder's business ?? * also, the conversion stuff might seem to make sense, but seems to not mind * segment stuff etc at all * Supposedly that's backward compatibility ... */ static gboolean -gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) +gst_audio_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstAudioDecoder *dec; - GstPad *peerpad; gboolean res = FALSE; - dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad)); - if (G_UNLIKELY (dec == NULL)) - return FALSE; - - peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad)); + dec = GST_AUDIO_DECODER (parent); GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query); @@ -1844,7 +1854,7 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) GstFormat format; /* upstream in any case */ - if ((res = gst_pad_query_default (pad, query))) + if ((res = gst_pad_query_default (pad, parent, query))) break; gst_query_parse_duration (query, &format, NULL); @@ -1852,12 +1862,11 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) if (format == GST_FORMAT_TIME && gst_audio_decoder_do_byte (dec)) { gint64 value; - format = GST_FORMAT_BYTES; - if (gst_pad_query_peer_duration (dec->sinkpad, &format, &value)) { + if (gst_pad_peer_query_duration (dec->sinkpad, GST_FORMAT_BYTES, + &value)) { GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value); - format = GST_FORMAT_TIME; if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value, - &format, &value)) { + GST_FORMAT_TIME, &value)) { gst_query_set_duration (query, GST_FORMAT_TIME, value); res = TRUE; } @@ -1876,7 +1885,7 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) } /* we start from the last seen time */ - time = dec->segment.last_stop; + time = dec->segment.position; /* correct for the segment values */ time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); @@ -1886,7 +1895,7 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) /* and convert to the final format */ gst_query_parse_position (query, &format, NULL); if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time, - &format, &value))) + format, &value))) break; gst_query_set_position (query, format, value); @@ -1939,11 +1948,10 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query) break; } default: - res = gst_pad_query_default (pad, query); + res = gst_pad_query_default (pad, parent, query); break; } - gst_object_unref (peerpad); return res; } @@ -2063,7 +2071,7 @@ gst_audio_decoder_change_state (GstElement * element, GstStateChange transition) break; } - ret = parent_class->change_state (element, transition); + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: