opus: make it build against current, and remove cruft
[platform/upstream/gstreamer.git] / ext / opus / gstopusenc.c
1 /* GStreamer Opus Encoder
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Based on the speexenc element
23  */
24
25 /**
26  * SECTION:element-opusenc
27  * @see_also: opusdec, oggmux
28  *
29  * This element encodes raw audio to OPUS.
30  *
31  * <refsect2>
32  * <title>Example pipelines</title>
33  * |[
34  * gst-launch -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! opusenc ! oggmux ! filesink location=sine.ogg
35  * ]| Encode a test sine signal to Ogg/OPUS.
36  * </refsect2>
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45 #include <math.h>
46 #include <opus/opus.h>
47
48 #include <gst/gsttagsetter.h>
49 #include <gst/tag/tag.h>
50 #include <gst/audio/audio.h>
51 #include "gstopusenc.h"
52
53 GST_DEBUG_CATEGORY_STATIC (opusenc_debug);
54 #define GST_CAT_DEFAULT opusenc_debug
55
56 #define GST_OPUS_ENC_TYPE_BANDWIDTH (gst_opus_enc_bandwidth_get_type())
57 static GType
58 gst_opus_enc_bandwidth_get_type (void)
59 {
60   static const GEnumValue values[] = {
61     {OPUS_BANDWIDTH_NARROWBAND, "Narrow band", "narrowband"},
62     {OPUS_BANDWIDTH_MEDIUMBAND, "Medium band", "mediumband"},
63     {OPUS_BANDWIDTH_WIDEBAND, "Wide band", "wideband"},
64     {OPUS_BANDWIDTH_SUPERWIDEBAND, "Super wide band", "superwideband"},
65     {OPUS_BANDWIDTH_FULLBAND, "Full band", "fullband"},
66     {OPUS_AUTO, "Auto", "auto"},
67     {0, NULL, NULL}
68   };
69   static volatile GType id = 0;
70
71   if (g_once_init_enter ((gsize *) & id)) {
72     GType _id;
73
74     _id = g_enum_register_static ("GstOpusEncBandwidth", values);
75
76     g_once_init_leave ((gsize *) & id, _id);
77   }
78
79   return id;
80 }
81
82 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
83     GST_PAD_SINK,
84     GST_PAD_ALWAYS,
85     GST_STATIC_CAPS ("audio/x-raw-int, "
86         "rate = (int) { 8000, 12000, 16000, 24000, 48000 }, "
87         "channels = (int) [ 1, 2 ], "
88         "endianness = (int) BYTE_ORDER, "
89         "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16")
90     );
91
92 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
93     GST_PAD_SRC,
94     GST_PAD_ALWAYS,
95     GST_STATIC_CAPS ("audio/x-opus, "
96         "rate = (int) { 8000, 12000, 16000, 24000, 48000 }, "
97         "channels = (int) [ 1, 2 ], " "frame-size = (int) [ 2, 60 ]")
98     );
99
100 #define DEFAULT_AUDIO           TRUE
101 #define DEFAULT_BITRATE         64000
102 #define DEFAULT_BANDWIDTH       OPUS_BANDWIDTH_FULLBAND
103 #define DEFAULT_FRAMESIZE       20
104 #define DEFAULT_CBR             TRUE
105 #define DEFAULT_CONSTRAINED_VBR TRUE
106 #define DEFAULT_COMPLEXITY      10
107 #define DEFAULT_INBAND_FEC      FALSE
108 #define DEFAULT_DTX             FALSE
109 #define DEFAULT_PACKET_LOSS_PERCENT 0
110
111 enum
112 {
113   PROP_0,
114   PROP_AUDIO,
115   PROP_BITRATE,
116   PROP_BANDWIDTH,
117   PROP_FRAME_SIZE,
118   PROP_CBR,
119   PROP_CONSTRAINED_VBR,
120   PROP_COMPLEXITY,
121   PROP_INBAND_FEC,
122   PROP_DTX,
123   PROP_PACKET_LOSS_PERCENT
124 };
125
126 static void gst_opus_enc_finalize (GObject * object);
127
128 static gboolean gst_opus_enc_sinkevent (GstPad * pad, GstEvent * event);
129 static GstFlowReturn gst_opus_enc_chain (GstPad * pad, GstBuffer * buf);
130 static gboolean gst_opus_enc_setup (GstOpusEnc * enc);
131
132 static void gst_opus_enc_get_property (GObject * object, guint prop_id,
133     GValue * value, GParamSpec * pspec);
134 static void gst_opus_enc_set_property (GObject * object, guint prop_id,
135     const GValue * value, GParamSpec * pspec);
136 static GstStateChangeReturn gst_opus_enc_change_state (GstElement * element,
137     GstStateChange transition);
138
139 static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush);
140
141 static void
142 gst_opus_enc_setup_interfaces (GType opusenc_type)
143 {
144   static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
145   const GInterfaceInfo preset_interface_info = {
146     NULL,                       /* interface_init */
147     NULL,                       /* interface_finalize */
148     NULL                        /* interface_data */
149   };
150
151   g_type_add_interface_static (opusenc_type, GST_TYPE_TAG_SETTER,
152       &tag_setter_info);
153   g_type_add_interface_static (opusenc_type, GST_TYPE_PRESET,
154       &preset_interface_info);
155
156   GST_DEBUG_CATEGORY_INIT (opusenc_debug, "opusenc", 0, "Opus encoder");
157 }
158
159 GST_BOILERPLATE_FULL (GstOpusEnc, gst_opus_enc, GstElement, GST_TYPE_ELEMENT,
160     gst_opus_enc_setup_interfaces);
161
162 static void
163 gst_opus_enc_base_init (gpointer g_class)
164 {
165   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
166
167   gst_element_class_add_pad_template (element_class,
168       gst_static_pad_template_get (&src_factory));
169   gst_element_class_add_pad_template (element_class,
170       gst_static_pad_template_get (&sink_factory));
171   gst_element_class_set_details_simple (element_class, "Opus audio encoder",
172       "Codec/Encoder/Audio",
173       "Encodes audio in Opus format",
174       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
175 }
176
177 static void
178 gst_opus_enc_class_init (GstOpusEncClass * klass)
179 {
180   GObjectClass *gobject_class;
181   GstElementClass *gstelement_class;
182
183   gobject_class = (GObjectClass *) klass;
184   gstelement_class = (GstElementClass *) klass;
185
186   gobject_class->set_property = gst_opus_enc_set_property;
187   gobject_class->get_property = gst_opus_enc_get_property;
188
189   g_object_class_install_property (gobject_class, PROP_AUDIO,
190       g_param_spec_boolean ("audio", "Audio or voice",
191           "Audio or voice", DEFAULT_AUDIO,
192           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
193   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BITRATE,
194       g_param_spec_int ("bitrate", "Encoding Bit-rate",
195           "Specify an encoding bit-rate (in bps).",
196           1, 320000, DEFAULT_BITRATE,
197           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
198   g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
199       g_param_spec_enum ("bandwidth", "Band Width",
200           "Audio Band Width", GST_OPUS_ENC_TYPE_BANDWIDTH, DEFAULT_BANDWIDTH,
201           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
202   g_object_class_install_property (gobject_class, PROP_FRAME_SIZE,
203       g_param_spec_int ("frame-size", "Frame Size",
204           "The duration of an audio frame, in ms", 2, 60, DEFAULT_FRAMESIZE,
205           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
206   g_object_class_install_property (gobject_class, PROP_CBR,
207       g_param_spec_boolean ("cbr", "Constant bit rate",
208           "Constant bit rate", DEFAULT_CBR,
209           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
210   g_object_class_install_property (gobject_class, PROP_CONSTRAINED_VBR,
211       g_param_spec_boolean ("constrained-cbr", "Constrained VBR",
212           "Constrained VBR", DEFAULT_CONSTRAINED_VBR,
213           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
214   g_object_class_install_property (gobject_class, PROP_COMPLEXITY,
215       g_param_spec_int ("complexity", "Complexity",
216           "Complexity", 0, 10, DEFAULT_COMPLEXITY,
217           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
218   g_object_class_install_property (gobject_class, PROP_INBAND_FEC,
219       g_param_spec_boolean ("inband-fec", "In-band FEC",
220           "Enable forward error correction", DEFAULT_INBAND_FEC,
221           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222   g_object_class_install_property (gobject_class, PROP_DTX,
223       g_param_spec_boolean ("dtx", "DTX",
224           "DTX", DEFAULT_DTX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
225   g_object_class_install_property (G_OBJECT_CLASS (klass),
226       PROP_PACKET_LOSS_PERCENT, g_param_spec_int ("packet-loss-percentage",
227           "Loss percentage", "Packet loss percentage", 0, 100,
228           DEFAULT_PACKET_LOSS_PERCENT,
229           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
230
231   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_opus_enc_finalize);
232
233   gstelement_class->change_state =
234       GST_DEBUG_FUNCPTR (gst_opus_enc_change_state);
235 }
236
237 static void
238 gst_opus_enc_finalize (GObject * object)
239 {
240   GstOpusEnc *enc;
241
242   enc = GST_OPUS_ENC (object);
243
244   g_object_unref (enc->adapter);
245
246   G_OBJECT_CLASS (parent_class)->finalize (object);
247 }
248
249 static gboolean
250 gst_opus_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
251 {
252   GstOpusEnc *enc;
253   GstStructure *structure;
254   GstCaps *otherpadcaps;
255
256   enc = GST_OPUS_ENC (GST_PAD_PARENT (pad));
257   enc->setup = FALSE;
258   enc->frame_size = DEFAULT_FRAMESIZE;
259   otherpadcaps = gst_pad_get_allowed_caps (pad);
260
261   structure = gst_caps_get_structure (caps, 0);
262   gst_structure_get_int (structure, "channels", &enc->n_channels);
263   gst_structure_get_int (structure, "rate", &enc->sample_rate);
264
265   if (otherpadcaps) {
266     if (!gst_caps_is_empty (otherpadcaps)) {
267       GstStructure *ps = gst_caps_get_structure (otherpadcaps, 0);
268       gst_structure_get_int (ps, "frame-size", &enc->frame_size);
269     }
270     gst_caps_unref (otherpadcaps);
271   }
272
273   GST_ERROR_OBJECT (pad, "channels=%d rate=%d frame-size=%d",
274       enc->n_channels, enc->sample_rate, enc->frame_size);
275   switch (enc->frame_size) {
276     case 2:
277       enc->frame_samples = enc->sample_rate / 400;
278       break;
279     case 5:
280       enc->frame_samples = enc->sample_rate / 200;
281       break;
282     case 10:
283       enc->frame_samples = enc->sample_rate / 100;
284       break;
285     case 20:
286       enc->frame_samples = enc->sample_rate / 50;
287       break;
288     case 40:
289       enc->frame_samples = enc->sample_rate / 20;
290       break;
291     case 60:
292       enc->frame_samples = 3 * enc->sample_rate / 50;
293       break;
294     default:
295       return FALSE;
296       break;
297   }
298   GST_ERROR ("frame_samples %d", enc->frame_samples);
299
300   gst_opus_enc_setup (enc);
301
302   return TRUE;
303 }
304
305
306 static GstCaps *
307 gst_opus_enc_sink_getcaps (GstPad * pad)
308 {
309   GstCaps *caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
310   GstCaps *peercaps = NULL;
311   GstOpusEnc *enc = GST_OPUS_ENC (gst_pad_get_parent_element (pad));
312
313   peercaps = gst_pad_peer_get_caps (enc->srcpad);
314
315   if (peercaps) {
316     if (!gst_caps_is_empty (peercaps) && !gst_caps_is_any (peercaps)) {
317       GstStructure *ps = gst_caps_get_structure (peercaps, 0);
318       GstStructure *s = gst_caps_get_structure (caps, 0);
319       gint rate, channels;
320
321       if (gst_structure_get_int (ps, "rate", &rate)) {
322         gst_structure_fixate_field_nearest_int (s, "rate", rate);
323       }
324
325       if (gst_structure_get_int (ps, "channels", &channels)) {
326         gst_structure_fixate_field_nearest_int (s, "channels", channels);
327       }
328     }
329     gst_caps_unref (peercaps);
330   }
331
332   gst_object_unref (enc);
333
334   return caps;
335 }
336
337
338 static gboolean
339 gst_opus_enc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
340     GstFormat * dest_format, gint64 * dest_value)
341 {
342   gboolean res = TRUE;
343   GstOpusEnc *enc;
344   gint64 avg;
345
346   enc = GST_OPUS_ENC (GST_PAD_PARENT (pad));
347
348   if (enc->samples_in == 0 || enc->bytes_out == 0 || enc->sample_rate == 0)
349     return FALSE;
350
351   avg = (enc->bytes_out * enc->sample_rate) / (enc->samples_in);
352
353   switch (src_format) {
354     case GST_FORMAT_BYTES:
355       switch (*dest_format) {
356         case GST_FORMAT_TIME:
357           *dest_value = src_value * GST_SECOND / avg;
358           break;
359         default:
360           res = FALSE;
361       }
362       break;
363     case GST_FORMAT_TIME:
364       switch (*dest_format) {
365         case GST_FORMAT_BYTES:
366           *dest_value = src_value * avg / GST_SECOND;
367           break;
368         default:
369           res = FALSE;
370       }
371       break;
372     default:
373       res = FALSE;
374   }
375   return res;
376 }
377
378 static gboolean
379 gst_opus_enc_convert_sink (GstPad * pad, GstFormat src_format,
380     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
381 {
382   gboolean res = TRUE;
383   guint scale = 1;
384   gint bytes_per_sample;
385   GstOpusEnc *enc;
386
387   enc = GST_OPUS_ENC (GST_PAD_PARENT (pad));
388
389   bytes_per_sample = enc->n_channels * 2;
390
391   switch (src_format) {
392     case GST_FORMAT_BYTES:
393       switch (*dest_format) {
394         case GST_FORMAT_DEFAULT:
395           if (bytes_per_sample == 0)
396             return FALSE;
397           *dest_value = src_value / bytes_per_sample;
398           break;
399         case GST_FORMAT_TIME:
400         {
401           gint byterate = bytes_per_sample * enc->sample_rate;
402
403           if (byterate == 0)
404             return FALSE;
405           *dest_value = src_value * GST_SECOND / byterate;
406           break;
407         }
408         default:
409           res = FALSE;
410       }
411       break;
412     case GST_FORMAT_DEFAULT:
413       switch (*dest_format) {
414         case GST_FORMAT_BYTES:
415           *dest_value = src_value * bytes_per_sample;
416           break;
417         case GST_FORMAT_TIME:
418           if (enc->sample_rate == 0)
419             return FALSE;
420           *dest_value = src_value * GST_SECOND / enc->sample_rate;
421           break;
422         default:
423           res = FALSE;
424       }
425       break;
426     case GST_FORMAT_TIME:
427       switch (*dest_format) {
428         case GST_FORMAT_BYTES:
429           scale = bytes_per_sample;
430           /* fallthrough */
431         case GST_FORMAT_DEFAULT:
432           *dest_value = src_value * scale * enc->sample_rate / GST_SECOND;
433           break;
434         default:
435           res = FALSE;
436       }
437       break;
438     default:
439       res = FALSE;
440   }
441   return res;
442 }
443
444 static gint64
445 gst_opus_enc_get_latency (GstOpusEnc * enc)
446 {
447   return gst_util_uint64_scale (enc->frame_samples, GST_SECOND,
448       enc->sample_rate);
449 }
450
451 static const GstQueryType *
452 gst_opus_enc_get_query_types (GstPad * pad)
453 {
454   static const GstQueryType gst_opus_enc_src_query_types[] = {
455     GST_QUERY_POSITION,
456     GST_QUERY_DURATION,
457     GST_QUERY_CONVERT,
458     GST_QUERY_LATENCY,
459     0
460   };
461
462   return gst_opus_enc_src_query_types;
463 }
464
465 static gboolean
466 gst_opus_enc_src_query (GstPad * pad, GstQuery * query)
467 {
468   gboolean res = TRUE;
469   GstOpusEnc *enc;
470
471   enc = GST_OPUS_ENC (gst_pad_get_parent (pad));
472
473   switch (GST_QUERY_TYPE (query)) {
474     case GST_QUERY_POSITION:
475     {
476       GstFormat fmt, req_fmt;
477       gint64 pos, val;
478
479       gst_query_parse_position (query, &req_fmt, NULL);
480       if ((res = gst_pad_query_peer_position (enc->sinkpad, &req_fmt, &val))) {
481         gst_query_set_position (query, req_fmt, val);
482         break;
483       }
484
485       fmt = GST_FORMAT_TIME;
486       if (!(res = gst_pad_query_peer_position (enc->sinkpad, &fmt, &pos)))
487         break;
488
489       if ((res =
490               gst_pad_query_peer_convert (enc->sinkpad, fmt, pos, &req_fmt,
491                   &val)))
492         gst_query_set_position (query, req_fmt, val);
493
494       break;
495     }
496     case GST_QUERY_DURATION:
497     {
498       GstFormat fmt, req_fmt;
499       gint64 dur, val;
500
501       gst_query_parse_duration (query, &req_fmt, NULL);
502       if ((res = gst_pad_query_peer_duration (enc->sinkpad, &req_fmt, &val))) {
503         gst_query_set_duration (query, req_fmt, val);
504         break;
505       }
506
507       fmt = GST_FORMAT_TIME;
508       if (!(res = gst_pad_query_peer_duration (enc->sinkpad, &fmt, &dur)))
509         break;
510
511       if ((res =
512               gst_pad_query_peer_convert (enc->sinkpad, fmt, dur, &req_fmt,
513                   &val))) {
514         gst_query_set_duration (query, req_fmt, val);
515       }
516       break;
517     }
518     case GST_QUERY_CONVERT:
519     {
520       GstFormat src_fmt, dest_fmt;
521       gint64 src_val, dest_val;
522
523       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
524       if (!(res = gst_opus_enc_convert_src (pad, src_fmt, src_val, &dest_fmt,
525                   &dest_val)))
526         goto error;
527       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
528       break;
529     }
530     case GST_QUERY_LATENCY:
531     {
532       gboolean live;
533       GstClockTime min_latency, max_latency;
534       gint64 latency;
535
536       if ((res = gst_pad_peer_query (pad, query))) {
537         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
538
539         latency = gst_opus_enc_get_latency (enc);
540
541         /* add our latency */
542         min_latency += latency;
543         if (max_latency != -1)
544           max_latency += latency;
545
546         gst_query_set_latency (query, live, min_latency, max_latency);
547       }
548       break;
549     }
550     default:
551       res = gst_pad_peer_query (pad, query);
552       break;
553   }
554
555 error:
556
557   gst_object_unref (enc);
558
559   return res;
560 }
561
562 static gboolean
563 gst_opus_enc_sink_query (GstPad * pad, GstQuery * query)
564 {
565   gboolean res = TRUE;
566
567   switch (GST_QUERY_TYPE (query)) {
568     case GST_QUERY_CONVERT:
569     {
570       GstFormat src_fmt, dest_fmt;
571       gint64 src_val, dest_val;
572
573       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
574       if (!(res =
575               gst_opus_enc_convert_sink (pad, src_fmt, src_val, &dest_fmt,
576                   &dest_val)))
577         goto error;
578       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
579       break;
580     }
581     default:
582       res = gst_pad_query_default (pad, query);
583       break;
584   }
585
586 error:
587   return res;
588 }
589
590 static void
591 gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass)
592 {
593   enc->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
594   gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
595   gst_pad_set_event_function (enc->sinkpad,
596       GST_DEBUG_FUNCPTR (gst_opus_enc_sinkevent));
597   gst_pad_set_chain_function (enc->sinkpad,
598       GST_DEBUG_FUNCPTR (gst_opus_enc_chain));
599   gst_pad_set_setcaps_function (enc->sinkpad,
600       GST_DEBUG_FUNCPTR (gst_opus_enc_sink_setcaps));
601   gst_pad_set_getcaps_function (enc->sinkpad,
602       GST_DEBUG_FUNCPTR (gst_opus_enc_sink_getcaps));
603   gst_pad_set_query_function (enc->sinkpad,
604       GST_DEBUG_FUNCPTR (gst_opus_enc_sink_query));
605
606   enc->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
607   gst_pad_set_query_function (enc->srcpad,
608       GST_DEBUG_FUNCPTR (gst_opus_enc_src_query));
609   gst_pad_set_query_type_function (enc->srcpad,
610       GST_DEBUG_FUNCPTR (gst_opus_enc_get_query_types));
611   gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
612
613   enc->n_channels = -1;
614   enc->sample_rate = -1;
615   enc->frame_samples = 0;
616
617   enc->bitrate = DEFAULT_BITRATE;
618   enc->bandwidth = DEFAULT_BANDWIDTH;
619   enc->frame_size = DEFAULT_FRAMESIZE;
620   enc->cbr = DEFAULT_CBR;
621   enc->constrained_vbr = DEFAULT_CONSTRAINED_VBR;
622   enc->complexity = DEFAULT_COMPLEXITY;
623   enc->inband_fec = DEFAULT_INBAND_FEC;
624   enc->dtx = DEFAULT_DTX;
625   enc->packet_loss_percentage = DEFAULT_PACKET_LOSS_PERCENT;
626
627   enc->setup = FALSE;
628   enc->header_sent = FALSE;
629
630   enc->adapter = gst_adapter_new ();
631 }
632
633 #if 0
634 static GstBuffer *
635 gst_opus_enc_create_metadata_buffer (GstOpusEnc * enc)
636 {
637   const GstTagList *tags;
638   GstTagList *empty_tags = NULL;
639   GstBuffer *comments = NULL;
640
641   tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
642
643   GST_DEBUG_OBJECT (enc, "tags = %" GST_PTR_FORMAT, tags);
644
645   if (tags == NULL) {
646     /* FIXME: better fix chain of callers to not write metadata at all,
647      * if there is none */
648     empty_tags = gst_tag_list_new ();
649     tags = empty_tags;
650   }
651   comments = gst_tag_list_to_vorbiscomment_buffer (tags, NULL,
652       0, "Encoded with GStreamer Opusenc");
653
654   GST_BUFFER_OFFSET (comments) = enc->bytes_out;
655   GST_BUFFER_OFFSET_END (comments) = 0;
656
657   if (empty_tags)
658     gst_tag_list_free (empty_tags);
659
660   return comments;
661 }
662 #endif
663
664 static gboolean
665 gst_opus_enc_setup (GstOpusEnc * enc)
666 {
667   int error = OPUS_OK;
668
669   enc->setup = FALSE;
670
671   enc->state = opus_encoder_create (enc->sample_rate, enc->n_channels,
672       enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP,
673       &error);
674   if (!enc->state || error != OPUS_OK)
675     goto encoder_creation_failed;
676
677   opus_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0);
678   opus_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth), 0);
679   opus_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
680   opus_encoder_ctl (enc->state, OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr),
681       0);
682   opus_encoder_ctl (enc->state, OPUS_SET_COMPLEXITY (enc->complexity), 0);
683   opus_encoder_ctl (enc->state, OPUS_SET_INBAND_FEC (enc->inband_fec), 0);
684   opus_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0);
685   opus_encoder_ctl (enc->state,
686       OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);
687
688   GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size);
689
690   enc->setup = TRUE;
691
692   return TRUE;
693
694 #if 0
695 mode_initialization_failed:
696   GST_ERROR_OBJECT (enc, "Mode initialization failed: %d", error);
697   return FALSE;
698 #endif
699
700 encoder_creation_failed:
701   GST_ERROR_OBJECT (enc, "Encoder creation failed");
702   return FALSE;
703 }
704
705
706 /* push out the buffer and do internal bookkeeping */
707 static GstFlowReturn
708 gst_opus_enc_push_buffer (GstOpusEnc * enc, GstBuffer * buffer)
709 {
710   guint size;
711
712   size = GST_BUFFER_SIZE (buffer);
713
714   enc->bytes_out += size;
715
716   GST_DEBUG_OBJECT (enc, "pushing output buffer of size %u", size);
717
718   return gst_pad_push (enc->srcpad, buffer);
719 }
720
721 #if 0
722 static GstCaps *
723 gst_opus_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
724     GstBuffer * buf2)
725 {
726   GstStructure *structure = NULL;
727   GstBuffer *buf;
728   GValue array = { 0 };
729   GValue value = { 0 };
730
731   caps = gst_caps_make_writable (caps);
732   structure = gst_caps_get_structure (caps, 0);
733
734   g_assert (gst_buffer_is_metadata_writable (buf1));
735   g_assert (gst_buffer_is_metadata_writable (buf2));
736
737   /* mark buffers */
738   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
739   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
740
741   /* put buffers in a fixed list */
742   g_value_init (&array, GST_TYPE_ARRAY);
743   g_value_init (&value, GST_TYPE_BUFFER);
744   buf = gst_buffer_copy (buf1);
745   gst_value_set_buffer (&value, buf);
746   gst_buffer_unref (buf);
747   gst_value_array_append_value (&array, &value);
748   g_value_unset (&value);
749   g_value_init (&value, GST_TYPE_BUFFER);
750   buf = gst_buffer_copy (buf2);
751   gst_value_set_buffer (&value, buf);
752   gst_buffer_unref (buf);
753   gst_value_array_append_value (&array, &value);
754   gst_structure_set_value (structure, "streamheader", &array);
755   g_value_unset (&value);
756   g_value_unset (&array);
757
758   return caps;
759 }
760 #endif
761
762
763 static gboolean
764 gst_opus_enc_sinkevent (GstPad * pad, GstEvent * event)
765 {
766   gboolean res = TRUE;
767   GstOpusEnc *enc;
768
769   enc = GST_OPUS_ENC (gst_pad_get_parent (pad));
770
771   switch (GST_EVENT_TYPE (event)) {
772     case GST_EVENT_EOS:
773       gst_opus_enc_encode (enc, TRUE);
774       res = gst_pad_event_default (pad, event);
775       break;
776     case GST_EVENT_TAG:
777     {
778       GstTagList *list;
779       GstTagSetter *setter = GST_TAG_SETTER (enc);
780       const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
781
782       gst_event_parse_tag (event, &list);
783       gst_tag_setter_merge_tags (setter, list, mode);
784       res = gst_pad_event_default (pad, event);
785       break;
786     }
787     default:
788       res = gst_pad_event_default (pad, event);
789       break;
790   }
791
792   gst_object_unref (enc);
793
794   return res;
795 }
796
797 static GstFlowReturn
798 gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush)
799 {
800
801   GstFlowReturn ret = GST_FLOW_OK;
802   gint bytes = enc->frame_samples * 2 * enc->n_channels;
803   gint bytes_per_packet;
804
805   bytes_per_packet =
806       (enc->bitrate * enc->frame_samples / enc->sample_rate + 4) / 8;
807
808   if (flush && gst_adapter_available (enc->adapter) % bytes != 0) {
809     guint diff = gst_adapter_available (enc->adapter) % bytes;
810     GstBuffer *buf = gst_buffer_new_and_alloc (diff);
811
812     memset (GST_BUFFER_DATA (buf), 0, diff);
813     gst_adapter_push (enc->adapter, buf);
814   }
815
816
817   while (gst_adapter_available (enc->adapter) >= bytes) {
818     gint16 *data;
819     gint outsize;
820     GstBuffer *outbuf;
821
822     ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
823         GST_BUFFER_OFFSET_NONE, bytes_per_packet, GST_PAD_CAPS (enc->srcpad),
824         &outbuf);
825
826     if (GST_FLOW_OK != ret)
827       goto done;
828
829     data = (gint16 *) gst_adapter_take (enc->adapter, bytes);
830     enc->samples_in += enc->frame_samples;
831
832     GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
833         enc->frame_samples, bytes);
834
835     outsize = opus_encode (enc->state, data, enc->frame_samples,
836         GST_BUFFER_DATA (outbuf), bytes_per_packet);
837
838     g_free (data);
839
840     if (outsize < 0) {
841       GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
842       ret = GST_FLOW_ERROR;
843       goto done;
844     }
845
846     GST_BUFFER_TIMESTAMP (outbuf) = enc->start_ts +
847         gst_util_uint64_scale_int (enc->frameno_out * enc->frame_samples,
848         GST_SECOND, enc->sample_rate);
849     GST_BUFFER_DURATION (outbuf) =
850         gst_util_uint64_scale_int (enc->frame_samples, GST_SECOND,
851         enc->sample_rate);
852     GST_BUFFER_OFFSET (outbuf) =
853         gst_util_uint64_scale_int (GST_BUFFER_OFFSET_END (outbuf), GST_SECOND,
854         enc->sample_rate);
855
856     enc->frameno++;
857     enc->frameno_out++;
858
859     ret = gst_opus_enc_push_buffer (enc, outbuf);
860
861     if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
862       goto done;
863   }
864
865 done:
866
867   return ret;
868 }
869
870 static GstFlowReturn
871 gst_opus_enc_chain (GstPad * pad, GstBuffer * buf)
872 {
873   GstOpusEnc *enc;
874   GstFlowReturn ret = GST_FLOW_OK;
875
876   enc = GST_OPUS_ENC (GST_PAD_PARENT (pad));
877
878   if (!enc->setup)
879     goto not_setup;
880
881 #if 0
882   if (!enc->header_sent) {
883     /* Opus streams begin with two headers; the initial header (with
884        most of the codec setup parameters) which is mandated by the Ogg
885        bitstream spec.  The second header holds any comment fields.
886        We merely need to make the headers, then pass them to libopus 
887        one at a time; libopus handles the additional Ogg bitstream 
888        constraints */
889     GstBuffer *buf1, *buf2;
890     GstCaps *caps;
891     guchar data[100];
892
893     /* create header buffer */
894     opus_header_to_packet (&enc->header, data, 100);
895     buf1 = gst_opus_enc_buffer_from_data (enc, data, 100, 0);
896
897     /* create comment buffer */
898     buf2 = gst_opus_enc_create_metadata_buffer (enc);
899
900     /* mark and put on caps */
901     caps = gst_pad_get_caps (enc->srcpad);
902     caps = gst_opus_enc_set_header_on_caps (caps, buf1, buf2);
903
904     gst_caps_set_simple (caps,
905         "rate", G_TYPE_INT, enc->sample_rate,
906         "channels", G_TYPE_INT, enc->n_channels,
907         "frame-size", G_TYPE_INT, enc->frame_size, NULL);
908
909     /* negotiate with these caps */
910     GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
911     GST_LOG_OBJECT (enc, "rate=%d channels=%d frame-size=%d",
912         enc->sample_rate, enc->n_channels, enc->frame_size);
913     gst_pad_set_caps (enc->srcpad, caps);
914
915     gst_buffer_set_caps (buf1, caps);
916     gst_buffer_set_caps (buf2, caps);
917     gst_caps_unref (caps);
918
919     /* push out buffers */
920     ret = gst_opus_enc_push_buffer (enc, buf1);
921
922     if (ret != GST_FLOW_OK) {
923       gst_buffer_unref (buf2);
924       goto done;
925     }
926
927     ret = gst_opus_enc_push_buffer (enc, buf2);
928
929     if (ret != GST_FLOW_OK)
930       goto done;
931
932     enc->header_sent = TRUE;
933   }
934 #endif
935
936   GST_DEBUG_OBJECT (enc, "received buffer of %u bytes", GST_BUFFER_SIZE (buf));
937
938   /* Save the timestamp of the first buffer. This will be later
939    * used as offset for all following buffers */
940   if (enc->start_ts == GST_CLOCK_TIME_NONE) {
941     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
942       enc->start_ts = GST_BUFFER_TIMESTAMP (buf);
943     } else {
944       enc->start_ts = 0;
945     }
946   }
947
948
949   /* Check if we have a continous stream, if not drop some samples or the buffer or
950    * insert some silence samples */
951   if (enc->next_ts != GST_CLOCK_TIME_NONE &&
952       GST_BUFFER_TIMESTAMP (buf) < enc->next_ts) {
953     guint64 diff = enc->next_ts - GST_BUFFER_TIMESTAMP (buf);
954     guint64 diff_bytes;
955
956     GST_WARNING_OBJECT (enc, "Buffer is older than previous "
957         "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
958         "), cannot handle. Clipping buffer.",
959         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
960         GST_TIME_ARGS (enc->next_ts));
961
962     diff_bytes =
963         GST_CLOCK_TIME_TO_FRAMES (diff, enc->sample_rate) * enc->n_channels * 2;
964     if (diff_bytes >= GST_BUFFER_SIZE (buf)) {
965       gst_buffer_unref (buf);
966       return GST_FLOW_OK;
967     }
968     buf = gst_buffer_make_metadata_writable (buf);
969     GST_BUFFER_DATA (buf) += diff_bytes;
970     GST_BUFFER_SIZE (buf) -= diff_bytes;
971
972     GST_BUFFER_TIMESTAMP (buf) += diff;
973     if (GST_BUFFER_DURATION_IS_VALID (buf))
974       GST_BUFFER_DURATION (buf) -= diff;
975   }
976
977   if (enc->next_ts != GST_CLOCK_TIME_NONE
978       && GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
979     guint64 max_diff =
980         gst_util_uint64_scale (enc->frame_size, GST_SECOND, enc->sample_rate);
981
982     if (GST_BUFFER_TIMESTAMP (buf) != enc->next_ts &&
983         GST_BUFFER_TIMESTAMP (buf) - enc->next_ts > max_diff) {
984       GST_WARNING_OBJECT (enc,
985           "Discontinuity detected: %" G_GUINT64_FORMAT " > %" G_GUINT64_FORMAT,
986           GST_BUFFER_TIMESTAMP (buf) - enc->next_ts, max_diff);
987
988       gst_opus_enc_encode (enc, TRUE);
989
990       enc->frameno_out = 0;
991       enc->start_ts = GST_BUFFER_TIMESTAMP (buf);
992     }
993   }
994
995   if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)
996       && GST_BUFFER_DURATION_IS_VALID (buf))
997     enc->next_ts = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
998   else
999     enc->next_ts = GST_CLOCK_TIME_NONE;
1000
1001   /* push buffer to adapter */
1002   gst_adapter_push (enc->adapter, buf);
1003   buf = NULL;
1004
1005   ret = gst_opus_enc_encode (enc, FALSE);
1006
1007 done:
1008
1009   if (buf)
1010     gst_buffer_unref (buf);
1011
1012   return ret;
1013
1014   /* ERRORS */
1015 not_setup:
1016   {
1017     GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
1018         ("encoder not initialized (input is not audio?)"));
1019     ret = GST_FLOW_NOT_NEGOTIATED;
1020     goto done;
1021   }
1022
1023 }
1024
1025
1026 static void
1027 gst_opus_enc_get_property (GObject * object, guint prop_id, GValue * value,
1028     GParamSpec * pspec)
1029 {
1030   GstOpusEnc *enc;
1031
1032   enc = GST_OPUS_ENC (object);
1033
1034   switch (prop_id) {
1035     case PROP_AUDIO:
1036       g_value_set_boolean (value, enc->audio_or_voip);
1037       break;
1038     case PROP_BITRATE:
1039       g_value_set_int (value, enc->bitrate);
1040       break;
1041     case PROP_BANDWIDTH:
1042       g_value_set_int (value, enc->bandwidth);
1043       break;
1044     case PROP_FRAME_SIZE:
1045       g_value_set_int (value, enc->frame_size);
1046       break;
1047     case PROP_CBR:
1048       g_value_set_boolean (value, enc->cbr);
1049       break;
1050     case PROP_CONSTRAINED_VBR:
1051       g_value_set_boolean (value, enc->constrained_vbr);
1052       break;
1053     case PROP_COMPLEXITY:
1054       g_value_set_int (value, enc->complexity);
1055       break;
1056     case PROP_INBAND_FEC:
1057       g_value_set_boolean (value, enc->inband_fec);
1058       break;
1059     case PROP_DTX:
1060       g_value_set_boolean (value, enc->dtx);
1061       break;
1062     case PROP_PACKET_LOSS_PERCENT:
1063       g_value_set_int (value, enc->packet_loss_percentage);
1064       break;
1065     default:
1066       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1067       break;
1068   }
1069 }
1070
1071 static void
1072 gst_opus_enc_set_property (GObject * object, guint prop_id,
1073     const GValue * value, GParamSpec * pspec)
1074 {
1075   GstOpusEnc *enc;
1076
1077   enc = GST_OPUS_ENC (object);
1078
1079   switch (prop_id) {
1080     case PROP_AUDIO:
1081       enc->audio_or_voip = g_value_get_boolean (value);
1082       break;
1083     case PROP_BITRATE:
1084       enc->bitrate = g_value_get_int (value);
1085       break;
1086     case PROP_BANDWIDTH:
1087       enc->bandwidth = g_value_get_int (value);
1088       break;
1089     case PROP_FRAME_SIZE:
1090       enc->frame_size = g_value_get_int (value);
1091       break;
1092     case PROP_CBR:
1093       enc->cbr = g_value_get_boolean (value);
1094       break;
1095     case PROP_CONSTRAINED_VBR:
1096       enc->constrained_vbr = g_value_get_boolean (value);
1097       break;
1098     case PROP_COMPLEXITY:
1099       enc->complexity = g_value_get_int (value);
1100       break;
1101     case PROP_INBAND_FEC:
1102       enc->inband_fec = g_value_get_boolean (value);
1103       break;
1104     case PROP_DTX:
1105       enc->dtx = g_value_get_boolean (value);
1106       break;
1107     case PROP_PACKET_LOSS_PERCENT:
1108       enc->packet_loss_percentage = g_value_get_int (value);
1109       break;
1110     default:
1111       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1112       break;
1113   }
1114 }
1115
1116 static GstStateChangeReturn
1117 gst_opus_enc_change_state (GstElement * element, GstStateChange transition)
1118 {
1119   GstOpusEnc *enc = GST_OPUS_ENC (element);
1120   GstStateChangeReturn res;
1121
1122   switch (transition) {
1123     case GST_STATE_CHANGE_NULL_TO_READY:
1124       break;
1125     case GST_STATE_CHANGE_READY_TO_PAUSED:
1126       enc->frameno = 0;
1127       enc->samples_in = 0;
1128       enc->frameno_out = 0;
1129       enc->start_ts = GST_CLOCK_TIME_NONE;
1130       enc->next_ts = GST_CLOCK_TIME_NONE;
1131       break;
1132     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1133       /* fall through */
1134     default:
1135       break;
1136   }
1137
1138   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1139   if (res == GST_STATE_CHANGE_FAILURE)
1140     return res;
1141
1142   switch (transition) {
1143     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1144       break;
1145     case GST_STATE_CHANGE_PAUSED_TO_READY:
1146       enc->setup = FALSE;
1147       enc->header_sent = FALSE;
1148       if (enc->state) {
1149         opus_encoder_destroy (enc->state);
1150         enc->state = NULL;
1151       }
1152       break;
1153     case GST_STATE_CHANGE_READY_TO_NULL:
1154       gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
1155     default:
1156       break;
1157   }
1158
1159   return res;
1160 }