diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/audio.c | 65 | ||||
-rw-r--r-- | src/audio.h | 4 | ||||
-rw-r--r-- | src/cmumble.c | 2 | ||||
-rw-r--r-- | src/cmumble.h | 2 |
5 files changed, 66 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac index fed636d..d95007d 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,7 @@ PKG_CHECK_MODULES(PROTOBUF, [libprotobuf-c],[], [ ]) PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.28]) PKG_CHECK_MODULES(GIO, [gio-2.0]) -PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10 gstreamer-app-0.10]) +PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0 gstreamer-app-1.0]) PKG_CHECK_MODULES(CELT, [celt]) GST_ELEMENTS="appsrc appsink celtdec celtenc capsfilter 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; } diff --git a/src/audio.h b/src/audio.h index 90dc13d..3ab1d4c 100644 --- a/src/audio.h +++ b/src/audio.h @@ -6,7 +6,7 @@ #include <gst/gst.h> #include <gst/app/gstappsrc.h> #include <gst/app/gstappsink.h> -#include <gst/app/gstappbuffer.h> +//#include <gst/app/gstappbuffer.h> #include <celt/celt.h> #include <celt/celt_header.h> @@ -35,6 +35,6 @@ cmumble_audio_create_playback_pipeline(struct cmumble *cm, void cmumble_audio_push(struct cmumble *cm, struct cmumble_user *user, - const guint8 *data, gsize size); + const guint8 *data, gsize size, gint64 sequence); #endif /* _AUDIO_H_ */ diff --git a/src/cmumble.c b/src/cmumble.c index 61afdbc..5df4e6a 100644 --- a/src/cmumble.c +++ b/src/cmumble.c @@ -36,7 +36,7 @@ cmumble_read_audio_packet(struct cmumble *cm, uint8_t *data, size_t len) if (frame_len == 0 || frame_len > len-pos) break; - cmumble_audio_push(cm, user, &data[pos], frame_len); + cmumble_audio_push(cm, user, &data[pos], frame_len, sequence); pos += frame_len; sequence++; diff --git a/src/cmumble.h b/src/cmumble.h index 212991c..9e12ef3 100644 --- a/src/cmumble.h +++ b/src/cmumble.h @@ -49,6 +49,8 @@ struct cmumble_user { GstElement *pipeline; GstAppSrc *src; + + GstClockTimeDiff sequence_start_time; }; struct cmumble_channel { |