#include "util.h" #include #include #include #include #include gpointer cmumble_find_by_id(GList *list, gsize member_offset, guint id) { gpointer el = NULL; GList *l; for (l = list; l; l = l->next) { if (G_STRUCT_MEMBER(uint32_t, l->data, member_offset) == id) { el = l->data; break; } } return el; } gchar * cmumble_get_os_name(void) { FILE *f; char *line = NULL; char *os = NULL, *value, *end; size_t key_len = strlen("PRETTY_NAME="); size_t n; f = fopen("/etc/os-release", "r"); if (f == NULL) return NULL; while (getline(&line, &n, f) != -1) { if (strncmp("PRETTY_NAME=", line, key_len) == 0 && (n - key_len) > 1) { value = &line[key_len]; if (strlen(value) == 0) continue; end = &value[strlen(value) - 1]; if (*end == '\n') *end-- = '\0'; if (strlen(value) < 2) continue; if (value[0] == '"') value++; if (*end == '"') *end = '\0'; os = strdup(value); goto out; } } out: free(line); 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;