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 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
153 * with newer GLib versions (>= 2.31.0) */
154 #define GLIB_DISABLE_DEPRECATION_WARNINGS
156 #include "gstaudiodecoder.h"
157 #include <gst/pbutils/descriptions.h>
161 GST_DEBUG_CATEGORY (audiodecoder_debug);
162 #define GST_CAT_DEFAULT audiodecoder_debug
164 #define GST_AUDIO_DECODER_GET_PRIVATE(obj) \
165 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_DECODER, \
166 GstAudioDecoderPrivate))
181 #define DEFAULT_LATENCY 0
182 #define DEFAULT_TOLERANCE 0
183 #define DEFAULT_PLC FALSE
184 #define DEFAULT_DRAINABLE TRUE
185 #define DEFAULT_NEEDS_FORMAT FALSE
187 typedef struct _GstAudioDecoderContext
190 /* (output) audio format */
202 gboolean do_byte_time;
204 /* MT-protected (with LOCK) */
205 GstClockTime min_latency;
206 GstClockTime max_latency;
207 } GstAudioDecoderContext;
209 struct _GstAudioDecoderPrivate
211 /* activation status */
214 /* input base/first ts as basis for output ts */
215 GstClockTime base_ts;
216 /* input samples processed and sent downstream so far (w.r.t. base_ts) */
219 /* collected input data */
221 /* tracking input ts for changes */
222 GstClockTime prev_ts;
224 guint64 prev_distance;
226 /* frames obtained from input */
228 /* collected output data */
229 GstAdapter *adapter_out;
230 /* ts and duration for output data collected above */
231 GstClockTime out_ts, out_dur;
232 /* mark outgoing discont */
235 /* subclass gave all it could already */
237 /* subclass currently being forcibly drained */
240 /* input bps estimatation */
241 /* global in bytes seen */
243 /* global samples sent out */
245 /* bytes flushed during parsing */
252 /* whether circumstances allow output aggregation */
255 /* reverse playback queues */
260 /* reversed output */
263 /* context storage */
264 GstAudioDecoderContext ctx;
267 GstClockTime latency;
268 GstClockTime tolerance;
271 gboolean needs_format;
273 /* pending serialized sink events, will be sent from finish_frame() */
274 GList *pending_events;
278 static void gst_audio_decoder_finalize (GObject * object);
279 static void gst_audio_decoder_set_property (GObject * object,
280 guint prop_id, const GValue * value, GParamSpec * pspec);
281 static void gst_audio_decoder_get_property (GObject * object,
282 guint prop_id, GValue * value, GParamSpec * pspec);
284 static void gst_audio_decoder_clear_queues (GstAudioDecoder * dec);
285 static GstFlowReturn gst_audio_decoder_chain_reverse (GstAudioDecoder *
286 dec, GstBuffer * buf);
288 static GstStateChangeReturn gst_audio_decoder_change_state (GstElement *
289 element, GstStateChange transition);
290 static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event);
291 static gboolean gst_audio_decoder_src_event (GstPad * pad, GstEvent * event);
292 static gboolean gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps);
293 static gboolean gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps);
294 static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstBuffer * buf);
295 static gboolean gst_audio_decoder_src_query (GstPad * pad, GstQuery * query);
296 static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query);
297 static const GstQueryType *gst_audio_decoder_get_query_types (GstPad * pad);
298 static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);
301 GST_BOILERPLATE (GstAudioDecoder, gst_audio_decoder, GstElement,
305 gst_audio_decoder_base_init (gpointer g_class)
310 gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
312 GObjectClass *gobject_class;
313 GstElementClass *element_class;
315 gobject_class = G_OBJECT_CLASS (klass);
316 element_class = GST_ELEMENT_CLASS (klass);
318 parent_class = g_type_class_peek_parent (klass);
320 g_type_class_add_private (klass, sizeof (GstAudioDecoderPrivate));
322 GST_DEBUG_CATEGORY_INIT (audiodecoder_debug, "audiodecoder", 0,
323 "audio decoder base class");
325 gobject_class->set_property = gst_audio_decoder_set_property;
326 gobject_class->get_property = gst_audio_decoder_get_property;
327 gobject_class->finalize = gst_audio_decoder_finalize;
329 element_class->change_state = gst_audio_decoder_change_state;
332 g_object_class_install_property (gobject_class, PROP_LATENCY,
333 g_param_spec_int64 ("min-latency", "Minimum Latency",
334 "Aggregate output data to a minimum of latency time (ns)",
335 0, G_MAXINT64, DEFAULT_LATENCY,
336 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
338 g_object_class_install_property (gobject_class, PROP_TOLERANCE,
339 g_param_spec_int64 ("tolerance", "Tolerance",
340 "Perfect ts while timestamp jitter/imperfection within tolerance (ns)",
341 0, G_MAXINT64, DEFAULT_TOLERANCE,
342 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
344 g_object_class_install_property (gobject_class, PROP_PLC,
345 g_param_spec_boolean ("plc", "Packet Loss Concealment",
346 "Perform packet loss concealment (if supported)",
347 DEFAULT_PLC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
351 gst_audio_decoder_init (GstAudioDecoder * dec, GstAudioDecoderClass * klass)
353 GstPadTemplate *pad_template;
355 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_init");
357 dec->priv = GST_AUDIO_DECODER_GET_PRIVATE (dec);
361 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
362 g_return_if_fail (pad_template != NULL);
364 dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
365 gst_pad_set_event_function (dec->sinkpad,
366 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_event));
367 gst_pad_set_setcaps_function (dec->sinkpad,
368 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_setcaps));
369 gst_pad_set_chain_function (dec->sinkpad,
370 GST_DEBUG_FUNCPTR (gst_audio_decoder_chain));
371 gst_pad_set_query_function (dec->sinkpad,
372 GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_query));
373 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
374 GST_DEBUG_OBJECT (dec, "sinkpad created");
376 /* Setup source pad */
378 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
379 g_return_if_fail (pad_template != NULL);
381 dec->srcpad = gst_pad_new_from_template (pad_template, "src");
382 gst_pad_set_setcaps_function (dec->srcpad,
383 GST_DEBUG_FUNCPTR (gst_audio_decoder_src_setcaps));
384 gst_pad_set_event_function (dec->srcpad,
385 GST_DEBUG_FUNCPTR (gst_audio_decoder_src_event));
386 gst_pad_set_query_function (dec->srcpad,
387 GST_DEBUG_FUNCPTR (gst_audio_decoder_src_query));
388 gst_pad_set_query_type_function (dec->srcpad,
389 GST_DEBUG_FUNCPTR (gst_audio_decoder_get_query_types));
390 gst_pad_use_fixed_caps (dec->srcpad);
391 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
392 GST_DEBUG_OBJECT (dec, "srcpad created");
394 dec->priv->adapter = gst_adapter_new ();
395 dec->priv->adapter_out = gst_adapter_new ();
396 g_queue_init (&dec->priv->frames);
398 g_static_rec_mutex_init (&dec->stream_lock);
400 /* property default */
401 dec->priv->latency = DEFAULT_LATENCY;
402 dec->priv->tolerance = DEFAULT_TOLERANCE;
403 dec->priv->plc = DEFAULT_PLC;
404 dec->priv->drainable = DEFAULT_DRAINABLE;
405 dec->priv->needs_format = DEFAULT_NEEDS_FORMAT;
408 gst_audio_decoder_reset (dec, TRUE);
409 GST_DEBUG_OBJECT (dec, "init ok");
413 gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
415 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_reset");
417 GST_AUDIO_DECODER_STREAM_LOCK (dec);
420 dec->priv->active = FALSE;
421 dec->priv->bytes_in = 0;
422 dec->priv->samples_out = 0;
424 dec->priv->error_count = 0;
425 gst_audio_decoder_clear_queues (dec);
427 gst_audio_info_clear (&dec->priv->ctx.info);
428 memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
429 dec->priv->ctx.max_errors = GST_AUDIO_DECODER_MAX_ERRORS;
431 if (dec->priv->taglist) {
432 gst_tag_list_free (dec->priv->taglist);
433 dec->priv->taglist = NULL;
436 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
438 g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
439 g_list_free (dec->priv->pending_events);
440 dec->priv->pending_events = NULL;
443 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
444 g_queue_clear (&dec->priv->frames);
445 gst_adapter_clear (dec->priv->adapter);
446 gst_adapter_clear (dec->priv->adapter_out);
447 dec->priv->out_ts = GST_CLOCK_TIME_NONE;
448 dec->priv->out_dur = 0;
449 dec->priv->prev_ts = GST_CLOCK_TIME_NONE;
451 dec->priv->prev_distance = 0;
453 dec->priv->drained = TRUE;
454 dec->priv->base_ts = GST_CLOCK_TIME_NONE;
455 dec->priv->samples = 0;
456 dec->priv->discont = TRUE;
457 dec->priv->sync_flush = FALSE;
459 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
463 gst_audio_decoder_finalize (GObject * object)
465 GstAudioDecoder *dec;
467 g_return_if_fail (GST_IS_AUDIO_DECODER (object));
468 dec = GST_AUDIO_DECODER (object);
470 if (dec->priv->adapter) {
471 g_object_unref (dec->priv->adapter);
473 if (dec->priv->adapter_out) {
474 g_object_unref (dec->priv->adapter_out);
477 g_static_rec_mutex_free (&dec->stream_lock);
479 G_OBJECT_CLASS (parent_class)->finalize (object);
482 /* automagically perform sanity checking of src caps;
483 * also extracts output data format */
485 gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
487 GstAudioDecoder *dec;
491 dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
493 GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
495 GST_AUDIO_DECODER_STREAM_LOCK (dec);
497 /* parse caps here to check subclass;
498 * also makes us aware of output format */
499 if (!gst_caps_is_fixed (caps))
502 /* adjust ts tracking to new sample rate */
503 old_rate = GST_AUDIO_INFO_RATE (&dec->priv->ctx.info);
504 if (GST_CLOCK_TIME_IS_VALID (dec->priv->base_ts) && old_rate) {
505 dec->priv->base_ts +=
506 GST_FRAMES_TO_CLOCK_TIME (dec->priv->samples, old_rate);
507 dec->priv->samples = 0;
510 if (!gst_audio_info_from_caps (&dec->priv->ctx.info, caps))
514 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
516 gst_object_unref (dec);
522 GST_WARNING_OBJECT (dec, "rejected caps %" GST_PTR_FORMAT, caps);
529 gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
531 GstAudioDecoder *dec;
532 GstAudioDecoderClass *klass;
535 dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
536 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
538 GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
540 GST_AUDIO_DECODER_STREAM_LOCK (dec);
541 /* NOTE pbutils only needed here */
542 /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
543 if (dec->priv->taglist)
544 gst_tag_list_free (dec->priv->taglist);
545 dec->priv->taglist = gst_tag_list_new ();
546 gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist,
547 GST_TAG_AUDIO_CODEC, caps);
549 if (klass->set_format)
550 res = klass->set_format (dec, caps);
552 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
554 g_object_unref (dec);
559 gst_audio_decoder_setup (GstAudioDecoder * dec)
564 /* check if in live pipeline, then latency messing is no-no */
565 query = gst_query_new_latency ();
566 res = gst_pad_peer_query (dec->sinkpad, query);
568 gst_query_parse_latency (query, &res, NULL, NULL);
571 gst_query_unref (query);
573 /* normalize to bool */
574 dec->priv->agg = ! !res;
578 gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf)
580 GstAudioDecoderClass *klass;
581 GstAudioDecoderPrivate *priv;
582 GstAudioDecoderContext *ctx;
583 GstFlowReturn ret = GST_FLOW_OK;
585 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
587 ctx = &dec->priv->ctx;
589 g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
591 if (G_UNLIKELY (!buf)) {
592 g_assert_not_reached ();
596 GST_LOG_OBJECT (dec, "clipping buffer of size %d with ts %" GST_TIME_FORMAT
597 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
598 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
599 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
602 buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
604 if (G_UNLIKELY (!buf)) {
605 GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
610 gst_buffer_set_caps (buf, GST_PAD_CAPS (dec->srcpad));
612 if (G_UNLIKELY (priv->discont)) {
613 GST_LOG_OBJECT (dec, "marking discont");
614 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
615 priv->discont = FALSE;
618 /* track where we are */
619 if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
620 /* duration should always be valid for raw audio */
621 g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
622 dec->segment.last_stop =
623 GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
626 if (klass->pre_push) {
627 /* last chance for subclass to do some dirty stuff */
628 ret = klass->pre_push (dec, &buf);
629 if (ret != GST_FLOW_OK || !buf) {
630 GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
631 gst_flow_get_name (ret), buf);
633 gst_buffer_unref (buf);
638 GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT
639 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
640 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
641 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
643 ret = gst_pad_push (dec->srcpad, buf);
649 /* mini aggregator combining output buffers into fewer larger ones,
650 * if so allowed/configured */
652 gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf)
654 GstAudioDecoderPrivate *priv;
655 GstFlowReturn ret = GST_FLOW_OK;
656 GstBuffer *inbuf = NULL;
660 if (G_UNLIKELY (priv->agg < 0))
661 gst_audio_decoder_setup (dec);
663 if (G_LIKELY (buf)) {
664 GST_LOG_OBJECT (dec, "output buffer of size %d with ts %" GST_TIME_FORMAT
665 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
666 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
667 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
672 if (priv->agg && dec->priv->latency > 0) {
674 gboolean assemble = FALSE;
675 const GstClockTimeDiff tol = 10 * GST_MSECOND;
676 GstClockTimeDiff diff = -100 * GST_MSECOND;
678 av = gst_adapter_available (priv->adapter_out);
679 if (G_UNLIKELY (!buf)) {
680 /* forcibly send current */
682 GST_LOG_OBJECT (dec, "forcing fragment flush");
683 } else if (av && (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) ||
684 !GST_CLOCK_TIME_IS_VALID (priv->out_ts) ||
685 ((diff = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP (buf),
686 priv->out_ts + priv->out_dur)) > tol) || diff < -tol)) {
688 GST_LOG_OBJECT (dec, "buffer %d ms apart from current fragment",
689 (gint) (diff / GST_MSECOND));
691 /* add or start collecting */
693 GST_LOG_OBJECT (dec, "starting new fragment");
694 priv->out_ts = GST_BUFFER_TIMESTAMP (buf);
696 GST_LOG_OBJECT (dec, "adding to fragment");
698 gst_adapter_push (priv->adapter_out, buf);
699 priv->out_dur += GST_BUFFER_DURATION (buf);
700 av += GST_BUFFER_SIZE (buf);
703 if (priv->out_dur > dec->priv->latency)
705 if (av && assemble) {
706 GST_LOG_OBJECT (dec, "assembling fragment");
708 buf = gst_adapter_take_buffer (priv->adapter_out, av);
709 GST_BUFFER_TIMESTAMP (buf) = priv->out_ts;
710 GST_BUFFER_DURATION (buf) = priv->out_dur;
711 priv->out_ts = GST_CLOCK_TIME_NONE;
716 if (G_LIKELY (buf)) {
717 if (dec->segment.rate > 0.0) {
718 ret = gst_audio_decoder_push_forward (dec, buf);
719 GST_LOG_OBJECT (dec, "buffer pushed: %s", gst_flow_get_name (ret));
722 priv->queued = g_list_prepend (priv->queued, buf);
723 GST_LOG_OBJECT (dec, "buffer queued");
736 * gst_audio_decoder_finish_frame:
737 * @dec: a #GstAudioDecoder
739 * @frames: number of decoded frames represented by decoded data
741 * Collects decoded data and pushes it downstream.
743 * @buf may be NULL in which case the indicated number of frames
744 * are discarded and considered to have produced no output
745 * (e.g. lead-in or setup frames).
746 * Otherwise, source pad caps must be set when it is called with valid
749 * Note that a frame received in gst_audio_decoder_handle_frame() may be
750 * invalidated by a call to this function.
752 * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
757 gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf,
760 GstAudioDecoderPrivate *priv;
761 GstAudioDecoderContext *ctx;
763 GstClockTime ts, next_ts;
764 GstFlowReturn ret = GST_FLOW_OK;
766 /* subclass should know what it is producing by now */
767 g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL,
769 /* subclass should not hand us no data */
770 g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
772 /* no dummy calls please */
773 g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
776 ctx = &dec->priv->ctx;
778 /* must know the output format by now */
779 g_return_val_if_fail (buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info),
782 GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
783 buf ? GST_BUFFER_SIZE (buf) : -1,
784 buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames);
786 GST_AUDIO_DECODER_STREAM_LOCK (dec);
788 if (priv->pending_events) {
789 GList *pending_events, *l;
791 pending_events = priv->pending_events;
792 priv->pending_events = NULL;
794 GST_DEBUG_OBJECT (dec, "Pushing pending events");
795 for (l = pending_events; l; l = l->next)
796 gst_pad_push_event (dec->srcpad, l->data);
797 g_list_free (pending_events);
800 /* output shoud be whole number of sample frames */
801 if (G_LIKELY (buf && ctx->info.bpf)) {
802 if (GST_BUFFER_SIZE (buf) % ctx->info.bpf)
804 /* per channel least */
805 samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf;
808 /* frame and ts book-keeping */
809 if (G_UNLIKELY (frames < 0)) {
810 if (G_UNLIKELY (-frames - 1 > priv->frames.length))
812 frames = priv->frames.length + frames + 1;
813 } else if (G_UNLIKELY (frames > priv->frames.length)) {
814 if (G_LIKELY (!priv->force)) {
815 /* no way we can let this pass */
816 g_assert_not_reached ();
822 if (G_LIKELY (priv->frames.length))
823 ts = GST_BUFFER_TIMESTAMP (priv->frames.head->data);
825 ts = GST_CLOCK_TIME_NONE;
827 GST_DEBUG_OBJECT (dec, "leading frame ts %" GST_TIME_FORMAT,
830 while (priv->frames.length && frames) {
831 gst_buffer_unref (g_queue_pop_head (&priv->frames));
832 dec->priv->ctx.delay = dec->priv->frames.length;
836 if (G_UNLIKELY (!buf))
840 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
842 GST_DEBUG_OBJECT (dec, "base_ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
845 /* slightly convoluted approach caters for perfect ts if subclass desires */
846 if (GST_CLOCK_TIME_IS_VALID (ts)) {
847 if (dec->priv->tolerance > 0) {
848 GstClockTimeDiff diff;
850 g_assert (GST_CLOCK_TIME_IS_VALID (priv->base_ts));
851 next_ts = priv->base_ts +
852 gst_util_uint64_scale (priv->samples, GST_SECOND, ctx->info.rate);
854 "buffer is %" G_GUINT64_FORMAT " samples past base_ts %"
855 GST_TIME_FORMAT ", expected ts %" GST_TIME_FORMAT, priv->samples,
856 GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
857 diff = GST_CLOCK_DIFF (next_ts, ts);
858 GST_LOG_OBJECT (dec, "ts diff %d ms", (gint) (diff / GST_MSECOND));
859 /* if within tolerance,
860 * discard buffer ts and carry on producing perfect stream,
861 * otherwise resync to ts */
862 if (G_UNLIKELY (diff < (gint64) - dec->priv->tolerance ||
863 diff > (gint64) dec->priv->tolerance)) {
864 GST_DEBUG_OBJECT (dec, "base_ts resync");
869 GST_DEBUG_OBJECT (dec, "base_ts resync");
875 /* delayed one-shot stuff until confirmed data */
877 GST_DEBUG_OBJECT (dec, "codec tag %" GST_PTR_FORMAT, priv->taglist);
878 if (gst_tag_list_is_empty (priv->taglist)) {
879 gst_tag_list_free (priv->taglist);
881 gst_element_found_tags (GST_ELEMENT (dec), priv->taglist);
883 priv->taglist = NULL;
886 buf = gst_buffer_make_metadata_writable (buf);
887 if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
888 GST_BUFFER_TIMESTAMP (buf) =
890 GST_FRAMES_TO_CLOCK_TIME (priv->samples, ctx->info.rate);
891 GST_BUFFER_DURATION (buf) = priv->base_ts +
892 GST_FRAMES_TO_CLOCK_TIME (priv->samples + samples, ctx->info.rate) -
893 GST_BUFFER_TIMESTAMP (buf);
895 GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
896 GST_BUFFER_DURATION (buf) =
897 GST_FRAMES_TO_CLOCK_TIME (samples, ctx->info.rate);
899 priv->samples += samples;
900 priv->samples_out += samples;
902 /* we got data, so note things are looking up */
903 if (G_UNLIKELY (dec->priv->error_count))
904 dec->priv->error_count--;
907 ret = gst_audio_decoder_output (dec, buf);
909 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
916 GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
917 ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf),
919 gst_buffer_unref (buf);
920 ret = GST_FLOW_ERROR;
925 GST_ELEMENT_ERROR (dec, STREAM, ENCODE,
926 ("received more decoded frames %d than provided %d", frames,
927 priv->frames.length), (NULL));
929 gst_buffer_unref (buf);
930 ret = GST_FLOW_ERROR;
936 gst_audio_decoder_handle_frame (GstAudioDecoder * dec,
937 GstAudioDecoderClass * klass, GstBuffer * buffer)
939 if (G_LIKELY (buffer)) {
940 /* keep around for admin */
941 GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT,
942 GST_BUFFER_SIZE (buffer),
943 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
944 g_queue_push_tail (&dec->priv->frames, buffer);
945 dec->priv->ctx.delay = dec->priv->frames.length;
946 dec->priv->bytes_in += GST_BUFFER_SIZE (buffer);
948 GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
951 return klass->handle_frame (dec, buffer);
954 /* maybe subclass configurable instead, but this allows for a whole lot of
955 * raw samples, so at least quite some encoded ... */
956 #define GST_AUDIO_DECODER_MAX_SYNC 10 * 8 * 2 * 1024
959 gst_audio_decoder_push_buffers (GstAudioDecoder * dec, gboolean force)
961 GstAudioDecoderClass *klass;
962 GstAudioDecoderPrivate *priv;
963 GstAudioDecoderContext *ctx;
964 GstFlowReturn ret = GST_FLOW_OK;
968 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
970 ctx = &dec->priv->ctx;
972 g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
974 av = gst_adapter_available (priv->adapter);
975 GST_DEBUG_OBJECT (dec, "available: %d", av);
977 while (ret == GST_FLOW_OK) {
987 /* parse if needed */
991 /* limited (legacy) parsing; avoid whole of baseparse */
992 GST_DEBUG_OBJECT (dec, "parsing available: %d", av);
993 /* piggyback sync state on discont */
994 ctx->sync = !priv->discont;
995 ret = klass->parse (dec, priv->adapter, &offset, &len);
997 g_assert (offset <= av);
1000 GST_DEBUG_OBJECT (dec, "setting DISCONT");
1001 gst_adapter_flush (priv->adapter, offset);
1003 /* avoid parsing indefinitely */
1004 priv->sync_flush += offset;
1005 if (priv->sync_flush > GST_AUDIO_DECODER_MAX_SYNC)
1009 if (ret == GST_FLOW_UNEXPECTED) {
1010 GST_LOG_OBJECT (dec, "no frame yet");
1013 } else if (ret == GST_FLOW_OK) {
1014 GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
1016 g_assert (offset + len <= av);
1017 priv->sync_flush = 0;
1024 /* track upstream ts, but do not get stuck if nothing new upstream */
1026 ts = gst_adapter_prev_timestamp (priv->adapter, NULL);
1027 if (ts == priv->prev_ts) {
1028 GST_LOG_OBJECT (dec, "ts == prev_ts; discarding");
1029 ts = GST_CLOCK_TIME_NONE;
1034 ts = gst_adapter_prev_timestamp (priv->adapter, &distance);
1035 if (ts != priv->prev_ts || distance <= priv->prev_distance) {
1037 priv->prev_distance = distance;
1039 GST_LOG_OBJECT (dec, "ts == prev_ts; discarding");
1040 ts = GST_CLOCK_TIME_NONE;
1043 buffer = gst_adapter_take_buffer (priv->adapter, len);
1044 buffer = gst_buffer_make_metadata_writable (buffer);
1045 GST_BUFFER_TIMESTAMP (buffer) = ts;
1050 if (!priv->drainable) {
1051 priv->drained = TRUE;
1057 ret = gst_audio_decoder_handle_frame (dec, klass, buffer);
1059 /* do not keep pushing it ... */
1060 if (G_UNLIKELY (!av)) {
1061 priv->drained = TRUE;
1069 GST_LOG_OBJECT (dec, "done pushing to subclass");
1075 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("failed to parse stream"));
1076 return GST_FLOW_ERROR;
1080 static GstFlowReturn
1081 gst_audio_decoder_drain (GstAudioDecoder * dec)
1085 if (dec->priv->drained && !dec->priv->gather)
1088 /* dispatch reverse pending buffers */
1089 /* chain eventually calls upon drain as well, but by that time
1090 * gather list should be clear, so ok ... */
1091 if (dec->segment.rate < 0.0 && dec->priv->gather)
1092 gst_audio_decoder_chain_reverse (dec, NULL);
1093 /* have subclass give all it can */
1094 ret = gst_audio_decoder_push_buffers (dec, TRUE);
1095 /* ensure all output sent */
1096 ret = gst_audio_decoder_output (dec, NULL);
1097 /* everything should be away now */
1098 if (dec->priv->frames.length) {
1099 /* not fatal/impossible though if subclass/codec eats stuff */
1100 GST_WARNING_OBJECT (dec, "still %d frames left after draining",
1101 dec->priv->frames.length);
1102 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
1103 g_queue_clear (&dec->priv->frames);
1105 /* discard (unparsed) leftover */
1106 gst_adapter_clear (dec->priv->adapter);
1112 /* hard == FLUSH, otherwise discont */
1113 static GstFlowReturn
1114 gst_audio_decoder_flush (GstAudioDecoder * dec, gboolean hard)
1116 GstAudioDecoderClass *klass;
1117 GstFlowReturn ret = GST_FLOW_OK;
1119 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1121 GST_LOG_OBJECT (dec, "flush hard %d", hard);
1124 ret = gst_audio_decoder_drain (dec);
1126 gst_audio_decoder_clear_queues (dec);
1127 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
1128 dec->priv->error_count = 0;
1130 /* only bother subclass with flushing if known it is already alive
1131 * and kicking out stuff */
1132 if (klass->flush && dec->priv->samples_out > 0)
1133 klass->flush (dec, hard);
1134 /* and get (re)set for the sequel */
1135 gst_audio_decoder_reset (dec, FALSE);
1140 static GstFlowReturn
1141 gst_audio_decoder_chain_forward (GstAudioDecoder * dec, GstBuffer * buffer)
1143 GstFlowReturn ret = GST_FLOW_OK;
1145 /* discard silly case, though maybe ts may be of value ?? */
1146 if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) == 0)) {
1147 GST_DEBUG_OBJECT (dec, "discarding empty buffer");
1148 gst_buffer_unref (buffer);
1153 gst_adapter_push (dec->priv->adapter, buffer);
1155 /* new stuff, so we can push subclass again */
1156 dec->priv->drained = FALSE;
1158 /* hand to subclass */
1159 ret = gst_audio_decoder_push_buffers (dec, FALSE);
1162 GST_LOG_OBJECT (dec, "chain-done");
1167 gst_audio_decoder_clear_queues (GstAudioDecoder * dec)
1169 GstAudioDecoderPrivate *priv = dec->priv;
1171 g_list_foreach (priv->queued, (GFunc) gst_mini_object_unref, NULL);
1172 g_list_free (priv->queued);
1173 priv->queued = NULL;
1174 g_list_foreach (priv->gather, (GFunc) gst_mini_object_unref, NULL);
1175 g_list_free (priv->gather);
1176 priv->gather = NULL;
1177 g_list_foreach (priv->decode, (GFunc) gst_mini_object_unref, NULL);
1178 g_list_free (priv->decode);
1179 priv->decode = NULL;
1184 * Buffer decoding order: 7 8 9 4 5 6 3 1 2 EOS
1185 * Discont flag: D D D D
1187 * - Each Discont marks a discont in the decoding order.
1189 * for vorbis, each buffer is a keyframe when we have the previous
1190 * buffer. This means that to decode buffer 7, we need buffer 6, which
1191 * arrives out of order.
1193 * we first gather buffers in the gather queue until we get a DISCONT. We
1194 * prepend each incomming buffer so that they are in reversed order.
1196 * gather queue: 9 8 7
1200 * When a DISCONT is received (buffer 4), we move the gather queue to the
1201 * decode queue. This is simply done be taking the head of the gather queue
1202 * and prepending it to the decode queue. This yields:
1205 * decode queue: 7 8 9
1208 * Then we decode each buffer in the decode queue in order and put the output
1209 * buffer in the output queue. The first buffer (7) will not produce any output
1210 * because it needs the previous buffer (6) which did not arrive yet. This
1214 * decode queue: 7 8 9
1217 * Then we remove the consumed buffers from the decode queue. Buffer 7 is not
1218 * completely consumed, we need to keep it around for when we receive buffer
1225 * Then we accumulate more buffers:
1227 * gather queue: 6 5 4
1231 * prepending to the decode queue on DISCONT yields:
1234 * decode queue: 4 5 6 7
1237 * after decoding and keeping buffer 4:
1241 * output queue: 7 6 5
1245 static GstFlowReturn
1246 gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
1248 GstAudioDecoderPrivate *priv = dec->priv;
1249 GstFlowReturn res = GST_FLOW_OK;
1250 GstClockTime timestamp;
1253 walk = priv->decode;
1255 GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");
1257 /* clear buffer and decoder state */
1258 gst_audio_decoder_flush (dec, FALSE);
1262 GstBuffer *buf = GST_BUFFER_CAST (walk->data);
1264 GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1265 buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1267 next = g_list_next (walk);
1268 /* decode buffer, resulting data prepended to output queue */
1269 gst_buffer_ref (buf);
1270 res = gst_audio_decoder_chain_forward (dec, buf);
1272 /* if we generated output, we can discard the buffer, else we
1273 * keep it in the queue */
1275 GST_DEBUG_OBJECT (dec, "decoded buffer to %p", priv->queued->data);
1276 priv->decode = g_list_delete_link (priv->decode, walk);
1277 gst_buffer_unref (buf);
1279 GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
1284 /* drain any aggregation (or otherwise) leftover */
1285 gst_audio_decoder_drain (dec);
1287 /* now send queued data downstream */
1288 timestamp = GST_CLOCK_TIME_NONE;
1289 while (priv->queued) {
1290 GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
1292 /* duration should always be valid for raw audio */
1293 g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
1295 /* interpolate (backward) if needed */
1296 if (G_LIKELY (timestamp != -1))
1297 timestamp -= GST_BUFFER_DURATION (buf);
1299 if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1300 GST_LOG_OBJECT (dec, "applying reverse interpolated ts %"
1301 GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
1302 GST_BUFFER_TIMESTAMP (buf) = timestamp;
1304 /* track otherwise */
1305 timestamp = GST_BUFFER_TIMESTAMP (buf);
1306 GST_LOG_OBJECT (dec, "tracking ts %" GST_TIME_FORMAT,
1307 GST_TIME_ARGS (timestamp));
1310 if (G_LIKELY (res == GST_FLOW_OK)) {
1311 GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, "
1312 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1313 GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1314 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1315 /* should be already, but let's be sure */
1316 buf = gst_buffer_make_metadata_writable (buf);
1317 /* avoid stray DISCONT from forward processing,
1318 * which have no meaning in reverse pushing */
1319 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
1320 res = gst_audio_decoder_push_forward (dec, buf);
1322 gst_buffer_unref (buf);
1325 priv->queued = g_list_delete_link (priv->queued, priv->queued);
1331 static GstFlowReturn
1332 gst_audio_decoder_chain_reverse (GstAudioDecoder * dec, GstBuffer * buf)
1334 GstAudioDecoderPrivate *priv = dec->priv;
1335 GstFlowReturn result = GST_FLOW_OK;
1337 /* if we have a discont, move buffers to the decode list */
1338 if (!buf || GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1339 GST_DEBUG_OBJECT (dec, "received discont");
1340 while (priv->gather) {
1343 gbuf = GST_BUFFER_CAST (priv->gather->data);
1344 /* remove from the gather list */
1345 priv->gather = g_list_delete_link (priv->gather, priv->gather);
1346 /* copy to decode queue */
1347 priv->decode = g_list_prepend (priv->decode, gbuf);
1349 /* decode stuff in the decode queue */
1350 gst_audio_decoder_flush_decode (dec);
1353 if (G_LIKELY (buf)) {
1354 GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, "
1355 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1356 GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1357 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1359 /* add buffer to gather queue */
1360 priv->gather = g_list_prepend (priv->gather, buf);
1366 static GstFlowReturn
1367 gst_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
1369 GstAudioDecoder *dec;
1372 dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
1374 if (G_UNLIKELY (!GST_PAD_CAPS (pad) && dec->priv->needs_format))
1375 goto not_negotiated;
1377 GST_LOG_OBJECT (dec,
1378 "received buffer of size %d with ts %" GST_TIME_FORMAT
1379 ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
1380 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1381 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1383 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1385 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
1388 /* track present position */
1389 ts = dec->priv->base_ts;
1390 samples = dec->priv->samples;
1392 GST_DEBUG_OBJECT (dec, "handling discont");
1393 gst_audio_decoder_flush (dec, FALSE);
1394 dec->priv->discont = TRUE;
1396 /* buffer may claim DISCONT loudly, if it can't tell us where we are now,
1397 * we'll stick to where we were ...
1398 * Particularly useful/needed for upstream BYTE based */
1399 if (dec->segment.rate > 0.0 && !GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
1400 GST_DEBUG_OBJECT (dec, "... but restoring previous ts tracking");
1401 dec->priv->base_ts = ts;
1402 dec->priv->samples = samples;
1406 if (dec->segment.rate > 0.0)
1407 ret = gst_audio_decoder_chain_forward (dec, buffer);
1409 ret = gst_audio_decoder_chain_reverse (dec, buffer);
1411 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1418 GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
1419 ("decoder not initialized"));
1420 gst_buffer_unref (buffer);
1421 return GST_FLOW_NOT_NEGOTIATED;
1425 /* perform upstream byte <-> time conversion (duration, seeking)
1426 * if subclass allows and if enough data for moderately decent conversion */
1427 static inline gboolean
1428 gst_audio_decoder_do_byte (GstAudioDecoder * dec)
1430 return dec->priv->ctx.do_byte_time && dec->priv->ctx.info.bpf &&
1431 dec->priv->ctx.info.rate <= dec->priv->samples_out;
1435 gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
1437 gboolean handled = FALSE;
1439 switch (GST_EVENT_TYPE (event)) {
1440 case GST_EVENT_NEWSEGMENT:
1443 gdouble rate, arate;
1444 gint64 start, stop, time;
1447 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1448 gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
1449 &start, &stop, &time);
1451 if (format == GST_FORMAT_TIME) {
1452 GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
1453 " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
1454 ", rate %g, applied_rate %g",
1455 GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
1458 GstFormat dformat = GST_FORMAT_TIME;
1460 GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT
1461 " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
1462 ", rate %g, applied_rate %g", start, stop, time, rate, arate);
1463 /* handle newsegment resulting from legacy simple seeking */
1464 /* note that we need to convert this whether or not enough data
1465 * to handle initial newsegment */
1466 if (dec->priv->ctx.do_byte_time &&
1467 gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, start,
1468 &dformat, &start)) {
1469 /* best attempt convert */
1470 /* as these are only estimates, stop is kept open-ended to avoid
1471 * premature cutting */
1472 GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
1473 GST_TIME_ARGS (start));
1474 format = GST_FORMAT_TIME;
1476 stop = GST_CLOCK_TIME_NONE;
1478 gst_event_unref (event);
1479 event = gst_event_new_new_segment_full (update, rate, arate,
1480 GST_FORMAT_TIME, start, stop, time);
1482 GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
1483 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1488 /* finish current segment */
1489 gst_audio_decoder_drain (dec);
1492 /* time progressed without data, see if we can fill the gap with
1493 * some concealment data */
1494 GST_DEBUG_OBJECT (dec,
1495 "segment update: plc %d, do_plc %d, last_stop %" GST_TIME_FORMAT,
1496 dec->priv->plc, dec->priv->ctx.do_plc,
1497 GST_TIME_ARGS (dec->segment.last_stop));
1498 if (dec->priv->plc && dec->priv->ctx.do_plc &&
1499 dec->segment.rate > 0.0 && dec->segment.last_stop < start) {
1500 GstAudioDecoderClass *klass;
1503 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1504 /* hand subclass empty frame with duration that needs covering */
1505 buf = gst_buffer_new ();
1506 GST_BUFFER_DURATION (buf) = start - dec->segment.last_stop;
1507 /* best effort, not much error handling */
1508 gst_audio_decoder_handle_frame (dec, klass, buf);
1511 /* prepare for next one */
1512 gst_audio_decoder_flush (dec, FALSE);
1513 /* and that's where we time from,
1514 * in case upstream does not come up with anything better
1515 * (e.g. upstream BYTE) */
1516 if (format != GST_FORMAT_TIME) {
1517 dec->priv->base_ts = start;
1518 dec->priv->samples = 0;
1522 /* and follow along with segment */
1523 gst_segment_set_newsegment_full (&dec->segment, update, rate, arate,
1524 format, start, stop, time);
1526 dec->priv->pending_events =
1527 g_list_append (dec->priv->pending_events, event);
1529 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1533 case GST_EVENT_FLUSH_START:
1536 case GST_EVENT_FLUSH_STOP:
1537 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1538 /* prepare for fresh start */
1539 gst_audio_decoder_flush (dec, TRUE);
1541 g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL);
1542 g_list_free (dec->priv->pending_events);
1543 dec->priv->pending_events = NULL;
1544 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1548 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1549 gst_audio_decoder_drain (dec);
1550 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1561 gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event)
1563 GstAudioDecoder *dec;
1564 GstAudioDecoderClass *klass;
1565 gboolean handled = FALSE;
1566 gboolean ret = TRUE;
1568 dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
1569 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
1571 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1572 GST_EVENT_TYPE_NAME (event));
1575 handled = klass->event (dec, event);
1578 handled = gst_audio_decoder_sink_eventfunc (dec, event);
1581 /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1582 * For EOS this is required because no buffer or serialized event
1583 * will come after EOS and nothing could trigger another
1584 * _finish_frame() call.
1586 * For FLUSH_STOP this is required because it is expected
1587 * to be forwarded immediately and no buffers are queued anyway.
1589 if (!GST_EVENT_IS_SERIALIZED (event)
1590 || GST_EVENT_TYPE (event) == GST_EVENT_EOS
1591 || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1592 ret = gst_pad_event_default (pad, event);
1594 GST_AUDIO_DECODER_STREAM_LOCK (dec);
1595 dec->priv->pending_events =
1596 g_list_append (dec->priv->pending_events, event);
1597 GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
1602 GST_DEBUG_OBJECT (dec, "event handled");
1604 gst_object_unref (dec);
1609 gst_audio_decoder_do_seek (GstAudioDecoder * dec, GstEvent * event)
1612 GstSeekType start_type, end_type;
1615 gint64 start, start_time, end_time;
1616 GstSegment seek_segment;
1619 gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
1620 &start_time, &end_type, &end_time);
1622 /* we'll handle plain open-ended flushing seeks with the simple approach */
1624 GST_DEBUG_OBJECT (dec, "unsupported seek: rate");
1628 if (start_type != GST_SEEK_TYPE_SET) {
1629 GST_DEBUG_OBJECT (dec, "unsupported seek: start time");
1633 if (end_type != GST_SEEK_TYPE_NONE ||
1634 (end_type == GST_SEEK_TYPE_SET && end_time != GST_CLOCK_TIME_NONE)) {
1635 GST_DEBUG_OBJECT (dec, "unsupported seek: end time");
1639 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1640 GST_DEBUG_OBJECT (dec, "unsupported seek: not flushing");
1644 memcpy (&seek_segment, &dec->segment, sizeof (seek_segment));
1645 gst_segment_set_seek (&seek_segment, rate, format, flags, start_type,
1646 start_time, end_type, end_time, NULL);
1647 start_time = seek_segment.last_stop;
1649 format = GST_FORMAT_BYTES;
1650 if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
1652 GST_DEBUG_OBJECT (dec, "conversion failed");
1656 seqnum = gst_event_get_seqnum (event);
1657 event = gst_event_new_seek (1.0, GST_FORMAT_BYTES, flags,
1658 GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE, -1);
1659 gst_event_set_seqnum (event, seqnum);
1661 GST_DEBUG_OBJECT (dec, "seeking to %" GST_TIME_FORMAT " at byte offset %"
1662 G_GINT64_FORMAT, GST_TIME_ARGS (start_time), start);
1664 return gst_pad_push_event (dec->sinkpad, event);
1668 gst_audio_decoder_src_event (GstPad * pad, GstEvent * event)
1670 GstAudioDecoder *dec;
1671 gboolean res = FALSE;
1673 dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
1674 if (G_UNLIKELY (dec == NULL)) {
1675 gst_event_unref (event);
1679 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1680 GST_EVENT_TYPE_NAME (event));
1682 switch (GST_EVENT_TYPE (event)) {
1683 case GST_EVENT_SEEK:
1685 GstFormat format, tformat;
1688 GstSeekType cur_type, stop_type;
1693 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1695 seqnum = gst_event_get_seqnum (event);
1697 /* upstream gets a chance first */
1698 if ((res = gst_pad_push_event (dec->sinkpad, event)))
1701 /* if upstream fails for a time seek, maybe we can help if allowed */
1702 if (format == GST_FORMAT_TIME) {
1703 if (gst_audio_decoder_do_byte (dec))
1704 res = gst_audio_decoder_do_seek (dec, event);
1708 /* ... though a non-time seek can be aided as well */
1709 /* First bring the requested format to time */
1710 tformat = GST_FORMAT_TIME;
1711 if (!(res = gst_pad_query_convert (pad, format, cur, &tformat, &tcur)))
1713 if (!(res = gst_pad_query_convert (pad, format, stop, &tformat, &tstop)))
1716 /* then seek with time on the peer */
1717 event = gst_event_new_seek (rate, GST_FORMAT_TIME,
1718 flags, cur_type, tcur, stop_type, tstop);
1719 gst_event_set_seqnum (event, seqnum);
1721 res = gst_pad_push_event (dec->sinkpad, event);
1725 res = gst_pad_push_event (dec->sinkpad, event);
1729 gst_object_unref (dec);
1736 GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
1742 * gst_audio_encoded_audio_convert:
1743 * @fmt: audio format of the encoded audio
1744 * @bytes: number of encoded bytes
1745 * @samples: number of encoded samples
1746 * @src_format: source format
1747 * @src_value: source value
1748 * @dest_format: destination format
1749 * @dest_value: destination format
1751 * Helper function to convert @src_value in @src_format to @dest_value in
1752 * @dest_format for encoded audio data. Conversion is possible between
1753 * BYTE and TIME format by using estimated bitrate based on
1754 * @samples and @bytes (and @fmt).
1756 /* FIXME: make gst_audio_encoded_audio_convert() public? */
1758 gst_audio_encoded_audio_convert (GstAudioInfo * fmt,
1759 gint64 bytes, gint64 samples, GstFormat src_format,
1760 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1762 gboolean res = FALSE;
1764 g_return_val_if_fail (dest_format != NULL, FALSE);
1765 g_return_val_if_fail (dest_value != NULL, FALSE);
1767 if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
1770 *dest_value = src_value;
1774 if (samples == 0 || bytes == 0 || fmt->rate == 0) {
1775 GST_DEBUG ("not enough metadata yet to convert");
1781 switch (src_format) {
1782 case GST_FORMAT_BYTES:
1783 switch (*dest_format) {
1784 case GST_FORMAT_TIME:
1785 *dest_value = gst_util_uint64_scale (src_value,
1786 GST_SECOND * samples, bytes);
1793 case GST_FORMAT_TIME:
1794 switch (*dest_format) {
1795 case GST_FORMAT_BYTES:
1796 *dest_value = gst_util_uint64_scale (src_value, bytes,
1797 samples * GST_SECOND);
1813 gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query)
1815 gboolean res = TRUE;
1816 GstAudioDecoder *dec;
1818 dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
1820 switch (GST_QUERY_TYPE (query)) {
1821 case GST_QUERY_FORMATS:
1823 gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
1827 case GST_QUERY_CONVERT:
1829 GstFormat src_fmt, dest_fmt;
1830 gint64 src_val, dest_val;
1832 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1833 if (!(res = gst_audio_encoded_audio_convert (&dec->priv->ctx.info,
1834 dec->priv->bytes_in, dec->priv->samples_out,
1835 src_fmt, src_val, &dest_fmt, &dest_val)))
1837 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1841 res = gst_pad_query_default (pad, query);
1846 gst_object_unref (dec);
1850 static const GstQueryType *
1851 gst_audio_decoder_get_query_types (GstPad * pad)
1853 static const GstQueryType gst_audio_decoder_src_query_types[] = {
1861 return gst_audio_decoder_src_query_types;
1864 /* FIXME ? are any of these queries (other than latency) a decoder's business ??
1865 * also, the conversion stuff might seem to make sense, but seems to not mind
1866 * segment stuff etc at all
1867 * Supposedly that's backward compatibility ... */
1869 gst_audio_decoder_src_query (GstPad * pad, GstQuery * query)
1871 GstAudioDecoder *dec;
1873 gboolean res = FALSE;
1875 dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
1876 if (G_UNLIKELY (dec == NULL))
1879 peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad));
1881 GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
1883 switch (GST_QUERY_TYPE (query)) {
1884 case GST_QUERY_DURATION:
1888 /* upstream in any case */
1889 if ((res = gst_pad_query_default (pad, query)))
1892 gst_query_parse_duration (query, &format, NULL);
1893 /* try answering TIME by converting from BYTE if subclass allows */
1894 if (format == GST_FORMAT_TIME && gst_audio_decoder_do_byte (dec)) {
1897 format = GST_FORMAT_BYTES;
1898 if (gst_pad_query_peer_duration (dec->sinkpad, &format, &value)) {
1899 GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
1900 format = GST_FORMAT_TIME;
1901 if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
1903 gst_query_set_duration (query, GST_FORMAT_TIME, value);
1910 case GST_QUERY_POSITION:
1915 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1916 GST_LOG_OBJECT (dec, "returning peer response");
1920 /* we start from the last seen time */
1921 time = dec->segment.last_stop;
1922 /* correct for the segment values */
1923 time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
1925 GST_LOG_OBJECT (dec,
1926 "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
1928 /* and convert to the final format */
1929 gst_query_parse_position (query, &format, NULL);
1930 if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
1934 gst_query_set_position (query, format, value);
1936 GST_LOG_OBJECT (dec,
1937 "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
1941 case GST_QUERY_FORMATS:
1943 gst_query_set_formats (query, 3,
1944 GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
1948 case GST_QUERY_CONVERT:
1950 GstFormat src_fmt, dest_fmt;
1951 gint64 src_val, dest_val;
1953 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1954 if (!(res = gst_audio_info_convert (&dec->priv->ctx.info,
1955 src_fmt, src_val, dest_fmt, &dest_val)))
1957 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1960 case GST_QUERY_LATENCY:
1962 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1964 GstClockTime min_latency, max_latency;
1966 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1967 GST_DEBUG_OBJECT (dec, "Peer latency: live %d, min %"
1968 GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1969 GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1971 GST_OBJECT_LOCK (dec);
1972 /* add our latency */
1973 if (min_latency != -1)
1974 min_latency += dec->priv->ctx.min_latency;
1975 if (max_latency != -1)
1976 max_latency += dec->priv->ctx.max_latency;
1977 GST_OBJECT_UNLOCK (dec);
1979 gst_query_set_latency (query, live, min_latency, max_latency);
1984 res = gst_pad_query_default (pad, query);
1988 gst_object_unref (peerpad);
1993 gst_audio_decoder_stop (GstAudioDecoder * dec)
1995 GstAudioDecoderClass *klass;
1996 gboolean ret = TRUE;
1998 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_stop");
2000 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
2003 ret = klass->stop (dec);
2007 gst_audio_decoder_reset (dec, TRUE);
2010 dec->priv->active = FALSE;
2016 gst_audio_decoder_start (GstAudioDecoder * dec)
2018 GstAudioDecoderClass *klass;
2019 gboolean ret = TRUE;
2021 GST_DEBUG_OBJECT (dec, "gst_audio_decoder_start");
2023 klass = GST_AUDIO_DECODER_GET_CLASS (dec);
2025 /* arrange clean state */
2026 gst_audio_decoder_reset (dec, TRUE);
2029 ret = klass->start (dec);
2033 dec->priv->active = TRUE;
2039 gst_audio_decoder_get_property (GObject * object, guint prop_id,
2040 GValue * value, GParamSpec * pspec)
2042 GstAudioDecoder *dec;
2044 dec = GST_AUDIO_DECODER (object);
2048 g_value_set_int64 (value, dec->priv->latency);
2050 case PROP_TOLERANCE:
2051 g_value_set_int64 (value, dec->priv->tolerance);
2054 g_value_set_boolean (value, dec->priv->plc);
2057 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2063 gst_audio_decoder_set_property (GObject * object, guint prop_id,
2064 const GValue * value, GParamSpec * pspec)
2066 GstAudioDecoder *dec;
2068 dec = GST_AUDIO_DECODER (object);
2072 dec->priv->latency = g_value_get_int64 (value);
2074 case PROP_TOLERANCE:
2075 dec->priv->tolerance = g_value_get_int64 (value);
2078 dec->priv->plc = g_value_get_boolean (value);
2081 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2086 static GstStateChangeReturn
2087 gst_audio_decoder_change_state (GstElement * element, GstStateChange transition)
2089 GstAudioDecoder *codec;
2090 GstStateChangeReturn ret;
2092 codec = GST_AUDIO_DECODER (element);
2094 switch (transition) {
2095 case GST_STATE_CHANGE_NULL_TO_READY:
2097 case GST_STATE_CHANGE_READY_TO_PAUSED:
2098 if (!gst_audio_decoder_start (codec)) {
2102 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2108 ret = parent_class->change_state (element, transition);
2110 switch (transition) {
2111 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2113 case GST_STATE_CHANGE_PAUSED_TO_READY:
2114 if (!gst_audio_decoder_stop (codec)) {
2118 case GST_STATE_CHANGE_READY_TO_NULL:
2128 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to start codec"));
2129 return GST_STATE_CHANGE_FAILURE;
2133 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
2134 return GST_STATE_CHANGE_FAILURE;
2139 _gst_audio_decoder_error (GstAudioDecoder * dec, gint weight,
2140 GQuark domain, gint code, gchar * txt, gchar * dbg, const gchar * file,
2141 const gchar * function, gint line)
2144 GST_WARNING_OBJECT (dec, "error: %s", txt);
2146 GST_WARNING_OBJECT (dec, "error: %s", dbg);
2147 dec->priv->error_count += weight;
2148 dec->priv->discont = TRUE;
2149 if (dec->priv->ctx.max_errors < dec->priv->error_count) {
2150 gst_element_message_full (GST_ELEMENT (dec), GST_MESSAGE_ERROR,
2151 domain, code, txt, dbg, file, function, line);
2152 return GST_FLOW_ERROR;
2159 * gst_audio_decoder_get_audio_info:
2160 * @dec: a #GstAudioDecoder
2162 * Returns: a #GstAudioInfo describing the input audio format
2167 gst_audio_decoder_get_audio_info (GstAudioDecoder * dec)
2169 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), NULL);
2171 return &dec->priv->ctx.info;
2175 * gst_audio_decoder_set_plc_aware:
2176 * @dec: a #GstAudioDecoder
2177 * @plc: new plc state
2179 * Indicates whether or not subclass handles packet loss concealment (plc).
2184 gst_audio_decoder_set_plc_aware (GstAudioDecoder * dec, gboolean plc)
2186 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2188 dec->priv->ctx.do_plc = plc;
2192 * gst_audio_decoder_get_plc_aware:
2193 * @dec: a #GstAudioDecoder
2195 * Returns: currently configured plc handling
2200 gst_audio_decoder_get_plc_aware (GstAudioDecoder * dec)
2202 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2204 return dec->priv->ctx.do_plc;
2208 * gst_audio_decoder_set_byte_time:
2209 * @dec: a #GstAudioDecoder
2210 * @enabled: whether to enable byte to time conversion
2212 * Allows baseclass to perform byte to time estimated conversion.
2217 gst_audio_decoder_set_byte_time (GstAudioDecoder * dec, gboolean enabled)
2219 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2221 dec->priv->ctx.do_byte_time = enabled;
2225 * gst_audio_decoder_get_byte_time:
2226 * @dec: a #GstAudioDecoder
2228 * Returns: currently configured byte to time conversion setting
2233 gst_audio_decoder_get_byte_time (GstAudioDecoder * dec)
2235 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2237 return dec->priv->ctx.do_byte_time;
2241 * gst_audio_decoder_get_delay:
2242 * @dec: a #GstAudioDecoder
2244 * Returns: currently configured decoder delay
2249 gst_audio_decoder_get_delay (GstAudioDecoder * dec)
2251 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2253 return dec->priv->ctx.delay;
2257 * gst_audio_decoder_set_max_errors:
2258 * @dec: a #GstAudioDecoder
2259 * @num: max tolerated errors
2261 * Sets numbers of tolerated decoder errors, where a tolerated one is then only
2262 * warned about, but more than tolerated will lead to fatal error. Default
2263 * is set to GST_AUDIO_DECODER_MAX_ERRORS.
2268 gst_audio_decoder_set_max_errors (GstAudioDecoder * dec, gint num)
2270 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2272 dec->priv->ctx.max_errors = num;
2276 * gst_audio_decoder_get_max_errors:
2277 * @dec: a #GstAudioDecoder
2279 * Returns: currently configured decoder tolerated error count.
2284 gst_audio_decoder_get_max_errors (GstAudioDecoder * dec)
2286 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2288 return dec->priv->ctx.max_errors;
2292 * gst_audio_decoder_set_latency:
2293 * @dec: a #GstAudioDecoder
2294 * @min: minimum latency
2295 * @max: maximum latency
2297 * Sets decoder latency.
2302 gst_audio_decoder_set_latency (GstAudioDecoder * dec,
2303 GstClockTime min, GstClockTime max)
2305 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2307 GST_OBJECT_LOCK (dec);
2308 dec->priv->ctx.min_latency = min;
2309 dec->priv->ctx.max_latency = max;
2310 GST_OBJECT_UNLOCK (dec);
2314 * gst_audio_decoder_get_latency:
2315 * @dec: a #GstAudioDecoder
2316 * @min: (out) (allow-none): a pointer to storage to hold minimum latency
2317 * @max: (out) (allow-none): a pointer to storage to hold maximum latency
2319 * Sets the variables pointed to by @min and @max to the currently configured
2325 gst_audio_decoder_get_latency (GstAudioDecoder * dec,
2326 GstClockTime * min, GstClockTime * max)
2328 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2330 GST_OBJECT_LOCK (dec);
2332 *min = dec->priv->ctx.min_latency;
2334 *max = dec->priv->ctx.max_latency;
2335 GST_OBJECT_UNLOCK (dec);
2339 * gst_audio_decoder_get_parse_state:
2340 * @dec: a #GstAudioDecoder
2341 * @sync: a pointer to a variable to hold the current sync state
2342 * @eos: a pointer to a variable to hold the current eos state
2344 * Return current parsing (sync and eos) state.
2349 gst_audio_decoder_get_parse_state (GstAudioDecoder * dec,
2350 gboolean * sync, gboolean * eos)
2352 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2355 *sync = dec->priv->ctx.sync;
2357 *eos = dec->priv->ctx.eos;
2361 * gst_audio_decoder_set_plc:
2362 * @dec: a #GstAudioDecoder
2363 * @enabled: new state
2365 * Enable or disable decoder packet loss concealment, provided subclass
2366 * and codec are capable and allow handling plc.
2373 gst_audio_decoder_set_plc (GstAudioDecoder * dec, gboolean enabled)
2375 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2377 GST_LOG_OBJECT (dec, "enabled: %d", enabled);
2379 GST_OBJECT_LOCK (dec);
2380 dec->priv->plc = enabled;
2381 GST_OBJECT_UNLOCK (dec);
2385 * gst_audio_decoder_get_plc:
2386 * @dec: a #GstAudioDecoder
2388 * Queries decoder packet loss concealment handling.
2390 * Returns: TRUE if packet loss concealment is enabled.
2397 gst_audio_decoder_get_plc (GstAudioDecoder * dec)
2401 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
2403 GST_OBJECT_LOCK (dec);
2404 result = dec->priv->plc;
2405 GST_OBJECT_UNLOCK (dec);
2411 * gst_audio_decoder_set_min_latency:
2412 * @dec: a #GstAudioDecoder
2413 * @num: new minimum latency
2415 * Sets decoder minimum aggregation latency.
2422 gst_audio_decoder_set_min_latency (GstAudioDecoder * dec, gint64 num)
2424 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2426 GST_OBJECT_LOCK (dec);
2427 dec->priv->latency = num;
2428 GST_OBJECT_UNLOCK (dec);
2432 * gst_audio_decoder_get_min_latency:
2433 * @dec: a #GstAudioDecoder
2435 * Queries decoder's latency aggregation.
2437 * Returns: aggregation latency.
2444 gst_audio_decoder_get_min_latency (GstAudioDecoder * dec)
2448 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
2450 GST_OBJECT_LOCK (dec);
2451 result = dec->priv->latency;
2452 GST_OBJECT_UNLOCK (dec);
2458 * gst_audio_decoder_set_tolerance:
2459 * @dec: a #GstAudioDecoder
2460 * @tolerance: new tolerance
2462 * Configures decoder audio jitter tolerance threshold.
2469 gst_audio_decoder_set_tolerance (GstAudioDecoder * dec, gint64 tolerance)
2471 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2473 GST_OBJECT_LOCK (dec);
2474 dec->priv->tolerance = tolerance;
2475 GST_OBJECT_UNLOCK (dec);
2479 * gst_audio_decoder_get_tolerance:
2480 * @dec: a #GstAudioDecoder
2482 * Queries current audio jitter tolerance threshold.
2484 * Returns: decoder audio jitter tolerance threshold.
2491 gst_audio_decoder_get_tolerance (GstAudioDecoder * dec)
2495 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2497 GST_OBJECT_LOCK (dec);
2498 result = dec->priv->tolerance;
2499 GST_OBJECT_UNLOCK (dec);
2505 * gst_audio_decoder_set_drainable:
2506 * @dec: a #GstAudioDecoder
2507 * @enabled: new state
2509 * Configures decoder drain handling. If drainable, subclass might
2510 * be handed a NULL buffer to have it return any leftover decoded data.
2511 * Otherwise, it is not considered so capable and will only ever be passed
2519 gst_audio_decoder_set_drainable (GstAudioDecoder * dec, gboolean enabled)
2521 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2523 GST_OBJECT_LOCK (dec);
2524 dec->priv->drainable = enabled;
2525 GST_OBJECT_UNLOCK (dec);
2529 * gst_audio_decoder_get_drainable:
2530 * @dec: a #GstAudioDecoder
2532 * Queries decoder drain handling.
2534 * Returns: TRUE if drainable handling is enabled.
2541 gst_audio_decoder_get_drainable (GstAudioDecoder * dec)
2545 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2547 GST_OBJECT_LOCK (dec);
2548 result = dec->priv->drainable;
2549 GST_OBJECT_UNLOCK (dec);
2555 * gst_audio_decoder_set_needs_format:
2556 * @dec: a #GstAudioDecoder
2557 * @enabled: new state
2559 * Configures decoder format needs. If enabled, subclass needs to be
2560 * negotiated with format caps before it can process any data. It will then
2561 * never be handed any data before it has been configured.
2562 * Otherwise, it might be handed data without having been configured and
2563 * is then expected being able to do so either by default
2564 * or based on the input data.
2571 gst_audio_decoder_set_needs_format (GstAudioDecoder * dec, gboolean enabled)
2573 g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
2575 GST_OBJECT_LOCK (dec);
2576 dec->priv->needs_format = enabled;
2577 GST_OBJECT_UNLOCK (dec);
2581 * gst_audio_decoder_get_needs_format:
2582 * @dec: a #GstAudioDecoder
2584 * Queries decoder required format handling.
2586 * Returns: TRUE if required format handling is enabled.
2593 gst_audio_decoder_get_needs_format (GstAudioDecoder * dec)
2597 g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), 0);
2599 GST_OBJECT_LOCK (dec);
2600 result = dec->priv->needs_format;
2601 GST_OBJECT_UNLOCK (dec);