summaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/src/audio.c b/src/audio.c
index af92db5..a5c41d3 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -8,11 +8,32 @@
void
cmumble_audio_push(struct cmumble *cm, struct cmumble_user *user,
- const guint8 *data, gsize size)
+ const guint8 *data, gsize size, gint64 sequence)
{
GstBuffer *gstbuf;
+ GstClock *clock;
+ GstClockTime time = 0;
+ GstClockTime base_time, now;
+
+ clock = gst_pipeline_get_clock(GST_PIPELINE(user->pipeline));
+ now = gst_clock_get_time(clock);
+ g_object_unref(clock);
+ base_time = gst_element_get_base_time(user->pipeline);
+
+ if (user->sequence_start_time == GST_CLOCK_TIME_NONE && sequence > 0)
+ user->sequence_start_time = GST_CLOCK_DIFF(now, base_time) -
+ gst_util_uint64_scale_int(sequence, GST_SECOND, 100);
+
+ if (sequence == 0) {
+ user->sequence_start_time = GST_CLOCK_DIFF(now, base_time);
+ time = user->sequence_start_time;
+ } else if (sequence > 0) {
+ time = user->sequence_start_time +
+ gst_util_uint64_scale_int(sequence, GST_SECOND, 100);
+ }
gstbuf = gst_app_buffer_new(g_memdup(data, size), size, g_free, NULL);
+ GST_BUFFER_TIMESTAMP(gstbuf) = time;
gst_app_src_push_buffer(user->src, gstbuf);
}
@@ -135,13 +156,44 @@ out:
g_object_unref(G_OBJECT(elm));
}
+static void
+need_data(GstAppSrc *src, guint length, gpointer user_data)
+{
+ //g_print("%s: %d\n", __func__, length);
+}
+static void
+enough_data(GstAppSrc *src, gpointer user_data)
+{
+ g_print("%s\n", __func__);
+}
+
+static gboolean
+seek_data(GstAppSrc *src, guint64 offset, gpointer user_data)
+{
+ g_print("%s\n", __func__);
+ return FALSE;
+}
+
+static void
+destroy_notify(gpointer user_data)
+{
+ g_print("%s\n", __func__);
+}
+
+static GstAppSrcCallbacks cbs = {
+ need_data,
+ enough_data,
+ seek_data
+};
+
int
cmumble_audio_create_playback_pipeline(struct cmumble *cm,
struct cmumble_user *user)
{
GstElement *pipeline, *sink_bin;
GError *error = NULL;
- char *desc = "appsrc name=src ! celtdec ! audioconvert ! autoaudiosink name=sink";
+ //identity sync=TRUE datarate=48000 !
+ char *desc = "appsrc name=src ! celtdec ! audiorate ! audioconvert ! autoaudiosink name=sink";
pipeline = gst_parse_launch(desc, &error);
if (error) {
@@ -151,13 +203,16 @@ cmumble_audio_create_playback_pipeline(struct cmumble *cm,
user->pipeline = pipeline;
user->src = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline), "src"));
+ user->sequence_start_time = GST_CLOCK_TIME_NONE;
/* Important! */
gst_base_src_set_live(GST_BASE_SRC(user->src), TRUE);
- gst_base_src_set_do_timestamp(GST_BASE_SRC(user->src), TRUE);
+ //gst_base_src_set_do_timestamp(GST_BASE_SRC(user->src), TRUE);
gst_base_src_set_format(GST_BASE_SRC(user->src), GST_FORMAT_TIME);
+ //gst_base_src_set_format(GST_BASE_SRC(user->src), GST_FORMAT_BYTES);
gst_app_src_set_stream_type(user->src, GST_APP_STREAM_TYPE_STREAM);
+ gst_app_src_set_callbacks(user->src, &cbs, cm, destroy_notify);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
@@ -168,9 +223,9 @@ cmumble_audio_create_playback_pipeline(struct cmumble *cm,
/* Setup Celt Decoder */
cmumble_audio_push(cm, user,
- cm->audio.celt_header_packet, sizeof(CELTHeader));
+ cm->audio.celt_header_packet, sizeof(CELTHeader), -1);
/* fake vorbiscomment buffer */
- cmumble_audio_push(cm, user, NULL, 0);
+ cmumble_audio_push(cm, user, NULL, 0, -1);
return 0;
}