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 * Copyright (C) <2011> Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 * Based on the speexenc element
27 * SECTION:element-opusenc
28 * @see_also: opusdec, oggmux
30 * This element encodes raw audio to OPUS.
33 * <title>Example pipelines</title>
35 * gst-launch -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! opusenc ! oggmux ! filesink location=sine.ogg
36 * ]| Encode a test sine signal to Ogg/OPUS.
47 #include <opus/opus.h>
49 #include <gst/gsttagsetter.h>
50 #include <gst/audio/audio.h>
51 #include "gstopusheader.h"
52 #include "gstopuscommon.h"
53 #include "gstopusenc.h"
55 GST_DEBUG_CATEGORY_STATIC (opusenc_debug);
56 #define GST_CAT_DEFAULT opusenc_debug
58 /* Some arbitrary bounds beyond which it really doesn't make sense.
59 The spec mentions 6 kb/s to 510 kb/s, so 4000 and 650000 ought to be
60 safe as property bounds. */
61 #define LOWEST_BITRATE 4000
62 #define HIGHEST_BITRATE 650000
64 #define GST_OPUS_ENC_TYPE_BANDWIDTH (gst_opus_enc_bandwidth_get_type())
66 gst_opus_enc_bandwidth_get_type (void)
68 static const GEnumValue values[] = {
69 {OPUS_BANDWIDTH_NARROWBAND, "Narrow band", "narrowband"},
70 {OPUS_BANDWIDTH_MEDIUMBAND, "Medium band", "mediumband"},
71 {OPUS_BANDWIDTH_WIDEBAND, "Wide band", "wideband"},
72 {OPUS_BANDWIDTH_SUPERWIDEBAND, "Super wide band", "superwideband"},
73 {OPUS_BANDWIDTH_FULLBAND, "Full band", "fullband"},
74 {OPUS_AUTO, "Auto", "auto"},
77 static volatile GType id = 0;
79 if (g_once_init_enter ((gsize *) & id)) {
82 _id = g_enum_register_static ("GstOpusEncBandwidth", values);
84 g_once_init_leave ((gsize *) & id, _id);
90 #define GST_OPUS_ENC_TYPE_FRAME_SIZE (gst_opus_enc_frame_size_get_type())
92 gst_opus_enc_frame_size_get_type (void)
94 static const GEnumValue values[] = {
103 static volatile GType id = 0;
105 if (g_once_init_enter ((gsize *) & id)) {
108 _id = g_enum_register_static ("GstOpusEncFrameSize", values);
110 g_once_init_leave ((gsize *) & id, _id);
116 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
119 GST_STATIC_CAPS ("audio/x-raw-int, "
120 "rate = (int) { 48000, 24000, 16000, 12000, 8000 }, "
121 "channels = (int) [ 1, 8 ], "
122 "endianness = (int) BYTE_ORDER, "
123 "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16")
126 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
129 GST_STATIC_CAPS ("audio/x-opus")
132 #define DEFAULT_AUDIO TRUE
133 #define DEFAULT_BITRATE 64000
134 #define DEFAULT_BANDWIDTH OPUS_BANDWIDTH_FULLBAND
135 #define DEFAULT_FRAMESIZE 20
136 #define DEFAULT_CBR TRUE
137 #define DEFAULT_CONSTRAINED_VBR TRUE
138 #define DEFAULT_COMPLEXITY 10
139 #define DEFAULT_INBAND_FEC FALSE
140 #define DEFAULT_DTX FALSE
141 #define DEFAULT_PACKET_LOSS_PERCENT 0
142 #define DEFAULT_MAX_PAYLOAD_SIZE 1024
152 PROP_CONSTRAINED_VBR,
156 PROP_PACKET_LOSS_PERCENT,
157 PROP_MAX_PAYLOAD_SIZE
160 static void gst_opus_enc_finalize (GObject * object);
162 static gboolean gst_opus_enc_sink_event (GstAudioEncoder * benc,
164 static gboolean gst_opus_enc_setup (GstOpusEnc * enc);
166 static void gst_opus_enc_get_property (GObject * object, guint prop_id,
167 GValue * value, GParamSpec * pspec);
168 static void gst_opus_enc_set_property (GObject * object, guint prop_id,
169 const GValue * value, GParamSpec * pspec);
171 static gboolean gst_opus_enc_start (GstAudioEncoder * benc);
172 static gboolean gst_opus_enc_stop (GstAudioEncoder * benc);
173 static gboolean gst_opus_enc_set_format (GstAudioEncoder * benc,
174 GstAudioInfo * info);
175 static GstFlowReturn gst_opus_enc_handle_frame (GstAudioEncoder * benc,
177 static gint64 gst_opus_enc_get_latency (GstOpusEnc * enc);
179 static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buffer);
182 gst_opus_enc_setup_interfaces (GType opusenc_type)
184 static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
185 const GInterfaceInfo preset_interface_info = {
186 NULL, /* interface_init */
187 NULL, /* interface_finalize */
188 NULL /* interface_data */
191 g_type_add_interface_static (opusenc_type, GST_TYPE_TAG_SETTER,
193 g_type_add_interface_static (opusenc_type, GST_TYPE_PRESET,
194 &preset_interface_info);
196 GST_DEBUG_CATEGORY_INIT (opusenc_debug, "opusenc", 0, "Opus encoder");
199 GST_BOILERPLATE_FULL (GstOpusEnc, gst_opus_enc, GstAudioEncoder,
200 GST_TYPE_AUDIO_ENCODER, gst_opus_enc_setup_interfaces);
203 gst_opus_enc_base_init (gpointer g_class)
205 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
207 gst_element_class_add_pad_template (element_class,
208 gst_static_pad_template_get (&src_factory));
209 gst_element_class_add_pad_template (element_class,
210 gst_static_pad_template_get (&sink_factory));
211 gst_element_class_set_details_simple (element_class, "Opus audio encoder",
212 "Codec/Encoder/Audio",
213 "Encodes audio in Opus format",
214 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
218 gst_opus_enc_class_init (GstOpusEncClass * klass)
220 GObjectClass *gobject_class;
221 GstElementClass *gstelement_class;
222 GstAudioEncoderClass *base_class;
224 gobject_class = (GObjectClass *) klass;
225 gstelement_class = (GstElementClass *) klass;
226 base_class = (GstAudioEncoderClass *) klass;
228 gobject_class->set_property = gst_opus_enc_set_property;
229 gobject_class->get_property = gst_opus_enc_get_property;
231 base_class->start = GST_DEBUG_FUNCPTR (gst_opus_enc_start);
232 base_class->stop = GST_DEBUG_FUNCPTR (gst_opus_enc_stop);
233 base_class->set_format = GST_DEBUG_FUNCPTR (gst_opus_enc_set_format);
234 base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_opus_enc_handle_frame);
235 base_class->event = GST_DEBUG_FUNCPTR (gst_opus_enc_sink_event);
237 g_object_class_install_property (gobject_class, PROP_AUDIO,
238 g_param_spec_boolean ("audio", "Audio or voice",
239 "Audio or voice", DEFAULT_AUDIO,
240 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
241 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BITRATE,
242 g_param_spec_int ("bitrate", "Encoding Bit-rate",
243 "Specify an encoding bit-rate (in bps).",
244 LOWEST_BITRATE, HIGHEST_BITRATE, DEFAULT_BITRATE,
245 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
246 GST_PARAM_MUTABLE_PLAYING));
247 g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
248 g_param_spec_enum ("bandwidth", "Band Width", "Audio Band Width",
249 GST_OPUS_ENC_TYPE_BANDWIDTH, DEFAULT_BANDWIDTH,
250 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
251 GST_PARAM_MUTABLE_PLAYING));
252 g_object_class_install_property (gobject_class, PROP_FRAME_SIZE,
253 g_param_spec_enum ("frame-size", "Frame Size",
254 "The duration of an audio frame, in ms", GST_OPUS_ENC_TYPE_FRAME_SIZE,
256 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
257 GST_PARAM_MUTABLE_PLAYING));
258 g_object_class_install_property (gobject_class, PROP_CBR,
259 g_param_spec_boolean ("cbr", "Constant bit rate", "Constant bit rate",
261 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
262 GST_PARAM_MUTABLE_PLAYING));
263 g_object_class_install_property (gobject_class, PROP_CONSTRAINED_VBR,
264 g_param_spec_boolean ("constrained-vbr", "Constrained VBR",
265 "Constrained VBR", DEFAULT_CONSTRAINED_VBR,
266 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
267 GST_PARAM_MUTABLE_PLAYING));
268 g_object_class_install_property (gobject_class, PROP_COMPLEXITY,
269 g_param_spec_int ("complexity", "Complexity", "Complexity", 0, 10,
271 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
272 GST_PARAM_MUTABLE_PLAYING));
273 g_object_class_install_property (gobject_class, PROP_INBAND_FEC,
274 g_param_spec_boolean ("inband-fec", "In-band FEC",
275 "Enable forward error correction", DEFAULT_INBAND_FEC,
276 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
277 GST_PARAM_MUTABLE_PLAYING));
278 g_object_class_install_property (gobject_class, PROP_DTX,
279 g_param_spec_boolean ("dtx", "DTX", "DTX", DEFAULT_DTX,
280 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
281 GST_PARAM_MUTABLE_PLAYING));
282 g_object_class_install_property (G_OBJECT_CLASS (klass),
283 PROP_PACKET_LOSS_PERCENT, g_param_spec_int ("packet-loss-percentage",
284 "Loss percentage", "Packet loss percentage", 0, 100,
285 DEFAULT_PACKET_LOSS_PERCENT,
286 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
287 GST_PARAM_MUTABLE_PLAYING));
288 g_object_class_install_property (G_OBJECT_CLASS (klass),
289 PROP_MAX_PAYLOAD_SIZE, g_param_spec_uint ("max-payload-size",
290 "Max payload size", "Maximum payload size in bytes", 2, 1275,
291 DEFAULT_MAX_PAYLOAD_SIZE,
292 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
293 GST_PARAM_MUTABLE_PLAYING));
295 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_opus_enc_finalize);
299 gst_opus_enc_finalize (GObject * object)
303 enc = GST_OPUS_ENC (object);
305 g_mutex_free (enc->property_lock);
307 G_OBJECT_CLASS (parent_class)->finalize (object);
311 gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass)
313 GstAudioEncoder *benc = GST_AUDIO_ENCODER (enc);
315 GST_DEBUG_OBJECT (enc, "init");
317 enc->property_lock = g_mutex_new ();
319 enc->n_channels = -1;
320 enc->sample_rate = -1;
321 enc->frame_samples = 0;
323 enc->bitrate = DEFAULT_BITRATE;
324 enc->bandwidth = DEFAULT_BANDWIDTH;
325 enc->frame_size = DEFAULT_FRAMESIZE;
326 enc->cbr = DEFAULT_CBR;
327 enc->constrained_vbr = DEFAULT_CONSTRAINED_VBR;
328 enc->complexity = DEFAULT_COMPLEXITY;
329 enc->inband_fec = DEFAULT_INBAND_FEC;
330 enc->dtx = DEFAULT_DTX;
331 enc->packet_loss_percentage = DEFAULT_PACKET_LOSS_PERCENT;
332 enc->max_payload_size = DEFAULT_MAX_PAYLOAD_SIZE;
334 /* arrange granulepos marking (and required perfect ts) */
335 gst_audio_encoder_set_mark_granule (benc, TRUE);
336 gst_audio_encoder_set_perfect_timestamp (benc, TRUE);
340 gst_opus_enc_start (GstAudioEncoder * benc)
342 GstOpusEnc *enc = GST_OPUS_ENC (benc);
344 GST_DEBUG_OBJECT (enc, "start");
345 enc->tags = gst_tag_list_new ();
346 enc->header_sent = FALSE;
352 gst_opus_enc_stop (GstAudioEncoder * benc)
354 GstOpusEnc *enc = GST_OPUS_ENC (benc);
356 GST_DEBUG_OBJECT (enc, "stop");
357 enc->header_sent = FALSE;
359 opus_multistream_encoder_destroy (enc->state);
362 gst_tag_list_free (enc->tags);
364 g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
366 gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
372 gst_opus_enc_get_latency (GstOpusEnc * enc)
374 gint64 latency = gst_util_uint64_scale (enc->frame_samples, GST_SECOND,
376 GST_DEBUG_OBJECT (enc, "Latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency));
381 gst_opus_enc_setup_base_class (GstOpusEnc * enc, GstAudioEncoder * benc)
383 gst_audio_encoder_set_latency (benc,
384 gst_opus_enc_get_latency (enc), gst_opus_enc_get_latency (enc));
385 gst_audio_encoder_set_frame_samples_min (benc,
386 enc->frame_samples * enc->n_channels * 2);
387 gst_audio_encoder_set_frame_samples_max (benc,
388 enc->frame_samples * enc->n_channels * 2);
389 gst_audio_encoder_set_frame_max (benc, 0);
393 gst_opus_enc_get_frame_samples (GstOpusEnc * enc)
395 gint frame_samples = 0;
396 switch (enc->frame_size) {
398 frame_samples = enc->sample_rate / 400;
401 frame_samples = enc->sample_rate / 200;
404 frame_samples = enc->sample_rate / 100;
407 frame_samples = enc->sample_rate / 50;
410 frame_samples = enc->sample_rate / 25;
413 frame_samples = 3 * enc->sample_rate / 50;
416 GST_WARNING_OBJECT (enc, "Unsupported frame size: %d", enc->frame_size);
420 return frame_samples;
424 gst_opus_enc_setup_channel_mapping (GstOpusEnc * enc, const GstAudioInfo * info)
426 #define MAPS(idx,pos) (GST_AUDIO_INFO_POSITION (info, (idx)) == GST_AUDIO_CHANNEL_POSITION_##pos)
430 GST_DEBUG_OBJECT (enc, "Setting up channel mapping for %d channels",
433 /* Start by setting up a default trivial mapping */
434 for (n = 0; n < 255; ++n)
435 enc->channel_mapping[n] = n;
437 /* For one channel, use the basic RTP mapping */
438 if (enc->n_channels == 1) {
439 GST_INFO_OBJECT (enc, "Mono, trivial RTP mapping");
440 enc->channel_mapping_family = 0;
441 enc->channel_mapping[0] = 0;
445 /* For two channels, use the basic RTP mapping if the channels are
446 mapped as left/right. */
447 if (enc->n_channels == 2) {
448 if (MAPS (0, FRONT_LEFT) && MAPS (1, FRONT_RIGHT)) {
449 GST_INFO_OBJECT (enc, "Stereo, canonical mapping");
450 enc->channel_mapping_family = 0;
451 /* The channel mapping is implicit for family 0, that's why we do not
452 attempt to create one for right/left - this will be mapped to the
453 Vorbis mapping below. */
455 GST_DEBUG_OBJECT (enc, "Stereo, but not canonical mapping, continuing");
459 /* For channels between 1 and 8, we use the Vorbis mapping if we can
460 find a permutation that matches it. Mono will have been taken care
461 of earlier, but this code also handles it. */
462 if (enc->n_channels >= 1 && enc->n_channels <= 8) {
463 GST_DEBUG_OBJECT (enc,
464 "In range for the Vorbis mapping, checking channel positions");
465 for (n = 0; n < enc->n_channels; ++n) {
466 GstAudioChannelPosition pos = GST_AUDIO_INFO_POSITION (info, n);
469 GST_DEBUG_OBJECT (enc, "Channel %d has position %d", n, pos);
470 for (c = 0; c < enc->n_channels; ++c) {
471 if (gst_opus_channel_positions[enc->n_channels - 1][c] == pos) {
472 GST_DEBUG_OBJECT (enc, "Found in Vorbis mapping as channel %d", c);
476 if (c == enc->n_channels) {
477 /* We did not find that position, so use undefined */
478 GST_WARNING_OBJECT (enc,
479 "Position %d not found in Vorbis mapping, using unknown mapping",
481 enc->channel_mapping_family = 255;
484 GST_DEBUG_OBJECT (enc, "Mapping output channel %d to %d", c, n);
485 enc->channel_mapping[c] = n;
487 GST_INFO_OBJECT (enc, "Permutation found, using Vorbis mapping");
488 enc->channel_mapping_family = 1;
492 /* For other cases, we use undefined, with the default trivial mapping */
493 GST_WARNING_OBJECT (enc, "Unknown mapping");
494 enc->channel_mapping_family = 255;
500 gst_opus_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
504 enc = GST_OPUS_ENC (benc);
506 g_mutex_lock (enc->property_lock);
508 enc->n_channels = GST_AUDIO_INFO_CHANNELS (info);
509 enc->sample_rate = GST_AUDIO_INFO_RATE (info);
510 gst_opus_enc_setup_channel_mapping (enc, info);
511 GST_DEBUG_OBJECT (benc, "Setup with %d channels, %d Hz", enc->n_channels,
514 /* handle reconfigure */
516 opus_multistream_encoder_destroy (enc->state);
519 if (!gst_opus_enc_setup (enc))
522 enc->frame_samples = gst_opus_enc_get_frame_samples (enc);
524 /* feedback to base class */
525 gst_opus_enc_setup_base_class (enc, benc);
527 g_mutex_unlock (enc->property_lock);
533 gst_opus_enc_setup (GstOpusEnc * enc)
535 int error = OPUS_OK, n;
536 guint8 trivial_mapping[256];
538 GST_DEBUG_OBJECT (enc, "setup");
540 for (n = 0; n < 256; ++n)
541 trivial_mapping[n] = n;
544 opus_multistream_encoder_create (enc->sample_rate, enc->n_channels,
545 (enc->n_channels + 1) / 2, enc->n_channels / 2, trivial_mapping,
546 enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP,
548 if (!enc->state || error != OPUS_OK)
549 goto encoder_creation_failed;
551 opus_multistream_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0);
552 opus_multistream_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth),
554 opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
555 opus_multistream_encoder_ctl (enc->state,
556 OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr), 0);
557 opus_multistream_encoder_ctl (enc->state,
558 OPUS_SET_COMPLEXITY (enc->complexity), 0);
559 opus_multistream_encoder_ctl (enc->state,
560 OPUS_SET_INBAND_FEC (enc->inband_fec), 0);
561 opus_multistream_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0);
562 opus_multistream_encoder_ctl (enc->state,
563 OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);
565 GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size);
569 encoder_creation_failed:
570 GST_ERROR_OBJECT (enc, "Encoder creation failed");
575 gst_opus_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
579 enc = GST_OPUS_ENC (benc);
581 GST_DEBUG_OBJECT (enc, "sink event: %s", GST_EVENT_TYPE_NAME (event));
582 switch (GST_EVENT_TYPE (event)) {
586 GstTagSetter *setter = GST_TAG_SETTER (enc);
587 const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
589 gst_event_parse_tag (event, &list);
590 gst_tag_setter_merge_tags (setter, list, mode);
601 gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
603 guint8 *bdata, *data, *mdata = NULL;
606 gint ret = GST_FLOW_OK;
608 g_mutex_lock (enc->property_lock);
610 bytes = enc->frame_samples * enc->n_channels * 2;
611 if (G_LIKELY (buf)) {
612 bdata = GST_BUFFER_DATA (buf);
613 bsize = GST_BUFFER_SIZE (buf);
614 if (G_UNLIKELY (bsize % bytes)) {
615 GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
617 size = ((bsize / bytes) + 1) * bytes;
618 mdata = g_malloc0 (size);
619 memcpy (mdata, bdata, bsize);
627 GST_DEBUG_OBJECT (enc, "nothing to drain");
636 ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
637 GST_BUFFER_OFFSET_NONE, enc->max_payload_size * enc->n_channels,
638 GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);
640 if (GST_FLOW_OK != ret)
643 GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
644 enc->frame_samples, (int) bytes);
647 opus_multistream_encode (enc->state, (const gint16 *) data,
648 enc->frame_samples, GST_BUFFER_DATA (outbuf),
649 enc->max_payload_size * enc->n_channels);
652 GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
653 ret = GST_FLOW_ERROR;
655 } else if (outsize > enc->max_payload_size) {
656 GST_WARNING_OBJECT (enc,
657 "Encoded size %d is higher than max payload size (%d bytes)",
658 outsize, enc->max_payload_size);
659 ret = GST_FLOW_ERROR;
663 GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", outsize);
664 GST_BUFFER_SIZE (outbuf) = outsize;
667 gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
670 if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
679 g_mutex_unlock (enc->property_lock);
688 gst_opus_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
691 GstFlowReturn ret = GST_FLOW_OK;
693 enc = GST_OPUS_ENC (benc);
694 GST_DEBUG_OBJECT (enc, "handle_frame");
696 if (!enc->header_sent) {
699 g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
702 gst_opus_header_create_caps (&caps, &enc->headers, enc->n_channels,
703 enc->sample_rate, enc->channel_mapping_family, enc->channel_mapping,
704 gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc)));
707 /* negotiate with these caps */
708 GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
710 gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), caps);
712 enc->header_sent = TRUE;
715 GST_DEBUG_OBJECT (enc, "received buffer %p of %u bytes", buf,
716 buf ? GST_BUFFER_SIZE (buf) : 0);
718 ret = gst_opus_enc_encode (enc, buf);
724 gst_opus_enc_get_property (GObject * object, guint prop_id, GValue * value,
729 enc = GST_OPUS_ENC (object);
731 g_mutex_lock (enc->property_lock);
735 g_value_set_boolean (value, enc->audio_or_voip);
738 g_value_set_int (value, enc->bitrate);
741 g_value_set_enum (value, enc->bandwidth);
743 case PROP_FRAME_SIZE:
744 g_value_set_enum (value, enc->frame_size);
747 g_value_set_boolean (value, enc->cbr);
749 case PROP_CONSTRAINED_VBR:
750 g_value_set_boolean (value, enc->constrained_vbr);
752 case PROP_COMPLEXITY:
753 g_value_set_int (value, enc->complexity);
755 case PROP_INBAND_FEC:
756 g_value_set_boolean (value, enc->inband_fec);
759 g_value_set_boolean (value, enc->dtx);
761 case PROP_PACKET_LOSS_PERCENT:
762 g_value_set_int (value, enc->packet_loss_percentage);
764 case PROP_MAX_PAYLOAD_SIZE:
765 g_value_set_uint (value, enc->max_payload_size);
768 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
772 g_mutex_unlock (enc->property_lock);
776 gst_opus_enc_set_property (GObject * object, guint prop_id,
777 const GValue * value, GParamSpec * pspec)
781 enc = GST_OPUS_ENC (object);
783 #define GST_OPUS_UPDATE_PROPERTY(prop,type,ctl) do { \
784 g_mutex_lock (enc->property_lock); \
785 enc->prop = g_value_get_##type (value); \
787 opus_multistream_encoder_ctl (enc->state, OPUS_SET_##ctl (enc->prop)); \
789 g_mutex_unlock (enc->property_lock); \
794 enc->audio_or_voip = g_value_get_boolean (value);
797 GST_OPUS_UPDATE_PROPERTY (bitrate, int, BITRATE);
800 GST_OPUS_UPDATE_PROPERTY (bandwidth, enum, BANDWIDTH);
802 case PROP_FRAME_SIZE:
803 g_mutex_lock (enc->property_lock);
804 enc->frame_size = g_value_get_enum (value);
805 enc->frame_samples = gst_opus_enc_get_frame_samples (enc);
806 gst_opus_enc_setup_base_class (enc, GST_AUDIO_ENCODER (enc));
807 g_mutex_unlock (enc->property_lock);
810 /* this one has an opposite meaning to the opus ctl... */
811 g_mutex_lock (enc->property_lock);
812 enc->cbr = g_value_get_boolean (value);
813 opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr));
814 g_mutex_unlock (enc->property_lock);
816 case PROP_CONSTRAINED_VBR:
817 GST_OPUS_UPDATE_PROPERTY (constrained_vbr, boolean, VBR_CONSTRAINT);
819 case PROP_COMPLEXITY:
820 GST_OPUS_UPDATE_PROPERTY (complexity, int, COMPLEXITY);
822 case PROP_INBAND_FEC:
823 GST_OPUS_UPDATE_PROPERTY (inband_fec, boolean, INBAND_FEC);
826 GST_OPUS_UPDATE_PROPERTY (dtx, boolean, DTX);
828 case PROP_PACKET_LOSS_PERCENT:
829 GST_OPUS_UPDATE_PROPERTY (packet_loss_percentage, int, PACKET_LOSS_PERC);
831 case PROP_MAX_PAYLOAD_SIZE:
832 g_mutex_lock (enc->property_lock);
833 enc->max_payload_size = g_value_get_uint (value);
834 g_mutex_unlock (enc->property_lock);
837 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
841 #undef GST_OPUS_UPDATE_PROPERTY