diff options
Diffstat (limited to 'src/audio.c')
-rw-r--r-- | src/audio.c | 65 |
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; } |