summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
index 1f6fd41..186251e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <glib.h>
+#include <gst/base/gstbytewriter.h>
+
gpointer
cmumble_find_by_id(GList *list, gsize member_offset, guint id)
{
@@ -62,3 +64,74 @@ out:
fclose(f);
return os;
}
+
+/* This code is taken from gst-plugins-bad/ext/opus/gstopusheader.c */
+GstBuffer *
+_gst_opus_enc_create_id_buffer(gint nchannels, gint n_stereo_streams,
+ gint sample_rate, guint8 channel_mapping_family,
+ const guint8 *channel_mapping)
+{
+ GstBuffer *buffer;
+ GstByteWriter bw;
+ gboolean hdl = TRUE;
+
+ g_return_val_if_fail (nchannels > 0 && nchannels < 256, NULL);
+ g_return_val_if_fail (n_stereo_streams >= 0, NULL);
+ g_return_val_if_fail (n_stereo_streams <= nchannels - n_stereo_streams, NULL);
+
+ gst_byte_writer_init (&bw);
+
+ /* See http://wiki.xiph.org/OggOpus */
+ hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
+ hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
+ hdl &= gst_byte_writer_put_uint8 (&bw, nchannels);
+ hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* pre-skip */
+ hdl &= gst_byte_writer_put_uint32_le (&bw, sample_rate);
+ hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* output gain */
+ hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
+ if (channel_mapping_family > 0) {
+ hdl &= gst_byte_writer_put_uint8 (&bw, nchannels - n_stereo_streams);
+ hdl &= gst_byte_writer_put_uint8 (&bw, n_stereo_streams);
+ hdl &= gst_byte_writer_put_data (&bw, channel_mapping, nchannels);
+ }
+
+ if (!hdl)
+ GST_WARNING ("Error creating header");
+
+ buffer = gst_byte_writer_reset_and_get_buffer (&bw);
+
+ GST_BUFFER_OFFSET (buffer) = 0;
+ GST_BUFFER_OFFSET_END (buffer) = 0;
+
+ return buffer;
+}
+
+static int
+create_gst_buffer_array (GValue *array, GstBuffer * buf, ...)
+{
+ va_list va;
+ GValue value = { 0 };
+
+ g_value_init (array, GST_TYPE_ARRAY);
+
+ va_start (va, buf);
+ /* put buffers in a fixed list */
+ while (buf) {
+ g_assert (gst_buffer_is_writable (buf));
+
+ /* mark buffer */
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
+
+ g_value_init (&value, GST_TYPE_BUFFER);
+ buf = gst_buffer_copy (buf);
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
+ gst_value_set_buffer (&value, buf);
+ gst_buffer_unref (buf);
+ gst_value_array_append_value (&array, &value);
+ g_value_unset (&value);
+
+ buf = va_arg (va, GstBuffer *);
+ }
+
+ return 0;
+