2 * Copyright (C) 2009 Igalia S.L.
3 * Author: Iago Toral Quiroga <itoral@igalia.com>
4 * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
5 * Copyright (C) 2011 Nokia Corporation. All rights reserved.
6 * Contact: Stefan Kost <stefan.kost@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * SECTION:gstaudiodecoder
26 * @short_description: Base class for audio decoders
27 * @see_also: #GstBaseTransform
30 * This base class is for audio decoders turning encoded data into
33 * GstAudioDecoder and subclass should cooperate as follows.
36 * <itemizedlist><title>Configuration</title>
38 * Initially, GstAudioDecoder calls @start when the decoder element
39 * is activated, which allows subclass to perform any global setup.
40 * Base class (context) parameters can already be set according to subclass
41 * capabilities (or possibly upon receive more information in subsequent
45 * GstAudioDecoder calls @set_format to inform subclass of the format
46 * of input audio data that it is about to receive.
47 * While unlikely, it might be called more than once, if changing input
48 * parameters require reconfiguration.
51 * GstAudioDecoder calls @stop at end of all processing.
55 * As of configuration stage, and throughout processing, GstAudioDecoder
56 * provides various (context) parameters, e.g. describing the format of
57 * output audio data (valid when output caps have been set) or current parsing state.
58 * Conversely, subclass can and should configure context to inform
59 * base class of its expectation w.r.t. buffer handling.
62 * <title>Data processing</title>
64 * Base class gathers input data, and optionally allows subclass
65 * to parse this into subsequently manageable (as defined by subclass)
66 * chunks. Such chunks are subsequently referred to as 'frames',
67 * though they may or may not correspond to 1 (or more) audio format frame.
70 * Input frame is provided to subclass' @handle_frame.
73 * If codec processing results in decoded data, subclass should call
74 * @gst_audio_decoder_finish_frame to have decoded data pushed
78 * Just prior to actually pushing a buffer downstream,
79 * it is passed to @pre_push. Subclass should either use this callback
80 * to arrange for additional downstream pushing or otherwise ensure such
81 * custom pushing occurs after at least a method call has finished since
82 * setting src pad caps.
85 * During the parsing process GstAudioDecoderClass will handle both
86 * srcpad and sinkpad events. Sink events will be passed to subclass
87 * if @event callback has been provided.
92 * <itemizedlist><title>Shutdown phase</title>
94 * GstAudioDecoder class calls @stop to inform the subclass that data
95 * parsing will be stopped.
101 * Subclass is responsible for providing pad template caps for
102 * source and sink pads. The pads need to be named "sink" and "src". It also
103 * needs to set the fixed caps on srcpad, when the format is ensured. This
104 * is typically when base class calls subclass' @set_format function, though
105 * it might be delayed until calling @gst_audio_decoder_finish_frame.
107 * In summary, above process should have subclass concentrating on
108 * codec data processing while leaving other matters to base class,
109 * such as most notably timestamp handling. While it may exert more control
110 * in this area (see e.g. @pre_push), it is very much not recommended.
112 * In particular, base class will try to arrange for perfect output timestamps
113 * as much as possible while tracking upstream timestamps.
114 * To this end, if deviation between the next ideal expected perfect timestamp
115 * and upstream exceeds #GstAudioDecoder:tolerance, then resync to upstream
116 * occurs (which would happen always if the tolerance mechanism is disabled).
118 * In non-live pipelines, baseclass can also (configurably) arrange for
119 * output buffer aggregation which may help to redue large(r) numbers of
120 * small(er) buffers being pushed and processed downstream.
122 * On the other hand, it should be noted that baseclass only provides limited
123 * seeking support (upon explicit subclass request), as full-fledged support
124 * should rather be left to upstream demuxer, parser or alike. This simple
125 * approach caters for seeking and duration reporting using estimated input
128 * Things that subclass need to take care of:
130 * <listitem><para>Provide pad templates</para></listitem>
132 * Set source pad caps when appropriate
135 * Set user-configurable properties to sane defaults for format and
136 * implementing codec at hand, and convey some subclass capabilities and
137 * expectations in context.
140 * Accept data in @handle_frame and provide encoded results to
141 * @gst_audio_decoder_finish_frame. If it is prepared to perform
142 * PLC, it should also accept NULL data in @handle_frame and provide for
143 * data for indicated duration.
152 #include "gstaudiodecoder.h"
153 #include <gst/pbutils/descriptions.h>
157 GST_DEBUG_CATEGORY (audiodecoder_debug);
158 #define GST_CAT_DEFAULT audiodecoder_debug
160 #define GST_AUDIO_DECODER_GET_PRIVATE(obj) \
161 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_DECODER, \
162 GstAudioDecoderPrivate))
177 #define DEFAULT_LATENCY 0
178 #define DEFAULT_TOLERANCE 0
179 #define DEFAULT_PLC FALSE
180 #define DEFAULT_DRAINABLE TRUE
181 #define DEFAULT_NEEDS_FORMAT FALSE
183 typedef struct _GstAudioDecoderContext
186 /* (output) audio format */
198 gboolean do_byte_time;
200 /* MT-protected (with LOCK) */
201 GstClockTime min_latency;
202 GstClockTime max_latency;
203 } GstAudioDecoderContext;
205 struct _GstAudioDecoderPrivate
207 /* activation status */
210 /* input base/first ts as basis for output ts */
211 GstClockTime base_ts;
212 /* input samples processed and sent downstream so far (w.r.t. base_ts) */
215 /* collected input data */
217 /* tracking input ts for changes */
218 GstClockTime prev_ts;
219 /* frames obtained from input */
221 /* collected output data */
222 GstAdapter *adapter_out;
223 /* ts and duration for output data collected above */
224 GstClockTime out_ts, out_dur;
225 /* mark outgoing discont */
228 /* subclass gave all it could already */
230 /* subclass currently being forcibly drained */
233 /* input bps estimatation */
234 /* global in bytes seen */
236 /* global samples sent out */
238 /* bytes flushed during parsing */
245 /* whether circumstances allow output aggregation */
248 /* reverse playback queues */
253 /* reversed output */
256 /* context storage */
257 GstAudioDecoderContext ctx;
260 GstClockTime latency;
261 GstClockTime tolerance;
264 gboolean needs_format;
266 /* pending serialized sink events, will be sent from finish_frame() */
267 GList *pending_events;
271 static void gst_audio_decoder_finalize (GObject * object);
272 static void gst_audio_decoder_set_property (GObject * object,
273 guint prop_id, const GValue * value, GParamSpec * pspec);
274 static void gst_audio_decoder_get_property (GObject * object,
275 guint prop_id, GValue * value, GParamSpec * pspec);
277 static void gst_audio_decoder_clear_queues (GstAudioDecoder * dec);
278 static GstFlowReturn gst_audio_decoder_chain_reverse (GstAudioDecoder *
279 dec, GstBuffer * buf);
281 static GstStateChangeReturn gst_audio_decoder_change_state (GstElement *
282 element, GstStateChange transition);
283 static gboolean gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec,
285 static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
287 static gboolean gst_audio_decoder_src_event (GstPad * pad, GstObject * parent,
289 static gboolean gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec,
291 static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstObject * parent,
293 static gboolean gst_audio_decoder_src_query (GstPad * pad, GstObject * parent,
295 static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
297 static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);
299 static GstElementClass *parent_class = NULL;
301 static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass);
302 static void gst_audio_decoder_init (GstAudioDecoder * dec,
303 GstAudioDecoderClass * klass);
306 gst_audio_decoder_get_type (void)
308 static volatile gsize audio_decoder_type = 0;
310 if (g_once_init_enter (&audio_decoder_type)) {
312 static const GTypeInfo audio_decoder_info = {
313 sizeof (GstAudioDecoderClass),
316 (GClassInitFunc) gst_audio_decoder_class_init,
319 sizeof (GstAudioDecoder),
321 (GInstanceInitFunc) gst_audio_decoder_init,
324 _type = g_type_register_static (GST_TYPE_ELEMENT,
325 "GstAudioDecoder", &audio_decoder_info, G_TYPE_FLAG_ABSTRACT);
326 g_once_init_leave (&audio_decoder_type, _type);
328 return audio_decoder_type;
333 gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
335 GObjectClass *gobject_class;
336 GstElementClass *element_class;
337 GstAudioDecoderClass *audiodecoder_class;
339 gobject_class = G_OBJECT_CLASS (klass);
340 element_class = GST_ELEMENT_CLASS (klass);
341 audiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);
343 parent_class = g_type_class_peek_parent (klass);
345 g_type_class_add_private (klass, sizeof (GstAudioDecoderPrivate));
347 GST_DEBUG_CATEGORY_INIT (audiodecoder_debug, "audiodecoder", 0,
348 "audio decoder base class");
350 gobject_class->set_property = gst_audio_decoder_set_property;
351 gobject_class->get_property = gst_audio_decoder_get_property;
352 gobject_class->finalize = gst_audio_decoder_finalize;
354 element_class->change_state =
355 GST_DEBUG_FUNCPTR (gst_audio_decoder_change_state);
358 g_object_class_install_property (gobject_class, PROP_LATENCY,
359 g_param_spec_int64 ("min-latency", "Minimum Latency",
360 "Aggregate output data to a minimum of latency time (ns)",
361 0, G_MAXINT64, DEFAULT_LATENCY,
362 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
364 g_object_class_install_property (gobject_class, PROP_TOLERANCE,
365 g_param_spec_int64 ("tolerance", "Tolerance",
366 "Perfect ts while timestamp jitter/imperfection within tolerance (ns)",
367 0, G_MAXINT64, DEFAULT_TOLERANCE,
368 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
370 g_object_class_install_property (gobject_class, PROP_PLC,
371 g_param_spec_boolean ("plc", "Packet Loss Concealment",
372 "Perform packet loss concealment (if supported)",
373 DEFAULT_PLC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
375 audiodecoder_class->event =
376 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_eventfunc);
380 gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass)
382 GstPadTemplate *pad_template;
384 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_init");
386 dec->priv = GST_AUDIO_DECODER_GET_PRIVATE (dec);
390 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
391 g_return_if_fail (pad_template != NULL);
393 dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
394 gst_pad_set_event_function (dec->sinkpad,
395 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_event));
396 gst_pad_set_chain_function (dec->sinkpad,
397 GST_DEBUG_FUNCPTR (gst_audio_decoder_chain));
398 gst_pad_set_query_function (dec->sinkpad,
399 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_query));
400 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
401 GST_DEBUG_OBJECT (dec, "sinkpad created");
403 /* Setup source pad */
405 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
406 g_return_if_fail (pad_template != NULL);
408 dec->srcpad = gst_pad_new_from_template (pad_template, "src");
409 gst_pad_set_event_function (dec->srcpad,
410 GST_DEBUG_FUNCPTR (gst_audio_decoder_src_event));
411 gst_pad_set_query_function (dec->srcpad,
412 GST_DEBUG_FUNCPTR (gst_audio_decoder_src_query));
413 gst_pad_use_fixed_caps (dec->srcpad);
414 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
415 GST_DEBUG_OBJECT (dec, "srcpad created");
417 dec->priv->adapter = gst_adapter_new ();
418 dec->priv->adapter_out = gst_adapter_new ();
419 g_queue_init (&dec->priv->frames);
421 g_rec_mutex_init (&dec->stream_lock);
423 /* property default */
424 dec->priv->latency = DEFAULT_LATENCY;
425 dec->priv->tolerance = DEFAULT_TOLERANCE;
426 dec->priv->plc = DEFAULT_PLC;
427 dec->priv->drainable = DEFAULT_DRAINABLE;
428 dec->priv->needs_format = DEFAULT_NEEDS_FORMAT;
431 gst_audio_decoder_reset (dec, TRUE);
432 GST_DEBUG_OBJECT (dec, "init ok");
436 gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
438 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_reset");
440 GST_AUDIO_DECODER_STREAM_LOCK (dec);
443 dec->priv->active = FALSE;
444 dec->priv->bytes_in = 0;
445 dec->priv->samples_out = 0;
447 dec->priv->error_count = 0;
448 gst_audio_decoder_clear_queues (dec);
450 gst_audio_info_init (&dec->priv->ctx.info);
451 memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
452 dec->priv->ctx.max_errors = GST_AUDIO_DECODER_MAX_ERRORS;
454 if (dec->priv->taglist) {
455 gst_tag_list_free (dec->priv->taglist);
456 dec->priv->taglist = NULL;
459 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
461 g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
462 g_list_free (dec->priv->pending_events);
463 dec->priv->pending_events = NULL;
466 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
467 g_queue_clear (&dec->priv->frames);
468 gst_adapter_clear (dec->priv->adapter);
469 gst_adapter_clear (dec->priv->adapter_out);
470 dec->priv->out_ts = GST_CLOCK_TIME_NONE;
471 dec->priv->out_dur = 0;
472 dec->priv->prev_ts = GST_CLOCK_TIME_NONE;
473 dec->priv->drained = TRUE;
474 dec->priv->base_ts = GST_CLOCK_TIME_NONE;
475 dec->priv->samples = 0;
476 dec->priv->discont = TRUE;
477 dec->priv->sync_flush = FALSE;
479 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
483 gst_audio_decoder_finalize (GObject * object)
485 GstAudioDecoder *dec;
487 g_return_if_fail (GST_IS_AUDIO_DECODER (object));
488 dec = GST_AUDIO_DECODER (object);
490 if (dec->priv->adapter) {
491 g_object_unref (dec->priv->adapter);
493 if (dec->priv->adapter_out) {
494 g_object_unref (dec->priv->adapter_out);
497 g_rec_mutex_clear (&dec->stream_lock);
499 G_OBJECT_CLASS (parent_class)->finalize (object);
503 * gst_audio_decoder_set_output_format:
504 * @dec: a #GstAudioDecoder
505 * @info: #GstAudioInfo
507 * Configure output info on the srcpad of @dec.
509 * Returns: %TRUE on success.
512 gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
513 const GstAudioInfo * info)
520 GST_DEBUG_OBJECT (dec, "Setting output format");
522 GST_AUDIO_DECODER_STREAM_LOCK (dec);
524 /* If the audio info can't be converted to caps,
526 caps = gst_audio_info_to_caps (info);
530 /* Only allow caps that are a subset of the template caps */
531 templ_caps = gst_pad_get_pad_template_caps (dec->srcpad);
532 if (!gst_caps_is_subset (caps, templ_caps)) {
533 gst_caps_unref (caps);
534 gst_caps_unref (templ_caps);
537 gst_caps_unref (templ_caps);
539 /* adjust ts tracking to new sample rate */
540 old_rate = GST_AUDIO_INFO_RATE (&dec->priv->ctx.info);
541 if (GST_CLOCK_TIME_IS_VALID (dec->priv->base_ts) && old_rate) {
542 dec->priv->base_ts +=
543 GST_FRAMES_TO_CLOCK_TIME (dec->priv->samples, old_rate);
544 dec->priv->samples = 0;
547 /* copy the GstAudioInfo */
548 dec->priv->ctx.info = *info;
550 GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
552 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
554 res = gst_pad_set_caps (dec->srcpad, caps);
555 gst_caps_unref (caps);
563 GST_WARNING_OBJECT (dec, "invalid output format");
570 gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, GstCaps * caps)
572 GstAudioDecoderClass *klass;
575 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
577 GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
579 GST_AUDIO_DECODER_STREAM_LOCK (dec);
580 /* NOTE pbutils only needed here */
581 /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
583 if (dec->priv->taglist)
584 gst_tag_list_free (dec->priv->taglist);
585 dec->priv->taglist = gst_tag_list_new ();
586 gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist,
587 GST_TAG_AUDIO_CODEC, caps);
590 if (klass->set_format)
591 res = klass->set_format (dec, caps);
593 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
599 gst_audio_decoder_setup (GstAudioDecoder * dec)
604 /* check if in live pipeline, then latency messing is no-no */
605 query = gst_query_new_latency ();
606 res = gst_pad_peer_query (dec->sinkpad, query);
608 gst_query_parse_latency (query, &res, NULL, NULL);
611 gst_query_unref (query);
613 /* normalize to bool */
614 dec->priv->agg = ! !res;
618 gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf)
620 GstAudioDecoderClass *klass;
621 GstAudioDecoderPrivate *priv;
622 GstAudioDecoderContext *ctx;
623 GstFlowReturn ret = GST_FLOW_OK;
625 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
627 ctx = &dec->priv->ctx;
629 g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
631 if (G_UNLIKELY (!buf)) {
632 g_assert_not_reached ();
637 "clipping buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
638 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
639 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
640 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
643 buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
645 if (G_UNLIKELY (!buf)) {
646 GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
651 if (G_UNLIKELY (priv->discont)) {
652 GST_LOG_OBJECT (dec, "marking discont");
653 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
654 priv->discont = FALSE;
657 /* track where we are */
658 if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
659 /* duration should always be valid for raw audio */
660 g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
661 dec->segment.position =
662 GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
665 if (klass->pre_push) {
666 /* last chance for subclass to do some dirty stuff */
667 ret = klass->pre_push (dec, &buf);
668 if (ret != GST_FLOW_OK || !buf) {
669 GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
670 gst_flow_get_name (ret), buf);
672 gst_buffer_unref (buf);
678 "pushing buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
679 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
680 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
681 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
683 ret = gst_pad_push (dec->srcpad, buf);
689 /* mini aggregator combining output buffers into fewer larger ones,
690 * if so allowed/configured */
692 gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf)
694 GstAudioDecoderPrivate *priv;
695 GstFlowReturn ret = GST_FLOW_OK;
696 GstBuffer *inbuf = NULL;
700 if (G_UNLIKELY (priv->agg < 0))
701 gst_audio_decoder_setup (dec);
703 if (G_LIKELY (buf)) {
705 "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
706 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
707 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
708 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
713 if (priv->agg && dec->priv->latency > 0) {
715 gboolean assemble = FALSE;
716 const GstClockTimeDiff tol = 10 * GST_MSECOND;
717 GstClockTimeDiff diff = -100 * GST_MSECOND;
719 av = gst_adapter_available (priv->adapter_out);
720 if (G_UNLIKELY (!buf)) {
721 /* forcibly send current */
723 GST_LOG_OBJECT (dec, "forcing fragment flush");
724 } else if (av && (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) ||
725 !GST_CLOCK_TIME_IS_VALID (priv->out_ts) ||
726 ((diff = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP (buf),
727 priv->out_ts + priv->out_dur)) > tol) || diff < -tol)) {
729 GST_LOG_OBJECT (dec, "buffer %d ms apart from current fragment",
730 (gint) (diff / GST_MSECOND));
732 /* add or start collecting */
734 GST_LOG_OBJECT (dec, "starting new fragment");
735 priv->out_ts = GST_BUFFER_TIMESTAMP (buf);
737 GST_LOG_OBJECT (dec, "adding to fragment");
739 gst_adapter_push (priv->adapter_out, buf);
740 priv->out_dur += GST_BUFFER_DURATION (buf);
741 av += gst_buffer_get_size (buf);
744 if (priv->out_dur > dec->priv->latency)
746 if (av && assemble) {
747 GST_LOG_OBJECT (dec, "assembling fragment");
749 buf = gst_adapter_take_buffer (priv->adapter_out, av);
750 GST_BUFFER_TIMESTAMP (buf) = priv->out_ts;
751 GST_BUFFER_DURATION (buf) = priv->out_dur;
752 priv->out_ts = GST_CLOCK_TIME_NONE;
757 if (G_LIKELY (buf)) {
758 if (dec->segment.rate > 0.0) {
759 ret = gst_audio_decoder_push_forward (dec, buf);
760 GST_LOG_OBJECT (dec, "buffer pushed: %s", gst_flow_get_name (ret));
763 priv->queued = g_list_prepend (priv->queued, buf);
764 GST_LOG_OBJECT (dec, "buffer queued");
777 * gst_audio_decoder_finish_frame:
778 * @dec: a #GstAudioDecoder
780 * @frames: number of decoded frames represented by decoded data
782 * Collects decoded data and pushes it downstream.
784 * @buf may be NULL in which case the indicated number of frames
785 * are discarded and considered to have produced no output
786 * (e.g. lead-in or setup frames).
787 * Otherwise, source pad caps must be set when it is called with valid
790 * Note that a frame received in gst_audio_decoder_handle_frame() may be
791 * invalidated by a call to this function.
793 * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
798 gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf,
801 GstAudioDecoderPrivate *priv;
802 GstAudioDecoderContext *ctx;
804 GstClockTime ts, next_ts;
806 GstFlowReturn ret = GST_FLOW_OK;
808 /* subclass should know what it is producing by now */
809 g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
811 /* subclass should not hand us no data */
812 g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
814 /* no dummy calls please */
815 g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
818 ctx = &dec->priv->ctx;
819 size = buf ? gst_buffer_get_size (buf) : 0;
821 /* must know the output format by now */
822 g_return_val_if_fail (buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info),
826 "accepting %" G_GSIZE_FORMAT " bytes == %" G_GSIZE_FORMAT
827 " samples for %d frames", buf ? size : -1,
828 buf ? size / ctx->info.bpf : -1, frames);
830 GST_AUDIO_DECODER_STREAM_LOCK (dec);
832 if (priv->pending_events) {
833 GList *pending_events, *l;
835 pending_events = priv->pending_events;
836 priv->pending_events = NULL;
838 GST_DEBUG_OBJECT (dec, "Pushing pending events");
839 for (l = pending_events; l; l = l->next)
840 gst_pad_push_event (dec->srcpad, l->data);
841 g_list_free (pending_events);
844 /* output shoud be whole number of sample frames */
845 if (G_LIKELY (buf && ctx->info.bpf)) {
846 if (size % ctx->info.bpf)
848 /* per channel least */
849 samples = size / ctx->info.bpf;
852 /* frame and ts book-keeping */
853 if (G_UNLIKELY (frames < 0)) {
854 if (G_UNLIKELY (-frames - 1 > priv->frames.length))
856 frames = priv->frames.length + frames + 1;
857 } else if (G_UNLIKELY (frames > priv->frames.length)) {
858 if (G_LIKELY (!priv->force)) {
859 /* no way we can let this pass */
860 g_assert_not_reached ();
866 if (G_LIKELY (priv->frames.length))
867 ts = GST_BUFFER_TIMESTAMP (priv->frames.head->data);
869 ts = GST_CLOCK_TIME_NONE;
871 GST_DEBUG_OBJECT (dec, "leading frame ts %" GST_TIME_FORMAT,
874 while (priv->frames.length && frames) {
875 gst_buffer_unref (g_queue_pop_head (&priv->frames));
876 dec->priv->ctx.delay = dec->priv->frames.length;
880 if (G_UNLIKELY (!buf))
884 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
886 GST_DEBUG_OBJECT (dec, "base_ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
889 /* slightly convoluted approach caters for perfect ts if subclass desires */
890 if (GST_CLOCK_TIME_IS_VALID (ts)) {
891 if (dec->priv->tolerance > 0) {
892 GstClockTimeDiff diff;
894 g_assert (GST_CLOCK_TIME_IS_VALID (priv->base_ts));
895 next_ts = priv->base_ts +
896 gst_util_uint64_scale (priv->samples, GST_SECOND, ctx->info.rate);
898 "buffer is %" G_GUINT64_FORMAT " samples past base_ts %"
899 GST_TIME_FORMAT ", expected ts %" GST_TIME_FORMAT, priv->samples,
900 GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
901 diff = GST_CLOCK_DIFF (next_ts, ts);
902 GST_LOG_OBJECT (dec, "ts diff %d ms", (gint) (diff / GST_MSECOND));
903 /* if within tolerance,
904 * discard buffer ts and carry on producing perfect stream,
905 * otherwise resync to ts */
906 if (G_UNLIKELY (diff < (gint64) - dec->priv->tolerance ||
907 diff > (gint64) dec->priv->tolerance)) {
908 GST_DEBUG_OBJECT (dec, "base_ts resync");
913 GST_DEBUG_OBJECT (dec, "base_ts resync");
919 /* delayed one-shot stuff until confirmed data */
921 GST_DEBUG_OBJECT (dec, "codec tag %" GST_PTR_FORMAT, priv->taglist);
922 if (gst_tag_list_is_empty (priv->taglist)) {
923 gst_tag_list_free (priv->taglist);
925 gst_pad_push_event (dec->srcpad, gst_event_new_tag (priv->taglist));
927 priv->taglist = NULL;
930 buf = gst_buffer_make_writable (buf);
931 if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
932 GST_BUFFER_TIMESTAMP (buf) =
934 GST_FRAMES_TO_CLOCK_TIME (priv->samples, ctx->info.rate);
935 GST_BUFFER_DURATION (buf) = priv->base_ts +
936 GST_FRAMES_TO_CLOCK_TIME (priv->samples + samples, ctx->info.rate) -
937 GST_BUFFER_TIMESTAMP (buf);
939 GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
940 GST_BUFFER_DURATION (buf) =
941 GST_FRAMES_TO_CLOCK_TIME (samples, ctx->info.rate);
943 priv->samples += samples;
944 priv->samples_out += samples;
946 /* we got data, so note things are looking up */
947 if (G_UNLIKELY (dec->priv->error_count))
948 dec->priv->error_count--;
951 ret = gst_audio_decoder_output (dec, buf);
953 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
960 GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
961 ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d", size,
963 gst_buffer_unref (buf);
964 ret = GST_FLOW_ERROR;
969 GST_ELEMENT_ERROR (dec, STREAM, ENCODE,
970 ("received more decoded frames %d than provided %d", frames,
971 priv->frames.length), (NULL));
973 gst_buffer_unref (buf);
974 ret = GST_FLOW_ERROR;
980 gst_audio_decoder_handle_frame (GstAudioDecoder * dec,
981 GstAudioDecoderClass * klass, GstBuffer * buffer)
983 if (G_LIKELY (buffer)) {
984 gsize size = gst_buffer_get_size (buffer);
985 /* keep around for admin */
987 "tracking frame size %" G_GSIZE_FORMAT ", ts %" GST_TIME_FORMAT, size,
988 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
989 g_queue_push_tail (&dec->priv->frames, buffer);
990 dec->priv->ctx.delay = dec->priv->frames.length;
991 dec->priv->bytes_in += size;
993 GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
996 return klass->handle_frame (dec, buffer);
999 /* maybe subclass configurable instead, but this allows for a whole lot of
1000 * raw samples, so at least quite some encoded ... */
1001 #define GST_AUDIO_DECODER_MAX_SYNC 10 * 8 * 2 * 1024
1003 static GstFlowReturn
1004 gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
1006 GstAudioDecoderClass *klass;
1007 GstAudioDecoderPrivate *priv;
1008 GstAudioDecoderContext *ctx;
1009 GstFlowReturn ret = GST_FLOW_OK;
1013 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1015 ctx = &dec->priv->ctx;
1017 g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
1019 av = gst_adapter_available (priv->adapter);
1020 GST_DEBUG_OBJECT (dec, "available: %d", av);
1022 while (ret == GST_FLOW_OK) {
1027 if (G_LIKELY (av)) {
1031 /* parse if needed */
1035 /* limited (legacy) parsing; avoid whole of baseparse */
1036 GST_DEBUG_OBJECT (dec, "parsing available: %d", av);
1037 /* piggyback sync state on discont */
1038 ctx->sync = !priv->discont;
1039 ret = klass->parse (dec, priv->adapter, &offset, &len);
1041 g_assert (offset <= av);
1044 GST_DEBUG_OBJECT (dec, "skipped %d; setting DISCONT", offset);
1045 gst_adapter_flush (priv->adapter, offset);
1047 /* avoid parsing indefinitely */
1048 priv->sync_flush += offset;
1049 if (priv->sync_flush > GST_AUDIO_DECODER_MAX_SYNC)
1053 if (ret == GST_FLOW_EOS) {
1054 GST_LOG_OBJECT (dec, "no frame yet");
1057 } else if (ret == GST_FLOW_OK) {
1058 GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
1060 g_assert (offset + len <= av);
1061 priv->sync_flush = 0;
1068 /* track upstream ts, but do not get stuck if nothing new upstream */
1069 ts = gst_adapter_prev_timestamp (priv->adapter, NULL);
1070 if (ts == priv->prev_ts) {
1071 GST_LOG_OBJECT (dec, "ts == prev_ts; discarding");
1072 ts = GST_CLOCK_TIME_NONE;
1076 buffer = gst_adapter_take_buffer (priv->adapter, len);
1077 buffer = gst_buffer_make_writable (buffer);
1078 GST_BUFFER_TIMESTAMP (buffer) = ts;
1083 if (!priv->drainable) {
1084 priv->drained = TRUE;
1090 ret = gst_audio_decoder_handle_frame (dec, klass, buffer);
1092 /* do not keep pushing it ... */
1093 if (G_UNLIKELY (!av)) {
1094 priv->drained = TRUE;
1102 GST_LOG_OBJECT (dec, "done pushing to subclass");
1108 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("failed to parse stream"));
1109 return GST_FLOW_ERROR;
1113 static GstFlowReturn
1114 gst_audio_decoder_drain (GstAudioDecoder * dec)
1118 if (dec->priv->drained && !dec->priv->gather)
1121 /* dispatch reverse pending buffers */
1122 /* chain eventually calls upon drain as well, but by that time
1123 * gather list should be clear, so ok ... */
1124 if (dec->segment.rate < 0.0 && dec->priv->gather)
1125 gst_audio_decoder_chain_reverse (dec, NULL);
1126 /* have subclass give all it can */
1127 ret = gst_audio_decoder_push_buffers (dec, TRUE);
1128 /* ensure all output sent */
1129 ret = gst_audio_decoder_output (dec, NULL);
1130 /* everything should be away now */
1131 if (dec->priv->frames.length) {
1132 /* not fatal/impossible though if subclass/codec eats stuff */
1133 GST_WARNING_OBJECT (dec, "still %d frames left after draining",
1134 dec->priv->frames.length);
1135 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
1136 g_queue_clear (&dec->priv->frames);
1138 /* discard (unparsed) leftover */
1139 gst_adapter_clear (dec->priv->adapter);
1145 /* hard == FLUSH, otherwise discont */
1146 static GstFlowReturn
1147 gst_audio_decoder_flush (GstAudioDecoder * dec, gboolean hard)
1149 GstAudioDecoderClass *klass;
1150 GstFlowReturn ret = GST_FLOW_OK;
1152 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1154 GST_LOG_OBJECT (dec, "flush hard %d", hard);
1157 ret = gst_audio_decoder_drain (dec);
1159 gst_audio_decoder_clear_queues (dec);
1160 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
1161 dec->priv->error_count = 0;
1163 /* only bother subclass with flushing if known it is already alive
1164 * and kicking out stuff */
1165 if (klass->flush && dec->priv->samples_out > 0)
1166 klass->flush (dec, hard);
1167 /* and get (re)set for the sequel */
1168 gst_audio_decoder_reset (dec, FALSE);
1173 static GstFlowReturn
1174 gst_audio_decoder_chain_forward (GstAudioDecoder * dec, GstBuffer * buffer)
1176 GstFlowReturn ret = GST_FLOW_OK;
1178 /* discard silly case, though maybe ts may be of value ?? */
1179 if (G_UNLIKELY (gst_buffer_get_size (buffer) == 0)) {
1180 GST_DEBUG_OBJECT (dec, "discarding empty buffer");
1181 gst_buffer_unref (buffer);
1186 gst_adapter_push (dec->priv->adapter, buffer);
1188 /* new stuff, so we can push subclass again */
1189 dec->priv->drained = FALSE;
1191 /* hand to subclass */
1192 ret = gst_audio_decoder_push_buffers (dec, FALSE);
1195 GST_LOG_OBJECT (dec, "chain-done");
1200 gst_audio_decoder_clear_queues (GstAudioDecoder * dec)
1202 GstAudioDecoderPrivate *priv = dec->priv;
1204 g_list_foreach (priv->queued, (GFunc) gst_mini_object_unref, NULL);
1205 g_list_free (priv->queued);
1206 priv->queued = NULL;
1207 g_list_foreach (priv->gather, (GFunc) gst_mini_object_unref, NULL);
1208 g_list_free (priv->gather);
1209 priv->gather = NULL;
1210 g_list_foreach (priv->decode, (GFunc) gst_mini_object_unref, NULL);
1211 g_list_free (priv->decode);
1212 priv->decode = NULL;
1217 * Buffer decoding order: 7 8 9 4 5 6 3 1 2 EOS
1218 * Discont flag: D D D D
1220 * - Each Discont marks a discont in the decoding order.
1222 * for vorbis, each buffer is a keyframe when we have the previous
1223 * buffer. This means that to decode buffer 7, we need buffer 6, which
1224 * arrives out of order.
1226 * we first gather buffers in the gather queue until we get a DISCONT. We
1227 * prepend each incomming buffer so that they are in reversed order.
1229 * gather queue: 9 8 7
1233 * When a DISCONT is received (buffer 4), we move the gather queue to the
1234 * decode queue. This is simply done be taking the head of the gather queue
1235 * and prepending it to the decode queue. This yields:
1238 * decode queue: 7 8 9
1241 * Then we decode each buffer in the decode queue in order and put the output
1242 * buffer in the output queue. The first buffer (7) will not produce any output
1243 * because it needs the previous buffer (6) which did not arrive yet. This
1247 * decode queue: 7 8 9
1250 * Then we remove the consumed buffers from the decode queue. Buffer 7 is not
1251 * completely consumed, we need to keep it around for when we receive buffer
1258 * Then we accumulate more buffers:
1260 * gather queue: 6 5 4
1264 * prepending to the decode queue on DISCONT yields:
1267 * decode queue: 4 5 6 7
1270 * after decoding and keeping buffer 4:
1274 * output queue: 7 6 5
1278 static GstFlowReturn
1279 gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
1281 GstAudioDecoderPrivate *priv = dec->priv;
1282 GstFlowReturn res = GST_FLOW_OK;
1283 GstClockTime timestamp;
1286 walk = priv->decode;
1288 GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");
1290 /* clear buffer and decoder state */
1291 gst_audio_decoder_flush (dec, FALSE);
1295 GstBuffer *buf = GST_BUFFER_CAST (walk->data);
1297 GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1298 buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1300 next = g_list_next (walk);
1301 /* decode buffer, resulting data prepended to output queue */
1302 gst_buffer_ref (buf);
1303 res = gst_audio_decoder_chain_forward (dec, buf);
1305 /* if we generated output, we can discard the buffer, else we
1306 * keep it in the queue */
1308 GST_DEBUG_OBJECT (dec, "decoded buffer to %p", priv->queued->data);
1309 priv->decode = g_list_delete_link (priv->decode, walk);
1310 gst_buffer_unref (buf);
1312 GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
1317 /* drain any aggregation (or otherwise) leftover */
1318 gst_audio_decoder_drain (dec);
1320 /* now send queued data downstream */
1321 timestamp = GST_CLOCK_TIME_NONE;
1322 while (priv->queued) {
1323 GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
1325 /* duration should always be valid for raw audio */
1326 g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
1328 /* interpolate (backward) if needed */
1329 if (G_LIKELY (timestamp != -1))
1330 timestamp -= GST_BUFFER_DURATION (buf);
1332 if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1333 GST_LOG_OBJECT (dec, "applying reverse interpolated ts %"
1334 GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
1335 GST_BUFFER_TIMESTAMP (buf) = timestamp;
1337 /* track otherwise */
1338 timestamp = GST_BUFFER_TIMESTAMP (buf);
1339 GST_LOG_OBJECT (dec, "tracking ts %" GST_TIME_FORMAT,
1340 GST_TIME_ARGS (timestamp));
1343 if (G_LIKELY (res == GST_FLOW_OK)) {
1344 GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %" G_GSIZE_FORMAT ", "
1345 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1346 gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1347 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1348 /* should be already, but let's be sure */
1349 buf = gst_buffer_make_writable (buf);
1350 /* avoid stray DISCONT from forward processing,
1351 * which have no meaning in reverse pushing */
1352 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
1353 res = gst_audio_decoder_push_forward (dec, buf);
1355 gst_buffer_unref (buf);
1358 priv->queued = g_list_delete_link (priv->queued, priv->queued);
1364 static GstFlowReturn
1365 gst_audio_decoder_chain_reverse (GstAudioDecoder * dec, GstBuffer * buf)
1367 GstAudioDecoderPrivate *priv = dec->priv;
1368 GstFlowReturn result = GST_FLOW_OK;
1370 /* if we have a discont, move buffers to the decode list */
1371 if (!buf || GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1372 GST_DEBUG_OBJECT (dec, "received discont");
1373 while (priv->gather) {
1376 gbuf = GST_BUFFER_CAST (priv->gather->data);
1377 /* remove from the gather list */
1378 priv->gather = g_list_delete_link (priv->gather, priv->gather);
1379 /* copy to decode queue */
1380 priv->decode = g_list_prepend (priv->decode, gbuf);
1382 /* decode stuff in the decode queue */
1383 gst_audio_decoder_flush_decode (dec);
1386 if (G_LIKELY (buf)) {
1387 GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %" G_GSIZE_FORMAT ", "
1388 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1389 gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1390 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1392 /* add buffer to gather queue */
1393 priv->gather = g_list_prepend (priv->gather, buf);
1399 static GstFlowReturn
1400 gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1402 GstAudioDecoder *dec;
1405 dec = GST_AUDIO_DECODER (parent);
1407 if (G_UNLIKELY (!gst_pad_has_current_caps (pad) && dec->priv->needs_format))
1408 goto not_negotiated;
1410 GST_LOG_OBJECT (dec,
1411 "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
1412 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
1413 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1414 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1416 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1418 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
1421 /* track present position */
1422 ts = dec->priv->base_ts;
1423 samples = dec->priv->samples;
1425 GST_DEBUG_OBJECT (dec, "handling discont");
1426 gst_audio_decoder_flush (dec, FALSE);
1427 dec->priv->discont = TRUE;
1429 /* buffer may claim DISCONT loudly, if it can't tell us where we are now,
1430 * we'll stick to where we were ...
1431 * Particularly useful/needed for upstream BYTE based */
1432 if (dec->segment.rate > 0.0 && !GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
1433 GST_DEBUG_OBJECT (dec, "... but restoring previous ts tracking");
1434 dec->priv->base_ts = ts;
1435 dec->priv->samples = samples;
1439 if (dec->segment.rate > 0.0)
1440 ret = gst_audio_decoder_chain_forward (dec, buffer);
1442 ret = gst_audio_decoder_chain_reverse (dec, buffer);
1444 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1451 GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
1452 ("decoder not initialized"));
1453 gst_buffer_unref (buffer);
1454 return GST_FLOW_NOT_NEGOTIATED;
1458 /* perform upstream byte <-> time conversion (duration, seeking)
1459 * if subclass allows and if enough data for moderately decent conversion */
1460 static inline gboolean
1461 gst_audio_decoder_do_byte (GstAudioDecoder * dec)
1463 return dec->priv->ctx.do_byte_time && dec->priv->ctx.info.bpf &&
1464 dec->priv->ctx.info.rate <= dec->priv->samples_out;
1468 gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
1472 switch (GST_EVENT_TYPE (event)) {
1473 case GST_EVENT_SEGMENT:
1477 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1478 gst_event_copy_segment (event, &seg);
1480 if (seg.format == GST_FORMAT_TIME) {
1481 GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_SEGMENT_FORMAT,
1485 GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg);
1486 /* handle newsegment resulting from legacy simple seeking */
1487 /* note that we need to convert this whether or not enough data
1488 * to handle initial newsegment */
1489 if (dec->priv->ctx.do_byte_time &&
1490 gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start,
1491 GST_FORMAT_TIME, &nstart)) {
1492 /* best attempt convert */
1493 /* as these are only estimates, stop is kept open-ended to avoid
1494 * premature cutting */
1495 GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
1496 GST_TIME_ARGS (nstart));
1497 seg.format = GST_FORMAT_TIME;
1500 seg.stop = GST_CLOCK_TIME_NONE;
1502 gst_event_unref (event);
1503 event = gst_event_new_segment (&seg);
1505 GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
1506 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1507 gst_event_unref (event);
1513 /* finish current segment */
1514 gst_audio_decoder_drain (dec);
1518 /* time progressed without data, see if we can fill the gap with
1519 * some concealment data */
1520 GST_DEBUG_OBJECT (dec,
1521 "segment update: plc %d, do_plc %d, position %" GST_TIME_FORMAT,
1522 dec->priv->plc, dec->priv->ctx.do_plc,
1523 GST_TIME_ARGS (dec->segment.position));
1524 if (dec->priv->plc && dec->priv->ctx.do_plc &&
1525 dec->segment.rate > 0.0 && dec->segment.position < start) {
1526 GstAudioDecoderClass *klass;
1529 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1530 /* hand subclass empty frame with duration that needs covering */
1531 buf = gst_buffer_new ();
1532 GST_BUFFER_DURATION (buf) = start - dec->segment.position;
1533 /* best effort, not much error handling */
1534 gst_audio_decoder_handle_frame (dec, klass, buf);
1539 /* prepare for next one */
1540 gst_audio_decoder_flush (dec, FALSE);
1541 /* and that's where we time from,
1542 * in case upstream does not come up with anything better
1543 * (e.g. upstream BYTE) */
1544 if (seg.format != GST_FORMAT_TIME) {
1545 dec->priv->base_ts = seg.start;
1546 dec->priv->samples = 0;
1550 /* and follow along with segment */
1552 dec->priv->pending_events =
1553 g_list_append (dec->priv->pending_events, event);
1554 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1560 case GST_EVENT_FLUSH_STOP:
1561 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1562 /* prepare for fresh start */
1563 gst_audio_decoder_flush (dec, TRUE);
1565 g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
1566 g_list_free (dec->priv->pending_events);
1567 dec->priv->pending_events = NULL;
1568 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1570 /* Forward FLUSH_STOP, it is expected to be forwarded immediately
1571 * and no buffers are queued anyway. */
1572 ret = gst_pad_push_event (dec->srcpad, event);
1576 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1577 gst_audio_decoder_drain (dec);
1578 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1580 /* Forward EOS because no buffer or serialized event will come after
1581 * EOS and nothing could trigger another _finish_frame() call. */
1582 ret = gst_pad_push_event (dec->srcpad, event);
1585 case GST_EVENT_CAPS:
1589 gst_event_parse_caps (event, &caps);
1590 gst_audio_decoder_sink_setcaps (dec, caps);
1591 gst_event_unref (event);
1596 if (!GST_EVENT_IS_SERIALIZED (event)) {
1598 gst_pad_event_default (dec->sinkpad, GST_OBJECT_CAST (dec), event);
1600 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1601 dec->priv->pending_events =
1602 g_list_append (dec->priv->pending_events, event);
1603 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1612 gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
1615 GstAudioDecoder *dec;
1616 GstAudioDecoderClass *klass;
1619 dec = GST_AUDIO_DECODER (parent);
1620 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1622 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1623 GST_EVENT_TYPE_NAME (event));
1626 ret = klass->event (dec, event);
1628 gst_event_unref (event);
1635 gst_audio_decoder_do_seek (GstAudioDecoder * dec, GstEvent * event)
1638 GstSeekType start_type, end_type;
1641 gint64 start, start_time, end_time;
1642 GstSegment seek_segment;
1645 gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
1646 &start_time, &end_type, &end_time);
1648 /* we'll handle plain open-ended flushing seeks with the simple approach */
1650 GST_DEBUG_OBJECT (dec, "unsupported seek: rate");
1654 if (start_type != GST_SEEK_TYPE_SET) {
1655 GST_DEBUG_OBJECT (dec, "unsupported seek: start time");
1659 if (end_type != GST_SEEK_TYPE_NONE ||
1660 (end_type == GST_SEEK_TYPE_SET && end_time != GST_CLOCK_TIME_NONE)) {
1661 GST_DEBUG_OBJECT (dec, "unsupported seek: end time");
1665 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1666 GST_DEBUG_OBJECT (dec, "unsupported seek: not flushing");
1670 memcpy (&seek_segment, &dec->segment, sizeof (seek_segment));
1671 gst_segment_do_seek (&seek_segment, rate, format, flags, start_type,
1672 start_time, end_type, end_time, NULL);
1673 start_time = seek_segment.position;
1675 if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
1676 GST_FORMAT_BYTES, &start)) {
1677 GST_DEBUG_OBJECT (dec, "conversion failed");
1681 seqnum = gst_event_get_seqnum (event);
1682 event = gst_event_new_seek (1.0, GST_FORMAT_BYTES, flags,
1683 GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE, -1);
1684 gst_event_set_seqnum (event, seqnum);
1686 GST_DEBUG_OBJECT (dec, "seeking to %" GST_TIME_FORMAT " at byte offset %"
1687 G_GINT64_FORMAT, GST_TIME_ARGS (start_time), start);
1689 return gst_pad_push_event (dec->sinkpad, event);
1693 gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1695 GstAudioDecoder *dec;
1696 gboolean res = FALSE;
1698 dec = GST_AUDIO_DECODER (parent);
1700 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1701 GST_EVENT_TYPE_NAME (event));
1703 switch (GST_EVENT_TYPE (event)) {
1704 case GST_EVENT_SEEK:
1709 GstSeekType cur_type, stop_type;
1714 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1716 seqnum = gst_event_get_seqnum (event);
1718 /* upstream gets a chance first */
1719 if ((res = gst_pad_push_event (dec->sinkpad, event)))
1722 /* if upstream fails for a time seek, maybe we can help if allowed */
1723 if (format == GST_FORMAT_TIME) {
1724 if (gst_audio_decoder_do_byte (dec))
1725 res = gst_audio_decoder_do_seek (dec, event);
1729 /* ... though a non-time seek can be aided as well */
1730 /* First bring the requested format to time */
1732 gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
1735 gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
1739 /* then seek with time on the peer */
1740 event = gst_event_new_seek (rate, GST_FORMAT_TIME,
1741 flags, cur_type, tcur, stop_type, tstop);
1742 gst_event_set_seqnum (event, seqnum);
1744 res = gst_pad_push_event (dec->sinkpad, event);
1748 res = gst_pad_event_default (pad, parent, event);
1757 GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
1763 * gst_audio_encoded_audio_convert:
1764 * @fmt: audio format of the encoded audio
1765 * @bytes: number of encoded bytes
1766 * @samples: number of encoded samples
1767 * @src_format: source format
1768 * @src_value: source value
1769 * @dest_format: destination format
1770 * @dest_value: destination format
1772 * Helper function to convert @src_value in @src_format to @dest_value in
1773 * @dest_format for encoded audio data. Conversion is possible between
1774 * BYTE and TIME format by using estimated bitrate based on
1775 * @samples and @bytes (and @fmt).
1777 /* FIXME: make gst_audio_encoded_audio_convert() public? */
1779 gst_audio_encoded_audio_convert (GstAudioInfo * fmt,
1780 gint64 bytes, gint64 samples, GstFormat src_format,
1781 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1783 gboolean res = FALSE;
1785 g_return_val_if_fail (dest_format != NULL, FALSE);
1786 g_return_val_if_fail (dest_value != NULL, FALSE);
1788 if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
1791 *dest_value = src_value;
1795 if (samples == 0 || bytes == 0 || fmt->rate == 0) {
1796 GST_DEBUG ("not enough metadata yet to convert");
1802 switch (src_format) {
1803 case GST_FORMAT_BYTES:
1804 switch (*dest_format) {
1805 case GST_FORMAT_TIME:
1806 *dest_value = gst_util_uint64_scale (src_value,
1807 GST_SECOND * samples, bytes);
1814 case GST_FORMAT_TIME:
1815 switch (*dest_format) {
1816 case GST_FORMAT_BYTES:
1817 *dest_value = gst_util_uint64_scale (src_value, bytes,
1818 samples * GST_SECOND);
1834 gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
1837 gboolean res = FALSE;
1838 GstAudioDecoder *dec;
1840 dec = GST_AUDIO_DECODER (parent);
1842 GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
1844 switch (GST_QUERY_TYPE (query)) {
1845 case GST_QUERY_FORMATS:
1847 gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
1851 case GST_QUERY_CONVERT:
1853 GstFormat src_fmt, dest_fmt;
1854 gint64 src_val, dest_val;
1856 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1857 if (!(res = gst_audio_encoded_audio_convert (&dec->priv->ctx.info,
1858 dec->priv->bytes_in, dec->priv->samples_out,
1859 src_fmt, src_val, &dest_fmt, &dest_val)))
1861 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1864 case GST_QUERY_SEEKING:
1868 /* non-TIME segments are discarded, so we won't seek that way either */
1869 gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
1870 if (format != GST_FORMAT_TIME) {
1871 GST_DEBUG_OBJECT (dec, "discarding non-TIME SEEKING query");
1878 res = gst_pad_query_default (pad, parent, query);
1886 /* FIXME ? are any of these queries (other than latency) a decoder's business ??
1887 * also, the conversion stuff might seem to make sense, but seems to not mind
1888 * segment stuff etc at all
1889 * Supposedly that's backward compatibility ... */
1891 gst_audio_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1893 GstAudioDecoder *dec;
1894 gboolean res = FALSE;
1896 dec = GST_AUDIO_DECODER (parent);
1898 GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
1900 switch (GST_QUERY_TYPE (query)) {
1901 case GST_QUERY_DURATION:
1905 /* upstream in any case */
1906 if ((res = gst_pad_query_default (pad, parent, query)))
1909 gst_query_parse_duration (query, &format, NULL);
1910 /* try answering TIME by converting from BYTE if subclass allows */
1911 if (format == GST_FORMAT_TIME && gst_audio_decoder_do_byte (dec)) {
1914 if (gst_pad_peer_query_duration (dec->sinkpad, GST_FORMAT_BYTES,
1916 GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
1917 if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
1918 GST_FORMAT_TIME, &value)) {
1919 gst_query_set_duration (query, GST_FORMAT_TIME, value);
1926 case GST_QUERY_POSITION:
1931 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1932 GST_LOG_OBJECT (dec, "returning peer response");
1936 /* we start from the last seen time */
1937 time = dec->segment.position;
1938 /* correct for the segment values */
1939 time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
1941 GST_LOG_OBJECT (dec,
1942 "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
1944 /* and convert to the final format */
1945 gst_query_parse_position (query, &format, NULL);
1946 if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
1950 gst_query_set_position (query, format, value);
1952 GST_LOG_OBJECT (dec,
1953 "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
1957 case GST_QUERY_FORMATS:
1959 gst_query_set_formats (query, 3,
1960 GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
1964 case GST_QUERY_CONVERT:
1966 GstFormat src_fmt, dest_fmt;
1967 gint64 src_val, dest_val;
1969 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1970 if (!(res = gst_audio_info_convert (&dec->priv->ctx.info,
1971 src_fmt, src_val, dest_fmt, &dest_val)))
1973 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1976 case GST_QUERY_LATENCY:
1978 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1980 GstClockTime min_latency, max_latency;
1982 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1983 GST_DEBUG_OBJECT (dec, "Peer latency: live %d, min %"
1984 GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1985 GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1987 GST_OBJECT_LOCK (dec);
1988 /* add our latency */
1989 if (min_latency != -1)
1990 min_latency += dec->priv->ctx.min_latency;
1991 if (max_latency != -1)
1992 max_latency += dec->priv->ctx.max_latency;
1993 GST_OBJECT_UNLOCK (dec);
1995 gst_query_set_latency (query, live, min_latency, max_latency);
2000 res = gst_pad_query_default (pad, parent, query);
2008 gst_audio_decoder_stop (GstAudioDecoder * dec)
2010 GstAudioDecoderClass *klass;
2011 gboolean ret = TRUE;
2013 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_stop");
2015 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
2018 ret = klass->stop (dec);
2022 gst_audio_decoder_reset (dec, TRUE);
2025 dec->priv->active = FALSE;
2031 gst_audio_decoder_start (GstAudioDecoder * dec)
2033 GstAudioDecoderClass *klass;
2034 gboolean ret = TRUE;
2036 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_start");
2038 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
2040 /* arrange clean state */
2041 gst_audio_decoder_reset (dec, TRUE);
2044 ret = klass->start (dec);
2048 dec->priv->active = TRUE;
2054 gst_audio_decoder_get_property (GObject * object, guint prop_id,
2055 GValue * value, GParamSpec * pspec)
2057 GstAudioDecoder *dec;
2059 dec = GST_AUDIO_DECODER (object);
2063 g_value_set_int64 (value, dec->priv->latency);
2065 case PROP_TOLERANCE:
2066 g_value_set_int64 (value, dec->priv->tolerance);
2069 g_value_set_boolean (value, dec->priv->plc);
2072 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2078 gst_audio_decoder_set_property (GObject * object, guint prop_id,
2079 const GValue * value, GParamSpec * pspec)
2081 GstAudioDecoder *dec;
2083 dec = GST_AUDIO_DECODER (object);
2087 dec->priv->latency = g_value_get_int64 (value);
2089 case PROP_TOLERANCE:
2090 dec->priv->tolerance = g_value_get_int64 (value);
2093 dec->priv->plc = g_value_get_boolean (value);
2096 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2101 static GstStateChangeReturn
2102 gst_audio_decoder_change_state (GstElement * element, GstStateChange transition)
2104 GstAudioDecoder *codec;
2105 GstAudioDecoderClass *klass;
2106 GstStateChangeReturn ret;
2108 codec = GST_AUDIO_DECODER (element);
2109 klass = GST_AUDIO_DECODER_GET_CLASS (codec);
2111 switch (transition) {
2112 case GST_STATE_CHANGE_NULL_TO_READY:
2114 if (!klass->open (codec))
2118 case GST_STATE_CHANGE_READY_TO_PAUSED:
2119 if (!gst_audio_decoder_start (codec)) {
2123 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2129 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2131 switch (transition) {
2132 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2134 case GST_STATE_CHANGE_PAUSED_TO_READY:
2135 if (!gst_audio_decoder_stop (codec)) {
2139 case GST_STATE_CHANGE_READY_TO_NULL:
2141 if (!klass->close (codec))
2153 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to start codec"));
2154 return GST_STATE_CHANGE_FAILURE;
2158 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
2159 return GST_STATE_CHANGE_FAILURE;
2163 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to open codec"));
2164 return GST_STATE_CHANGE_FAILURE;
2168 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to close codec"));
2169 return GST_STATE_CHANGE_FAILURE;
2174 _gst_audio_decoder_error (GstAudioDecoder * dec, gint weight,
2175 GQuark domain, gint code, gchar * txt, gchar * dbg, const gchar * file,
2176 const gchar * function, gint line)
2179 GST_WARNING_OBJECT (dec, "error: %s", txt);
2181 GST_WARNING_OBJECT (dec, "error: %s", dbg);
2182 dec->priv->error_count += weight;
2183 dec->priv->discont = TRUE;
2184 if (dec->priv->ctx.max_errors < dec->priv->error_count) {
2185 gst_element_message_full (GST_ELEMENT (dec), GST_MESSAGE_ERROR,
2186 domain, code, txt, dbg, file, function, line);
2187 return GST_FLOW_ERROR;
2194 * gst_audio_decoder_get_audio_info:
2195 * @dec: a #GstAudioDecoder
2197 * Returns: a #GstAudioInfo describing the input audio format
2202 gst_audio_decoder_get_audio_info (GstAudioDecoder * dec)
2204 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), NULL);
2206 return &dec->priv->ctx.info;
2210 * gst_audio_decoder_set_plc_aware:
2211 * @dec: a #GstAudioDecoder
2212 * @plc: new plc state
2214 * Indicates whether or not subclass handles packet loss concealment (plc).
2219 gst_audio_decoder_set_plc_aware (GstAudioDecoder * dec, gboolean plc)
2221 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2223 dec->priv->ctx.do_plc = plc;
2227 * gst_audio_decoder_get_plc_aware:
2228 * @dec: a #GstAudioDecoder
2230 * Returns: currently configured plc handling
2235 gst_audio_decoder_get_plc_aware (GstAudioDecoder * dec)
2237 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2239 return dec->priv->ctx.do_plc;
2243 * gst_audio_decoder_set_byte_time:
2244 * @dec: a #GstAudioDecoder
2245 * @enabled: whether to enable byte to time conversion
2247 * Allows baseclass to perform byte to time estimated conversion.
2252 gst_audio_decoder_set_byte_time (GstAudioDecoder * dec, gboolean enabled)
2254 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2256 dec->priv->ctx.do_byte_time = enabled;
2260 * gst_audio_decoder_get_byte_time:
2261 * @dec: a #GstAudioDecoder
2263 * Returns: currently configured byte to time conversion setting
2268 gst_audio_decoder_get_byte_time (GstAudioDecoder * dec)
2270 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2272 return dec->priv->ctx.do_byte_time;
2276 * gst_audio_decoder_get_delay:
2277 * @dec: a #GstAudioDecoder
2279 * Returns: currently configured decoder delay
2284 gst_audio_decoder_get_delay (GstAudioDecoder * dec)
2286 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2288 return dec->priv->ctx.delay;
2292 * gst_audio_decoder_set_max_errors:
2293 * @dec: a #GstAudioDecoder
2294 * @num: max tolerated errors
2296 * Sets numbers of tolerated decoder errors, where a tolerated one is then only
2297 * warned about, but more than tolerated will lead to fatal error. Default
2298 * is set to GST_AUDIO_DECODER_MAX_ERRORS.
2303 gst_audio_decoder_set_max_errors (GstAudioDecoder * dec, gint num)
2305 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2307 dec->priv->ctx.max_errors = num;
2311 * gst_audio_decoder_get_max_errors:
2312 * @dec: a #GstAudioDecoder
2314 * Returns: currently configured decoder tolerated error count.
2319 gst_audio_decoder_get_max_errors (GstAudioDecoder * dec)
2321 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2323 return dec->priv->ctx.max_errors;
2327 * gst_audio_decoder_set_latency:
2328 * @dec: a #GstAudioDecoder
2329 * @min: minimum latency
2330 * @max: maximum latency
2332 * Sets decoder latency.
2337 gst_audio_decoder_set_latency (GstAudioDecoder * dec,
2338 GstClockTime min, GstClockTime max)
2340 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2342 GST_OBJECT_LOCK (dec);
2343 dec->priv->ctx.min_latency = min;
2344 dec->priv->ctx.max_latency = max;
2345 GST_OBJECT_UNLOCK (dec);
2349 * gst_audio_decoder_get_latency:
2350 * @dec: a #GstAudioDecoder
2351 * @min: (out) (allow-none): a pointer to storage to hold minimum latency
2352 * @max: (out) (allow-none): a pointer to storage to hold maximum latency
2354 * Sets the variables pointed to by @min and @max to the currently configured
2360 gst_audio_decoder_get_latency (GstAudioDecoder * dec,
2361 GstClockTime * min, GstClockTime * max)
2363 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2365 GST_OBJECT_LOCK (dec);
2367 *min = dec->priv->ctx.min_latency;
2369 *max = dec->priv->ctx.max_latency;
2370 GST_OBJECT_UNLOCK (dec);
2374 * gst_audio_decoder_get_parse_state:
2375 * @dec: a #GstAudioDecoder
2376 * @sync: a pointer to a variable to hold the current sync state
2377 * @eos: a pointer to a variable to hold the current eos state
2379 * Return current parsing (sync and eos) state.
2384 gst_audio_decoder_get_parse_state (GstAudioDecoder * dec,
2385 gboolean * sync, gboolean * eos)
2387 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2390 *sync = dec->priv->ctx.sync;
2392 *eos = dec->priv->ctx.eos;
2396 * gst_audio_decoder_set_plc:
2397 * @dec: a #GstAudioDecoder
2398 * @enabled: new state
2400 * Enable or disable decoder packet loss concealment, provided subclass
2401 * and codec are capable and allow handling plc.
2408 gst_audio_decoder_set_plc (GstAudioDecoder * dec, gboolean enabled)
2410 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2412 GST_LOG_OBJECT (dec, "enabled: %d", enabled);
2414 GST_OBJECT_LOCK (dec);
2415 dec->priv->plc = enabled;
2416 GST_OBJECT_UNLOCK (dec);
2420 * gst_audio_decoder_get_plc:
2421 * @dec: a #GstAudioDecoder
2423 * Queries decoder packet loss concealment handling.
2425 * Returns: TRUE if packet loss concealment is enabled.
2432 gst_audio_decoder_get_plc (GstAudioDecoder * dec)
2436 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
2438 GST_OBJECT_LOCK (dec);
2439 result = dec->priv->plc;
2440 GST_OBJECT_UNLOCK (dec);
2446 * gst_audio_decoder_set_min_latency:
2447 * @dec: a #GstAudioDecoder
2448 * @num: new minimum latency
2450 * Sets decoder minimum aggregation latency.
2457 gst_audio_decoder_set_min_latency (GstAudioDecoder * dec, gint64 num)
2459 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2461 GST_OBJECT_LOCK (dec);
2462 dec->priv->latency = num;
2463 GST_OBJECT_UNLOCK (dec);
2467 * gst_audio_decoder_get_min_latency:
2468 * @dec: a #GstAudioDecoder
2470 * Queries decoder's latency aggregation.
2472 * Returns: aggregation latency.
2479 gst_audio_decoder_get_min_latency (GstAudioDecoder * dec)
2483 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
2485 GST_OBJECT_LOCK (dec);
2486 result = dec->priv->latency;
2487 GST_OBJECT_UNLOCK (dec);
2493 * gst_audio_decoder_set_tolerance:
2494 * @dec: a #GstAudioDecoder
2495 * @tolerance: new tolerance
2497 * Configures decoder audio jitter tolerance threshold.
2504 gst_audio_decoder_set_tolerance (GstAudioDecoder * dec, gint64 tolerance)
2506 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2508 GST_OBJECT_LOCK (dec);
2509 dec->priv->tolerance = tolerance;
2510 GST_OBJECT_UNLOCK (dec);
2514 * gst_audio_decoder_get_tolerance:
2515 * @dec: a #GstAudioDecoder
2517 * Queries current audio jitter tolerance threshold.
2519 * Returns: decoder audio jitter tolerance threshold.
2526 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec)
2530 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2532 GST_OBJECT_LOCK (dec);
2533 result = dec->priv->tolerance;
2534 GST_OBJECT_UNLOCK (dec);
2540 * gst_audio_decoder_set_drainable:
2541 * @dec: a #GstAudioDecoder
2542 * @enabled: new state
2544 * Configures decoder drain handling. If drainable, subclass might
2545 * be handed a NULL buffer to have it return any leftover decoded data.
2546 * Otherwise, it is not considered so capable and will only ever be passed
2554 gst_audio_decoder_set_drainable (GstAudioDecoder * dec, gboolean enabled)
2556 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2558 GST_OBJECT_LOCK (dec);
2559 dec->priv->drainable = enabled;
2560 GST_OBJECT_UNLOCK (dec);
2564 * gst_audio_decoder_get_drainable:
2565 * @dec: a #GstAudioDecoder
2567 * Queries decoder drain handling.
2569 * Returns: TRUE if drainable handling is enabled.
2576 gst_audio_decoder_get_drainable (GstAudioDecoder * dec)
2580 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2582 GST_OBJECT_LOCK (dec);
2583 result = dec->priv->drainable;
2584 GST_OBJECT_UNLOCK (dec);
2590 * gst_audio_decoder_set_needs_format:
2591 * @dec: a #GstAudioDecoder
2592 * @enabled: new state
2594 * Configures decoder format needs. If enabled, subclass needs to be
2595 * negotiated with format caps before it can process any data. It will then
2596 * never be handed any data before it has been configured.
2597 * Otherwise, it might be handed data without having been configured and
2598 * is then expected being able to do so either by default
2599 * or based on the input data.
2606 gst_audio_decoder_set_needs_format (GstAudioDecoder * dec, gboolean enabled)
2608 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2610 GST_OBJECT_LOCK (dec);
2611 dec->priv->needs_format = enabled;
2612 GST_OBJECT_UNLOCK (dec);
2616 * gst_audio_decoder_get_needs_format:
2617 * @dec: a #GstAudioDecoder
2619 * Queries decoder required format handling.
2621 * Returns: TRUE if required format handling is enabled.
2628 gst_audio_decoder_get_needs_format (GstAudioDecoder * dec)
2632 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2634 GST_OBJECT_LOCK (dec);
2635 result = dec->priv->needs_format;
2636 GST_OBJECT_UNLOCK (dec);
2642 * gst_audio_decoder_merge_tags:
2643 * @dec: a #GstAudioDecoder
2644 * @tags: a #GstTagList to merge
2645 * @mode: the #GstTagMergeMode to use
2647 * Adds tags to so-called pending tags, which will be processed
2648 * before pushing out data downstream.
2650 * Note that this is provided for convenience, and the subclass is
2651 * not required to use this and can still do tag handling on its own,
2652 * although it should be aware that baseclass already takes care
2653 * of the usual CODEC/AUDIO_CODEC tags.
2660 gst_audio_decoder_merge_tags (GstAudioDecoder * dec,
2661 const GstTagList * tags, GstTagMergeMode mode)
2665 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2666 g_return_if_fail (tags == NULL || GST_IS_TAG_LIST (tags));
2668 GST_AUDIO_DECODER_STREAM_LOCK (dec);
2670 GST_DEBUG_OBJECT (dec, "merging tags %" GST_PTR_FORMAT, tags);
2671 otags = dec->priv->taglist;
2672 dec->priv->taglist = gst_tag_list_merge (dec->priv->taglist, tags, mode);
2674 gst_tag_list_free (otags);
2675 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);