summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/audio.c65
-rw-r--r--src/audio.h4
-rw-r--r--src/cmumble.c2
-rw-r--r--src/cmumble.h2
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 {