base: port to 0.11
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / gstbaseaudiodecoder.c
1 /* GStreamer
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>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 /**
25  * SECTION:gstbaseaudiodecoder
26  * @short_description: Base class for audio decoders
27  * @see_also: #GstBaseTransform
28  * @since: 0.10.36
29  *
30  * This base class is for audio decoders turning encoded data into
31  * raw audio samples.
32  *
33  * GstBaseAudioDecoder and subclass should cooperate as follows.
34  * <orderedlist>
35  * <listitem>
36  *   <itemizedlist><title>Configuration</title>
37  *   <listitem><para>
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
42  *     @set_format).
43  *   </para></listitem>
44  *   <listitem><para>
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.
49  *   </para></listitem>
50  *   <listitem><para>
51  *     GstBaseAudioDecoder calls @stop at end of all processing.
52  *   </para></listitem>
53  *   </itemizedlist>
54  * </listitem>
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.
60  * <listitem>
61  *   <itemizedlist>
62  *   <title>Data processing</title>
63  *     <listitem><para>
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.
68  *     </para></listitem>
69  *     <listitem><para>
70  *       Input frame is provided to subclass' @handle_frame.
71  *     </para></listitem>
72  *     <listitem><para>
73  *       If codec processing results in decoded data, subclass should call
74  *       @gst_base_audio_decoder_finish_frame to have decoded data pushed
75  *       downstream.
76  *     </para></listitem>
77  *     <listitem><para>
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.
83  *     </para></listitem>
84  *     <listitem><para>
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.
88  *     </para></listitem>
89  *   </itemizedlist>
90  * </listitem>
91  * <listitem>
92  *   <itemizedlist><title>Shutdown phase</title>
93  *   <listitem><para>
94  *     GstBaseAudioDecoder class calls @stop to inform the subclass that data
95  *     parsing will be stopped.
96  *   </para></listitem>
97  *   </itemizedlist>
98  * </listitem>
99  * </orderedlist>
100  *
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.
106  *
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.
111  *
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).
117  *
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.
121  *
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
126  * bitrates.
127  *
128  * Things that subclass need to take care of:
129  * <itemizedlist>
130  *   <listitem><para>Provide pad templates</para></listitem>
131  *   <listitem><para>
132  *      Set source pad caps when appropriate
133  *   </para></listitem>
134  *   <listitem><para>
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.
138  *   </para></listitem>
139  *   <listitem><para>
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.
144  *   </para></listitem>
145  * </itemizedlist>
146  */
147
148 #ifdef HAVE_CONFIG_H
149 #include "config.h"
150 #endif
151
152 #include "gstbaseaudiodecoder.h"
153 #include <gst/pbutils/descriptions.h>
154
155 #include <string.h>
156
157 GST_DEBUG_CATEGORY (baseaudiodecoder_debug);
158 #define GST_CAT_DEFAULT baseaudiodecoder_debug
159
160 #define GST_BASE_AUDIO_DECODER_GET_PRIVATE(obj)  \
161     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_AUDIO_DECODER, \
162         GstBaseAudioDecoderPrivate))
163
164 enum
165 {
166   LAST_SIGNAL
167 };
168
169 enum
170 {
171   PROP_0,
172   PROP_LATENCY,
173   PROP_TOLERANCE,
174   PROP_PLC
175 };
176
177 #define DEFAULT_LATENCY    0
178 #define DEFAULT_TOLERANCE  0
179 #define DEFAULT_PLC        FALSE
180
181 typedef struct _GstBaseAudioDecoderContext
182 {
183   /* input */
184   /* (output) audio format */
185   GstAudioInfo info;
186
187   /* parsing state */
188   gboolean eos;
189   gboolean sync;
190
191   /* misc */
192   gint delay;
193
194   /* output */
195   gboolean do_plc;
196   gboolean do_byte_time;
197   gint max_errors;
198   /* MT-protected (with LOCK) */
199   GstClockTime min_latency;
200   GstClockTime max_latency;
201 } GstBaseAudioDecoderContext;
202
203 struct _GstBaseAudioDecoderPrivate
204 {
205   /* activation status */
206   gboolean active;
207
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) */
211   guint64 samples;
212
213   /* collected input data */
214   GstAdapter *adapter;
215   /* tracking input ts for changes */
216   GstClockTime prev_ts;
217   /* frames obtained from input */
218   GQueue frames;
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 */
224   gboolean discont;
225
226   /* subclass gave all it could already */
227   gboolean drained;
228   /* subclass currently being forcibly drained */
229   gboolean force;
230
231   /* input bps estimatation */
232   /* global in bytes seen */
233   guint64 bytes_in;
234   /* global samples sent out */
235   guint64 samples_out;
236   /* bytes flushed during parsing */
237   guint sync_flush;
238   /* error count */
239   gint error_count;
240   /* codec id tag */
241   GstTagList *taglist;
242
243   /* whether circumstances allow output aggregation */
244   gint agg;
245
246   /* reverse playback queues */
247   /* collect input */
248   GList *gather;
249   /* to-be-decoded */
250   GList *decode;
251   /* reversed output */
252   GList *queued;
253
254   /* context storage */
255   GstBaseAudioDecoderContext ctx;
256
257   /* properties */
258   GstClockTime latency;
259   GstClockTime tolerance;
260   gboolean plc;
261
262 };
263
264
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);
270
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);
274
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,
278     GstEvent * event);
279 static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
280     GstEvent * event);
281 static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad,
282     GstBuffer * buf);
283 static gboolean gst_base_audio_decoder_src_query (GstPad * pad,
284     GstQuery * query);
285 static gboolean gst_base_audio_decoder_sink_query (GstPad * pad,
286     GstQuery * query);
287 static const GstQueryType *gst_base_audio_decoder_get_query_types (GstPad *
288     pad);
289 static void gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec,
290     gboolean full);
291
292 #define gst_base_audio_decoder_parent_class parent_class
293 G_DEFINE_TYPE (GstBaseAudioDecoder, gst_base_audio_decoder, GST_TYPE_ELEMENT);
294
295 static void
296 gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass)
297 {
298   GObjectClass *gobject_class;
299   GstElementClass *element_class;
300
301   gobject_class = G_OBJECT_CLASS (klass);
302   element_class = GST_ELEMENT_CLASS (klass);
303
304   parent_class = g_type_class_peek_parent (klass);
305
306   g_type_class_add_private (klass, sizeof (GstBaseAudioDecoderPrivate));
307
308   GST_DEBUG_CATEGORY_INIT (baseaudiodecoder_debug, "baseaudiodecoder", 0,
309       "baseaudiodecoder element");
310
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;
314
315   element_class->change_state = gst_base_audio_decoder_change_state;
316
317   /* Properties */
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));
323
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));
329
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));
334 }
335
336 static void
337 gst_base_audio_decoder_init (GstBaseAudioDecoder * dec)
338 {
339   GstBaseAudioDecoderClass *klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
340   GstPadTemplate *pad_template;
341
342   GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_init");
343
344   dec->priv = GST_BASE_AUDIO_DECODER_GET_PRIVATE (dec);
345
346   /* Setup sink pad */
347   pad_template =
348       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
349   g_return_if_fail (pad_template != NULL);
350
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");
360
361   /* Setup source pad */
362   pad_template =
363       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
364   g_return_if_fail (pad_template != NULL);
365
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");
376
377   dec->priv->adapter = gst_adapter_new ();
378   dec->priv->adapter_out = gst_adapter_new ();
379   g_queue_init (&dec->priv->frames);
380
381   /* property default */
382   dec->priv->latency = DEFAULT_LATENCY;
383   dec->priv->tolerance = DEFAULT_TOLERANCE;
384   dec->priv->plc = DEFAULT_PLC;
385
386   /* init state */
387   gst_base_audio_decoder_reset (dec, TRUE);
388   GST_DEBUG_OBJECT (dec, "init ok");
389 }
390
391 static void
392 gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full)
393 {
394   GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_reset");
395
396   GST_OBJECT_LOCK (dec);
397
398   if (full) {
399     dec->priv->active = FALSE;
400     dec->priv->bytes_in = 0;
401     dec->priv->samples_out = 0;
402     dec->priv->agg = -1;
403     dec->priv->error_count = 0;
404     gst_base_audio_decoder_clear_queues (dec);
405
406     gst_audio_info_init (&dec->priv->ctx.info);
407     memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
408
409     if (dec->priv->taglist) {
410       gst_tag_list_free (dec->priv->taglist);
411       dec->priv->taglist = NULL;
412     }
413
414     gst_segment_init (&dec->segment, GST_FORMAT_TIME);
415   }
416
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;
429
430   GST_OBJECT_UNLOCK (dec);
431 }
432
433 static void
434 gst_base_audio_decoder_finalize (GObject * object)
435 {
436   GstBaseAudioDecoder *dec;
437
438   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (object));
439   dec = GST_BASE_AUDIO_DECODER (object);
440
441   if (dec->priv->adapter) {
442     g_object_unref (dec->priv->adapter);
443   }
444   if (dec->priv->adapter_out) {
445     g_object_unref (dec->priv->adapter_out);
446   }
447
448   G_OBJECT_CLASS (parent_class)->finalize (object);
449 }
450
451 /* automagically perform sanity checking of src caps;
452  * also extracts output data format */
453 gboolean
454 gst_base_audio_decoder_src_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
455 {
456   gboolean res = TRUE;
457   guint old_rate;
458
459   GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
460
461   /* parse caps here to check subclass;
462    * also makes us aware of output format */
463   if (!gst_caps_is_fixed (caps))
464     goto refuse_caps;
465
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;
472   }
473
474   if (!gst_audio_info_from_caps (&dec->priv->ctx.info, caps))
475     goto refuse_caps;
476
477   gst_object_unref (dec);
478   return res;
479
480   /* ERRORS */
481 refuse_caps:
482   {
483     GST_WARNING_OBJECT (dec, "rejected caps %" GST_PTR_FORMAT, caps);
484     gst_object_unref (dec);
485     return res;
486   }
487 }
488
489 static gboolean
490 gst_base_audio_decoder_sink_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
491 {
492   GstBaseAudioDecoderClass *klass;
493   gboolean res = TRUE;
494
495   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
496
497   GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
498
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);
506
507   if (klass->set_format)
508     res = klass->set_format (dec, caps);
509
510   return res;
511 }
512
513 static void
514 gst_base_audio_decoder_setup (GstBaseAudioDecoder * dec)
515 {
516   GstQuery *query;
517   gboolean res;
518
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);
522   if (res) {
523     gst_query_parse_latency (query, &res, NULL, NULL);
524     res = !res;
525   }
526   gst_query_unref (query);
527
528   /* normalize to bool */
529   dec->priv->agg = !!res;
530 }
531
532 /* mini aggregator combining output buffers into fewer larger ones,
533  * if so allowed/configured */
534 static GstFlowReturn
535 gst_base_audio_decoder_output (GstBaseAudioDecoder * dec, GstBuffer * buf)
536 {
537   GstBaseAudioDecoderClass *klass;
538   GstBaseAudioDecoderPrivate *priv;
539   GstBaseAudioDecoderContext *ctx;
540   GstFlowReturn ret = GST_FLOW_OK;
541   GstBuffer *inbuf = NULL;
542
543   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
544   priv = dec->priv;
545   ctx = &dec->priv->ctx;
546
547   if (G_UNLIKELY (priv->agg < 0))
548     gst_base_audio_decoder_setup (dec);
549
550   if (G_LIKELY (buf)) {
551     g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
552
553     GST_LOG_OBJECT (dec,
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)));
558
559     /* clip buffer */
560     buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
561         ctx->info.bpf);
562     if (G_UNLIKELY (!buf)) {
563       GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
564     } else {
565       GST_LOG_OBJECT (dec,
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)));
570     }
571   } else {
572     GST_DEBUG_OBJECT (dec, "no output buffer");
573   }
574
575 again:
576   inbuf = NULL;
577   if (priv->agg && dec->priv->latency > 0) {
578     gint av;
579     gboolean assemble = FALSE;
580     const GstClockTimeDiff tol = 10 * GST_MSECOND;
581     GstClockTimeDiff diff = -100 * GST_MSECOND;
582
583     av = gst_adapter_available (priv->adapter_out);
584     if (G_UNLIKELY (!buf)) {
585       /* forcibly send current */
586       assemble = TRUE;
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)) {
592       assemble = TRUE;
593       GST_LOG_OBJECT (dec, "buffer %d ms apart from current fragment",
594           (gint) (diff / GST_MSECOND));
595     } else {
596       /* add or start collecting */
597       if (!av) {
598         GST_LOG_OBJECT (dec, "starting new fragment");
599         priv->out_ts = GST_BUFFER_TIMESTAMP (buf);
600       } else {
601         GST_LOG_OBJECT (dec, "adding to fragment");
602       }
603       gst_adapter_push (priv->adapter_out, buf);
604       priv->out_dur += GST_BUFFER_DURATION (buf);
605       av += gst_buffer_get_size (buf);
606       buf = NULL;
607     }
608     if (priv->out_dur > dec->priv->latency)
609       assemble = TRUE;
610     if (av && assemble) {
611       GST_LOG_OBJECT (dec, "assembling fragment");
612       inbuf = buf;
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;
617       priv->out_dur = 0;
618     }
619   }
620
621   if (G_LIKELY (buf)) {
622
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;
627     }
628
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);
634     }
635
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);
642         if (buf)
643           gst_buffer_unref (buf);
644         goto exit;
645       }
646     }
647
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)));
652
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));
656     } else {
657       ret = GST_FLOW_OK;
658       priv->queued = g_list_prepend (priv->queued, buf);
659       GST_LOG_OBJECT (dec, "buffer queued");
660     }
661
662   exit:
663     if (inbuf) {
664       buf = inbuf;
665       goto again;
666     }
667   }
668
669   return ret;
670 }
671
672 GstFlowReturn
673 gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf,
674     gint frames)
675 {
676   GstBaseAudioDecoderPrivate *priv;
677   GstBaseAudioDecoderContext *ctx;
678   gint samples = 0;
679   GstClockTime ts, next_ts;
680   gsize size;
681
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),
684       GST_FLOW_ERROR);
685   /* subclass should not hand us no data */
686   g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
687       GST_FLOW_ERROR);
688   /* no dummy calls please */
689   g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
690
691   priv = dec->priv;
692   ctx = &dec->priv->ctx;
693   size = buf ? gst_buffer_get_size (buf) : 0;
694
695   GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
696       buf ? size : -1, buf ? size / ctx->info.bpf : -1, frames);
697
698   /* output shoud be whole number of sample frames */
699   if (G_LIKELY (buf && ctx->info.bpf)) {
700     if (size % ctx->info.bpf)
701       goto wrong_buffer;
702     /* per channel least */
703     samples = size / ctx->info.bpf;
704   }
705
706   /* frame and ts book-keeping */
707   if (G_UNLIKELY (frames < 0)) {
708     if (G_UNLIKELY (-frames - 1 > priv->frames.length))
709       goto overflow;
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 ();
715       /* really no way */
716       goto overflow;
717     }
718   }
719
720   if (G_LIKELY (priv->frames.length))
721     ts = GST_BUFFER_TIMESTAMP (priv->frames.head->data);
722   else
723     ts = GST_CLOCK_TIME_NONE;
724
725   GST_DEBUG_OBJECT (dec, "leading frame ts %" GST_TIME_FORMAT,
726       GST_TIME_ARGS (ts));
727
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;
731     frames--;
732   }
733
734   /* lock on */
735   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
736     priv->base_ts = ts;
737     GST_DEBUG_OBJECT (dec, "base_ts now %" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
738   }
739
740   if (G_UNLIKELY (!buf))
741     goto exit;
742
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;
747
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");
762         priv->base_ts = ts;
763         priv->samples = 0;
764       }
765     } else {
766       GST_DEBUG_OBJECT (dec, "base_ts resync");
767       priv->base_ts = ts;
768       priv->samples = 0;
769     }
770   }
771
772   /* delayed one-shot stuff until confirmed data */
773   if (priv->taglist) {
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);
777     } else {
778       gst_element_found_tags (GST_ELEMENT (dec), priv->taglist);
779     }
780     priv->taglist = NULL;
781   }
782
783   buf = gst_buffer_make_writable (buf);
784   if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
785     GST_BUFFER_TIMESTAMP (buf) =
786         priv->base_ts +
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);
791   } else {
792     GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
793     GST_BUFFER_DURATION (buf) =
794         GST_FRAMES_TO_CLOCK_TIME (samples, ctx->info.rate);
795   }
796   priv->samples += samples;
797   priv->samples_out += samples;
798
799   /* we got data, so note things are looking up */
800   if (G_UNLIKELY (dec->priv->error_count))
801     dec->priv->error_count--;
802
803 exit:
804   return gst_base_audio_decoder_output (dec, buf);
805
806   /* ERRORS */
807 wrong_buffer:
808   {
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;
813   }
814 overflow:
815   {
816     GST_ELEMENT_ERROR (dec, STREAM, ENCODE,
817         ("received more decoded frames %d than provided %d", frames,
818             priv->frames.length), (NULL));
819     if (buf)
820       gst_buffer_unref (buf);
821     return GST_FLOW_ERROR;
822   }
823 }
824
825 static GstFlowReturn
826 gst_base_audio_decoder_handle_frame (GstBaseAudioDecoder * dec,
827     GstBaseAudioDecoderClass * klass, GstBuffer * buffer)
828 {
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;
837   } else {
838     GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
839   }
840
841   return klass->handle_frame (dec, buffer);
842 }
843
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
847
848 static GstFlowReturn
849 gst_base_audio_decoder_push_buffers (GstBaseAudioDecoder * dec, gboolean force)
850 {
851   GstBaseAudioDecoderClass *klass;
852   GstBaseAudioDecoderPrivate *priv;
853   GstBaseAudioDecoderContext *ctx;
854   GstFlowReturn ret = GST_FLOW_OK;
855   GstBuffer *buffer;
856   gint av, flush;
857
858   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
859   priv = dec->priv;
860   ctx = &dec->priv->ctx;
861
862   g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
863
864   av = gst_adapter_available (priv->adapter);
865   GST_DEBUG_OBJECT (dec, "available: %d", av);
866
867   while (ret == GST_FLOW_OK) {
868
869     flush = 0;
870     ctx->eos = force;
871
872     if (G_LIKELY (av)) {
873       gint len;
874       GstClockTime ts;
875
876       /* parse if needed */
877       if (klass->parse) {
878         gint offset = 0;
879
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);
885
886         g_assert (offset <= av);
887         if (offset) {
888           /* jumped a bit */
889           GST_DEBUG_OBJECT (dec, "setting DISCONT");
890           gst_adapter_flush (priv->adapter, offset);
891           flush = offset;
892           /* avoid parsing indefinitely */
893           priv->sync_flush += offset;
894           if (priv->sync_flush > GST_BASE_AUDIO_DECODER_MAX_SYNC)
895             goto parse_failed;
896         }
897
898         if (ret == GST_FLOW_UNEXPECTED) {
899           GST_LOG_OBJECT (dec, "no frame yet");
900           ret = GST_FLOW_OK;
901           break;
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;
906         } else {
907           break;
908         }
909       } else {
910         len = av;
911       }
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;
917       } else {
918         priv->prev_ts = ts;
919       }
920       buffer = gst_adapter_take_buffer (priv->adapter, len);
921       buffer = gst_buffer_make_writable (buffer);
922       GST_BUFFER_TIMESTAMP (buffer) = ts;
923       flush += len;
924     } else {
925       if (!force)
926         break;
927       buffer = NULL;
928     }
929
930     ret = gst_base_audio_decoder_handle_frame (dec, klass, buffer);
931
932     /* do not keep pushing it ... */
933     if (G_UNLIKELY (!av)) {
934       priv->drained = TRUE;
935       break;
936     }
937
938     av -= flush;
939     g_assert (av >= 0);
940   }
941
942   GST_LOG_OBJECT (dec, "done pushing to subclass");
943   return ret;
944
945   /* ERRORS */
946 parse_failed:
947   {
948     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("failed to parse stream"));
949     return GST_FLOW_ERROR;
950   }
951 }
952
953 static GstFlowReturn
954 gst_base_audio_decoder_drain (GstBaseAudioDecoder * dec)
955 {
956   GstFlowReturn ret;
957
958   if (dec->priv->drained)
959     return GST_FLOW_OK;
960   else {
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);
977     }
978     /* discard (unparsed) leftover */
979     gst_adapter_clear (dec->priv->adapter);
980
981     return ret;
982   }
983 }
984
985 /* hard == FLUSH, otherwise discont */
986 static GstFlowReturn
987 gst_base_audio_decoder_flush (GstBaseAudioDecoder * dec, gboolean hard)
988 {
989   GstBaseAudioDecoderClass *klass;
990   GstFlowReturn ret = GST_FLOW_OK;
991
992   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
993
994   GST_LOG_OBJECT (dec, "flush hard %d", hard);
995
996   if (!hard) {
997     ret = gst_base_audio_decoder_drain (dec);
998   } else {
999     gst_base_audio_decoder_clear_queues (dec);
1000     gst_segment_init (&dec->segment, GST_FORMAT_TIME);
1001     dec->priv->error_count = 0;
1002   }
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);
1009
1010   return ret;
1011 }
1012
1013 static GstFlowReturn
1014 gst_base_audio_decoder_chain_forward (GstBaseAudioDecoder * dec,
1015     GstBuffer * buffer)
1016 {
1017   GstFlowReturn ret;
1018
1019   /* grab buffer */
1020   gst_adapter_push (dec->priv->adapter, buffer);
1021   buffer = NULL;
1022   /* new stuff, so we can push subclass again */
1023   dec->priv->drained = FALSE;
1024
1025   /* hand to subclass */
1026   ret = gst_base_audio_decoder_push_buffers (dec, FALSE);
1027
1028   GST_LOG_OBJECT (dec, "chain-done");
1029   return ret;
1030 }
1031
1032 static void
1033 gst_base_audio_decoder_clear_queues (GstBaseAudioDecoder * dec)
1034 {
1035   GstBaseAudioDecoderPrivate *priv = dec->priv;
1036
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;
1046 }
1047
1048 /*
1049  * Input:
1050  *  Buffer decoding order:  7  8  9  4  5  6  3  1  2  EOS
1051  *  Discont flag:           D        D        D  D
1052  *
1053  * - Each Discont marks a discont in the decoding order.
1054  *
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.
1058  *
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.
1061  *
1062  *    gather queue:    9  8  7
1063  *    decode queue:
1064  *    output queue:
1065  *
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:
1069  *
1070  *    gather queue:
1071  *    decode queue:    7  8  9
1072  *    output queue:
1073  *
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
1077  * yields:
1078  *
1079  *    gather queue:
1080  *    decode queue:    7  8  9
1081  *    output queue:    9  8
1082  *
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
1085  * 6. This yields:
1086  *
1087  *    gather queue:
1088  *    decode queue:    7
1089  *    output queue:    9  8
1090  *
1091  * Then we accumulate more buffers:
1092  *
1093  *    gather queue:    6  5  4
1094  *    decode queue:    7
1095  *    output queue:
1096  *
1097  * prepending to the decode queue on DISCONT yields:
1098  *
1099  *    gather queue:
1100  *    decode queue:    4  5  6  7
1101  *    output queue:
1102  *
1103  * after decoding and keeping buffer 4:
1104  *
1105  *    gather queue:
1106  *    decode queue:    4
1107  *    output queue:    7  6  5
1108  *
1109  * Etc..
1110  */
1111 static GstFlowReturn
1112 gst_base_audio_decoder_flush_decode (GstBaseAudioDecoder * dec)
1113 {
1114   GstBaseAudioDecoderPrivate *priv = dec->priv;
1115   GstFlowReturn res = GST_FLOW_OK;
1116   GList *walk;
1117
1118   walk = priv->decode;
1119
1120   GST_DEBUG_OBJECT (dec, "flushing buffers to decoder");
1121
1122   /* clear buffer and decoder state */
1123   gst_base_audio_decoder_flush (dec, FALSE);
1124
1125   while (walk) {
1126     GList *next;
1127     GstBuffer *buf = GST_BUFFER_CAST (walk->data);
1128
1129     GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1130         buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1131
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);
1136
1137     /* if we generated output, we can discard the buffer, else we
1138      * keep it in the queue */
1139     if (priv->queued) {
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);
1143     } else {
1144       GST_DEBUG_OBJECT (dec, "buffer did not decode, keeping");
1145     }
1146     walk = next;
1147   }
1148
1149   /* drain any aggregation (or otherwise) leftover */
1150   gst_base_audio_decoder_drain (dec);
1151
1152   /* now send queued data downstream */
1153   while (priv->queued) {
1154     GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
1155
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);
1167     } else {
1168       gst_buffer_unref (buf);
1169     }
1170
1171     priv->queued = g_list_delete_link (priv->queued, priv->queued);
1172   }
1173
1174   return res;
1175 }
1176
1177 static GstFlowReturn
1178 gst_base_audio_decoder_chain_reverse (GstBaseAudioDecoder * dec,
1179     GstBuffer * buf)
1180 {
1181   GstBaseAudioDecoderPrivate *priv = dec->priv;
1182   GstFlowReturn result = GST_FLOW_OK;
1183
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) {
1188       GstBuffer *gbuf;
1189
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);
1195     }
1196     /* decode stuff in the decode queue */
1197     gst_base_audio_decoder_flush_decode (dec);
1198   }
1199
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)));
1205
1206     /* add buffer to gather queue */
1207     priv->gather = g_list_prepend (priv->gather, buf);
1208   }
1209
1210   return result;
1211 }
1212
1213 static GstFlowReturn
1214 gst_base_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
1215 {
1216   GstBaseAudioDecoder *dec;
1217   GstFlowReturn ret;
1218
1219   dec = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
1220
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)));
1226
1227   if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
1228     gint64 samples, ts;
1229
1230     /* track present position */
1231     ts = dec->priv->base_ts;
1232     samples = dec->priv->samples;
1233
1234     GST_DEBUG_OBJECT (dec, "handling discont");
1235     gst_base_audio_decoder_flush (dec, FALSE);
1236     dec->priv->discont = TRUE;
1237
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;
1245     }
1246   }
1247
1248   if (dec->segment.rate > 0.0)
1249     ret = gst_base_audio_decoder_chain_forward (dec, buffer);
1250   else
1251     ret = gst_base_audio_decoder_chain_reverse (dec, buffer);
1252
1253   return ret;
1254 }
1255
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)
1260 {
1261   return dec->priv->ctx.do_byte_time && dec->priv->ctx.info.bpf &&
1262       dec->priv->ctx.info.rate <= dec->priv->samples_out;
1263 }
1264
1265 static gboolean
1266 gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec,
1267     GstEvent * event)
1268 {
1269   gboolean handled = FALSE;
1270
1271   switch (GST_EVENT_TYPE (event)) {
1272     case GST_EVENT_SEGMENT:
1273     {
1274       GstSegment seg;
1275
1276       gst_event_copy_segment (event, &seg);
1277
1278       if (seg.format == GST_FORMAT_TIME) {
1279         GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
1280       } else {
1281         gint64 nstart;
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;
1295           seg.start = nstart;
1296           seg.time = nstart;
1297           seg.stop = GST_CLOCK_TIME_NONE;
1298           /* replace event */
1299           gst_event_unref (event);
1300           event = gst_event_new_segment (&seg);
1301         } else {
1302           GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
1303           break;
1304         }
1305       }
1306
1307       /* finish current segment */
1308       gst_base_audio_decoder_drain (dec);
1309
1310 #if 0
1311       if (update) {
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;
1321           GstBuffer *buf;
1322
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);
1329         }
1330       } else
1331 #endif
1332       {
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;
1341         }
1342       }
1343
1344       /* and follow along with segment */
1345       dec->segment = seg;
1346       gst_pad_push_event (dec->srcpad, event);
1347       handled = TRUE;
1348       break;
1349     }
1350
1351     case GST_EVENT_FLUSH_START:
1352       break;
1353
1354     case GST_EVENT_FLUSH_STOP:
1355       /* prepare for fresh start */
1356       gst_base_audio_decoder_flush (dec, TRUE);
1357       break;
1358
1359     case GST_EVENT_EOS:
1360       gst_base_audio_decoder_drain (dec);
1361       break;
1362
1363     case GST_EVENT_CAPS:
1364     {
1365       GstCaps *caps;
1366
1367       gst_event_parse_caps (event, &caps);
1368       gst_base_audio_decoder_sink_setcaps (dec, caps);
1369       gst_event_unref (event);
1370       handled = TRUE;
1371       break;
1372     }
1373     default:
1374       break;
1375   }
1376
1377   return handled;
1378 }
1379
1380 static gboolean
1381 gst_base_audio_decoder_sink_event (GstPad * pad, GstEvent * event)
1382 {
1383   GstBaseAudioDecoder *dec;
1384   GstBaseAudioDecoderClass *klass;
1385   gboolean handled = FALSE;
1386   gboolean ret = TRUE;
1387
1388   dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1389   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1390
1391   GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1392       GST_EVENT_TYPE_NAME (event));
1393
1394   if (klass->event)
1395     handled = klass->event (dec, event);
1396
1397   if (!handled)
1398     handled = gst_base_audio_decoder_sink_eventfunc (dec, event);
1399
1400   if (!handled)
1401     ret = gst_pad_event_default (pad, event);
1402
1403   GST_DEBUG_OBJECT (dec, "event handled");
1404
1405   gst_object_unref (dec);
1406   return ret;
1407 }
1408
1409 static gboolean
1410 gst_base_audio_decoder_do_seek (GstBaseAudioDecoder * dec, GstEvent * event)
1411 {
1412   GstSeekFlags flags;
1413   GstSeekType start_type, end_type;
1414   GstFormat format;
1415   gdouble rate;
1416   gint64 start, start_time, end_time;
1417   GstSegment seek_segment;
1418   guint32 seqnum;
1419
1420   gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
1421       &start_time, &end_type, &end_time);
1422
1423   /* we'll handle plain open-ended flushing seeks with the simple approach */
1424   if (rate != 1.0) {
1425     GST_DEBUG_OBJECT (dec, "unsupported seek: rate");
1426     return FALSE;
1427   }
1428
1429   if (start_type != GST_SEEK_TYPE_SET) {
1430     GST_DEBUG_OBJECT (dec, "unsupported seek: start time");
1431     return FALSE;
1432   }
1433
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");
1437     return FALSE;
1438   }
1439
1440   if (!(flags & GST_SEEK_FLAG_FLUSH)) {
1441     GST_DEBUG_OBJECT (dec, "unsupported seek: not flushing");
1442     return FALSE;
1443   }
1444
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;
1449
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");
1453     return FALSE;
1454   }
1455
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);
1460
1461   GST_DEBUG_OBJECT (dec, "seeking to %" GST_TIME_FORMAT " at byte offset %"
1462       G_GINT64_FORMAT, GST_TIME_ARGS (start_time), start);
1463
1464   return gst_pad_push_event (dec->sinkpad, event);
1465 }
1466
1467 static gboolean
1468 gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
1469 {
1470   GstBaseAudioDecoder *dec;
1471   gboolean res = FALSE;
1472
1473   dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1474
1475   GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
1476       GST_EVENT_TYPE_NAME (event));
1477
1478   switch (GST_EVENT_TYPE (event)) {
1479     case GST_EVENT_SEEK:
1480     {
1481       GstFormat format;
1482       gdouble rate;
1483       GstSeekFlags flags;
1484       GstSeekType cur_type, stop_type;
1485       gint64 cur, stop;
1486       gint64 tcur, tstop;
1487       guint32 seqnum;
1488
1489       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1490           &stop_type, &stop);
1491       seqnum = gst_event_get_seqnum (event);
1492
1493       /* upstream gets a chance first */
1494       if ((res = gst_pad_push_event (dec->sinkpad, event)))
1495         break;
1496
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);
1501         break;
1502       }
1503
1504       /* ... though a non-time seek can be aided as well */
1505       /* First bring the requested format to time */
1506       if (!(res =
1507               gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
1508         goto convert_error;
1509       if (!(res =
1510               gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
1511                   &tstop)))
1512         goto convert_error;
1513
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);
1518
1519       res = gst_pad_push_event (dec->sinkpad, event);
1520       break;
1521     }
1522     default:
1523       res = gst_pad_push_event (dec->sinkpad, event);
1524       break;
1525   }
1526 done:
1527   gst_object_unref (dec);
1528
1529   return res;
1530
1531   /* ERRORS */
1532 convert_error:
1533   {
1534     GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek");
1535     goto done;
1536   }
1537 }
1538
1539 /*
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
1548  *
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).
1553  */
1554 /* FIXME: make gst_base_audio_encoded_audio_convert() public? */
1555 static gboolean
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)
1559 {
1560   gboolean res = FALSE;
1561
1562   g_return_val_if_fail (dest_format != NULL, FALSE);
1563   g_return_val_if_fail (dest_value != NULL, FALSE);
1564
1565   if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
1566           src_value == -1)) {
1567     if (dest_value)
1568       *dest_value = src_value;
1569     return TRUE;
1570   }
1571
1572   if (samples == 0 || bytes == 0 || fmt->rate == 0) {
1573     GST_DEBUG ("not enough metadata yet to convert");
1574     goto exit;
1575   }
1576
1577   bytes *= fmt->rate;
1578
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);
1585           res = TRUE;
1586           break;
1587         default:
1588           res = FALSE;
1589       }
1590       break;
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);
1596           res = TRUE;
1597           break;
1598         default:
1599           res = FALSE;
1600       }
1601       break;
1602     default:
1603       res = FALSE;
1604   }
1605
1606 exit:
1607   return res;
1608 }
1609
1610 static gboolean
1611 gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query)
1612 {
1613   gboolean res = TRUE;
1614   GstBaseAudioDecoder *dec;
1615
1616   dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
1617
1618   switch (GST_QUERY_TYPE (query)) {
1619     case GST_QUERY_FORMATS:
1620     {
1621       gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
1622       res = TRUE;
1623       break;
1624     }
1625     case GST_QUERY_CONVERT:
1626     {
1627       GstFormat src_fmt, dest_fmt;
1628       gint64 src_val, dest_val;
1629
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)))
1634         goto error;
1635       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1636       break;
1637     }
1638     default:
1639       res = gst_pad_query_default (pad, query);
1640       break;
1641   }
1642
1643 error:
1644   gst_object_unref (dec);
1645   return res;
1646 }
1647
1648 static const GstQueryType *
1649 gst_base_audio_decoder_get_query_types (GstPad * pad)
1650 {
1651   static const GstQueryType gst_base_audio_decoder_src_query_types[] = {
1652     GST_QUERY_POSITION,
1653     GST_QUERY_DURATION,
1654     GST_QUERY_CONVERT,
1655     GST_QUERY_LATENCY,
1656     0
1657   };
1658
1659   return gst_base_audio_decoder_src_query_types;
1660 }
1661
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 ... */
1666 static gboolean
1667 gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
1668 {
1669   GstBaseAudioDecoder *dec;
1670   GstPad *peerpad;
1671   gboolean res = FALSE;
1672
1673   dec = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
1674   peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad));
1675
1676   GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
1677
1678   switch (GST_QUERY_TYPE (query)) {
1679     case GST_QUERY_DURATION:
1680     {
1681       GstFormat format;
1682
1683       /* upstream in any case */
1684       if ((res = gst_pad_query_default (pad, query)))
1685         break;
1686
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)) {
1690         gint64 value;
1691
1692         if (gst_pad_query_peer_duration (dec->sinkpad, GST_FORMAT_BYTES,
1693                 &value)) {
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);
1698             res = TRUE;
1699           }
1700         }
1701       }
1702       break;
1703     }
1704     case GST_QUERY_POSITION:
1705     {
1706       GstFormat format;
1707       gint64 time, value;
1708
1709       if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1710         GST_LOG_OBJECT (dec, "returning peer response");
1711         break;
1712       }
1713
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);
1718
1719       GST_LOG_OBJECT (dec,
1720           "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
1721
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,
1725                   format, &value)))
1726         break;
1727
1728       gst_query_set_position (query, format, value);
1729
1730       GST_LOG_OBJECT (dec,
1731           "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
1732           format);
1733       break;
1734     }
1735     case GST_QUERY_FORMATS:
1736     {
1737       gst_query_set_formats (query, 3,
1738           GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
1739       res = TRUE;
1740       break;
1741     }
1742     case GST_QUERY_CONVERT:
1743     {
1744       GstFormat src_fmt, dest_fmt;
1745       gint64 src_val, dest_val;
1746
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)))
1750         break;
1751       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1752       break;
1753     }
1754     case GST_QUERY_LATENCY:
1755     {
1756       if ((res = gst_pad_peer_query (dec->sinkpad, query))) {
1757         gboolean live;
1758         GstClockTime min_latency, max_latency;
1759
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));
1764
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);
1772
1773         gst_query_set_latency (query, live, min_latency, max_latency);
1774       }
1775       break;
1776     }
1777     default:
1778       res = gst_pad_query_default (pad, query);
1779       break;
1780   }
1781
1782   gst_object_unref (peerpad);
1783   return res;
1784 }
1785
1786 static gboolean
1787 gst_base_audio_decoder_stop (GstBaseAudioDecoder * dec)
1788 {
1789   GstBaseAudioDecoderClass *klass;
1790   gboolean ret = TRUE;
1791
1792   GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_stop");
1793
1794   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1795
1796   if (klass->stop) {
1797     ret = klass->stop (dec);
1798   }
1799
1800   /* clean up */
1801   gst_base_audio_decoder_reset (dec, TRUE);
1802
1803   if (ret)
1804     dec->priv->active = FALSE;
1805
1806   return TRUE;
1807 }
1808
1809 static gboolean
1810 gst_base_audio_decoder_start (GstBaseAudioDecoder * dec)
1811 {
1812   GstBaseAudioDecoderClass *klass;
1813   gboolean ret = TRUE;
1814
1815   GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_start");
1816
1817   klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
1818
1819   /* arrange clean state */
1820   gst_base_audio_decoder_reset (dec, TRUE);
1821
1822   if (klass->start) {
1823     ret = klass->start (dec);
1824   }
1825
1826   if (ret)
1827     dec->priv->active = TRUE;
1828
1829   return TRUE;
1830 }
1831
1832 static void
1833 gst_base_audio_decoder_get_property (GObject * object, guint prop_id,
1834     GValue * value, GParamSpec * pspec)
1835 {
1836   GstBaseAudioDecoder *dec;
1837
1838   dec = GST_BASE_AUDIO_DECODER (object);
1839
1840   switch (prop_id) {
1841     case PROP_LATENCY:
1842       g_value_set_int64 (value, dec->priv->latency);
1843       break;
1844     case PROP_TOLERANCE:
1845       g_value_set_int64 (value, dec->priv->tolerance);
1846       break;
1847     case PROP_PLC:
1848       g_value_set_boolean (value, dec->priv->plc);
1849       break;
1850     default:
1851       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1852       break;
1853   }
1854 }
1855
1856 static void
1857 gst_base_audio_decoder_set_property (GObject * object, guint prop_id,
1858     const GValue * value, GParamSpec * pspec)
1859 {
1860   GstBaseAudioDecoder *dec;
1861
1862   dec = GST_BASE_AUDIO_DECODER (object);
1863
1864   switch (prop_id) {
1865     case PROP_LATENCY:
1866       dec->priv->latency = g_value_get_int64 (value);
1867       break;
1868     case PROP_TOLERANCE:
1869       dec->priv->tolerance = g_value_get_int64 (value);
1870       break;
1871     case PROP_PLC:
1872       dec->priv->plc = g_value_get_boolean (value);
1873       break;
1874     default:
1875       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1876       break;
1877   }
1878 }
1879
1880 static GstStateChangeReturn
1881 gst_base_audio_decoder_change_state (GstElement * element,
1882     GstStateChange transition)
1883 {
1884   GstBaseAudioDecoder *codec;
1885   GstStateChangeReturn ret;
1886
1887   codec = GST_BASE_AUDIO_DECODER (element);
1888
1889   switch (transition) {
1890     case GST_STATE_CHANGE_NULL_TO_READY:
1891       break;
1892     case GST_STATE_CHANGE_READY_TO_PAUSED:
1893       if (!gst_base_audio_decoder_start (codec)) {
1894         goto start_failed;
1895       }
1896       break;
1897     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1898       break;
1899     default:
1900       break;
1901   }
1902
1903   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1904
1905   switch (transition) {
1906     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1907       break;
1908     case GST_STATE_CHANGE_PAUSED_TO_READY:
1909       if (!gst_base_audio_decoder_stop (codec)) {
1910         goto stop_failed;
1911       }
1912       break;
1913     case GST_STATE_CHANGE_READY_TO_NULL:
1914       break;
1915     default:
1916       break;
1917   }
1918
1919   return ret;
1920
1921 start_failed:
1922   {
1923     GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to start codec"));
1924     return GST_STATE_CHANGE_FAILURE;
1925   }
1926 stop_failed:
1927   {
1928     GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec"));
1929     return GST_STATE_CHANGE_FAILURE;
1930   }
1931 }
1932
1933 GstFlowReturn
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)
1937 {
1938   if (txt)
1939     GST_WARNING_OBJECT (dec, "error: %s", txt);
1940   if (dbg)
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;
1948   } else {
1949     return GST_FLOW_OK;
1950   }
1951 }
1952
1953 /**
1954  * gst_base_audio_decoder_get_audio_info:
1955  * @dec: a #GstBaseAudioDecoder
1956  *
1957  * Returns: a #GstAudioInfo describing the input audio format
1958  *
1959  * Since: 0.10.36
1960  */
1961 GstAudioInfo *
1962 gst_base_audio_decoder_get_audio_info (GstBaseAudioDecoder * dec)
1963 {
1964   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), NULL);
1965
1966   return &dec->priv->ctx.info;
1967 }
1968
1969 /**
1970  * gst_base_audio_decoder_set_plc_aware:
1971  * @dec: a #GstBaseAudioDecoder
1972  * @plc: new plc state
1973  *
1974  * Indicates whether or not subclass handles packet loss concealment (plc).
1975  *
1976  * Since: 0.10.36
1977  */
1978 void
1979 gst_base_audio_decoder_set_plc_aware (GstBaseAudioDecoder * dec, gboolean plc)
1980 {
1981   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
1982
1983   dec->priv->ctx.do_plc = plc;
1984 }
1985
1986 /**
1987  * gst_base_audio_decoder_get_plc_aware:
1988  * @dec: a #GstBaseAudioDecoder
1989  *
1990  * Returns: currently configured plc handling
1991  *
1992  * Since: 0.10.36
1993  */
1994 gint
1995 gst_base_audio_decoder_get_plc_aware (GstBaseAudioDecoder * dec)
1996 {
1997   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
1998
1999   return dec->priv->ctx.do_plc;
2000 }
2001
2002 /**
2003  * gst_base_audio_decoder_set_byte_time:
2004  * @dec: a #GstBaseAudioDecoder
2005  * @enabled: whether to enable byte to time conversion
2006  *
2007  * Allows baseclass to perform byte to time estimated conversion.
2008  *
2009  * Since: 0.10.36
2010  */
2011 void
2012 gst_base_audio_decoder_set_byte_time (GstBaseAudioDecoder * dec,
2013     gboolean enabled)
2014 {
2015   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2016
2017   dec->priv->ctx.do_byte_time = enabled;
2018 }
2019
2020 /**
2021  * gst_base_audio_decoder_get_byte_time:
2022  * @dec: a #GstBaseAudioDecoder
2023  *
2024  * Returns: currently configured byte to time conversion setting
2025  *
2026  * Since: 0.10.36
2027  */
2028 gint
2029 gst_base_audio_decoder_get_byte_time (GstBaseAudioDecoder * dec)
2030 {
2031   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2032
2033   return dec->priv->ctx.do_byte_time;
2034 }
2035
2036 /**
2037  * gst_base_audio_decoder_get_delay:
2038  * @dec: a #GstBaseAudioDecoder
2039  *
2040  * Returns: currently configured decoder delay
2041  *
2042  * Since: 0.10.36
2043  */
2044 gint
2045 gst_base_audio_decoder_get_delay (GstBaseAudioDecoder * dec)
2046 {
2047   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2048
2049   return dec->priv->ctx.delay;
2050 }
2051
2052 /**
2053  * gst_base_audio_decoder_set_max_errors:
2054  * @dec: a #GstBaseAudioDecoder
2055  * @num: max tolerated errors
2056  *
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.
2059  *
2060  * Since: 0.10.36
2061  */
2062 void
2063 gst_base_audio_decoder_set_max_errors (GstBaseAudioDecoder * enc, gint num)
2064 {
2065   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (enc));
2066
2067   enc->priv->ctx.max_errors = num;
2068 }
2069
2070 /**
2071  * gst_base_audio_decoder_get_max_errors:
2072  * @dec: a #GstBaseAudioDecoder
2073  *
2074  * Returns: currently configured decoder tolerated error count.
2075  *
2076  * Since: 0.10.36
2077  */
2078 gint
2079 gst_base_audio_decoder_get_max_errors (GstBaseAudioDecoder * dec)
2080 {
2081   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2082
2083   return dec->priv->ctx.max_errors;
2084 }
2085
2086 /**
2087  * gst_base_audio_decoder_set_latency:
2088  * @dec: a #GstBaseAudioDecoder
2089  * @min: minimum latency
2090  * @max: maximum latency
2091  *
2092  * Sets decoder latency.
2093  *
2094  * Since: 0.10.36
2095  */
2096 void
2097 gst_base_audio_decoder_set_latency (GstBaseAudioDecoder * dec,
2098     GstClockTime min, GstClockTime max)
2099 {
2100   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2101
2102   GST_OBJECT_LOCK (dec);
2103   dec->priv->ctx.min_latency = min;
2104   dec->priv->ctx.max_latency = max;
2105   GST_OBJECT_UNLOCK (dec);
2106 }
2107
2108 /**
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
2113  *
2114  * Returns currently configured latency.
2115  *
2116  * Since: 0.10.36
2117  */
2118 void
2119 gst_base_audio_decoder_get_latency (GstBaseAudioDecoder * dec,
2120     GstClockTime * min, GstClockTime * max)
2121 {
2122   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2123
2124   GST_OBJECT_LOCK (dec);
2125   if (min)
2126     *min = dec->priv->ctx.min_latency;
2127   if (max)
2128     *max = dec->priv->ctx.max_latency;
2129   GST_OBJECT_UNLOCK (dec);
2130 }
2131
2132 /**
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
2137  *
2138  * Return current parsing (sync and eos) state.
2139  *
2140  * Since: 0.10.36
2141  */
2142 void
2143 gst_base_audio_decoder_get_parse_state (GstBaseAudioDecoder * dec,
2144     gboolean * sync, gboolean * eos)
2145 {
2146   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2147
2148   if (sync)
2149     *sync = dec->priv->ctx.sync;
2150   if (eos)
2151     *eos = dec->priv->ctx.eos;
2152 }
2153
2154 /**
2155  * gst_base_audio_decoder_set_plc:
2156  * @dec: a #GstBaseAudioDecoder
2157  * @enabled: new state
2158  *
2159  * Enable or disable decoder packet loss concealment, provided subclass
2160  * and codec are capable and allow handling plc.
2161  *
2162  * MT safe.
2163  *
2164  * Since: 0.10.36
2165  */
2166 void
2167 gst_base_audio_decoder_set_plc (GstBaseAudioDecoder * dec, gboolean enabled)
2168 {
2169   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2170
2171   GST_LOG_OBJECT (dec, "enabled: %d", enabled);
2172
2173   GST_OBJECT_LOCK (dec);
2174   dec->priv->plc = enabled;
2175   GST_OBJECT_UNLOCK (dec);
2176 }
2177
2178 /**
2179  * gst_base_audio_decoder_get_plc:
2180  * @dec: a #GstBaseAudioDecoder
2181  *
2182  * Queries decoder packet loss concealment handling.
2183  *
2184  * Returns: TRUE if packet loss concealment is enabled.
2185  *
2186  * MT safe.
2187  *
2188  * Since: 0.10.36
2189  */
2190 gboolean
2191 gst_base_audio_decoder_get_plc (GstBaseAudioDecoder * dec)
2192 {
2193   gboolean result;
2194
2195   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), FALSE);
2196
2197   GST_OBJECT_LOCK (dec);
2198   result = dec->priv->plc;
2199   GST_OBJECT_UNLOCK (dec);
2200
2201   return result;
2202 }
2203
2204 /**
2205  * gst_base_audio_decoder_set_min_latency:
2206  * @dec: a #GstBaseAudioDecoder
2207  * @num: new minimum latency
2208  *
2209  * Sets decoder minimum aggregation latency.
2210  *
2211  * MT safe.
2212  *
2213  * Since: 0.10.36
2214  */
2215 void
2216 gst_base_audio_decoder_set_min_latency (GstBaseAudioDecoder * dec, gint64 num)
2217 {
2218   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2219
2220   GST_OBJECT_LOCK (dec);
2221   dec->priv->latency = num;
2222   GST_OBJECT_UNLOCK (dec);
2223 }
2224
2225 /**
2226  * gst_base_audio_decoder_get_min_latency:
2227  * @enc: a #GstBaseAudioDecoder
2228  *
2229  * Queries decoder's latency aggregation.
2230  *
2231  * Returns: aggregation latency.
2232  *
2233  * MT safe.
2234  *
2235  * Since: 0.10.36
2236  */
2237 gint64
2238 gst_base_audio_decoder_get_min_latency (GstBaseAudioDecoder * dec)
2239 {
2240   gint64 result;
2241
2242   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), FALSE);
2243
2244   GST_OBJECT_LOCK (dec);
2245   result = dec->priv->latency;
2246   GST_OBJECT_UNLOCK (dec);
2247
2248   return result;
2249 }
2250
2251 /**
2252  * gst_base_audio_decoder_set_tolerance:
2253  * @dec: a #GstBaseAudioDecoder
2254  * @tolerance: new tolerance
2255  *
2256  * Configures decoder audio jitter tolerance threshold.
2257  *
2258  * MT safe.
2259  *
2260  * Since: 0.10.36
2261  */
2262 void
2263 gst_base_audio_decoder_set_tolerance (GstBaseAudioDecoder * dec,
2264     gint64 tolerance)
2265 {
2266   g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (dec));
2267
2268   GST_OBJECT_LOCK (dec);
2269   dec->priv->tolerance = tolerance;
2270   GST_OBJECT_UNLOCK (dec);
2271 }
2272
2273 /**
2274  * gst_base_audio_decoder_get_tolerance:
2275  * @dec: a #GstBaseAudioDecoder
2276  *
2277  * Queries current audio jitter tolerance threshold.
2278  *
2279  * Returns: decoder audio jitter tolerance threshold.
2280  *
2281  * MT safe.
2282  *
2283  * Since: 0.10.36
2284  */
2285 gint64
2286 gst_base_audio_decoder_get_tolerance (GstBaseAudioDecoder * dec)
2287 {
2288   gint64 result;
2289
2290   g_return_val_if_fail (GST_IS_BASE_AUDIO_DECODER (dec), 0);
2291
2292   GST_OBJECT_LOCK (dec);
2293   result = dec->priv->tolerance;
2294   GST_OBJECT_UNLOCK (dec);
2295
2296   return result;
2297 }