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:gstbaseaudiodecoder
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 * GstBaseAudioDecoder and subclass should cooperate as follows.
36 * <itemizedlist><title>Configuration</title>
38 * Initially, GstBaseAudioDecoder 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 * GstBaseAudioDecoder 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 * GstBaseAudioDecoder calls @stop at end of all processing.
55 * As of configuration stage, and throughout processing, GstBaseAudioDecoder
56 * provides various (context) parameters, e.g. describing the format of
57 * output audio data (valid when output caps have been caps) 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_base_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 GstBaseAudioDecoderClass 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 * GstBaseAudioDecoder 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_base_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 #GstBaseAudioDecoder: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_base_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 "gstbaseaudiodecoder.h"
153 #include <gst/pbutils/descriptions.h>
157 GST_DEBUG_CATEGORY (baseaudiodecoder_debug);
158 #define GST_CAT_DEFAULT baseaudiodecoder_debug
160 #define GST_BASE_AUDIO_DECODER_GET_PRIVATE(obj) \
161 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_AUDIO_DECODER, \
162 GstBaseAudioDecoderPrivate))
177 #define DEFAULT_LATENCY 0
178 #define DEFAULT_TOLERANCE 0
179 #define DEFAULT_PLC FALSE
181 typedef struct _GstBaseAudioDecoderContext
184 /* (output) audio format */
196 gboolean do_byte_time;
198 /* MT-protected (with LOCK) */
199 GstClockTime min_latency;
200 GstClockTime max_latency;
201 } GstBaseAudioDecoderContext;
203 struct _GstBaseAudioDecoderPrivate
205 /* activation status */
208 /* input base/first ts as basis for output ts */
209 GstClockTime base_ts;
210 /* input samples processed and sent downstream so far (w.r.t. base_ts) */
213 /* collected input data */
215 /* tracking input ts for changes */
216 GstClockTime prev_ts;
217 /* frames obtained from input */
219 /* collected output data */
220 GstAdapter *adapter_out;
221 /* ts and duration for output data collected above */
222 GstClockTime out_ts, out_dur;
223 /* mark outgoing discont */
226 /* subclass gave all it could already */
228 /* subclass currently being forcibly drained */
231 /* input bps estimatation */
232 /* global in bytes seen */
234 /* global samples sent out */
236 /* bytes flushed during parsing */
243 /* whether circumstances allow output aggregation */
246 /* reverse playback queues */
251 /* reversed output */
254 /* context storage */
255 GstBaseAudioDecoderContext ctx;
258 GstClockTime latency;
259 GstClockTime tolerance;
265 static void gst_base_audio_decoder_finalize (GObject * object);
266 static void gst_base_audio_decoder_set_property (GObject * object,
267 guint prop_id, const GValue * value, GParamSpec * pspec);
268 static void gst_base_audio_decoder_get_property (GObject * object,
269 guint prop_id, GValue * value, GParamSpec * pspec);
271 static void gst_base_audio_decoder_clear_queues (GstBaseAudioDecoder * dec);
272 static GstFlowReturn gst_base_audio_decoder_chain_reverse (GstBaseAudioDecoder *
273 dec, GstBuffer * buf);
275 static GstStateChangeReturn gst_base_audio_decoder_change_state (GstElement *
276 element, GstStateChange transition);
277 static gboolean gst_base_audio_decoder_sink_event (GstPad * pad,
279 static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
281 static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad,
283 static gboolean gst_base_audio_decoder_src_query (GstPad * pad,
285 static gboolean gst_base_audio_decoder_sink_query (GstPad * pad,
287 static const GstQueryType *gst_base_audio_decoder_get_query_types (GstPad *
289 static void gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec,
292 #define gst_base_audio_decoder_parent_class parent_class
293 G_DEFINE_TYPE (GstBaseAudioDecoder, gst_base_audio_decoder, GST_TYPE_ELEMENT);
296 gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass)
298 GObjectClass *gobject_class;
299 GstElementClass *element_class;
301 gobject_class = G_OBJECT_CLASS (klass);
302 element_class = GST_ELEMENT_CLASS (klass);
304 parent_class = g_type_class_peek_parent (klass);
306 g_type_class_add_private (klass, sizeof (GstBaseAudioDecoderPrivate));
308 GST_DEBUG_CATEGORY_INIT (baseaudiodecoder_debug, "baseaudiodecoder", 0,
309 "baseaudiodecoder element");
311 gobject_class->set_property = gst_base_audio_decoder_set_property;
312 gobject_class->get_property = gst_base_audio_decoder_get_property;
313 gobject_class->finalize = gst_base_audio_decoder_finalize;
315 element_class->change_state = gst_base_audio_decoder_change_state;
318 g_object_class_install_property (gobject_class, PROP_LATENCY,
319 g_param_spec_int64 ("min-latency", "Minimum Latency",
320 "Aggregate output data to a minimum of latency time (ns)",
321 0, G_MAXINT64, DEFAULT_LATENCY,
322 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
324 g_object_class_install_property (gobject_class, PROP_TOLERANCE,
325 g_param_spec_int64 ("tolerance", "Tolerance",
326 "Perfect ts while timestamp jitter/imperfection within tolerance (ns)",
327 0, G_MAXINT64, DEFAULT_TOLERANCE,
328 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
330 g_object_class_install_property (gobject_class, PROP_PLC,
331 g_param_spec_boolean ("plc", "Packet Loss Concealment",
332 "Perform packet loss concealment (if supported)",
333 DEFAULT_PLC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
337 gst_base_audio_decoder_init (GstBaseAudioDecoder * dec)
339 GstBaseAudioDecoderClass *klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
340 GstPadTemplate *pad_template;
342 GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_init");
344 dec->priv = GST_BASE_AUDIO_DECODER_GET_PRIVATE (dec);
348 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
349 g_return_if_fail (pad_template != NULL);
351 dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
352 gst_pad_set_event_function (dec->sinkpad,
353 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_sink_event));
354 gst_pad_set_chain_function (dec->sinkpad,
355 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_chain));
356 gst_pad_set_query_function (dec->sinkpad,
357 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_sink_query));
358 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
359 GST_DEBUG_OBJECT (dec, "sinkpad created");
361 /* Setup source pad */
363 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
364 g_return_if_fail (pad_template != NULL);
366 dec->srcpad = gst_pad_new_from_template (pad_template, "src");
367 gst_pad_set_event_function (dec->srcpad,
368 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_src_event));
369 gst_pad_set_query_function (dec->srcpad,
370 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_src_query));
371 gst_pad_set_query_type_function (dec->srcpad,
372 GST_DEBUG_FUNCPTR (gst_base_audio_decoder_get_query_types));
373 gst_pad_use_fixed_caps (dec->srcpad);
374 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
375 GST_DEBUG_OBJECT (dec, "srcpad created");
377 dec->priv->adapter = gst_adapter_new ();
378 dec->priv->adapter_out = gst_adapter_new ();
379 g_queue_init (&dec->priv->frames);
381 /* property default */
382 dec->priv->latency = DEFAULT_LATENCY;
383 dec->priv->tolerance = DEFAULT_TOLERANCE;
384 dec->priv->plc = DEFAULT_PLC;
387 gst_base_audio_decoder_reset (dec, TRUE);
388 GST_DEBUG_OBJECT (dec, "init ok");
392 gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full)
394 GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_reset");
396 GST_OBJECT_LOCK (dec);
399 dec->priv->active = FALSE;
400 dec->priv->bytes_in = 0;
401 dec->priv->samples_out = 0;
403 dec->priv->error_count = 0;
404 gst_base_audio_decoder_clear_queues (dec);
406 gst_audio_info_init (&dec->priv->ctx.info);
407 memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
409 if (dec->priv->taglist) {
410 gst_tag_list_free (dec->priv->taglist);
411 dec->priv->taglist = NULL;
414 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
417 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
418 g_queue_clear (&dec->priv->frames);
419 gst_adapter_clear (dec->priv->adapter);
420 gst_adapter_clear (dec->priv->adapter_out);
421 dec->priv->out_ts = GST_CLOCK_TIME_NONE;
422 dec->priv->out_dur = 0;
423 dec->priv->prev_ts = GST_CLOCK_TIME_NONE;
424 dec->priv->drained = TRUE;
425 dec->priv->base_ts = GST_CLOCK_TIME_NONE;
426 dec->priv->samples = 0;
427 dec->priv->discont = TRUE;
428 dec->priv->sync_flush = FALSE;
430 GST_OBJECT_UNLOCK (dec);
434 gst_base_audio_decoder_finalize (GObject * object)
436 GstBaseAudioDecoder *dec;
438 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (object));
439 dec = GST_BASE_AUDIO_DECODER (object);
441 if (dec->priv->adapter) {
442 g_object_unref (dec->priv->adapter);
444 if (dec->priv->adapter_out) {
445 g_object_unref (dec->priv->adapter_out);
448 G_OBJECT_CLASS (parent_class)->finalize (object);
451 /* automagically perform sanity checking of src caps;
452 * also extracts output data format */
454 gst_base_audio_decoder_src_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
459 GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
461 /* parse caps here to check subclass;
462 * also makes us aware of output format */
463 if (!gst_caps_is_fixed (caps))
466 /* adjust ts tracking to new sample rate */
467 old_rate = GST_AUDIO_INFO_RATE (&dec->priv->ctx.info);
468 if (GST_CLOCK_TIME_IS_VALID (dec->priv->base_ts) && old_rate) {
469 dec->priv->base_ts +=
470 GST_FRAMES_TO_CLOCK_TIME (dec->priv->samples, old_rate);
471 dec->priv->samples = 0;
474 if (!gst_audio_info_from_caps (&dec->priv->ctx.info, caps))
477 gst_object_unref (dec);
483 GST_WARNING_OBJECT (dec, "rejected caps %" GST_PTR_FORMAT, caps);
484 gst_object_unref (dec);
490 gst_base_audio_decoder_sink_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
492 GstBaseAudioDecoderClass *klass;
495 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
497 GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
499 /* NOTE pbutils only needed here */
500 /* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
501 if (dec->priv->taglist)
502 gst_tag_list_free (dec->priv->taglist);
503 dec->priv->taglist = gst_tag_list_new ();
504 gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist,
505 GST_TAG_AUDIO_CODEC, caps);
507 if (klass->set_format)
508 res = klass->set_format (dec, caps);
514 gst_base_audio_decoder_setup (GstBaseAudioDecoder * dec)
519 /* check if in live pipeline, then latency messing is no-no */
520 query = gst_query_new_latency ();
521 res = gst_pad_peer_query (dec->sinkpad, query);
523 gst_query_parse_latency (query, &res, NULL, NULL);
526 gst_query_unref (query);
528 /* normalize to bool */
529 dec->priv->agg = !!res;
532 /* mini aggregator combining output buffers into fewer larger ones,
533 * if so allowed/configured */
535 gst_base_audio_decoder_output (GstBaseAudioDecoder * dec, GstBuffer * buf)
537 GstBaseAudioDecoderClass *klass;
538 GstBaseAudioDecoderPrivate *priv;
539 GstBaseAudioDecoderContext *ctx;
540 GstFlowReturn ret = GST_FLOW_OK;
541 GstBuffer *inbuf = NULL;
543 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
545 ctx = &dec->priv->ctx;
547 if (G_UNLIKELY (priv->agg < 0))
548 gst_base_audio_decoder_setup (dec);
550 if (G_LIKELY (buf)) {
551 g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
554 "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
555 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
556 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
557 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
560 buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
562 if (G_UNLIKELY (!buf)) {
563 GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
566 "buffer after segment clipping has size %" G_GSIZE_FORMAT " with ts %"
567 GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
568 gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
569 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
572 GST_DEBUG_OBJECT (dec, "no output buffer");
577 if (priv->agg && dec->priv->latency > 0) {
579 gboolean assemble = FALSE;
580 const GstClockTimeDiff tol = 10 * GST_MSECOND;
581 GstClockTimeDiff diff = -100 * GST_MSECOND;
583 av = gst_adapter_available (priv->adapter_out);
584 if (G_UNLIKELY (!buf)) {
585 /* forcibly send current */
587 GST_LOG_OBJECT (dec, "forcing fragment flush");
588 } else if (av && (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) ||
589 !GST_CLOCK_TIME_IS_VALID (priv->out_ts) ||
590 ((diff = GST_CLOCK_DIFF (GST_BUFFER_TIMESTAMP (buf),
591 priv->out_ts + priv->out_dur)) > tol) || diff < -tol)) {
593 GST_LOG_OBJECT (dec, "buffer %d ms apart from current fragment",
594 (gint) (diff / GST_MSECOND));
596 /* add or start collecting */
598 GST_LOG_OBJECT (dec, "starting new fragment");
599 priv->out_ts = GST_BUFFER_TIMESTAMP (buf);
601 GST_LOG_OBJECT (dec, "adding to fragment");
603 gst_adapter_push (priv->adapter_out, buf);
604 priv->out_dur += GST_BUFFER_DURATION (buf);
605 av += gst_buffer_get_size (buf);
608 if (priv->out_dur > dec->priv->latency)
610 if (av && assemble) {
611 GST_LOG_OBJECT (dec, "assembling fragment");
613 buf = gst_adapter_take_buffer (priv->adapter_out, av);
614 GST_BUFFER_TIMESTAMP (buf) = priv->out_ts;
615 GST_BUFFER_DURATION (buf) = priv->out_dur;
616 priv->out_ts = GST_CLOCK_TIME_NONE;
621 if (G_LIKELY (buf)) {
623 if (G_UNLIKELY (priv->discont)) {
624 GST_LOG_OBJECT (dec, "marking discont");
625 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
626 priv->discont = FALSE;
629 if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
630 /* duration should always be valid for raw audio */
631 g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
632 dec->segment.position =
633 GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
636 if (klass->pre_push) {
637 /* last chance for subclass to do some dirty stuff */
638 ret = klass->pre_push (dec, &buf);
639 if (ret != GST_FLOW_OK || !buf) {
640 GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
641 gst_flow_get_name (ret), buf);
643 gst_buffer_unref (buf);
648 GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT
649 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
650 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
651 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
653 if (dec->segment.rate > 0.0) {
654 ret = gst_pad_push (dec->srcpad, buf);
655 GST_LOG_OBJECT (dec, "buffer pushed: %s", gst_flow_get_name (ret));
658 priv->queued = g_list_prepend (priv->queued, buf);
659 GST_LOG_OBJECT (dec, "buffer queued");
673 gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf,
676 GstBaseAudioDecoderPrivate *priv;
677 GstBaseAudioDecoderContext *ctx;
679 GstClockTime ts, next_ts;
682 /* subclass should know what it is producing by now */
683 g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
685 /* subclass should not hand us no data */
686 g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
688 /* no dummy calls please */
689 g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
692 ctx = &dec->priv->ctx;
693 size = buf ? gst_buffer_get_size (buf) : 0;
695 GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
696 buf ? size : -1, buf ? size / ctx->info.bpf : -1, frames);
698 /* output shoud be whole number of sample frames */
699 if (G_LIKELY (buf && ctx->info.bpf)) {
700 if (size % ctx->info.bpf)
702 /* per channel least */
703 samples = size / ctx->info.bpf;
706 /* frame and ts book-keeping */
707 if (G_UNLIKELY (frames < 0)) {
708 if (G_UNLIKELY (-frames - 1 > priv->frames.length))
710 frames = priv->frames.length + frames + 1;
711 } else if (G_UNLIKELY (frames > priv->frames.length)) {
712 if (G_LIKELY (!priv->force)) {
713 /* no way we can let this pass */
714 g_assert_not_reached ();
720 if (G_LIKELY (priv->frames.length))
721 ts = GST_BUFFER_TIMESTAMP (priv->frames.head->data);
723 ts = GST_CLOCK_TIME_NONE;
725 GST_DEBUG_OBJECT (dec, "leading frame ts %" GST_TIME_FORMAT,
728 while (priv->frames.length && frames) {
729 gst_buffer_unref (g_queue_pop_head (&priv->frames));
730 dec->priv->ctx.delay = dec->priv->frames.length;
735 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
737 GST_DEBUG_OBJECT (dec, "base_ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
740 if (G_UNLIKELY (!buf))
743 /* slightly convoluted approach caters for perfect ts if subclass desires */
744 if (GST_CLOCK_TIME_IS_VALID (ts)) {
745 if (dec->priv->tolerance > 0) {
746 GstClockTimeDiff diff;
748 g_assert (GST_CLOCK_TIME_IS_VALID (priv->base_ts));
749 next_ts = priv->base_ts +
750 gst_util_uint64_scale (samples, GST_SECOND, ctx->info.rate);
751 GST_LOG_OBJECT (dec, "buffer is %d samples past base_ts %" GST_TIME_FORMAT
752 ", expected ts %" GST_TIME_FORMAT, samples,
753 GST_TIME_ARGS (priv->base_ts), GST_TIME_ARGS (next_ts));
754 diff = GST_CLOCK_DIFF (next_ts, ts);
755 GST_LOG_OBJECT (dec, "ts diff %d ms", (gint) (diff / GST_MSECOND));
756 /* if within tolerance,
757 * discard buffer ts and carry on producing perfect stream,
758 * otherwise resync to ts */
759 if (G_UNLIKELY (diff < -dec->priv->tolerance ||
760 diff > dec->priv->tolerance)) {
761 GST_DEBUG_OBJECT (dec, "base_ts resync");
766 GST_DEBUG_OBJECT (dec, "base_ts resync");
772 /* delayed one-shot stuff until confirmed data */
774 GST_DEBUG_OBJECT (dec, "codec tag %" GST_PTR_FORMAT, priv->taglist);
775 if (gst_tag_list_is_empty (priv->taglist)) {
776 gst_tag_list_free (priv->taglist);
778 gst_element_found_tags (GST_ELEMENT (dec), priv->taglist);
780 priv->taglist = NULL;
783 buf = gst_buffer_make_writable (buf);
784 if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
785 GST_BUFFER_TIMESTAMP (buf) =
787 GST_FRAMES_TO_CLOCK_TIME (priv->samples, ctx->info.rate);
788 GST_BUFFER_DURATION (buf) = priv->base_ts +
789 GST_FRAMES_TO_CLOCK_TIME (priv->samples + samples, ctx->info.rate) -
790 GST_BUFFER_TIMESTAMP (buf);
792 GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
793 GST_BUFFER_DURATION (buf) =
794 GST_FRAMES_TO_CLOCK_TIME (samples, ctx->info.rate);
796 priv->samples += samples;
797 priv->samples_out += samples;
799 /* we got data, so note things are looking up */
800 if (G_UNLIKELY (dec->priv->error_count))
801 dec->priv->error_count--;
804 return gst_base_audio_decoder_output (dec, buf);
809 GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
810 ("buffer size %d not a multiple of %d", size, ctx->info.bpf));
811 gst_buffer_unref (buf);
812 return GST_FLOW_ERROR;
816 GST_ELEMENT_ERROR (dec, STREAM, ENCODE,
817 ("received more decoded frames %d than provided %d", frames,
818 priv->frames.length), (NULL));
820 gst_buffer_unref (buf);
821 return GST_FLOW_ERROR;
826 gst_base_audio_decoder_handle_frame (GstBaseAudioDecoder * dec,
827 GstBaseAudioDecoderClass * klass, GstBuffer * buffer)
829 if (G_LIKELY (buffer)) {
830 gsize size = gst_buffer_get_size (buffer);
831 /* keep around for admin */
832 GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT,
833 size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
834 g_queue_push_tail (&dec->priv->frames, buffer);
835 dec->priv->ctx.delay = dec->priv->frames.length;
836 dec->priv->bytes_in += size;
838 GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
841 return klass->handle_frame (dec, buffer);
844 /* maybe subclass configurable instead, but this allows for a whole lot of
845 * raw samples, so at least quite some encoded ... */
846 #define GST_BASE_AUDIO_DECODER_MAX_SYNC 10 * 8 * 2 * 1024
849 gst_base_audio_decoder_push_buffers (GstBaseAudioDecoder * dec, gboolean force)
851 GstBaseAudioDecoderClass *klass;
852 GstBaseAudioDecoderPrivate *priv;
853 GstBaseAudioDecoderContext *ctx;
854 GstFlowReturn ret = GST_FLOW_OK;
858 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
860 ctx = &dec->priv->ctx;
862 g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
864 av = gst_adapter_available (priv->adapter);
865 GST_DEBUG_OBJECT (dec, "available: %d", av);
867 while (ret == GST_FLOW_OK) {
876 /* parse if needed */
880 /* limited (legacy) parsing; avoid whole of baseparse */
881 GST_DEBUG_OBJECT (dec, "parsing available: %d", av);
882 /* piggyback sync state on discont */
883 ctx->sync = !priv->discont;
884 ret = klass->parse (dec, priv->adapter, &offset, &len);
886 g_assert (offset <= av);
889 GST_DEBUG_OBJECT (dec, "setting DISCONT");
890 gst_adapter_flush (priv->adapter, offset);
892 /* avoid parsing indefinitely */
893 priv->sync_flush += offset;
894 if (priv->sync_flush > GST_BASE_AUDIO_DECODER_MAX_SYNC)
898 if (ret == GST_FLOW_UNEXPECTED) {
899 GST_LOG_OBJECT (dec, "no frame yet");
902 } else if (ret == GST_FLOW_OK) {
903 GST_LOG_OBJECT (dec, "frame at offset %d of length %d", offset, len);
904 g_assert (offset + len <= av);
905 priv->sync_flush = 0;
912 /* track upstream ts, but do not get stuck if nothing new upstream */
913 ts = gst_adapter_prev_timestamp (priv->adapter, NULL);
914 if (ts == priv->prev_ts) {
915 GST_LOG_OBJECT (dec, "ts == prev_ts; discarding");
916 ts = GST_CLOCK_TIME_NONE;
920 buffer = gst_adapter_take_buffer (priv->adapter, len);
921 buffer = gst_buffer_make_writable (buffer);
922 GST_BUFFER_TIMESTAMP (buffer) = ts;
930 ret = gst_base_audio_decoder_handle_frame (dec, klass, buffer);
932 /* do not keep pushing it ... */
933 if (G_UNLIKELY (!av)) {
934 priv->drained = TRUE;
942 GST_LOG_OBJECT (dec, "done pushing to subclass");
948 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("failed to parse stream"));
949 return GST_FLOW_ERROR;
954 gst_base_audio_decoder_drain (GstBaseAudioDecoder * dec)
958 if (dec->priv->drained)
961 /* dispatch reverse pending buffers */
962 /* chain eventually calls upon drain as well, but by that time
963 * gather list should be clear, so ok ... */
964 if (dec->segment.rate < 0.0 && dec->priv->gather)
965 gst_base_audio_decoder_chain_reverse (dec, NULL);
966 /* have subclass give all it can */
967 ret = gst_base_audio_decoder_push_buffers (dec, TRUE);
968 /* ensure all output sent */
969 ret = gst_base_audio_decoder_output (dec, NULL);
970 /* everything should be away now */
971 if (dec->priv->frames.length) {
972 /* not fatal/impossible though if subclass/codec eats stuff */
973 GST_WARNING_OBJECT (dec, "still %d frames left after draining",
974 dec->priv->frames.length);
975 g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL);
976 g_queue_clear (&dec->priv->frames);
978 /* discard (unparsed) leftover */
979 gst_adapter_clear (dec->priv->adapter);
985 /* hard == FLUSH, otherwise discont */
987 gst_base_audio_decoder_flush (GstBaseAudioDecoder * dec, gboolean hard)
989 GstBaseAudioDecoderClass *klass;
990 GstFlowReturn ret = GST_FLOW_OK;
992 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
994 GST_LOG_OBJECT (dec, "flush hard %d", hard);
997 ret = gst_base_audio_decoder_drain (dec);
999 gst_base_audio_decoder_clear_queues (dec);
1000 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
1001 dec->priv->error_count = 0;
1003 /* only bother subclass with flushing if known it is already alive
1004 * and kicking out stuff */
1005 if (klass->flush && dec->priv->samples_out > 0)
1006 klass->flush (dec, hard);
1007 /* and get (re)set for the sequel */
1008 gst_base_audio_decoder_reset (dec, FALSE);
1013 static GstFlowReturn
1014 gst_base_audio_decoder_chain_forward (GstBaseAudioDecoder * dec,
1020 gst_adapter_push (dec->priv->adapter, buffer);
1022 /* new stuff, so we can push subclass again */
1023 dec->priv->drained = FALSE;
1025 /* hand to subclass */
1026 ret = gst_base_audio_decoder_push_buffers (dec, FALSE);
1028 GST_LOG_OBJECT (dec, "chain-done");
1033 gst_base_audio_decoder_clear_queues (GstBaseAudioDecoder * dec)
1035 GstBaseAudioDecoderPrivate *priv = dec->priv;
1037 g_list_foreach (priv->queued, (GFunc) gst_mini_object_unref, NULL);
1038 g_list_free (priv->queued);
1039 priv->queued = NULL;
1040 g_list_foreach (priv->gather, (GFunc) gst_mini_object_unref, NULL);
1041 g_list_free (priv->gather);
1042 priv->gather = NULL;
1043 g_list_foreach (priv->decode, (GFunc) gst_mini_object_unref, NULL);
1044 g_list_free (priv->decode);
1045 priv->decode = NULL;
1050 * Buffer decoding order: 7 8 9 4 5 6 3 1 2 EOS
1051 * Discont flag: D D D D
1053 * - Each Discont marks a discont in the decoding order.
1055 * for vorbis, each buffer is a keyframe when we have the previous
1056 * buffer. This means that to decode buffer 7, we need buffer 6, which
1057 * arrives out of order.
1059 * we first gather buffers in the gather queue until we get a DISCONT. We
1060 * prepend each incomming buffer so that they are in reversed order.
1062 * gather queue: 9 8 7
1066 * When a DISCONT is received (buffer 4), we move the gather queue to the
1067 * decode queue. This is simply done be taking the head of the gather queue
1068 * and prepending it to the decode queue. This yields:
1071 * decode queue: 7 8 9
1074 * Then we decode each buffer in the decode queue in order and put the output
1075 * buffer in the output queue. The first buffer (7) will not produce any output
1076 * because it needs the previous buffer (6) which did not arrive yet. This
1080 * decode queue: 7 8 9
1083 * Then we remove the consumed buffers from the decode queue. Buffer 7 is not
1084 * completely consumed, we need to keep it around for when we receive buffer
1091 * Then we accumulate more buffers:
1093 * gather queue: 6 5 4
1097 * prepending to the decode queue on DISCONT yields:
1100 * decode queue: 4 5 6 7
1103 * after decoding and keeping buffer 4:
1107 * output queue: 7 6 5
1111 static GstFlowReturn
1112 gst_base_audio_decoder_flush_decode (GstBaseAudioDecoder * dec)
1114 GstBaseAudioDecoderPrivate *priv = dec->priv;
1115 GstFlowReturn res = GST_FLOW_OK;
1118 walk = priv->decode;
1120 GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");
1122 /* clear buffer and decoder state */
1123 gst_base_audio_decoder_flush (dec, FALSE);
1127 GstBuffer *buf = GST_BUFFER_CAST (walk->data);
1129 GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1130 buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1132 next = g_list_next (walk);
1133 /* decode buffer, resulting data prepended to output queue */
1134 gst_buffer_ref (buf);
1135 res = gst_base_audio_decoder_chain_forward (dec, buf);
1137 /* if we generated output, we can discard the buffer, else we
1138 * keep it in the queue */
1140 GST_DEBUG_OBJECT (dec, "decoded buffer to %p", priv->queued->data);
1141 priv->decode = g_list_delete_link (priv->decode, walk);
1142 gst_buffer_unref (buf);
1144 GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
1149 /* drain any aggregation (or otherwise) leftover */
1150 gst_base_audio_decoder_drain (dec);
1152 /* now send queued data downstream */
1153 while (priv->queued) {
1154 GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
1156 if (G_LIKELY (res == GST_FLOW_OK)) {
1157 GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, "
1158 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1159 gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1160 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1161 /* should be already, but let's be sure */
1162 buf = gst_buffer_make_writable (buf);
1163 /* avoid stray DISCONT from forward processing,
1164 * which have no meaning in reverse pushing */
1165 GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
1166 res = gst_pad_push (dec->srcpad, buf);
1168 gst_buffer_unref (buf);
1171 priv->queued = g_list_delete_link (priv->queued, priv->queued);
1177 static GstFlowReturn
1178 gst_base_audio_decoder_chain_reverse (GstBaseAudioDecoder * dec,
1181 GstBaseAudioDecoderPrivate *priv = dec->priv;
1182 GstFlowReturn result = GST_FLOW_OK;
1184 /* if we have a discont, move buffers to the decode list */
1185 if (!buf || GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1186 GST_DEBUG_OBJECT (dec, "received discont");
1187 while (priv->gather) {
1190 gbuf = GST_BUFFER_CAST (priv->gather->data);
1191 /* remove from the gather list */
1192 priv->gather = g_list_delete_link (priv->gather, priv->gather);
1193 /* copy to decode queue */
1194 priv->decode = g_list_prepend (priv->decode, gbuf);
1196 /* decode stuff in the decode queue */
1197 gst_base_audio_decoder_flush_decode (dec);
1200 if (G_LIKELY (buf)) {
1201 GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, "
1202 "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
1203 gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1204 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1206 /* add buffer to gather queue */
1207 priv->gather = g_list_prepend (priv->gather, buf);
1213 static GstFlowReturn
1214 gst_base_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
1216 GstBaseAudioDecoder *dec;
1219 dec = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
1221 GST_LOG_OBJECT (dec,
1222 "received buffer of size %d with ts %" GST_TIME_FORMAT
1223 ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
1224 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1225 GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1227 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
1230 /* track present position */
1231 ts = dec->priv->base_ts;
1232 samples = dec->priv->samples;
1234 GST_DEBUG_OBJECT (dec, "handling discont");
1235 gst_base_audio_decoder_flush (dec, FALSE);
1236 dec->priv->discont = TRUE;
1238 /* buffer may claim DISCONT loudly, if it can't tell us where we are now,
1239 * we'll stick to where we were ...
1240 * Particularly useful/needed for upstream BYTE based */
1241 if (dec->segment.rate > 0.0 && !GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
1242 GST_DEBUG_OBJECT (dec, "... but restoring previous ts tracking");
1243 dec->priv->base_ts = ts;
1244 dec->priv->samples = samples;
1248 if (dec->segment.rate > 0.0)
1249 ret = gst_base_audio_decoder_chain_forward (dec, buffer);
1251 ret = gst_base_audio_decoder_chain_reverse (dec, buffer);
1256 /* perform upstream byte <-> time conversion (duration, seeking)
1257 * if subclass allows and if enough data for moderately decent conversion */
1258 static inline gboolean
1259 gst_base_audio_decoder_do_byte (GstBaseAudioDecoder * dec)
1261 return dec->priv->ctx.do_byte_time && dec->priv->ctx.info.bpf &&
1262 dec->priv->ctx.info.rate <= dec->priv->samples_out;
1266 gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec,
1269 gboolean handled = FALSE;
1271 switch (GST_EVENT_TYPE (event)) {
1272 case GST_EVENT_SEGMENT:
1276 gst_event_copy_segment (event, &seg);
1278 if (seg.format == GST_FORMAT_TIME) {
1279 GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
1282 GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_PTR_FORMAT, &seg);
1283 /* handle newsegment resulting from legacy simple seeking */
1284 /* note that we need to convert this whether or not enough data
1285 * to handle initial newsegment */
1286 if (dec->priv->ctx.do_byte_time &&
1287 gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start,
1288 GST_FORMAT_TIME, &nstart)) {
1289 /* best attempt convert */
1290 /* as these are only estimates, stop is kept open-ended to avoid
1291 * premature cutting */
1292 GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
1293 GST_TIME_ARGS (nstart));
1294 seg.format = GST_FORMAT_TIME;
1297 seg.stop = GST_CLOCK_TIME_NONE;
1299 gst_event_unref (event);
1300 event = gst_event_new_segment (&seg);
1302 GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
1307 /* finish current segment */
1308 gst_base_audio_decoder_drain (dec);
1312 /* time progressed without data, see if we can fill the gap with
1313 * some concealment data */
1314 GST_DEBUG_OBJECT (dec,
1315 "segment update: plc %d, do_plc %d, position %" GST_TIME_FORMAT,
1316 dec->priv->plc, dec->priv->ctx.do_plc,
1317 GST_TIME_ARGS (dec->segment.position));
1318 if (dec->priv->plc && dec->priv->ctx.do_plc &&
1319 dec->segment.rate > 0.0 && dec->segment.position < start) {
1320 GstBaseAudioDecoderClass *klass;
1323 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1324 /* hand subclass empty frame with duration that needs covering */
1325 buf = gst_buffer_new ();
1326 GST_BUFFER_DURATION (buf) = start - dec->segment.position;
1327 /* best effort, not much error handling */
1328 gst_base_audio_decoder_handle_frame (dec, klass, buf);
1333 /* prepare for next one */
1334 gst_base_audio_decoder_flush (dec, FALSE);
1335 /* and that's where we time from,
1336 * in case upstream does not come up with anything better
1337 * (e.g. upstream BYTE) */
1338 if (seg.format != GST_FORMAT_TIME) {
1339 dec->priv->base_ts = seg.start;
1340 dec->priv->samples = 0;
1344 /* and follow along with segment */
1346 gst_pad_push_event (dec->srcpad, event);
1351 case GST_EVENT_FLUSH_START:
1354 case GST_EVENT_FLUSH_STOP:
1355 /* prepare for fresh start */
1356 gst_base_audio_decoder_flush (dec, TRUE);
1360 gst_base_audio_decoder_drain (dec);
1363 case GST_EVENT_CAPS:
1367 gst_event_parse_caps (event, &caps);
1368 gst_base_audio_decoder_sink_setcaps (dec, caps);
1369 gst_event_unref (event);
1381 gst_base_audio_decoder_sink_event (GstPad * pad, GstEvent * event)
1383 GstBaseAudioDecoder *dec;
1384 GstBaseAudioDecoderClass *klass;
1385 gboolean handled = FALSE;
1386 gboolean ret = TRUE;
1388 dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1389 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1391 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1392 GST_EVENT_TYPE_NAME (event));
1395 handled = klass->event (dec, event);
1398 handled = gst_base_audio_decoder_sink_eventfunc (dec, event);
1401 ret = gst_pad_event_default (pad, event);
1403 GST_DEBUG_OBJECT (dec, "event handled");
1405 gst_object_unref (dec);
1410 gst_base_audio_decoder_do_seek (GstBaseAudioDecoder * dec, GstEvent * event)
1413 GstSeekType start_type, end_type;
1416 gint64 start, start_time, end_time;
1417 GstSegment seek_segment;
1420 gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
1421 &start_time, &end_type, &end_time);
1423 /* we'll handle plain open-ended flushing seeks with the simple approach */
1425 GST_DEBUG_OBJECT (dec, "unsupported seek: rate");
1429 if (start_type != GST_SEEK_TYPE_SET) {
1430 GST_DEBUG_OBJECT (dec, "unsupported seek: start time");
1434 if (end_type != GST_SEEK_TYPE_NONE ||
1435 (end_type == GST_SEEK_TYPE_SET && end_time != GST_CLOCK_TIME_NONE)) {
1436 GST_DEBUG_OBJECT (dec, "unsupported seek: end time");
1440 if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1441 GST_DEBUG_OBJECT (dec, "unsupported seek: not flushing");
1445 memcpy (&seek_segment, &dec->segment, sizeof (seek_segment));
1446 gst_segment_do_seek (&seek_segment, rate, format, flags, start_type,
1447 start_time, end_type, end_time, NULL);
1448 start_time = seek_segment.position;
1450 if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
1451 GST_FORMAT_BYTES, &start)) {
1452 GST_DEBUG_OBJECT (dec, "conversion failed");
1456 seqnum = gst_event_get_seqnum (event);
1457 event = gst_event_new_seek (1.0, GST_FORMAT_BYTES, flags,
1458 GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE, -1);
1459 gst_event_set_seqnum (event, seqnum);
1461 GST_DEBUG_OBJECT (dec, "seeking to %" GST_TIME_FORMAT " at byte offset %"
1462 G_GINT64_FORMAT, GST_TIME_ARGS (start_time), start);
1464 return gst_pad_push_event (dec->sinkpad, event);
1468 gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
1470 GstBaseAudioDecoder *dec;
1471 gboolean res = FALSE;
1473 dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1475 GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1476 GST_EVENT_TYPE_NAME (event));
1478 switch (GST_EVENT_TYPE (event)) {
1479 case GST_EVENT_SEEK:
1484 GstSeekType cur_type, stop_type;
1489 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1491 seqnum = gst_event_get_seqnum (event);
1493 /* upstream gets a chance first */
1494 if ((res = gst_pad_push_event (dec->sinkpad, event)))
1497 /* if upstream fails for a time seek, maybe we can help if allowed */
1498 if (format == GST_FORMAT_TIME) {
1499 if (gst_base_audio_decoder_do_byte (dec))
1500 res = gst_base_audio_decoder_do_seek (dec, event);
1504 /* ... though a non-time seek can be aided as well */
1505 /* First bring the requested format to time */
1507 gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
1510 gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
1514 /* then seek with time on the peer */
1515 event = gst_event_new_seek (rate, GST_FORMAT_TIME,
1516 flags, cur_type, tcur, stop_type, tstop);
1517 gst_event_set_seqnum (event, seqnum);
1519 res = gst_pad_push_event (dec->sinkpad, event);
1523 res = gst_pad_push_event (dec->sinkpad, event);
1527 gst_object_unref (dec);
1534 GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
1540 * gst_base_audio_encoded_audio_convert:
1541 * @fmt: audio format of the encoded audio
1542 * @bytes: number of encoded bytes
1543 * @samples: number of encoded samples
1544 * @src_format: source format
1545 * @src_value: source value
1546 * @dest_format: destination format
1547 * @dest_value: destination format
1549 * Helper function to convert @src_value in @src_format to @dest_value in
1550 * @dest_format for encoded audio data. Conversion is possible between
1551 * BYTE and TIME format by using estimated bitrate based on
1552 * @samples and @bytes (and @fmt).
1554 /* FIXME: make gst_base_audio_encoded_audio_convert() public? */
1556 gst_base_audio_encoded_audio_convert (GstAudioInfo * fmt,
1557 gint64 bytes, gint64 samples, GstFormat src_format,
1558 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1560 gboolean res = FALSE;
1562 g_return_val_if_fail (dest_format != NULL, FALSE);
1563 g_return_val_if_fail (dest_value != NULL, FALSE);
1565 if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
1568 *dest_value = src_value;
1572 if (samples == 0 || bytes == 0 || fmt->rate == 0) {
1573 GST_DEBUG ("not enough metadata yet to convert");
1579 switch (src_format) {
1580 case GST_FORMAT_BYTES:
1581 switch (*dest_format) {
1582 case GST_FORMAT_TIME:
1583 *dest_value = gst_util_uint64_scale (src_value,
1584 GST_SECOND * samples, bytes);
1591 case GST_FORMAT_TIME:
1592 switch (*dest_format) {
1593 case GST_FORMAT_BYTES:
1594 *dest_value = gst_util_uint64_scale (src_value, bytes,
1595 samples * GST_SECOND);
1611 gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query)
1613 gboolean res = TRUE;
1614 GstBaseAudioDecoder *dec;
1616 dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1618 switch (GST_QUERY_TYPE (query)) {
1619 case GST_QUERY_FORMATS:
1621 gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
1625 case GST_QUERY_CONVERT:
1627 GstFormat src_fmt, dest_fmt;
1628 gint64 src_val, dest_val;
1630 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1631 if (!(res = gst_base_audio_encoded_audio_convert (&dec->priv->ctx.info,
1632 dec->priv->bytes_in, dec->priv->samples_out,
1633 src_fmt, src_val, &dest_fmt, &dest_val)))
1635 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1639 res = gst_pad_query_default (pad, query);
1644 gst_object_unref (dec);
1648 static const GstQueryType *
1649 gst_base_audio_decoder_get_query_types (GstPad * pad)
1651 static const GstQueryType gst_base_audio_decoder_src_query_types[] = {
1659 return gst_base_audio_decoder_src_query_types;
1662 /* FIXME ? are any of these queries (other than latency) a decoder's business ??
1663 * also, the conversion stuff might seem to make sense, but seems to not mind
1664 * segment stuff etc at all
1665 * Supposedly that's backward compatibility ... */
1667 gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
1669 GstBaseAudioDecoder *dec;
1671 gboolean res = FALSE;
1673 dec = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
1674 peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad));
1676 GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
1678 switch (GST_QUERY_TYPE (query)) {
1679 case GST_QUERY_DURATION:
1683 /* upstream in any case */
1684 if ((res = gst_pad_query_default (pad, query)))
1687 gst_query_parse_duration (query, &format, NULL);
1688 /* try answering TIME by converting from BYTE if subclass allows */
1689 if (format == GST_FORMAT_TIME && gst_base_audio_decoder_do_byte (dec)) {
1692 if (gst_pad_query_peer_duration (dec->sinkpad, GST_FORMAT_BYTES,
1694 GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
1695 if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
1696 GST_FORMAT_TIME, &value)) {
1697 gst_query_set_duration (query, GST_FORMAT_TIME, value);
1704 case GST_QUERY_POSITION:
1709 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1710 GST_LOG_OBJECT (dec, "returning peer response");
1714 /* we start from the last seen time */
1715 time = dec->segment.position;
1716 /* correct for the segment values */
1717 time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
1719 GST_LOG_OBJECT (dec,
1720 "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
1722 /* and convert to the final format */
1723 gst_query_parse_position (query, &format, NULL);
1724 if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
1728 gst_query_set_position (query, format, value);
1730 GST_LOG_OBJECT (dec,
1731 "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
1735 case GST_QUERY_FORMATS:
1737 gst_query_set_formats (query, 3,
1738 GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
1742 case GST_QUERY_CONVERT:
1744 GstFormat src_fmt, dest_fmt;
1745 gint64 src_val, dest_val;
1747 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
1748 if (!(res = gst_audio_info_convert (&dec->priv->ctx.info,
1749 src_fmt, src_val, dest_fmt, &dest_val)))
1751 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1754 case GST_QUERY_LATENCY:
1756 if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1758 GstClockTime min_latency, max_latency;
1760 gst_query_parse_latency (query, &live, &min_latency, &max_latency);
1761 GST_DEBUG_OBJECT (dec, "Peer latency: live %d, min %"
1762 GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
1763 GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
1765 GST_OBJECT_LOCK (dec);
1766 /* add our latency */
1767 if (min_latency != -1)
1768 min_latency += dec->priv->ctx.min_latency;
1769 if (max_latency != -1)
1770 max_latency += dec->priv->ctx.max_latency;
1771 GST_OBJECT_UNLOCK (dec);
1773 gst_query_set_latency (query, live, min_latency, max_latency);
1778 res = gst_pad_query_default (pad, query);
1782 gst_object_unref (peerpad);
1787 gst_base_audio_decoder_stop (GstBaseAudioDecoder * dec)
1789 GstBaseAudioDecoderClass *klass;
1790 gboolean ret = TRUE;
1792 GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_stop");
1794 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1797 ret = klass->stop (dec);
1801 gst_base_audio_decoder_reset (dec, TRUE);
1804 dec->priv->active = FALSE;
1810 gst_base_audio_decoder_start (GstBaseAudioDecoder * dec)
1812 GstBaseAudioDecoderClass *klass;
1813 gboolean ret = TRUE;
1815 GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_start");
1817 klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1819 /* arrange clean state */
1820 gst_base_audio_decoder_reset (dec, TRUE);
1823 ret = klass->start (dec);
1827 dec->priv->active = TRUE;
1833 gst_base_audio_decoder_get_property (GObject * object, guint prop_id,
1834 GValue * value, GParamSpec * pspec)
1836 GstBaseAudioDecoder *dec;
1838 dec = GST_BASE_AUDIO_DECODER (object);
1842 g_value_set_int64 (value, dec->priv->latency);
1844 case PROP_TOLERANCE:
1845 g_value_set_int64 (value, dec->priv->tolerance);
1848 g_value_set_boolean (value, dec->priv->plc);
1851 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1857 gst_base_audio_decoder_set_property (GObject * object, guint prop_id,
1858 const GValue * value, GParamSpec * pspec)
1860 GstBaseAudioDecoder *dec;
1862 dec = GST_BASE_AUDIO_DECODER (object);
1866 dec->priv->latency = g_value_get_int64 (value);
1868 case PROP_TOLERANCE:
1869 dec->priv->tolerance = g_value_get_int64 (value);
1872 dec->priv->plc = g_value_get_boolean (value);
1875 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1880 static GstStateChangeReturn
1881 gst_base_audio_decoder_change_state (GstElement * element,
1882 GstStateChange transition)
1884 GstBaseAudioDecoder *codec;
1885 GstStateChangeReturn ret;
1887 codec = GST_BASE_AUDIO_DECODER (element);
1889 switch (transition) {
1890 case GST_STATE_CHANGE_NULL_TO_READY:
1892 case GST_STATE_CHANGE_READY_TO_PAUSED:
1893 if (!gst_base_audio_decoder_start (codec)) {
1897 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1903 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1905 switch (transition) {
1906 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1908 case GST_STATE_CHANGE_PAUSED_TO_READY:
1909 if (!gst_base_audio_decoder_stop (codec)) {
1913 case GST_STATE_CHANGE_READY_TO_NULL:
1923 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to start codec"));
1924 return GST_STATE_CHANGE_FAILURE;
1928 GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
1929 return GST_STATE_CHANGE_FAILURE;
1934 _gst_base_audio_decoder_error (GstBaseAudioDecoder * dec, gint weight,
1935 GQuark domain, gint code, gchar * txt, gchar * dbg, const gchar * file,
1936 const gchar * function, gint line)
1939 GST_WARNING_OBJECT (dec, "error: %s", txt);
1941 GST_WARNING_OBJECT (dec, "error: %s", dbg);
1942 dec->priv->error_count += weight;
1943 dec->priv->discont = TRUE;
1944 if (dec->priv->ctx.max_errors < dec->priv->error_count) {
1945 gst_element_message_full (GST_ELEMENT (dec), GST_MESSAGE_ERROR,
1946 domain, code, txt, dbg, file, function, line);
1947 return GST_FLOW_ERROR;
1954 * gst_base_audio_decoder_get_audio_info:
1955 * @dec: a #GstBaseAudioDecoder
1957 * Returns: a #GstAudioInfo describing the input audio format
1962 gst_base_audio_decoder_get_audio_info (GstBaseAudioDecoder * dec)
1964 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), NULL);
1966 return &dec->priv->ctx.info;
1970 * gst_base_audio_decoder_set_plc_aware:
1971 * @dec: a #GstBaseAudioDecoder
1972 * @plc: new plc state
1974 * Indicates whether or not subclass handles packet loss concealment (plc).
1979 gst_base_audio_decoder_set_plc_aware (GstBaseAudioDecoder * dec, gboolean plc)
1981 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
1983 dec->priv->ctx.do_plc = plc;
1987 * gst_base_audio_decoder_get_plc_aware:
1988 * @dec: a #GstBaseAudioDecoder
1990 * Returns: currently configured plc handling
1995 gst_base_audio_decoder_get_plc_aware (GstBaseAudioDecoder * dec)
1997 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
1999 return dec->priv->ctx.do_plc;
2003 * gst_base_audio_decoder_set_byte_time:
2004 * @dec: a #GstBaseAudioDecoder
2005 * @enabled: whether to enable byte to time conversion
2007 * Allows baseclass to perform byte to time estimated conversion.
2012 gst_base_audio_decoder_set_byte_time (GstBaseAudioDecoder * dec,
2015 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2017 dec->priv->ctx.do_byte_time = enabled;
2021 * gst_base_audio_decoder_get_byte_time:
2022 * @dec: a #GstBaseAudioDecoder
2024 * Returns: currently configured byte to time conversion setting
2029 gst_base_audio_decoder_get_byte_time (GstBaseAudioDecoder * dec)
2031 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2033 return dec->priv->ctx.do_byte_time;
2037 * gst_base_audio_decoder_get_delay:
2038 * @dec: a #GstBaseAudioDecoder
2040 * Returns: currently configured decoder delay
2045 gst_base_audio_decoder_get_delay (GstBaseAudioDecoder * dec)
2047 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2049 return dec->priv->ctx.delay;
2053 * gst_base_audio_decoder_set_max_errors:
2054 * @dec: a #GstBaseAudioDecoder
2055 * @num: max tolerated errors
2057 * Sets numbers of tolerated decoder errors, where a tolerated one is then only
2058 * warned about, but more than tolerated will lead to fatal error.
2063 gst_base_audio_decoder_set_max_errors (GstBaseAudioDecoder * enc, gint num)
2065 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (enc));
2067 enc->priv->ctx.max_errors = num;
2071 * gst_base_audio_decoder_get_max_errors:
2072 * @dec: a #GstBaseAudioDecoder
2074 * Returns: currently configured decoder tolerated error count.
2079 gst_base_audio_decoder_get_max_errors (GstBaseAudioDecoder * dec)
2081 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2083 return dec->priv->ctx.max_errors;
2087 * gst_base_audio_decoder_set_latency:
2088 * @dec: a #GstBaseAudioDecoder
2089 * @min: minimum latency
2090 * @max: maximum latency
2092 * Sets decoder latency.
2097 gst_base_audio_decoder_set_latency (GstBaseAudioDecoder * dec,
2098 GstClockTime min, GstClockTime max)
2100 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2102 GST_OBJECT_LOCK (dec);
2103 dec->priv->ctx.min_latency = min;
2104 dec->priv->ctx.max_latency = max;
2105 GST_OBJECT_UNLOCK (dec);
2109 * gst_base_audio_decoder_get_latency:
2110 * @dec: a #GstBaseAudioDecoder
2111 * @min: a pointer to storage to hold minimum latency
2112 * @max: a pointer to storage to hold maximum latency
2114 * Returns currently configured latency.
2119 gst_base_audio_decoder_get_latency (GstBaseAudioDecoder * dec,
2120 GstClockTime * min, GstClockTime * max)
2122 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2124 GST_OBJECT_LOCK (dec);
2126 *min = dec->priv->ctx.min_latency;
2128 *max = dec->priv->ctx.max_latency;
2129 GST_OBJECT_UNLOCK (dec);
2133 * gst_base_audio_decoder_get_parse_state:
2134 * @dec: a #GstBaseAudioDecoder
2135 * @min: a pointer to storage to hold current sync state
2136 * @max: a pointer to storage to hold current eos state
2138 * Return current parsing (sync and eos) state.
2143 gst_base_audio_decoder_get_parse_state (GstBaseAudioDecoder * dec,
2144 gboolean * sync, gboolean * eos)
2146 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2149 *sync = dec->priv->ctx.sync;
2151 *eos = dec->priv->ctx.eos;
2155 * gst_base_audio_decoder_set_plc:
2156 * @dec: a #GstBaseAudioDecoder
2157 * @enabled: new state
2159 * Enable or disable decoder packet loss concealment, provided subclass
2160 * and codec are capable and allow handling plc.
2167 gst_base_audio_decoder_set_plc (GstBaseAudioDecoder * dec, gboolean enabled)
2169 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2171 GST_LOG_OBJECT (dec, "enabled: %d", enabled);
2173 GST_OBJECT_LOCK (dec);
2174 dec->priv->plc = enabled;
2175 GST_OBJECT_UNLOCK (dec);
2179 * gst_base_audio_decoder_get_plc:
2180 * @dec: a #GstBaseAudioDecoder
2182 * Queries decoder packet loss concealment handling.
2184 * Returns: TRUE if packet loss concealment is enabled.
2191 gst_base_audio_decoder_get_plc (GstBaseAudioDecoder * dec)
2195 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), FALSE);
2197 GST_OBJECT_LOCK (dec);
2198 result = dec->priv->plc;
2199 GST_OBJECT_UNLOCK (dec);
2205 * gst_base_audio_decoder_set_min_latency:
2206 * @dec: a #GstBaseAudioDecoder
2207 * @num: new minimum latency
2209 * Sets decoder minimum aggregation latency.
2216 gst_base_audio_decoder_set_min_latency (GstBaseAudioDecoder * dec, gint64 num)
2218 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2220 GST_OBJECT_LOCK (dec);
2221 dec->priv->latency = num;
2222 GST_OBJECT_UNLOCK (dec);
2226 * gst_base_audio_decoder_get_min_latency:
2227 * @enc: a #GstBaseAudioDecoder
2229 * Queries decoder's latency aggregation.
2231 * Returns: aggregation latency.
2238 gst_base_audio_decoder_get_min_latency (GstBaseAudioDecoder * dec)
2242 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), FALSE);
2244 GST_OBJECT_LOCK (dec);
2245 result = dec->priv->latency;
2246 GST_OBJECT_UNLOCK (dec);
2252 * gst_base_audio_decoder_set_tolerance:
2253 * @dec: a #GstBaseAudioDecoder
2254 * @tolerance: new tolerance
2256 * Configures decoder audio jitter tolerance threshold.
2263 gst_base_audio_decoder_set_tolerance (GstBaseAudioDecoder * dec,
2266 g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2268 GST_OBJECT_LOCK (dec);
2269 dec->priv->tolerance = tolerance;
2270 GST_OBJECT_UNLOCK (dec);
2274 * gst_base_audio_decoder_get_tolerance:
2275 * @dec: a #GstBaseAudioDecoder
2277 * Queries current audio jitter tolerance threshold.
2279 * Returns: decoder audio jitter tolerance threshold.
2286 gst_base_audio_decoder_get_tolerance (GstBaseAudioDecoder * dec)
2290 g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2292 GST_OBJECT_LOCK (dec);
2293 result = dec->priv->tolerance;
2294 GST_OBJECT_UNLOCK (dec);