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