1 /* GStreamer
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * SECTION:element-vorbisenc
22 * @title: vorbisenc
23 * @see_also: vorbisdec, oggmux
24 *
25 * This element encodes raw float audio into a Vorbis stream.
26 * <ulink url="http://www.vorbis.com/">Vorbis</ulink> is a royalty-free
27 * audio codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
28 * Foundation</ulink>.
29 *
30 * ## Example pipelines
31 * |[
32 * gst-launch-1.0 -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! vorbisenc ! oggmux ! filesink location=sine.ogg
33 * ]|
34 * Encode a test sine signal to Ogg/Vorbis. Note that the resulting file
35 * will be really small because a sine signal compresses very well.
36 * |[
37 * gst-launch-1.0 -v autoaudiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
38 * ]|
39 * Record from a sound card and encode to Ogg/Vorbis.
40 *
41 */
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>
49 #include <vorbis/vorbisenc.h>
50
51 #include <gst/gsttagsetter.h>
52 #include <gst/tag/tag.h>
53 #include <gst/audio/audio.h>
54 #include "gstvorbisenc.h"
55
56 #include "gstvorbiscommon.h"
57
58 GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
59 #define GST_CAT_DEFAULT vorbisenc_debug
60
61 static GstStaticPadTemplate vorbis_enc_src_factory =
62 GST_STATIC_PAD_TEMPLATE ("src",
63 GST_PAD_SRC,
64 GST_PAD_ALWAYS,
65 GST_STATIC_CAPS ("audio/x-vorbis, "
66 "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
67 );
68
69 enum
70 {
71 ARG_0,
72 ARG_MAX_BITRATE,
73 ARG_BITRATE,
74 ARG_MIN_BITRATE,
75 ARG_QUALITY,
76 ARG_MANAGED,
77 ARG_LAST_MESSAGE
78 };
79
80 static GstFlowReturn gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc);
81 static GstCaps *gst_vorbis_enc_generate_sink_caps (void);
82
83
84 #define MAX_BITRATE_DEFAULT -1
85 #define BITRATE_DEFAULT -1
86 #define MIN_BITRATE_DEFAULT -1
87 #define QUALITY_DEFAULT 0.3
88 #define LOWEST_BITRATE 6000 /* lowest allowed for a 8 kHz stream */
89 #define HIGHEST_BITRATE 250001 /* highest allowed for a 44 kHz stream */
90
91 static gboolean gst_vorbis_enc_start (GstAudioEncoder * enc);
92 static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc);
93 static gboolean gst_vorbis_enc_set_format (GstAudioEncoder * enc,
94 GstAudioInfo * info);
95 static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
96 GstBuffer * in_buf);
97 static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
98 GstEvent * event);
99
100 static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
101
102 static void gst_vorbis_enc_dispose (GObject * object);
103 static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
104 GValue * value, GParamSpec * pspec);
105 static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
106 const GValue * value, GParamSpec * pspec);
107 static void gst_vorbis_enc_flush (GstAudioEncoder * vorbisenc);
108
109 #define gst_vorbis_enc_parent_class parent_class
110 G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
111 GST_TYPE_AUDIO_ENCODER, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
112
113 static void
gst_vorbis_enc_class_init(GstVorbisEncClass * klass)114 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
115 {
116 GObjectClass *gobject_class;
117 GstElementClass *gstelement_class;
118 GstAudioEncoderClass *base_class;
119 GstCaps *sink_caps;
120 GstPadTemplate *sink_templ;
121
122 gobject_class = (GObjectClass *) klass;
123 gstelement_class = (GstElementClass *) klass;
124 base_class = (GstAudioEncoderClass *) (klass);
125
126 gobject_class->set_property = gst_vorbis_enc_set_property;
127 gobject_class->get_property = gst_vorbis_enc_get_property;
128 gobject_class->dispose = gst_vorbis_enc_dispose;
129
130 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
131 g_param_spec_int ("max-bitrate", "Maximum Bitrate",
132 "Specify a maximum bitrate (in bps). Useful for streaming "
133 "applications. (-1 == disabled)",
134 -1, HIGHEST_BITRATE, MAX_BITRATE_DEFAULT,
135 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
136 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
137 g_param_spec_int ("bitrate", "Target Bitrate",
138 "Attempt to encode at a bitrate averaging this (in bps). "
139 "This uses the bitrate management engine, and is not recommended for most users. "
140 "Quality is a better alternative. (-1 == disabled)", -1,
141 HIGHEST_BITRATE, BITRATE_DEFAULT,
142 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
143 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MIN_BITRATE,
144 g_param_spec_int ("min-bitrate", "Minimum Bitrate",
145 "Specify a minimum bitrate (in bps). Useful for encoding for a "
146 "fixed-size channel. (-1 == disabled)", -1, HIGHEST_BITRATE,
147 MIN_BITRATE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
148 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
149 g_param_spec_float ("quality", "Quality",
150 "Specify quality instead of specifying a particular bitrate.", -0.1,
151 1.0, QUALITY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
152 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MANAGED,
153 g_param_spec_boolean ("managed", "Managed",
154 "Enable bitrate management engine", FALSE,
155 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
157 g_param_spec_string ("last-message", "last-message",
158 "The last status message", NULL,
159 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
160
161 sink_caps = gst_vorbis_enc_generate_sink_caps ();
162 sink_templ = gst_pad_template_new ("sink",
163 GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
164 gst_element_class_add_pad_template (gstelement_class, sink_templ);
165 gst_caps_unref (sink_caps);
166
167 gst_element_class_add_static_pad_template (gstelement_class,
168 &vorbis_enc_src_factory);
169
170 gst_element_class_set_static_metadata (gstelement_class,
171 "Vorbis audio encoder", "Codec/Encoder/Audio",
172 "Encodes audio in Vorbis format",
173 "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
174
175 base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
176 base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
177 base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
178 base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
179 base_class->sink_event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
180 base_class->flush = GST_DEBUG_FUNCPTR (gst_vorbis_enc_flush);
181 }
182
183 static void
gst_vorbis_enc_init(GstVorbisEnc * vorbisenc)184 gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
185 {
186 GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
187
188 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (enc));
189
190 vorbisenc->channels = -1;
191 vorbisenc->frequency = -1;
192
193 vorbisenc->managed = FALSE;
194 vorbisenc->max_bitrate = MAX_BITRATE_DEFAULT;
195 vorbisenc->bitrate = BITRATE_DEFAULT;
196 vorbisenc->min_bitrate = MIN_BITRATE_DEFAULT;
197 vorbisenc->quality = QUALITY_DEFAULT;
198 vorbisenc->quality_set = FALSE;
199 vorbisenc->last_message = NULL;
200
201 /* arrange granulepos marking (and required perfect ts) */
202 gst_audio_encoder_set_mark_granule (enc, TRUE);
203 gst_audio_encoder_set_perfect_timestamp (enc, TRUE);
204 }
205
206 static void
gst_vorbis_enc_dispose(GObject * object)207 gst_vorbis_enc_dispose (GObject * object)
208 {
209 GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
210
211 if (vorbisenc->sinkcaps) {
212 gst_caps_unref (vorbisenc->sinkcaps);
213 vorbisenc->sinkcaps = NULL;
214 }
215
216 G_OBJECT_CLASS (parent_class)->dispose (object);
217 }
218
219 static gboolean
gst_vorbis_enc_start(GstAudioEncoder * enc)220 gst_vorbis_enc_start (GstAudioEncoder * enc)
221 {
222 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
223
224 GST_DEBUG_OBJECT (enc, "start");
225 vorbisenc->tags = gst_tag_list_new_empty ();
226 vorbisenc->header_sent = FALSE;
227 vorbisenc->last_size = 0;
228
229 return TRUE;
230 }
231
232 static gboolean
gst_vorbis_enc_stop(GstAudioEncoder * enc)233 gst_vorbis_enc_stop (GstAudioEncoder * enc)
234 {
235 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
236
237 GST_DEBUG_OBJECT (enc, "stop");
238 vorbis_block_clear (&vorbisenc->vb);
239 vorbis_dsp_clear (&vorbisenc->vd);
240 vorbis_info_clear (&vorbisenc->vi);
241 g_free (vorbisenc->last_message);
242 vorbisenc->last_message = NULL;
243 gst_tag_list_unref (vorbisenc->tags);
244 vorbisenc->tags = NULL;
245
246 gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
247
248 return TRUE;
249 }
250
251 static GstCaps *
gst_vorbis_enc_generate_sink_caps(void)252 gst_vorbis_enc_generate_sink_caps (void)
253 {
254 GstCaps *caps = gst_caps_new_empty ();
255 int i, c;
256
257 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
258 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
259 "layout", G_TYPE_STRING, "interleaved",
260 "rate", GST_TYPE_INT_RANGE, 1, 200000,
261 "channels", G_TYPE_INT, 1, NULL));
262
263 for (i = 2; i <= 8; i++) {
264 GstStructure *structure;
265 guint64 channel_mask = 0;
266 const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
267
268 for (c = 0; c < i; c++) {
269 channel_mask |= G_GUINT64_CONSTANT (1) << pos[c];
270 }
271
272 structure = gst_structure_new ("audio/x-raw",
273 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
274 "layout", G_TYPE_STRING, "interleaved",
275 "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
276 "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
277
278 gst_caps_append_structure (caps, structure);
279 }
280
281 gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
282 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
283 "layout", G_TYPE_STRING, "interleaved",
284 "rate", GST_TYPE_INT_RANGE, 1, 200000,
285 "channels", GST_TYPE_INT_RANGE, 9, 255,
286 "channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
287
288 return caps;
289 }
290
291 static gint64
gst_vorbis_enc_get_latency(GstVorbisEnc * vorbisenc)292 gst_vorbis_enc_get_latency (GstVorbisEnc * vorbisenc)
293 {
294 /* FIXME, this probably depends on the bitrate and other setting but for now
295 * we return this value, which was obtained by totally unscientific
296 * measurements */
297 return 58 * GST_MSECOND;
298 }
299
300 static gboolean
gst_vorbis_enc_set_format(GstAudioEncoder * enc,GstAudioInfo * info)301 gst_vorbis_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
302 {
303 GstVorbisEnc *vorbisenc;
304
305 vorbisenc = GST_VORBISENC (enc);
306
307 vorbisenc->channels = GST_AUDIO_INFO_CHANNELS (info);
308 vorbisenc->frequency = GST_AUDIO_INFO_RATE (info);
309
310 /* if re-configured, we were drained and cleared already */
311 vorbisenc->header_sent = FALSE;
312 if (!gst_vorbis_enc_setup (vorbisenc))
313 return FALSE;
314
315 /* feedback to base class */
316 gst_audio_encoder_set_latency (enc,
317 gst_vorbis_enc_get_latency (vorbisenc),
318 gst_vorbis_enc_get_latency (vorbisenc));
319
320 return TRUE;
321 }
322
323 static void
gst_vorbis_enc_metadata_set1(const GstTagList * list,const gchar * tag,gpointer vorbisenc)324 gst_vorbis_enc_metadata_set1 (const GstTagList * list, const gchar * tag,
325 gpointer vorbisenc)
326 {
327 GstVorbisEnc *enc = GST_VORBISENC (vorbisenc);
328 GList *vc_list, *l;
329
330 vc_list = gst_tag_to_vorbis_comments (list, tag);
331
332 for (l = vc_list; l != NULL; l = l->next) {
333 const gchar *vc_string = (const gchar *) l->data;
334 gchar *key = NULL, *val = NULL;
335
336 GST_LOG_OBJECT (vorbisenc, "vorbis comment: %s", vc_string);
337 if (gst_tag_parse_extended_comment (vc_string, &key, NULL, &val, TRUE)) {
338 vorbis_comment_add_tag (&enc->vc, key, val);
339 g_free (key);
340 g_free (val);
341 }
342 }
343
344 g_list_foreach (vc_list, (GFunc) g_free, NULL);
345 g_list_free (vc_list);
346 }
347
348 static void
gst_vorbis_enc_set_metadata(GstVorbisEnc * enc)349 gst_vorbis_enc_set_metadata (GstVorbisEnc * enc)
350 {
351 GstTagList *merged_tags;
352 const GstTagList *user_tags;
353
354 vorbis_comment_init (&enc->vc);
355
356 user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc));
357
358 GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags);
359 GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags);
360
361 /* gst_tag_list_merge() will handle NULL for either or both lists fine */
362 merged_tags = gst_tag_list_merge (user_tags, enc->tags,
363 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc)));
364
365 if (merged_tags) {
366 GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
367 gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc);
368 gst_tag_list_unref (merged_tags);
369 }
370 }
371
372 static gchar *
get_constraints_string(GstVorbisEnc * vorbisenc)373 get_constraints_string (GstVorbisEnc * vorbisenc)
374 {
375 gint min = vorbisenc->min_bitrate;
376 gint max = vorbisenc->max_bitrate;
377 gchar *result;
378
379 if (min > 0 && max > 0)
380 result = g_strdup_printf ("(min %d bps, max %d bps)", min, max);
381 else if (min > 0)
382 result = g_strdup_printf ("(min %d bps, no max)", min);
383 else if (max > 0)
384 result = g_strdup_printf ("(no min, max %d bps)", max);
385 else
386 result = g_strdup_printf ("(no min or max)");
387
388 return result;
389 }
390
391 static void
update_start_message(GstVorbisEnc * vorbisenc)392 update_start_message (GstVorbisEnc * vorbisenc)
393 {
394 gchar *constraints;
395
396 g_free (vorbisenc->last_message);
397
398 if (vorbisenc->bitrate > 0) {
399 if (vorbisenc->managed) {
400 constraints = get_constraints_string (vorbisenc);
401 vorbisenc->last_message =
402 g_strdup_printf ("encoding at average bitrate %d bps %s",
403 vorbisenc->bitrate, constraints);
404 g_free (constraints);
405 } else {
406 vorbisenc->last_message =
407 g_strdup_printf
408 ("encoding at approximate bitrate %d bps (VBR encoding enabled)",
409 vorbisenc->bitrate);
410 }
411 } else {
412 if (vorbisenc->quality_set) {
413 if (vorbisenc->managed) {
414 constraints = get_constraints_string (vorbisenc);
415 vorbisenc->last_message =
416 g_strdup_printf
417 ("encoding at quality level %2.2f using constrained VBR %s",
418 vorbisenc->quality, constraints);
419 g_free (constraints);
420 } else {
421 vorbisenc->last_message =
422 g_strdup_printf ("encoding at quality level %2.2f",
423 vorbisenc->quality);
424 }
425 } else {
426 constraints = get_constraints_string (vorbisenc);
427 vorbisenc->last_message =
428 g_strdup_printf ("encoding using bitrate management %s", constraints);
429 g_free (constraints);
430 }
431 }
432
433 g_object_notify (G_OBJECT (vorbisenc), "last_message");
434 }
435
436 static gboolean
gst_vorbis_enc_setup(GstVorbisEnc * vorbisenc)437 gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc)
438 {
439
440 GST_LOG_OBJECT (vorbisenc, "setup");
441
442 if (vorbisenc->bitrate < 0 && vorbisenc->min_bitrate < 0
443 && vorbisenc->max_bitrate < 0) {
444 vorbisenc->quality_set = TRUE;
445 }
446
447 update_start_message (vorbisenc);
448
449 /* choose an encoding mode */
450 /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
451 vorbis_info_init (&vorbisenc->vi);
452
453 if (vorbisenc->quality_set) {
454 if (vorbis_encode_setup_vbr (&vorbisenc->vi,
455 vorbisenc->channels, vorbisenc->frequency,
456 vorbisenc->quality) != 0) {
457 GST_ERROR_OBJECT (vorbisenc,
458 "vorbisenc: initialisation failed: invalid parameters for quality");
459 vorbis_info_clear (&vorbisenc->vi);
460 return FALSE;
461 }
462
463 /* do we have optional hard quality restrictions? */
464 if (vorbisenc->max_bitrate > 0 || vorbisenc->min_bitrate > 0) {
465 struct ovectl_ratemanage_arg ai;
466
467 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_GET, &ai);
468
469 ai.bitrate_hard_min = vorbisenc->min_bitrate;
470 ai.bitrate_hard_max = vorbisenc->max_bitrate;
471 ai.management_active = 1;
472
473 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, &ai);
474 }
475 } else {
476 long min_bitrate, max_bitrate;
477
478 min_bitrate = vorbisenc->min_bitrate > 0 ? vorbisenc->min_bitrate : -1;
479 max_bitrate = vorbisenc->max_bitrate > 0 ? vorbisenc->max_bitrate : -1;
480
481 if (vorbis_encode_setup_managed (&vorbisenc->vi,
482 vorbisenc->channels,
483 vorbisenc->frequency,
484 max_bitrate, vorbisenc->bitrate, min_bitrate) != 0) {
485 GST_ERROR_OBJECT (vorbisenc,
486 "vorbis_encode_setup_managed "
487 "(c %d, rate %d, max br %ld, br %d, min br %ld) failed",
488 vorbisenc->channels, vorbisenc->frequency, max_bitrate,
489 vorbisenc->bitrate, min_bitrate);
490 vorbis_info_clear (&vorbisenc->vi);
491 return FALSE;
492 }
493 }
494
495 if (vorbisenc->managed && vorbisenc->bitrate < 0) {
496 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_AVG, NULL);
497 } else if (!vorbisenc->managed) {
498 /* Turn off management entirely (if it was turned on). */
499 vorbis_encode_ctl (&vorbisenc->vi, OV_ECTL_RATEMANAGE_SET, NULL);
500 }
501 vorbis_encode_setup_init (&vorbisenc->vi);
502
503 /* set up the analysis state and auxiliary encoding storage */
504 vorbis_analysis_init (&vorbisenc->vd, &vorbisenc->vi);
505 vorbis_block_init (&vorbisenc->vd, &vorbisenc->vb);
506
507 /* samples == granulepos start at 0 again */
508 vorbisenc->samples_out = 0;
509
510 /* fresh encoder available */
511 vorbisenc->setup = TRUE;
512
513 return TRUE;
514 }
515
516 static GstFlowReturn
gst_vorbis_enc_clear(GstVorbisEnc * vorbisenc)517 gst_vorbis_enc_clear (GstVorbisEnc * vorbisenc)
518 {
519 GstFlowReturn ret = GST_FLOW_OK;
520
521 if (vorbisenc->setup) {
522 vorbis_analysis_wrote (&vorbisenc->vd, 0);
523 ret = gst_vorbis_enc_output_buffers (vorbisenc);
524
525 /* marked EOS to encoder, recreate if needed */
526 vorbisenc->setup = FALSE;
527 }
528
529 /* clean up and exit. vorbis_info_clear() must be called last */
530 vorbis_block_clear (&vorbisenc->vb);
531 vorbis_dsp_clear (&vorbisenc->vd);
532 vorbis_info_clear (&vorbisenc->vi);
533
534 return ret;
535 }
536
537 static void
gst_vorbis_enc_flush(GstAudioEncoder * enc)538 gst_vorbis_enc_flush (GstAudioEncoder * enc)
539 {
540 GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
541
542 gst_vorbis_enc_clear (vorbisenc);
543 vorbisenc->header_sent = FALSE;
544 }
545
546 /* copied and adapted from ext/ogg/gstoggstream.c */
547 static gint64
packet_duration_vorbis(GstVorbisEnc * enc,ogg_packet * packet)548 packet_duration_vorbis (GstVorbisEnc * enc, ogg_packet * packet)
549 {
550 int mode;
551 int size;
552 int duration;
553
554 if (packet->bytes == 0 || packet->packet[0] & 1)
555 return 0;
556
557 mode = (packet->packet[0] >> 1) & ((1 << enc->vorbis_log2_num_modes) - 1);
558 size = enc->vorbis_mode_sizes[mode] ? enc->long_size : enc->short_size;
559
560 if (enc->last_size == 0) {
561 duration = 0;
562 } else {
563 duration = enc->last_size / 4 + size / 4;
564 }
565 enc->last_size = size;
566
567 GST_DEBUG_OBJECT (enc, "duration %d", (int) duration);
568
569 return duration;
570 }
571
572 /* copied and adapted from ext/ogg/gstoggstream.c */
573 static void
parse_vorbis_header_packet(GstVorbisEnc * enc,ogg_packet * packet)574 parse_vorbis_header_packet (GstVorbisEnc * enc, ogg_packet * packet)
575 {
576 /*
577 * on the first (b_o_s) packet, determine the long and short sizes,
578 * and then calculate l/2, l/4 - s/4, 3 * l/4 - s/4, l/2 - s/2 and s/2
579 */
580
581 enc->long_size = 1 << (packet->packet[28] >> 4);
582 enc->short_size = 1 << (packet->packet[28] & 0xF);
583 }
584
585 /* copied and adapted from ext/ogg/gstoggstream.c */
586 static void
parse_vorbis_codebooks_packet(GstVorbisEnc * enc,ogg_packet * op)587 parse_vorbis_codebooks_packet (GstVorbisEnc * enc, ogg_packet * op)
588 {
589 /*
590 * the code pages, a whole bunch of other fairly useless stuff, AND,
591 * RIGHT AT THE END (of a bunch of variable-length compressed rubbish that
592 * basically has only one actual set of values that everyone uses BUT YOU
593 * CAN'T BE SURE OF THAT, OH NO YOU CAN'T) is the only piece of data that's
594 * actually useful to us - the packet modes (because it's inconceivable to
595 * think people might want _just that_ and nothing else, you know, for
596 * seeking and stuff).
597 *
598 * Fortunately, because of the mandate that non-used bits must be zero
599 * at the end of the packet, we might be able to sneakily work backwards
600 * and find out the information we need (namely a mapping of modes to
601 * packet sizes)
602 */
603 unsigned char *current_pos = &op->packet[op->bytes - 1];
604 int offset;
605 int size;
606 int size_check;
607 int *mode_size_ptr;
608 int i;
609 int ii;
610
611 /*
612 * This is the format of the mode data at the end of the packet for all
613 * Vorbis Version 1 :
614 *
615 * [ 6:number_of_modes ]
616 * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
617 * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
618 * [ 1:size | 16:window_type(0) | 16:transform_type(0) | 8:mapping ]
619 * [ 1:framing(1) ]
620 *
621 * e.g.:
622 *
623 * <-
624 * 0 0 0 0 0 1 0 0
625 * 0 0 1 0 0 0 0 0
626 * 0 0 1 0 0 0 0 0
627 * 0 0 1|0 0 0 0 0
628 * 0 0 0 0|0|0 0 0
629 * 0 0 0 0 0 0 0 0
630 * 0 0 0 0|0 0 0 0
631 * 0 0 0 0 0 0 0 0
632 * 0 0 0 0|0 0 0 0
633 * 0 0 0|1|0 0 0 0 |
634 * 0 0 0 0 0 0 0 0 V
635 * 0 0 0|0 0 0 0 0
636 * 0 0 0 0 0 0 0 0
637 * 0 0 1|0 0 0 0 0
638 * 0 0|1|0 0 0 0 0
639 *
640 *
641 * i.e. each entry is an important bit, 32 bits of 0, 8 bits of blah, a
642 * bit of 1.
643 * Let's find our last 1 bit first.
644 *
645 */
646
647 size = 0;
648
649 offset = 8;
650 while (!((1 << --offset) & *current_pos)) {
651 if (offset == 0) {
652 offset = 8;
653 current_pos -= 1;
654 }
655 }
656
657 while (1) {
658
659 /*
660 * from current_pos-5:(offset+1) to current_pos-1:(offset+1) should
661 * be zero
662 */
663 offset = (offset + 7) % 8;
664 if (offset == 7)
665 current_pos -= 1;
666
667 if (((current_pos[-5] & ~((1 << (offset + 1)) - 1)) != 0)
668 ||
669 current_pos[-4] != 0
670 ||
671 current_pos[-3] != 0
672 ||
673 current_pos[-2] != 0
674 || ((current_pos[-1] & ((1 << (offset + 1)) - 1)) != 0)
675 ) {
676 break;
677 }
678
679 size += 1;
680
681 current_pos -= 5;
682
683 }
684
685 /* Give ourselves a chance to recover if we went back too far by using
686 * the size check. */
687 for (ii = 0; ii < 2; ii++) {
688 if (offset > 4) {
689 size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
690 } else {
691 /* mask part of byte from current_pos */
692 size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
693 /* shift to appropriate position */
694 size_check <<= (5 - offset);
695 /* or in part of byte from current_pos - 1 */
696 size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
697 (offset + 3);
698 }
699
700 size_check += 1;
701 if (size_check == size) {
702 break;
703 }
704 offset = (offset + 1) % 8;
705 if (offset == 0)
706 current_pos += 1;
707 current_pos += 5;
708 size -= 1;
709 }
710
711 /* Store mode size information in our info struct */
712 i = -1;
713 while ((1 << (++i)) < size);
714 enc->vorbis_log2_num_modes = i;
715
716 mode_size_ptr = enc->vorbis_mode_sizes;
717
718 for (i = 0; i < size; i++) {
719 offset = (offset + 1) % 8;
720 if (offset == 0)
721 current_pos += 1;
722 *mode_size_ptr++ = (current_pos[0] >> offset) & 0x1;
723 current_pos += 5;
724 }
725
726 }
727
728 static GstBuffer *
gst_vorbis_enc_buffer_from_header_packet(GstVorbisEnc * vorbisenc,ogg_packet * packet)729 gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
730 ogg_packet * packet)
731 {
732 GstBuffer *outbuf;
733
734 if (packet->bytes > 0 && packet->packet[0] == '\001') {
735 parse_vorbis_header_packet (vorbisenc, packet);
736 } else if (packet->bytes > 0 && packet->packet[0] == '\005') {
737 parse_vorbis_codebooks_packet (vorbisenc, packet);
738 }
739
740 outbuf =
741 gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER (vorbisenc),
742 packet->bytes);
743 gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
744 GST_BUFFER_OFFSET (outbuf) = 0;
745 GST_BUFFER_OFFSET_END (outbuf) = 0;
746 GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
747 GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
748 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER);
749
750 GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
751 gst_buffer_get_size (outbuf));
752 return outbuf;
753 }
754
755 static gboolean
gst_vorbis_enc_sink_event(GstAudioEncoder * enc,GstEvent * event)756 gst_vorbis_enc_sink_event (GstAudioEncoder * enc, GstEvent * event)
757 {
758 GstVorbisEnc *vorbisenc;
759
760 vorbisenc = GST_VORBISENC (enc);
761
762 switch (GST_EVENT_TYPE (event)) {
763 case GST_EVENT_TAG:
764 if (vorbisenc->tags) {
765 GstTagList *list;
766
767 gst_event_parse_tag (event, &list);
768 gst_tag_list_insert (vorbisenc->tags, list,
769 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (vorbisenc)));
770 } else {
771 g_assert_not_reached ();
772 }
773 break;
774 /* fall through */
775 default:
776 break;
777 }
778
779 /* we only peeked, let base class handle it */
780 return GST_AUDIO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
781 }
782
783 /*
784 * (really really) FIXME: move into core (dixit tpm)
785 */
786 /*
787 * _gst_caps_set_buffer_array:
788 * @caps: (transfer full): a #GstCaps
789 * @field: field in caps to set
790 * @buf: header buffers
791 *
792 * Adds given buffers to an array of buffers set as the given @field
793 * on the given @caps. List of buffer arguments must be NULL-terminated.
794 *
795 * Returns: (transfer full): input caps with a streamheader field added, or NULL
796 * if some error occurred
797 */
798 static GstCaps *
_gst_caps_set_buffer_array(GstCaps * caps,const gchar * field,GstBuffer * buf,...)799 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
800 GstBuffer * buf, ...)
801 {
802 GstStructure *structure = NULL;
803 va_list va;
804 GValue array = { 0 };
805 GValue value = { 0 };
806
807 g_return_val_if_fail (caps != NULL, NULL);
808 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
809 g_return_val_if_fail (field != NULL, NULL);
810
811 caps = gst_caps_make_writable (caps);
812 structure = gst_caps_get_structure (caps, 0);
813
814 g_value_init (&array, GST_TYPE_ARRAY);
815
816 va_start (va, buf);
817 /* put buffers in a fixed list */
818 while (buf) {
819 g_value_init (&value, GST_TYPE_BUFFER);
820 gst_value_set_buffer (&value, buf);
821 gst_value_array_append_value (&array, &value);
822 g_value_unset (&value);
823
824 buf = va_arg (va, GstBuffer *);
825 }
826 va_end (va);
827
828 gst_structure_take_value (structure, field, &array);
829
830 return caps;
831 }
832
833 static GstFlowReturn
gst_vorbis_enc_handle_frame(GstAudioEncoder * enc,GstBuffer * buffer)834 gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
835 {
836 GstVorbisEnc *vorbisenc;
837 GstFlowReturn ret = GST_FLOW_OK;
838 GstMapInfo map;
839 gfloat *ptr;
840 gulong size;
841 gulong i, j;
842 float **vorbis_buffer;
843 GstBuffer *buf1, *buf2, *buf3;
844
845 vorbisenc = GST_VORBISENC (enc);
846
847 if (G_UNLIKELY (!vorbisenc->setup)) {
848 if (buffer) {
849 GST_DEBUG_OBJECT (vorbisenc, "forcing setup");
850 /* should not fail, as setup before same way */
851 if (!gst_vorbis_enc_setup (vorbisenc))
852 return GST_FLOW_ERROR;
853 } else {
854 /* end draining */
855 GST_LOG_OBJECT (vorbisenc, "already drained");
856 return GST_FLOW_OK;
857 }
858 }
859
860 if (!vorbisenc->header_sent) {
861 /* Vorbis streams begin with three headers; the initial header (with
862 most of the codec setup parameters) which is mandated by the Ogg
863 bitstream spec. The second header holds any comment fields. The
864 third header holds the bitstream codebook. We merely need to
865 make the headers, then pass them to libvorbis one at a time;
866 libvorbis handles the additional Ogg bitstream constraints */
867 ogg_packet header;
868 ogg_packet header_comm;
869 ogg_packet header_code;
870 GstCaps *caps;
871 GList *headers;
872
873 GST_DEBUG_OBJECT (vorbisenc, "creating and sending header packets");
874 gst_vorbis_enc_set_metadata (vorbisenc);
875 vorbis_analysis_headerout (&vorbisenc->vd, &vorbisenc->vc, &header,
876 &header_comm, &header_code);
877 vorbis_comment_clear (&vorbisenc->vc);
878
879 /* create header buffers */
880 buf1 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header);
881 buf2 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_comm);
882 buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
883
884 /* mark and put on caps */
885 caps = gst_caps_new_simple ("audio/x-vorbis",
886 "rate", G_TYPE_INT, vorbisenc->frequency,
887 "channels", G_TYPE_INT, vorbisenc->channels, NULL);
888 caps = _gst_caps_set_buffer_array (caps, "streamheader",
889 buf1, buf2, buf3, NULL);
890
891 /* negotiate with these caps */
892 GST_DEBUG_OBJECT (vorbisenc, "here are the caps: %" GST_PTR_FORMAT, caps);
893 gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (vorbisenc), caps);
894 gst_caps_unref (caps);
895
896 /* store buffers for later pre_push sending */
897 headers = NULL;
898 GST_DEBUG_OBJECT (vorbisenc, "storing header buffers");
899 headers = g_list_prepend (headers, buf3);
900 headers = g_list_prepend (headers, buf2);
901 headers = g_list_prepend (headers, buf1);
902 gst_audio_encoder_set_headers (enc, headers);
903
904 vorbisenc->header_sent = TRUE;
905 }
906
907 if (!buffer)
908 return gst_vorbis_enc_clear (vorbisenc);
909
910 gst_buffer_map (buffer, &map, GST_MAP_READ);
911
912 /* data to encode */
913 size = map.size / (vorbisenc->channels * sizeof (float));
914 ptr = (gfloat *) map.data;
915
916 /* expose the buffer to submit data */
917 vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
918
919 /* deinterleave samples, write the buffer data */
920 if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
921 for (i = 0; i < size; i++) {
922 for (j = 0; j < vorbisenc->channels; j++) {
923 vorbis_buffer[j][i] = *ptr++;
924 }
925 }
926 } else {
927 gint i, j;
928
929 /* Reorder */
930 for (i = 0; i < size; i++) {
931 for (j = 0; j < vorbisenc->channels; j++) {
932 vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
933 ptr[j];
934 }
935 ptr += vorbisenc->channels;
936 }
937 }
938
939 /* tell the library how much we actually submitted */
940 vorbis_analysis_wrote (&vorbisenc->vd, size);
941 gst_buffer_unmap (buffer, &map);
942
943 GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
944
945 ret = gst_vorbis_enc_output_buffers (vorbisenc);
946
947 return ret;
948 }
949
950 static GstFlowReturn
gst_vorbis_enc_output_buffers(GstVorbisEnc * vorbisenc)951 gst_vorbis_enc_output_buffers (GstVorbisEnc * vorbisenc)
952 {
953 GstFlowReturn ret;
954 gint64 duration;
955
956 /* vorbis does some data preanalysis, then divides up blocks for
957 more involved (potentially parallel) processing. Get a single
958 block for encoding now */
959 while (vorbis_analysis_blockout (&vorbisenc->vd, &vorbisenc->vb) == 1) {
960 ogg_packet op;
961
962 GST_LOG_OBJECT (vorbisenc, "analysed to a block");
963
964 /* analysis */
965 vorbis_analysis (&vorbisenc->vb, NULL);
966 vorbis_bitrate_addblock (&vorbisenc->vb);
967
968 while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
969 GstBuffer *buf;
970
971 GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
972 buf =
973 gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER
974 (vorbisenc), op.bytes);
975 gst_buffer_fill (buf, 0, op.packet, op.bytes);
976
977 /* we have to call this every packet, not just on e_o_s, since
978 each packet's duration depends on the previous one's */
979 duration = packet_duration_vorbis (vorbisenc, &op);
980 if (op.e_o_s) {
981 gint64 samples = op.granulepos - vorbisenc->samples_out;
982 if (samples < duration) {
983 gint64 trim_end = duration - samples;
984 GST_DEBUG_OBJECT (vorbisenc,
985 "Adding trim-end %" G_GUINT64_FORMAT, trim_end);
986 gst_buffer_add_audio_clipping_meta (buf, GST_FORMAT_DEFAULT, 0,
987 trim_end);
988 }
989 }
990 /* tracking granulepos should tell us samples accounted for */
991 ret =
992 gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER
993 (vorbisenc), buf, op.granulepos - vorbisenc->samples_out);
994 vorbisenc->samples_out = op.granulepos;
995
996 if (ret != GST_FLOW_OK)
997 return ret;
998 }
999 }
1000
1001 return GST_FLOW_OK;
1002 }
1003
1004 static void
gst_vorbis_enc_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1005 gst_vorbis_enc_get_property (GObject * object, guint prop_id, GValue * value,
1006 GParamSpec * pspec)
1007 {
1008 GstVorbisEnc *vorbisenc;
1009
1010 g_return_if_fail (GST_IS_VORBISENC (object));
1011
1012 vorbisenc = GST_VORBISENC (object);
1013
1014 switch (prop_id) {
1015 case ARG_MAX_BITRATE:
1016 g_value_set_int (value, vorbisenc->max_bitrate);
1017 break;
1018 case ARG_BITRATE:
1019 g_value_set_int (value, vorbisenc->bitrate);
1020 break;
1021 case ARG_MIN_BITRATE:
1022 g_value_set_int (value, vorbisenc->min_bitrate);
1023 break;
1024 case ARG_QUALITY:
1025 g_value_set_float (value, vorbisenc->quality);
1026 break;
1027 case ARG_MANAGED:
1028 g_value_set_boolean (value, vorbisenc->managed);
1029 break;
1030 case ARG_LAST_MESSAGE:
1031 g_value_set_string (value, vorbisenc->last_message);
1032 break;
1033 default:
1034 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1035 break;
1036 }
1037 }
1038
1039 static void
gst_vorbis_enc_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1040 gst_vorbis_enc_set_property (GObject * object, guint prop_id,
1041 const GValue * value, GParamSpec * pspec)
1042 {
1043 GstVorbisEnc *vorbisenc;
1044
1045 g_return_if_fail (GST_IS_VORBISENC (object));
1046
1047 vorbisenc = GST_VORBISENC (object);
1048
1049 switch (prop_id) {
1050 case ARG_MAX_BITRATE:
1051 {
1052 gboolean old_value = vorbisenc->managed;
1053
1054 vorbisenc->max_bitrate = g_value_get_int (value);
1055 if (vorbisenc->max_bitrate >= 0
1056 && vorbisenc->max_bitrate < LOWEST_BITRATE) {
1057 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1058 vorbisenc->max_bitrate = LOWEST_BITRATE;
1059 }
1060 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1061 vorbisenc->managed = TRUE;
1062 else
1063 vorbisenc->managed = FALSE;
1064
1065 if (old_value != vorbisenc->managed)
1066 g_object_notify (object, "managed");
1067 break;
1068 }
1069 case ARG_BITRATE:
1070 vorbisenc->bitrate = g_value_get_int (value);
1071 if (vorbisenc->bitrate >= 0 && vorbisenc->bitrate < LOWEST_BITRATE) {
1072 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1073 vorbisenc->bitrate = LOWEST_BITRATE;
1074 }
1075 break;
1076 case ARG_MIN_BITRATE:
1077 {
1078 gboolean old_value = vorbisenc->managed;
1079
1080 vorbisenc->min_bitrate = g_value_get_int (value);
1081 if (vorbisenc->min_bitrate >= 0
1082 && vorbisenc->min_bitrate < LOWEST_BITRATE) {
1083 g_warning ("Lowest allowed bitrate is %d", LOWEST_BITRATE);
1084 vorbisenc->min_bitrate = LOWEST_BITRATE;
1085 }
1086 if (vorbisenc->min_bitrate > 0 && vorbisenc->max_bitrate > 0)
1087 vorbisenc->managed = TRUE;
1088 else
1089 vorbisenc->managed = FALSE;
1090
1091 if (old_value != vorbisenc->managed)
1092 g_object_notify (object, "managed");
1093 break;
1094 }
1095 case ARG_QUALITY:
1096 vorbisenc->quality = g_value_get_float (value);
1097 if (vorbisenc->quality >= 0.0)
1098 vorbisenc->quality_set = TRUE;
1099 else
1100 vorbisenc->quality_set = FALSE;
1101 break;
1102 case ARG_MANAGED:
1103 vorbisenc->managed = g_value_get_boolean (value);
1104 break;
1105 default:
1106 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1107 break;
1108 }
1109 }
1110