a58ef74f97176e84b446ded4d4b50663114ed6aa
[platform/upstream/gstreamer.git] / gst / audiomixer / gstaudiomixer.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2001 Thomas <thomas@apestaart.org>
4  *               2005,2006 Wim Taymans <wim@fluendo.com>
5  *                    2013 Sebastian Dröge <sebastian@centricular.com>
6  *
7  * audiomixer.c: AudioMixer element, N in, one out, samples are added
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 /**
25  * SECTION:element-audiomixer
26  *
27  * The audiomixer allows to mix several streams into one by adding the data.
28  * Mixed data is clamped to the min/max values of the data format.
29  *
30  * The audiomixer currently mixes all data received on the sinkpads as soon as
31  * possible without trying to synchronize the streams.
32  *
33  * The input pads are from a GstPad subclass and have additional
34  * properties to mute each pad individually and set the volume:
35  *
36  * <itemizedlist>
37  * <listitem>
38  * "mute": Whether to mute the pad or not (#gboolean)
39  * </listitem>
40  * <listitem>
41  * "volume": The volume of the pad, between 0.0 and 10.0 (#gdouble)
42  * </listitem>
43  * </itemizedlist>
44  *
45  * <refsect2>
46  * <title>Example launch line</title>
47  * |[
48  * gst-launch audiotestsrc freq=100 ! audiomixer name=mix ! audioconvert ! alsasink audiotestsrc freq=500 ! mix.
49  * ]| This pipeline produces two sine waves mixed together.
50  * </refsect2>
51  *
52  */
53
54 #ifdef HAVE_CONFIG_H
55 #include "config.h"
56 #endif
57
58 #include "gstaudiomixer.h"
59 #include <gst/audio/audio.h>
60 #include <string.h>             /* strcmp */
61 #include "gstaudiomixerorc.h"
62
63 #define GST_CAT_DEFAULT gst_audiomixer_debug
64 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
65
66 #define DEFAULT_PAD_VOLUME (1.0)
67 #define DEFAULT_PAD_MUTE (FALSE)
68
69 /* some defines for audio processing */
70 /* the volume factor is a range from 0.0 to (arbitrary) VOLUME_MAX_DOUBLE = 10.0
71  * we map 1.0 to VOLUME_UNITY_INT*
72  */
73 #define VOLUME_UNITY_INT8            8  /* internal int for unity 2^(8-5) */
74 #define VOLUME_UNITY_INT8_BIT_SHIFT  3  /* number of bits to shift for unity */
75 #define VOLUME_UNITY_INT16           2048       /* internal int for unity 2^(16-5) */
76 #define VOLUME_UNITY_INT16_BIT_SHIFT 11 /* number of bits to shift for unity */
77 #define VOLUME_UNITY_INT24           524288     /* internal int for unity 2^(24-5) */
78 #define VOLUME_UNITY_INT24_BIT_SHIFT 19 /* number of bits to shift for unity */
79 #define VOLUME_UNITY_INT32           134217728  /* internal int for unity 2^(32-5) */
80 #define VOLUME_UNITY_INT32_BIT_SHIFT 27
81
82 enum
83 {
84   PROP_PAD_0,
85   PROP_PAD_VOLUME,
86   PROP_PAD_MUTE
87 };
88
89 G_DEFINE_TYPE (GstAudioMixerPad, gst_audiomixer_pad, GST_TYPE_AGGREGATOR_PAD);
90
91 static void
92 gst_audiomixer_pad_get_property (GObject * object, guint prop_id,
93     GValue * value, GParamSpec * pspec)
94 {
95   GstAudioMixerPad *pad = GST_AUDIO_MIXER_PAD (object);
96
97   switch (prop_id) {
98     case PROP_PAD_VOLUME:
99       g_value_set_double (value, pad->volume);
100       break;
101     case PROP_PAD_MUTE:
102       g_value_set_boolean (value, pad->mute);
103       break;
104     default:
105       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
106       break;
107   }
108 }
109
110 static void
111 gst_audiomixer_pad_set_property (GObject * object, guint prop_id,
112     const GValue * value, GParamSpec * pspec)
113 {
114   GstAudioMixerPad *pad = GST_AUDIO_MIXER_PAD (object);
115
116   switch (prop_id) {
117     case PROP_PAD_VOLUME:
118       GST_OBJECT_LOCK (pad);
119       pad->volume = g_value_get_double (value);
120       pad->volume_i8 = pad->volume * VOLUME_UNITY_INT8;
121       pad->volume_i16 = pad->volume * VOLUME_UNITY_INT16;
122       pad->volume_i32 = pad->volume * VOLUME_UNITY_INT32;
123       GST_OBJECT_UNLOCK (pad);
124       break;
125     case PROP_PAD_MUTE:
126       GST_OBJECT_LOCK (pad);
127       pad->mute = g_value_get_boolean (value);
128       GST_OBJECT_UNLOCK (pad);
129       break;
130     default:
131       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
132       break;
133   }
134 }
135
136 static gboolean
137 gst_audiomixer_pad_flush_pad (GstAggregatorPad * aggpad,
138     GstAggregator * aggregator)
139 {
140   GstAudioMixerPad *pad = GST_AUDIO_MIXER_PAD (aggpad);
141
142   GST_OBJECT_LOCK (aggpad);
143   pad->position = pad->size = 0;
144   pad->output_offset = pad->next_offset = -1;
145   pad->discont_time = GST_CLOCK_TIME_NONE;
146   gst_buffer_replace (&pad->buffer, NULL);
147   GST_OBJECT_UNLOCK (aggpad);
148
149   return TRUE;
150 }
151
152 static void
153 gst_audiomixer_pad_class_init (GstAudioMixerPadClass * klass)
154 {
155   GObjectClass *gobject_class = (GObjectClass *) klass;
156   GstAggregatorPadClass *aggpadclass = (GstAggregatorPadClass *) klass;
157
158   gobject_class->set_property = gst_audiomixer_pad_set_property;
159   gobject_class->get_property = gst_audiomixer_pad_get_property;
160
161   g_object_class_install_property (gobject_class, PROP_PAD_VOLUME,
162       g_param_spec_double ("volume", "Volume", "Volume of this pad",
163           0.0, 10.0, DEFAULT_PAD_VOLUME,
164           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
165   g_object_class_install_property (gobject_class, PROP_PAD_MUTE,
166       g_param_spec_boolean ("mute", "Mute", "Mute this pad",
167           DEFAULT_PAD_MUTE,
168           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
169
170   aggpadclass->flush = GST_DEBUG_FUNCPTR (gst_audiomixer_pad_flush_pad);
171 }
172
173 static void
174 gst_audiomixer_pad_init (GstAudioMixerPad * pad)
175 {
176   pad->volume = DEFAULT_PAD_VOLUME;
177   pad->mute = DEFAULT_PAD_MUTE;
178
179   pad->buffer = NULL;
180   pad->position = 0;
181   pad->size = 0;
182   pad->output_offset = -1;
183   pad->next_offset = -1;
184   pad->discont_time = GST_CLOCK_TIME_NONE;
185 }
186
187 #define DEFAULT_ALIGNMENT_THRESHOLD   (40 * GST_MSECOND)
188 #define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
189 #define DEFAULT_OUTPUT_BUFFER_DURATION (10 * GST_MSECOND)
190
191 enum
192 {
193   PROP_0,
194   PROP_FILTER_CAPS,
195   PROP_ALIGNMENT_THRESHOLD,
196   PROP_DISCONT_WAIT,
197   PROP_OUTPUT_BUFFER_DURATION
198 };
199
200 /* elementfactory information */
201
202 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
203 #define CAPS \
204   GST_AUDIO_CAPS_MAKE ("{ S32LE, U32LE, S16LE, U16LE, S8, U8, F32LE, F64LE }") \
205   ", layout = (string) { interleaved, non-interleaved }"
206 #else
207 #define CAPS \
208   GST_AUDIO_CAPS_MAKE ("{ S32BE, U32BE, S16BE, U16BE, S8, U8, F32BE, F64BE }") \
209   ", layout = (string) { interleaved, non-interleaved }"
210 #endif
211
212 static GstStaticPadTemplate gst_audiomixer_src_template =
213 GST_STATIC_PAD_TEMPLATE ("src",
214     GST_PAD_SRC,
215     GST_PAD_ALWAYS,
216     GST_STATIC_CAPS (CAPS)
217     );
218
219 static GstStaticPadTemplate gst_audiomixer_sink_template =
220 GST_STATIC_PAD_TEMPLATE ("sink_%u",
221     GST_PAD_SINK,
222     GST_PAD_REQUEST,
223     GST_STATIC_CAPS (CAPS)
224     );
225
226 static void gst_audiomixer_child_proxy_init (gpointer g_iface,
227     gpointer iface_data);
228
229 #define gst_audiomixer_parent_class parent_class
230 G_DEFINE_TYPE_WITH_CODE (GstAudioMixer, gst_audiomixer, GST_TYPE_AGGREGATOR,
231     G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
232         gst_audiomixer_child_proxy_init));
233
234 static void gst_audiomixer_dispose (GObject * object);
235 static void gst_audiomixer_set_property (GObject * object, guint prop_id,
236     const GValue * value, GParamSpec * pspec);
237 static void gst_audiomixer_get_property (GObject * object, guint prop_id,
238     GValue * value, GParamSpec * pspec);
239
240 static gboolean gst_audiomixer_setcaps (GstAudioMixer * audiomixer,
241     GstPad * pad, GstCaps * caps);
242 static GstPad *gst_audiomixer_request_new_pad (GstElement * element,
243     GstPadTemplate * temp, const gchar * req_name, const GstCaps * caps);
244 static void gst_audiomixer_release_pad (GstElement * element, GstPad * pad);
245
246 static GstFlowReturn
247 gst_audiomixer_do_clip (GstAggregator * agg,
248     GstAggregatorPad * bpad, GstBuffer * buffer, GstBuffer ** outbuf);
249 static GstFlowReturn gst_audiomixer_aggregate (GstAggregator * agg,
250     gboolean timeout);
251
252 static GstClockTime
253 gst_audiomixer_get_next_time (GstAggregator * agg)
254 {
255   if (agg->segment.position == -1)
256     return agg->segment.start;
257   else
258     return agg->segment.position;
259 }
260
261 /* we can only accept caps that we and downstream can handle.
262  * if we have filtercaps set, use those to constrain the target caps.
263  */
264 static GstCaps *
265 gst_audiomixer_sink_getcaps (GstPad * pad, GstCaps * filter)
266 {
267   GstAggregator *agg;
268   GstAudioMixer *audiomixer;
269   GstCaps *result, *peercaps, *current_caps, *filter_caps;
270   GstStructure *s;
271   gint i, n;
272
273   audiomixer = GST_AUDIO_MIXER (GST_PAD_PARENT (pad));
274   agg = GST_AGGREGATOR (audiomixer);
275
276   GST_OBJECT_LOCK (audiomixer);
277   /* take filter */
278   if ((filter_caps = audiomixer->filter_caps)) {
279     if (filter)
280       filter_caps =
281           gst_caps_intersect_full (filter, filter_caps,
282           GST_CAPS_INTERSECT_FIRST);
283     else
284       gst_caps_ref (filter_caps);
285   } else {
286     filter_caps = filter ? gst_caps_ref (filter) : NULL;
287   }
288   GST_OBJECT_UNLOCK (audiomixer);
289
290   if (filter_caps && gst_caps_is_empty (filter_caps)) {
291     GST_WARNING_OBJECT (pad, "Empty filter caps");
292     return filter_caps;
293   }
294
295   /* get the downstream possible caps */
296   peercaps = gst_pad_peer_query_caps (agg->srcpad, filter_caps);
297
298   /* get the allowed caps on this sinkpad */
299   GST_OBJECT_LOCK (audiomixer);
300   current_caps =
301       audiomixer->current_caps ? gst_caps_ref (audiomixer->current_caps) : NULL;
302   if (current_caps == NULL) {
303     current_caps = gst_pad_get_pad_template_caps (pad);
304     if (!current_caps)
305       current_caps = gst_caps_new_any ();
306   }
307   GST_OBJECT_UNLOCK (audiomixer);
308
309   if (peercaps) {
310     /* if the peer has caps, intersect */
311     GST_DEBUG_OBJECT (audiomixer, "intersecting peer and our caps");
312     result =
313         gst_caps_intersect_full (peercaps, current_caps,
314         GST_CAPS_INTERSECT_FIRST);
315     gst_caps_unref (peercaps);
316     gst_caps_unref (current_caps);
317   } else {
318     /* the peer has no caps (or there is no peer), just use the allowed caps
319      * of this sinkpad. */
320     /* restrict with filter-caps if any */
321     if (filter_caps) {
322       GST_DEBUG_OBJECT (audiomixer, "no peer caps, using filtered caps");
323       result =
324           gst_caps_intersect_full (filter_caps, current_caps,
325           GST_CAPS_INTERSECT_FIRST);
326       gst_caps_unref (current_caps);
327     } else {
328       GST_DEBUG_OBJECT (audiomixer, "no peer caps, using our caps");
329       result = current_caps;
330     }
331   }
332
333   result = gst_caps_make_writable (result);
334
335   n = gst_caps_get_size (result);
336   for (i = 0; i < n; i++) {
337     GstStructure *sref;
338
339     s = gst_caps_get_structure (result, i);
340     sref = gst_structure_copy (s);
341     gst_structure_set (sref, "channels", GST_TYPE_INT_RANGE, 0, 2, NULL);
342     if (gst_structure_is_subset (s, sref)) {
343       /* This field is irrelevant when in mono or stereo */
344       gst_structure_remove_field (s, "channel-mask");
345     }
346     gst_structure_free (sref);
347   }
348
349   if (filter_caps)
350     gst_caps_unref (filter_caps);
351
352   GST_LOG_OBJECT (audiomixer, "getting caps on pad %p,%s to %" GST_PTR_FORMAT,
353       pad, GST_PAD_NAME (pad), result);
354
355   return result;
356 }
357
358 static gboolean
359 gst_audiomixer_sink_query (GstAggregator * agg, GstAggregatorPad * aggpad,
360     GstQuery * query)
361 {
362   gboolean res = FALSE;
363
364   switch (GST_QUERY_TYPE (query)) {
365     case GST_QUERY_CAPS:
366     {
367       GstCaps *filter, *caps;
368
369       gst_query_parse_caps (query, &filter);
370       caps = gst_audiomixer_sink_getcaps (GST_PAD (aggpad), filter);
371       gst_query_set_caps_result (query, caps);
372       gst_caps_unref (caps);
373       res = TRUE;
374       break;
375     }
376     default:
377       res =
378           GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, aggpad, query);
379       break;
380   }
381
382   return res;
383 }
384
385 /* the first caps we receive on any of the sinkpads will define the caps for all
386  * the other sinkpads because we can only mix streams with the same caps.
387  */
388 static gboolean
389 gst_audiomixer_setcaps (GstAudioMixer * audiomixer, GstPad * pad,
390     GstCaps * orig_caps)
391 {
392   GstCaps *caps;
393   GstAudioInfo info;
394   GstStructure *s;
395   gint channels;
396
397   caps = gst_caps_copy (orig_caps);
398
399   s = gst_caps_get_structure (caps, 0);
400   if (gst_structure_get_int (s, "channels", &channels))
401     if (channels <= 2)
402       gst_structure_remove_field (s, "channel-mask");
403
404   if (!gst_audio_info_from_caps (&info, caps))
405     goto invalid_format;
406
407   GST_OBJECT_LOCK (audiomixer);
408   /* don't allow reconfiguration for now; there's still a race between the
409    * different upstream threads doing query_caps + accept_caps + sending
410    * (possibly different) CAPS events, but there's not much we can do about
411    * that, upstream needs to deal with it. */
412   if (audiomixer->current_caps != NULL) {
413     if (gst_audio_info_is_equal (&info, &audiomixer->info)) {
414       GST_OBJECT_UNLOCK (audiomixer);
415       gst_caps_unref (caps);
416       return TRUE;
417     } else {
418       GST_DEBUG_OBJECT (pad, "got input caps %" GST_PTR_FORMAT ", but "
419           "current caps are %" GST_PTR_FORMAT, caps, audiomixer->current_caps);
420       GST_OBJECT_UNLOCK (audiomixer);
421       gst_pad_push_event (pad, gst_event_new_reconfigure ());
422       gst_caps_unref (caps);
423       return FALSE;
424     }
425   }
426
427   GST_INFO_OBJECT (pad, "setting caps to %" GST_PTR_FORMAT, caps);
428   gst_caps_replace (&audiomixer->current_caps, caps);
429
430   memcpy (&audiomixer->info, &info, sizeof (info));
431   audiomixer->send_caps = TRUE;
432   GST_OBJECT_UNLOCK (audiomixer);
433   /* send caps event later, after stream-start event */
434
435   GST_INFO_OBJECT (pad, "handle caps change to %" GST_PTR_FORMAT, caps);
436
437   gst_caps_unref (caps);
438
439   return TRUE;
440
441   /* ERRORS */
442 invalid_format:
443   {
444     gst_caps_unref (caps);
445     GST_WARNING_OBJECT (audiomixer, "invalid format set as caps");
446     return FALSE;
447   }
448 }
449
450 /* FIXME, the duration query should reflect how long you will produce
451  * data, that is the amount of stream time until you will emit EOS.
452  *
453  * For synchronized mixing this is always the max of all the durations
454  * of upstream since we emit EOS when all of them finished.
455  *
456  * We don't do synchronized mixing so this really depends on where the
457  * streams where punched in and what their relative offsets are against
458  * eachother which we can get from the first timestamps we see.
459  *
460  * When we add a new stream (or remove a stream) the duration might
461  * also become invalid again and we need to post a new DURATION
462  * message to notify this fact to the parent.
463  * For now we take the max of all the upstream elements so the simple
464  * cases work at least somewhat.
465  */
466 static gboolean
467 gst_audiomixer_query_duration (GstAudioMixer * audiomixer, GstQuery * query)
468 {
469   gint64 max;
470   gboolean res;
471   GstFormat format;
472   GstIterator *it;
473   gboolean done;
474   GValue item = { 0, };
475
476   /* parse format */
477   gst_query_parse_duration (query, &format, NULL);
478
479   max = -1;
480   res = TRUE;
481   done = FALSE;
482
483   it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (audiomixer));
484   while (!done) {
485     GstIteratorResult ires;
486
487     ires = gst_iterator_next (it, &item);
488     switch (ires) {
489       case GST_ITERATOR_DONE:
490         done = TRUE;
491         break;
492       case GST_ITERATOR_OK:
493       {
494         GstPad *pad = g_value_get_object (&item);
495         gint64 duration;
496
497         /* ask sink peer for duration */
498         res &= gst_pad_peer_query_duration (pad, format, &duration);
499         /* take max from all valid return values */
500         if (res) {
501           /* valid unknown length, stop searching */
502           if (duration == -1) {
503             max = duration;
504             done = TRUE;
505           }
506           /* else see if bigger than current max */
507           else if (duration > max)
508             max = duration;
509         }
510         g_value_reset (&item);
511         break;
512       }
513       case GST_ITERATOR_RESYNC:
514         max = -1;
515         res = TRUE;
516         gst_iterator_resync (it);
517         break;
518       default:
519         res = FALSE;
520         done = TRUE;
521         break;
522     }
523   }
524   g_value_unset (&item);
525   gst_iterator_free (it);
526
527   if (res) {
528     /* and store the max */
529     GST_DEBUG_OBJECT (audiomixer, "Total duration in format %s: %"
530         GST_TIME_FORMAT, gst_format_get_name (format), GST_TIME_ARGS (max));
531     gst_query_set_duration (query, format, max);
532   }
533
534   return res;
535 }
536
537 static gboolean
538 gst_audiomixer_src_query (GstAggregator * agg, GstQuery * query)
539 {
540   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
541   gboolean res = FALSE;
542
543   switch (GST_QUERY_TYPE (query)) {
544     case GST_QUERY_POSITION:
545     {
546       GstFormat format;
547
548       gst_query_parse_position (query, &format, NULL);
549
550       switch (format) {
551         case GST_FORMAT_TIME:
552           /* FIXME, bring to stream time, might be tricky */
553           gst_query_set_position (query, format, agg->segment.position);
554           res = TRUE;
555           break;
556         case GST_FORMAT_DEFAULT:
557           gst_query_set_position (query, format, audiomixer->offset);
558           res = TRUE;
559           break;
560         default:
561           break;
562       }
563       break;
564     }
565     case GST_QUERY_DURATION:
566       res = gst_audiomixer_query_duration (audiomixer, query);
567       break;
568     default:
569       res =
570           GST_AGGREGATOR_CLASS (gst_audiomixer_parent_class)->src_query
571           (agg, query);
572       break;
573   }
574
575   return res;
576 }
577
578 /* event handling */
579
580 typedef struct
581 {
582   GstEvent *event;
583   gboolean flush;
584 } EventData;
585
586 static gboolean
587 gst_audiomixer_src_event (GstAggregator * agg, GstEvent * event)
588 {
589   gboolean result;
590
591   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
592   GST_DEBUG_OBJECT (agg->srcpad, "Got %s event on src pad",
593       GST_EVENT_TYPE_NAME (event));
594
595   switch (GST_EVENT_TYPE (event)) {
596     case GST_EVENT_QOS:
597       /* QoS might be tricky */
598       gst_event_unref (event);
599       return FALSE;
600     case GST_EVENT_NAVIGATION:
601       /* navigation is rather pointless. */
602       gst_event_unref (event);
603       return FALSE;
604       break;
605     case GST_EVENT_SEEK:
606     {
607       GstSeekFlags flags;
608       gdouble rate;
609       GstSeekType start_type, stop_type;
610       gint64 start, stop;
611       GstFormat seek_format, dest_format;
612
613       /* parse the seek parameters */
614       gst_event_parse_seek (event, &rate, &seek_format, &flags, &start_type,
615           &start, &stop_type, &stop);
616
617       /* Check the seeking parametters before linking up */
618       if ((start_type != GST_SEEK_TYPE_NONE)
619           && (start_type != GST_SEEK_TYPE_SET)) {
620         result = FALSE;
621         GST_DEBUG_OBJECT (audiomixer,
622             "seeking failed, unhandled seek type for start: %d", start_type);
623         goto done;
624       }
625       if ((stop_type != GST_SEEK_TYPE_NONE) && (stop_type != GST_SEEK_TYPE_SET)) {
626         result = FALSE;
627         GST_DEBUG_OBJECT (audiomixer,
628             "seeking failed, unhandled seek type for end: %d", stop_type);
629         goto done;
630       }
631
632       dest_format = agg->segment.format;
633       if (seek_format != dest_format) {
634         result = FALSE;
635         GST_DEBUG_OBJECT (audiomixer,
636             "seeking failed, unhandled seek format: %d", seek_format);
637         goto done;
638       }
639
640       /* Link up */
641       result = GST_AGGREGATOR_CLASS (parent_class)->src_event (agg, event);
642       goto done;
643     }
644       break;
645     default:
646       break;
647   }
648
649   return GST_AGGREGATOR_CLASS (parent_class)->src_event (agg, event);
650
651 done:
652   return result;
653 }
654
655 static gboolean
656 gst_audiomixer_sink_event (GstAggregator * agg, GstAggregatorPad * aggpad,
657     GstEvent * event)
658 {
659   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
660   gboolean res = TRUE;
661
662   GST_DEBUG_OBJECT (aggpad, "Got %s event on sink pad",
663       GST_EVENT_TYPE_NAME (event));
664
665   switch (GST_EVENT_TYPE (event)) {
666     case GST_EVENT_CAPS:
667     {
668       GstCaps *caps;
669
670       gst_event_parse_caps (event, &caps);
671       res = gst_audiomixer_setcaps (audiomixer, GST_PAD_CAST (aggpad), caps);
672       gst_event_unref (event);
673       event = NULL;
674       break;
675     }
676     case GST_EVENT_SEGMENT:
677     {
678       const GstSegment *segment;
679       gst_event_parse_segment (event, &segment);
680       if (segment->rate != agg->segment.rate) {
681         GST_ERROR_OBJECT (aggpad,
682             "Got segment event with wrong rate %lf, expected %lf",
683             segment->rate, agg->segment.rate);
684         res = FALSE;
685         gst_event_unref (event);
686         event = NULL;
687       } else if (segment->rate < 0.0) {
688         GST_ERROR_OBJECT (aggpad, "Negative rates not supported yet");
689         res = FALSE;
690         gst_event_unref (event);
691         event = NULL;
692       }
693       break;
694     }
695     default:
696       break;
697   }
698
699   if (event != NULL)
700     return GST_AGGREGATOR_CLASS (parent_class)->sink_event (agg, aggpad, event);
701
702   return res;
703 }
704
705 static void
706 gst_audiomixer_reset (GstAudioMixer * audiomixer)
707 {
708   GstAggregator *agg = GST_AGGREGATOR (audiomixer);
709
710   audiomixer->offset = 0;
711   agg->segment.position = -1;
712
713   gst_audio_info_init (&audiomixer->info);
714   gst_caps_replace (&audiomixer->current_caps, NULL);
715   gst_buffer_replace (&audiomixer->current_buffer, NULL);
716 }
717
718 static gboolean
719 gst_audiomixer_start (GstAggregator * agg)
720 {
721   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
722
723   gst_audiomixer_reset (audiomixer);
724
725   return TRUE;
726 }
727
728 static gboolean
729 gst_audiomixer_stop (GstAggregator * agg)
730 {
731   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
732
733   gst_audiomixer_reset (audiomixer);
734
735   return TRUE;
736 }
737
738 static GstFlowReturn
739 gst_audiomixer_flush (GstAggregator * agg)
740 {
741   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
742
743   audiomixer->offset = 0;
744   agg->segment.position = -1;
745   gst_buffer_replace (&audiomixer->current_buffer, NULL);
746
747   return GST_FLOW_OK;
748 }
749
750 static void
751 gst_audiomixer_class_init (GstAudioMixerClass * klass)
752 {
753   GObjectClass *gobject_class = (GObjectClass *) klass;
754   GstElementClass *gstelement_class = (GstElementClass *) klass;
755   GstAggregatorClass *agg_class = (GstAggregatorClass *) klass;
756
757   gobject_class->set_property = gst_audiomixer_set_property;
758   gobject_class->get_property = gst_audiomixer_get_property;
759   gobject_class->dispose = gst_audiomixer_dispose;
760
761   g_object_class_install_property (gobject_class, PROP_FILTER_CAPS,
762       g_param_spec_boxed ("caps", "Target caps",
763           "Set target format for mixing (NULL means ANY). "
764           "Setting this property takes a reference to the supplied GstCaps "
765           "object", GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
766
767   g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
768       g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold",
769           "Timestamp alignment threshold in nanoseconds", 0,
770           G_MAXUINT64 - 1, DEFAULT_ALIGNMENT_THRESHOLD,
771           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
772
773   g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT,
774       g_param_spec_uint64 ("discont-wait", "Discont Wait",
775           "Window of time in nanoseconds to wait before "
776           "creating a discontinuity", 0,
777           G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
778           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
779
780   g_object_class_install_property (gobject_class, PROP_OUTPUT_BUFFER_DURATION,
781       g_param_spec_uint64 ("output-buffer-duration", "Output Buffer Duration",
782           "Output block size in nanoseconds", 1,
783           G_MAXUINT64, DEFAULT_OUTPUT_BUFFER_DURATION,
784           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
785
786   gst_element_class_add_pad_template (gstelement_class,
787       gst_static_pad_template_get (&gst_audiomixer_src_template));
788   gst_element_class_add_pad_template (gstelement_class,
789       gst_static_pad_template_get (&gst_audiomixer_sink_template));
790   gst_element_class_set_static_metadata (gstelement_class, "AudioMixer",
791       "Generic/Audio",
792       "Mixes multiple audio streams",
793       "Sebastian Dröge <sebastian@centricular.com>");
794
795   gstelement_class->request_new_pad =
796       GST_DEBUG_FUNCPTR (gst_audiomixer_request_new_pad);
797   gstelement_class->release_pad =
798       GST_DEBUG_FUNCPTR (gst_audiomixer_release_pad);
799
800   agg_class->sinkpads_type = GST_TYPE_AUDIO_MIXER_PAD;
801   agg_class->start = gst_audiomixer_start;
802   agg_class->stop = gst_audiomixer_stop;
803
804   agg_class->get_next_time = gst_audiomixer_get_next_time;
805
806   agg_class->sink_query = GST_DEBUG_FUNCPTR (gst_audiomixer_sink_query);
807   agg_class->sink_event = GST_DEBUG_FUNCPTR (gst_audiomixer_sink_event);
808
809   agg_class->aggregate = GST_DEBUG_FUNCPTR (gst_audiomixer_aggregate);
810   agg_class->clip = GST_DEBUG_FUNCPTR (gst_audiomixer_do_clip);
811
812   agg_class->src_event = GST_DEBUG_FUNCPTR (gst_audiomixer_src_event);
813   agg_class->src_query = GST_DEBUG_FUNCPTR (gst_audiomixer_src_query);
814
815   agg_class->flush = GST_DEBUG_FUNCPTR (gst_audiomixer_flush);
816 }
817
818 static void
819 gst_audiomixer_init (GstAudioMixer * audiomixer)
820 {
821   audiomixer->current_caps = NULL;
822   gst_audio_info_init (&audiomixer->info);
823
824   audiomixer->filter_caps = NULL;
825   audiomixer->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
826   audiomixer->discont_wait = DEFAULT_DISCONT_WAIT;
827   audiomixer->output_buffer_duration = DEFAULT_OUTPUT_BUFFER_DURATION;
828   gst_aggregator_set_latency (GST_AGGREGATOR (audiomixer),
829       audiomixer->output_buffer_duration, audiomixer->output_buffer_duration);
830 }
831
832 static void
833 gst_audiomixer_dispose (GObject * object)
834 {
835   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (object);
836
837   gst_caps_replace (&audiomixer->filter_caps, NULL);
838   gst_caps_replace (&audiomixer->current_caps, NULL);
839
840   G_OBJECT_CLASS (parent_class)->dispose (object);
841 }
842
843 static void
844 gst_audiomixer_set_property (GObject * object, guint prop_id,
845     const GValue * value, GParamSpec * pspec)
846 {
847   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (object);
848
849   switch (prop_id) {
850     case PROP_FILTER_CAPS:{
851       GstCaps *new_caps = NULL;
852       GstCaps *old_caps;
853       const GstCaps *new_caps_val = gst_value_get_caps (value);
854
855       if (new_caps_val != NULL) {
856         new_caps = (GstCaps *) new_caps_val;
857         gst_caps_ref (new_caps);
858       }
859
860       GST_OBJECT_LOCK (audiomixer);
861       old_caps = audiomixer->filter_caps;
862       audiomixer->filter_caps = new_caps;
863       GST_OBJECT_UNLOCK (audiomixer);
864
865       if (old_caps)
866         gst_caps_unref (old_caps);
867
868       GST_DEBUG_OBJECT (audiomixer, "set new caps %" GST_PTR_FORMAT, new_caps);
869       break;
870     }
871     case PROP_ALIGNMENT_THRESHOLD:
872       audiomixer->alignment_threshold = g_value_get_uint64 (value);
873       break;
874     case PROP_DISCONT_WAIT:
875       audiomixer->discont_wait = g_value_get_uint64 (value);
876       break;
877     case PROP_OUTPUT_BUFFER_DURATION:
878       audiomixer->output_buffer_duration = g_value_get_uint64 (value);
879       gst_aggregator_set_latency (GST_AGGREGATOR (audiomixer),
880           audiomixer->output_buffer_duration,
881           audiomixer->output_buffer_duration);
882       break;
883     default:
884       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
885       break;
886   }
887 }
888
889 static void
890 gst_audiomixer_get_property (GObject * object, guint prop_id, GValue * value,
891     GParamSpec * pspec)
892 {
893   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (object);
894
895   switch (prop_id) {
896     case PROP_FILTER_CAPS:
897       GST_OBJECT_LOCK (audiomixer);
898       gst_value_set_caps (value, audiomixer->filter_caps);
899       GST_OBJECT_UNLOCK (audiomixer);
900       break;
901     case PROP_ALIGNMENT_THRESHOLD:
902       g_value_set_uint64 (value, audiomixer->alignment_threshold);
903       break;
904     case PROP_DISCONT_WAIT:
905       g_value_set_uint64 (value, audiomixer->discont_wait);
906       break;
907     case PROP_OUTPUT_BUFFER_DURATION:
908       g_value_set_uint64 (value, audiomixer->output_buffer_duration);
909       break;
910     default:
911       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
912       break;
913   }
914 }
915
916 static GstPad *
917 gst_audiomixer_request_new_pad (GstElement * element, GstPadTemplate * templ,
918     const gchar * req_name, const GstCaps * caps)
919 {
920   GstAudioMixerPad *newpad;
921
922   newpad = (GstAudioMixerPad *)
923       GST_ELEMENT_CLASS (parent_class)->request_new_pad (element,
924       templ, req_name, caps);
925
926   if (newpad == NULL)
927     goto could_not_create;
928
929   gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
930       GST_OBJECT_NAME (newpad));
931
932   return GST_PAD_CAST (newpad);
933
934 could_not_create:
935   {
936     GST_DEBUG_OBJECT (element, "could not create/add  pad");
937     return NULL;
938   }
939 }
940
941 static void
942 gst_audiomixer_release_pad (GstElement * element, GstPad * pad)
943 {
944   GstAudioMixer *audiomixer;
945
946   audiomixer = GST_AUDIO_MIXER (element);
947
948   GST_DEBUG_OBJECT (audiomixer, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));
949
950   gst_child_proxy_child_removed (GST_CHILD_PROXY (audiomixer), G_OBJECT (pad),
951       GST_OBJECT_NAME (pad));
952
953   GST_ELEMENT_CLASS (parent_class)->release_pad (element, pad);
954 }
955
956 static GstFlowReturn
957 gst_audiomixer_do_clip (GstAggregator * agg,
958     GstAggregatorPad * bpad, GstBuffer * buffer, GstBuffer ** out)
959 {
960   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (agg);
961   gint rate, bpf;
962
963   rate = GST_AUDIO_INFO_RATE (&audiomixer->info);
964   bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
965
966   buffer = gst_audio_buffer_clip (buffer, &bpad->segment, rate, bpf);
967
968   *out = buffer;
969   return GST_FLOW_OK;
970 }
971
972 static gboolean
973 gst_audio_mixer_fill_buffer (GstAudioMixer * audiomixer, GstAudioMixerPad * pad,
974     GstBuffer * inbuf)
975 {
976   GstClockTime start_time, end_time;
977   gboolean discont = FALSE;
978   guint64 start_offset, end_offset;
979   GstClockTime timestamp, stream_time;
980   gint rate, bpf;
981
982   GstAggregator *agg = GST_AGGREGATOR (audiomixer);
983   GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
984
985   g_assert (pad->buffer == NULL);
986
987   rate = GST_AUDIO_INFO_RATE (&audiomixer->info);
988   bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
989
990   timestamp = GST_BUFFER_TIMESTAMP (inbuf);
991   stream_time = gst_segment_to_stream_time (&agg->segment, GST_FORMAT_TIME,
992       timestamp);
993
994   /* sync object properties on stream time */
995   /* TODO: Ideally we would want to do that on every sample */
996   if (GST_CLOCK_TIME_IS_VALID (stream_time))
997     gst_object_sync_values (GST_OBJECT (pad), stream_time);
998
999   pad->position = 0;
1000   pad->size = gst_buffer_get_size (inbuf);
1001
1002   start_time = GST_BUFFER_PTS (inbuf);
1003   end_time =
1004       start_time + gst_util_uint64_scale_ceil (pad->size / bpf,
1005       GST_SECOND, rate);
1006
1007   start_offset = gst_util_uint64_scale (start_time, rate, GST_SECOND);
1008   end_offset = start_offset + pad->size / bpf;
1009
1010   if (GST_BUFFER_IS_DISCONT (inbuf)
1011       || GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_RESYNC)
1012       || pad->next_offset == -1) {
1013     discont = TRUE;
1014   } else {
1015     guint64 diff, max_sample_diff;
1016
1017     /* Check discont, based on audiobasesink */
1018     if (start_offset <= pad->next_offset)
1019       diff = pad->next_offset - start_offset;
1020     else
1021       diff = start_offset - pad->next_offset;
1022
1023     max_sample_diff =
1024         gst_util_uint64_scale_int (audiomixer->alignment_threshold, rate,
1025         GST_SECOND);
1026
1027     /* Discont! */
1028     if (G_UNLIKELY (diff >= max_sample_diff)) {
1029       if (audiomixer->discont_wait > 0) {
1030         if (pad->discont_time == GST_CLOCK_TIME_NONE) {
1031           pad->discont_time = start_time;
1032         } else if (start_time - pad->discont_time >= audiomixer->discont_wait) {
1033           discont = TRUE;
1034           pad->discont_time = GST_CLOCK_TIME_NONE;
1035         }
1036       } else {
1037         discont = TRUE;
1038       }
1039     } else if (G_UNLIKELY (pad->discont_time != GST_CLOCK_TIME_NONE)) {
1040       /* we have had a discont, but are now back on track! */
1041       pad->discont_time = GST_CLOCK_TIME_NONE;
1042     }
1043   }
1044
1045   if (discont) {
1046     /* Have discont, need resync */
1047     if (pad->next_offset != -1)
1048       GST_INFO_OBJECT (pad, "Have discont. Expected %"
1049           G_GUINT64_FORMAT ", got %" G_GUINT64_FORMAT,
1050           pad->next_offset, start_offset);
1051     pad->output_offset = -1;
1052   } else {
1053     pad->discont_time = GST_CLOCK_TIME_NONE;
1054   }
1055
1056   pad->next_offset = end_offset;
1057
1058   if (pad->output_offset == -1) {
1059     GstClockTime start_running_time;
1060     GstClockTime end_running_time;
1061     guint64 start_running_time_offset;
1062     guint64 end_running_time_offset;
1063
1064     start_running_time =
1065         gst_segment_to_running_time (&aggpad->segment,
1066         GST_FORMAT_TIME, start_time);
1067     end_running_time =
1068         gst_segment_to_running_time (&aggpad->segment,
1069         GST_FORMAT_TIME, end_time);
1070     start_running_time_offset =
1071         gst_util_uint64_scale (start_running_time, rate, GST_SECOND);
1072     end_running_time_offset =
1073         gst_util_uint64_scale (end_running_time, rate, GST_SECOND);
1074
1075     if (end_running_time_offset < audiomixer->offset) {
1076       GstBuffer *buf;
1077
1078       /* Before output segment, drop */
1079       gst_buffer_unref (inbuf);
1080       pad->buffer = NULL;
1081       buf = gst_aggregator_pad_steal_buffer (aggpad);
1082       if (buf)
1083         gst_buffer_unref (buf);
1084       pad->position = 0;
1085       pad->size = 0;
1086       pad->output_offset = -1;
1087       GST_DEBUG_OBJECT (pad,
1088           "Buffer before segment or current position: %" G_GUINT64_FORMAT " < %"
1089           G_GUINT64_FORMAT, end_running_time_offset, audiomixer->offset);
1090       return FALSE;
1091     }
1092
1093     if (start_running_time_offset < audiomixer->offset) {
1094       GstBuffer *buf;
1095       guint diff = (audiomixer->offset - start_running_time_offset) * bpf;
1096
1097       pad->position += diff;
1098       if (pad->position >= pad->size) {
1099         /* Empty buffer, drop */
1100         gst_buffer_unref (inbuf);
1101         pad->buffer = NULL;
1102         buf = gst_aggregator_pad_steal_buffer (aggpad);
1103         if (buf)
1104           gst_buffer_unref (buf);
1105         pad->position = 0;
1106         pad->size = 0;
1107         pad->output_offset = -1;
1108         GST_DEBUG_OBJECT (pad,
1109             "Buffer before segment or current position: %" G_GUINT64_FORMAT
1110             " < %" G_GUINT64_FORMAT, end_running_time_offset,
1111             audiomixer->offset);
1112         return FALSE;
1113       }
1114     }
1115
1116     pad->output_offset = MAX (start_running_time_offset, audiomixer->offset);
1117     GST_DEBUG_OBJECT (pad,
1118         "Buffer resynced: Pad offset %" G_GUINT64_FORMAT
1119         ", current mixer offset %" G_GUINT64_FORMAT, pad->output_offset,
1120         audiomixer->offset);
1121   }
1122
1123   GST_LOG_OBJECT (pad,
1124       "Queued new buffer at offset %" G_GUINT64_FORMAT, pad->output_offset);
1125   pad->buffer = inbuf;
1126
1127   return TRUE;
1128 }
1129
1130 static void
1131 gst_audio_mixer_mix_buffer (GstAudioMixer * audiomixer, GstAudioMixerPad * pad,
1132     GstMapInfo * outmap)
1133 {
1134   guint overlap;
1135   guint out_start;
1136   GstBuffer *inbuf;
1137   GstMapInfo inmap;
1138   gint bpf;
1139   guint blocksize;
1140
1141   GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
1142
1143   blocksize =
1144       gst_util_uint64_scale (audiomixer->output_buffer_duration,
1145       GST_AUDIO_INFO_RATE (&audiomixer->info), GST_SECOND);
1146   blocksize = MAX (1, blocksize);
1147
1148   bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
1149
1150   /* Overlap => mix */
1151   if (audiomixer->offset < pad->output_offset)
1152     out_start = pad->output_offset - audiomixer->offset;
1153   else
1154     out_start = 0;
1155
1156   overlap = pad->size / bpf - pad->position / bpf;
1157   if (overlap > blocksize - out_start)
1158     overlap = blocksize - out_start;
1159
1160   inbuf = gst_aggregator_pad_get_buffer (aggpad);
1161   if (inbuf == NULL)
1162     return;
1163
1164   GST_OBJECT_LOCK (pad);
1165   if (pad->mute || pad->volume < G_MINDOUBLE) {
1166     GST_DEBUG_OBJECT (pad, "Skipping muted pad");
1167     gst_buffer_unref (inbuf);
1168     pad->position += overlap * bpf;
1169     pad->output_offset += overlap;
1170     if (pad->position >= pad->size) {
1171       GstBuffer *buf;
1172       /* Buffer done, drop it */
1173       gst_buffer_replace (&pad->buffer, NULL);
1174       buf = gst_aggregator_pad_steal_buffer (aggpad);
1175       if (buf)
1176         gst_buffer_unref (buf);
1177     }
1178     GST_OBJECT_UNLOCK (pad);
1179     return;
1180   }
1181
1182   if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
1183     GstBuffer *aggpadbuf = gst_aggregator_pad_steal_buffer (aggpad);
1184
1185     /* skip gap buffer */
1186     GST_LOG_OBJECT (pad, "skipping GAP buffer");
1187     gst_buffer_unref (inbuf);
1188     pad->output_offset += pad->size / bpf;
1189     /* Buffer done, drop it */
1190     gst_buffer_replace (&pad->buffer, NULL);
1191     if (aggpadbuf)
1192       gst_buffer_unref (aggpadbuf);
1193     GST_OBJECT_UNLOCK (pad);
1194     return;
1195   }
1196
1197   gst_buffer_map (inbuf, &inmap, GST_MAP_READ);
1198   GST_LOG_OBJECT (pad, "mixing %u bytes at offset %u from offset %u",
1199       overlap * bpf, out_start * bpf, pad->position);
1200   /* further buffers, need to add them */
1201   if (pad->volume == 1.0) {
1202     switch (audiomixer->info.finfo->format) {
1203       case GST_AUDIO_FORMAT_U8:
1204         audiomixer_orc_add_u8 ((gpointer) (outmap->data + out_start * bpf),
1205             (gpointer) (inmap.data + pad->position),
1206             overlap * audiomixer->info.channels);
1207         break;
1208       case GST_AUDIO_FORMAT_S8:
1209         audiomixer_orc_add_s8 ((gpointer) (outmap->data + out_start * bpf),
1210             (gpointer) (inmap.data + pad->position),
1211             overlap * audiomixer->info.channels);
1212         break;
1213       case GST_AUDIO_FORMAT_U16:
1214         audiomixer_orc_add_u16 ((gpointer) (outmap->data + out_start * bpf),
1215             (gpointer) (inmap.data + pad->position),
1216             overlap * audiomixer->info.channels);
1217         break;
1218       case GST_AUDIO_FORMAT_S16:
1219         audiomixer_orc_add_s16 ((gpointer) (outmap->data + out_start * bpf),
1220             (gpointer) (inmap.data + pad->position),
1221             overlap * audiomixer->info.channels);
1222         break;
1223       case GST_AUDIO_FORMAT_U32:
1224         audiomixer_orc_add_u32 ((gpointer) (outmap->data + out_start * bpf),
1225             (gpointer) (inmap.data + pad->position),
1226             overlap * audiomixer->info.channels);
1227         break;
1228       case GST_AUDIO_FORMAT_S32:
1229         audiomixer_orc_add_s32 ((gpointer) (outmap->data + out_start * bpf),
1230             (gpointer) (inmap.data + pad->position),
1231             overlap * audiomixer->info.channels);
1232         break;
1233       case GST_AUDIO_FORMAT_F32:
1234         audiomixer_orc_add_f32 ((gpointer) (outmap->data + out_start * bpf),
1235             (gpointer) (inmap.data + pad->position),
1236             overlap * audiomixer->info.channels);
1237         break;
1238       case GST_AUDIO_FORMAT_F64:
1239         audiomixer_orc_add_f64 ((gpointer) (outmap->data + out_start * bpf),
1240             (gpointer) (inmap.data + pad->position),
1241             overlap * audiomixer->info.channels);
1242         break;
1243       default:
1244         g_assert_not_reached ();
1245         break;
1246     }
1247   } else {
1248     switch (audiomixer->info.finfo->format) {
1249       case GST_AUDIO_FORMAT_U8:
1250         audiomixer_orc_add_volume_u8 ((gpointer) (outmap->data +
1251                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1252             pad->volume_i8, overlap * audiomixer->info.channels);
1253         break;
1254       case GST_AUDIO_FORMAT_S8:
1255         audiomixer_orc_add_volume_s8 ((gpointer) (outmap->data +
1256                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1257             pad->volume_i8, overlap * audiomixer->info.channels);
1258         break;
1259       case GST_AUDIO_FORMAT_U16:
1260         audiomixer_orc_add_volume_u16 ((gpointer) (outmap->data +
1261                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1262             pad->volume_i16, overlap * audiomixer->info.channels);
1263         break;
1264       case GST_AUDIO_FORMAT_S16:
1265         audiomixer_orc_add_volume_s16 ((gpointer) (outmap->data +
1266                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1267             pad->volume_i16, overlap * audiomixer->info.channels);
1268         break;
1269       case GST_AUDIO_FORMAT_U32:
1270         audiomixer_orc_add_volume_u32 ((gpointer) (outmap->data +
1271                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1272             pad->volume_i32, overlap * audiomixer->info.channels);
1273         break;
1274       case GST_AUDIO_FORMAT_S32:
1275         audiomixer_orc_add_volume_s32 ((gpointer) (outmap->data +
1276                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1277             pad->volume_i32, overlap * audiomixer->info.channels);
1278         break;
1279       case GST_AUDIO_FORMAT_F32:
1280         audiomixer_orc_add_volume_f32 ((gpointer) (outmap->data +
1281                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1282             pad->volume, overlap * audiomixer->info.channels);
1283         break;
1284       case GST_AUDIO_FORMAT_F64:
1285         audiomixer_orc_add_volume_f64 ((gpointer) (outmap->data +
1286                 out_start * bpf), (gpointer) (inmap.data + pad->position),
1287             pad->volume, overlap * audiomixer->info.channels);
1288         break;
1289       default:
1290         g_assert_not_reached ();
1291         break;
1292     }
1293   }
1294   gst_buffer_unmap (inbuf, &inmap);
1295   gst_buffer_unref (inbuf);
1296
1297   pad->position += overlap * bpf;
1298   pad->output_offset += overlap;
1299
1300   if (pad->position == pad->size) {
1301     GstBuffer *buf;
1302
1303     /* Buffer done, drop it */
1304     gst_buffer_replace (&pad->buffer, NULL);
1305     buf = gst_aggregator_pad_steal_buffer (aggpad);
1306     if (buf)
1307       gst_buffer_unref (buf);
1308     GST_DEBUG_OBJECT (pad, "Finished mixing buffer, waiting for next");
1309   }
1310
1311   GST_OBJECT_UNLOCK (pad);
1312 }
1313
1314 static GstFlowReturn
1315 gst_audiomixer_aggregate (GstAggregator * agg, gboolean timeout)
1316 {
1317   /* Get all pads that have data for us and store them in a
1318    * new list.
1319    *
1320    * Calculate the current output offset/timestamp and
1321    * offset_end/timestamp_end. Allocate a silence buffer
1322    * for this and store it.
1323    *
1324    * For all pads:
1325    * 1) Once per input buffer (cached)
1326    *   1) Check discont (flag and timestamp with tolerance)
1327    *   2) If discont or new, resync. That means:
1328    *     1) Drop all start data of the buffer that comes before
1329    *        the current position/offset.
1330    *     2) Calculate the offset (output segment!) that the first
1331    *        frame of the input buffer corresponds to. Base this on
1332    *        the running time.
1333    *
1334    * 2) If the current pad's offset/offset_end overlaps with the output
1335    *    offset/offset_end, mix it at the appropiate position in the output
1336    *    buffer and advance the pad's position. Remember if this pad needs
1337    *    a new buffer to advance behind the output offset_end.
1338    *
1339    * 3) If we had no pad with a buffer, go EOS.
1340    *
1341    * 4) If we had at least one pad that did not advance behind output
1342    *    offset_end, let collected be called again for the current
1343    *    output offset/offset_end.
1344    */
1345   GstAudioMixer *audiomixer;
1346   GList *iter;
1347   GstFlowReturn ret;
1348   GstBuffer *outbuf = NULL;
1349   GstMapInfo outmap;
1350   gint64 next_offset;
1351   gint64 next_timestamp;
1352   gint rate, bpf;
1353   gboolean dropped = FALSE;
1354   gboolean is_eos = TRUE;
1355   gboolean is_done = TRUE;
1356   guint blocksize;
1357
1358   audiomixer = GST_AUDIO_MIXER (agg);
1359
1360   /* Update position from the segment start/stop if needed */
1361   if (agg->segment.position == -1) {
1362     if (agg->segment.rate > 0.0)
1363       agg->segment.position = agg->segment.start;
1364     else
1365       agg->segment.position = agg->segment.stop;
1366   }
1367
1368   if (G_UNLIKELY (audiomixer->info.finfo->format == GST_AUDIO_FORMAT_UNKNOWN)) {
1369     if (timeout) {
1370       GST_DEBUG_OBJECT (audiomixer,
1371           "Got timeout before receiving any caps, don't output anything");
1372
1373       /* Advance position */
1374       if (agg->segment.rate > 0.0)
1375         agg->segment.position += audiomixer->output_buffer_duration;
1376       else if (agg->segment.position > audiomixer->output_buffer_duration)
1377         agg->segment.position -= audiomixer->output_buffer_duration;
1378       else
1379         agg->segment.position = 0;
1380
1381       return GST_FLOW_OK;
1382     } else {
1383       goto not_negotiated;
1384     }
1385   }
1386
1387   blocksize =
1388       gst_util_uint64_scale (audiomixer->output_buffer_duration,
1389       GST_AUDIO_INFO_RATE (&audiomixer->info), GST_SECOND);
1390   blocksize = MAX (1, blocksize);
1391
1392   if (audiomixer->send_caps) {
1393     gst_aggregator_set_src_caps (agg, audiomixer->current_caps);
1394
1395     audiomixer->offset = gst_util_uint64_scale (agg->segment.position,
1396         GST_AUDIO_INFO_RATE (&audiomixer->info), GST_SECOND);
1397
1398     audiomixer->send_caps = FALSE;
1399   }
1400
1401   rate = GST_AUDIO_INFO_RATE (&audiomixer->info);
1402   bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
1403
1404   /* for the next timestamp, use the sample counter, which will
1405    * never accumulate rounding errors */
1406
1407   /* FIXME: Reverse mixing does not work at all yet */
1408   if (agg->segment.rate > 0.0) {
1409     next_offset = audiomixer->offset + blocksize;
1410   } else {
1411     next_offset = audiomixer->offset - blocksize;
1412   }
1413   next_timestamp = gst_util_uint64_scale (next_offset, GST_SECOND, rate);
1414
1415   if (audiomixer->current_buffer) {
1416     outbuf = audiomixer->current_buffer;
1417   } else {
1418     outbuf = gst_buffer_new_and_alloc (blocksize * bpf);
1419     gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
1420     gst_audio_format_fill_silence (audiomixer->info.finfo, outmap.data,
1421         outmap.size);
1422     gst_buffer_unmap (outbuf, &outmap);
1423     audiomixer->current_buffer = outbuf;
1424   }
1425
1426   GST_LOG_OBJECT (agg,
1427       "Starting to mix %u samples for offset %" G_GUINT64_FORMAT
1428       " with timestamp %" GST_TIME_FORMAT, blocksize,
1429       audiomixer->offset, GST_TIME_ARGS (agg->segment.position));
1430
1431   gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
1432
1433   GST_OBJECT_LOCK (agg);
1434   for (iter = GST_ELEMENT (agg)->sinkpads; iter; iter = iter->next) {
1435     GstBuffer *inbuf;
1436     GstAudioMixerPad *pad = GST_AUDIO_MIXER_PAD (iter->data);
1437     GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (iter->data);
1438
1439     if (!gst_aggregator_pad_is_eos (aggpad))
1440       is_eos = FALSE;
1441
1442     inbuf = gst_aggregator_pad_get_buffer (aggpad);
1443     if (!inbuf)
1444       continue;
1445
1446     g_assert (!pad->buffer || pad->buffer == inbuf);
1447
1448     /* New buffer? */
1449     if (!pad->buffer) {
1450       /* Takes ownership of buffer */
1451       if (!gst_audio_mixer_fill_buffer (audiomixer, pad, inbuf)) {
1452         dropped = TRUE;
1453         continue;
1454       }
1455     } else {
1456       gst_buffer_unref (inbuf);
1457     }
1458
1459     if (!pad->buffer && !dropped && gst_aggregator_pad_is_eos (aggpad)) {
1460       GST_DEBUG_OBJECT (aggpad, "Pad is in EOS state");
1461       continue;
1462     }
1463
1464     g_assert (pad->buffer);
1465
1466     /* This pad is lacking behind, we need to update the offset
1467      * and maybe drop the current buffer */
1468     if (pad->output_offset < audiomixer->offset) {
1469       gint64 diff = audiomixer->offset - pad->output_offset;
1470       gint bpf = GST_AUDIO_INFO_BPF (&audiomixer->info);
1471
1472       pad->position += diff * bpf;
1473       if (pad->position > pad->size) {
1474         diff = (pad->position - pad->size) / bpf;
1475         pad->position = pad->size;
1476       }
1477       pad->output_offset += diff;
1478
1479       if (pad->position == pad->size) {
1480         GstBuffer *buf;
1481
1482         /* Buffer done, drop it */
1483         gst_buffer_replace (&pad->buffer, NULL);
1484         buf = gst_aggregator_pad_steal_buffer (aggpad);
1485         if (buf)
1486           gst_buffer_unref (buf);
1487         dropped = TRUE;
1488         continue;
1489       }
1490     }
1491
1492     if (pad->output_offset >= audiomixer->offset
1493         && pad->output_offset < audiomixer->offset + blocksize && pad->buffer) {
1494       GST_LOG_OBJECT (aggpad, "Mixing buffer for current offset");
1495       gst_audio_mixer_mix_buffer (audiomixer, pad, &outmap);
1496
1497       if (pad->output_offset >= next_offset) {
1498         GST_DEBUG_OBJECT (pad,
1499             "Pad is after current offset: %" G_GUINT64_FORMAT " >= %"
1500             G_GUINT64_FORMAT, pad->output_offset, next_offset);
1501       } else {
1502         is_done = FALSE;
1503       }
1504     }
1505   }
1506   GST_OBJECT_UNLOCK (agg);
1507
1508   gst_buffer_unmap (outbuf, &outmap);
1509
1510   if (dropped && !timeout) {
1511     /* We dropped a buffer, retry */
1512     GST_INFO_OBJECT (audiomixer,
1513         "A pad dropped a buffer, wait for the next one");
1514     return GST_FLOW_OK;
1515   }
1516
1517   if (!is_done && !is_eos && !timeout) {
1518     /* Get more buffers */
1519     GST_INFO_OBJECT (audiomixer,
1520         "We're not done yet for the current offset, waiting for more data");
1521     return GST_FLOW_OK;
1522   }
1523
1524   if (is_eos) {
1525     gint64 max_offset = 0;
1526     gboolean empty_buffer = TRUE;
1527
1528     GST_DEBUG_OBJECT (audiomixer, "We're EOS");
1529
1530     GST_OBJECT_LOCK (agg);
1531     for (iter = GST_ELEMENT (agg)->sinkpads; iter; iter = iter->next) {
1532       GstAudioMixerPad *pad = GST_AUDIO_MIXER_PAD (iter->data);
1533
1534       max_offset = MAX ((gint64) max_offset, (gint64) pad->output_offset);
1535       if (pad->output_offset > audiomixer->offset)
1536         empty_buffer = FALSE;
1537     }
1538     GST_OBJECT_UNLOCK (agg);
1539
1540     /* This means EOS or no pads at all */
1541     if (empty_buffer) {
1542       gst_buffer_replace (&audiomixer->current_buffer, NULL);
1543       goto eos;
1544     }
1545
1546     if (max_offset <= next_offset) {
1547       GST_DEBUG_OBJECT (audiomixer,
1548           "Last buffer is incomplete: %" G_GUINT64_FORMAT " <= %"
1549           G_GUINT64_FORMAT, max_offset, next_offset);
1550       next_offset = max_offset;
1551       if (next_offset > audiomixer->offset)
1552         gst_buffer_resize (outbuf, 0, (next_offset - audiomixer->offset) * bpf);
1553
1554       next_timestamp = gst_util_uint64_scale (next_offset, GST_SECOND, rate);
1555     }
1556   }
1557
1558   /* set timestamps on the output buffer */
1559   if (agg->segment.rate > 0.0) {
1560     GST_BUFFER_TIMESTAMP (outbuf) = agg->segment.position;
1561     GST_BUFFER_OFFSET (outbuf) = audiomixer->offset;
1562     GST_BUFFER_OFFSET_END (outbuf) = next_offset;
1563     GST_BUFFER_DURATION (outbuf) = next_timestamp - agg->segment.position;
1564   } else {
1565     GST_BUFFER_TIMESTAMP (outbuf) = next_timestamp;
1566     GST_BUFFER_OFFSET (outbuf) = next_offset;
1567     GST_BUFFER_OFFSET_END (outbuf) = audiomixer->offset;
1568     GST_BUFFER_DURATION (outbuf) = agg->segment.position - next_timestamp;
1569   }
1570
1571   audiomixer->offset = next_offset;
1572   agg->segment.position = next_timestamp;
1573
1574   /* send it out */
1575   GST_LOG_OBJECT (audiomixer,
1576       "pushing outbuf %p, timestamp %" GST_TIME_FORMAT " offset %"
1577       G_GINT64_FORMAT, outbuf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1578       GST_BUFFER_OFFSET (outbuf));
1579
1580   ret = gst_aggregator_finish_buffer (agg, audiomixer->current_buffer);
1581   audiomixer->current_buffer = NULL;
1582
1583   GST_LOG_OBJECT (audiomixer, "pushed outbuf, result = %s",
1584       gst_flow_get_name (ret));
1585
1586   if (ret == GST_FLOW_OK && is_eos)
1587     goto eos;
1588
1589   return ret;
1590   /* ERRORS */
1591 not_negotiated:
1592   {
1593     GST_ELEMENT_ERROR (audiomixer, STREAM, FORMAT, (NULL),
1594         ("Unknown data received, not negotiated"));
1595     return GST_FLOW_NOT_NEGOTIATED;
1596   }
1597
1598 eos:
1599   {
1600     GST_DEBUG_OBJECT (audiomixer, "EOS");
1601     return GST_FLOW_EOS;
1602   }
1603 }
1604
1605 /* GstChildProxy implementation */
1606 static GObject *
1607 gst_audiomixer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
1608     guint index)
1609 {
1610   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (child_proxy);
1611   GObject *obj = NULL;
1612
1613   GST_OBJECT_LOCK (audiomixer);
1614   obj = g_list_nth_data (GST_ELEMENT_CAST (audiomixer)->sinkpads, index);
1615   if (obj)
1616     gst_object_ref (obj);
1617   GST_OBJECT_UNLOCK (audiomixer);
1618
1619   return obj;
1620 }
1621
1622 static guint
1623 gst_audiomixer_child_proxy_get_children_count (GstChildProxy * child_proxy)
1624 {
1625   guint count = 0;
1626   GstAudioMixer *audiomixer = GST_AUDIO_MIXER (child_proxy);
1627
1628   GST_OBJECT_LOCK (audiomixer);
1629   count = GST_ELEMENT_CAST (audiomixer)->numsinkpads;
1630   GST_OBJECT_UNLOCK (audiomixer);
1631   GST_INFO_OBJECT (audiomixer, "Children Count: %d", count);
1632
1633   return count;
1634 }
1635
1636 static void
1637 gst_audiomixer_child_proxy_init (gpointer g_iface, gpointer iface_data)
1638 {
1639   GstChildProxyInterface *iface = g_iface;
1640
1641   GST_INFO ("intializing child proxy interface");
1642   iface->get_child_by_index = gst_audiomixer_child_proxy_get_child_by_index;
1643   iface->get_children_count = gst_audiomixer_child_proxy_get_children_count;
1644 }
1645
1646 static gboolean
1647 plugin_init (GstPlugin * plugin)
1648 {
1649   GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "audiomixer", 0,
1650       "audio mixing element");
1651
1652   if (!gst_element_register (plugin, "audiomixer", GST_RANK_NONE,
1653           GST_TYPE_AUDIO_MIXER))
1654     return FALSE;
1655
1656   return TRUE;
1657 }
1658
1659 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1660     GST_VERSION_MINOR,
1661     audiomixer,
1662     "Mixes multiple audio streams",
1663     plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)