From 56c949815b03559ff857f0095a8fba41264ee57e Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 25 Sep 2013 15:42:13 +0200 Subject: [PATCH] First pass at Gstreamer 1.0 porting. This at least compiles against gstreamer 1.2. Things that work: * Playing audio * Automatically completing tags Things that don't work * Spotify * Moodbar Things I haven't tested * Transcoding --- CMakeLists.txt | 10 +- ext/clementine-spotifyblob/mediapipeline.cpp | 17 +- ext/libclementine-common/core/logging.cpp | 3 +- gst/moodbar/gstfftwspectrum.c | 223 +++++++++++++------ gst/moodbar/gstmoodbar.c | 142 ++++++------ src/core/songloader.cpp | 26 ++- src/core/songloader.h | 2 +- src/engines/gstengine.cpp | 26 ++- src/engines/gstenginepipeline.cpp | 65 +++--- src/engines/gstenginepipeline.h | 4 +- src/moodbar/moodbarpipeline.cpp | 16 +- src/musicbrainz/chromaprinter.cpp | 33 +-- src/musicbrainz/chromaprinter.h | 2 +- src/transcoder/transcoder.cpp | 18 +- src/ui/mainwindow.cpp | 2 + src/visualisations/projectmvisualisation.cpp | 8 +- 16 files changed, 367 insertions(+), 230 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ba5a8a56..d1083b531 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,11 +66,11 @@ pkg_check_modules(CHROMAPRINT libchromaprint) pkg_check_modules(GIO gio-2.0) pkg_check_modules(GLIB glib-2.0) pkg_check_modules(GOBJECT gobject-2.0) -pkg_check_modules(GSTREAMER gstreamer-0.10) -pkg_check_modules(GSTREAMER_APP gstreamer-app-0.10) -pkg_check_modules(GSTREAMER_BASE gstreamer-base-0.10) -pkg_check_modules(GSTREAMER_CDDA gstreamer-cdda-0.10) -pkg_check_modules(GSTREAMER_TAG gstreamer-tag-0.10) +pkg_check_modules(GSTREAMER gstreamer-1.0) +pkg_check_modules(GSTREAMER_APP gstreamer-app-1.0) +pkg_check_modules(GSTREAMER_BASE gstreamer-base-1.0) +#pkg_check_modules(GSTREAMER_CDDA gstreamer-cdda-0.10) +pkg_check_modules(GSTREAMER_TAG gstreamer-tag-1.0) pkg_check_modules(INDICATEQT indicate-qt) pkg_check_modules(LIBGPOD libgpod-1.0>=0.7.92) pkg_check_modules(LIBMTP libmtp>=1.0) diff --git a/ext/clementine-spotifyblob/mediapipeline.cpp b/ext/clementine-spotifyblob/mediapipeline.cpp index 38c3541ee..5e4740860 100644 --- a/ext/clementine-spotifyblob/mediapipeline.cpp +++ b/ext/clementine-spotifyblob/mediapipeline.cpp @@ -91,17 +91,14 @@ bool MediaPipeline::Init(int sample_rate, int channels) { gst_app_src_set_callbacks(appsrc_, &callbacks, this, NULL); #if Q_BYTE_ORDER == Q_BIG_ENDIAN - const int endianness = G_BIG_ENDIAN; + static const char* format = "S16BE"; #elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN - const int endianness = G_LITTLE_ENDIAN; + static const char* format = "S16LE"; #endif // Set caps - GstCaps* caps = gst_caps_new_simple("audio/x-raw-int", - "endianness", G_TYPE_INT, endianness, - "signed", G_TYPE_BOOLEAN, TRUE, - "width", G_TYPE_INT, 16, - "depth", G_TYPE_INT, 16, + GstCaps* caps = gst_caps_new_simple("audio/x-raw", + "format", G_TYPE_STRING, format, "rate", G_TYPE_INT, sample_rate, "channels", G_TYPE_INT, channels, NULL); @@ -123,8 +120,12 @@ void MediaPipeline::WriteData(const char* data, qint64 length) { return; GstBuffer* buffer = gst_buffer_new_and_alloc(length); + GstMapInfo map_info; + gst_buffer_map(buffer, &map_info, GST_MAP_WRITE); - memcpy(GST_BUFFER_DATA(buffer), data, length); + memcpy(map_info.data, data, length); + + gst_buffer_unmap(buffer, &map_info); GST_BUFFER_OFFSET(buffer) = offset_bytes_; GST_BUFFER_TIMESTAMP(buffer) = offset_bytes_ * kNsecPerSec / byte_rate_; diff --git a/ext/libclementine-common/core/logging.cpp b/ext/libclementine-common/core/logging.cpp index 3c53d7adc..7e00e9721 100644 --- a/ext/libclementine-common/core/logging.cpp +++ b/ext/libclementine-common/core/logging.cpp @@ -40,7 +40,8 @@ static Level sDefaultLevel = Level_Debug; static QMap* sClassLevels = NULL; static QIODevice* sNullDevice = NULL; -const char* kDefaultLogLevels = "GstEnginePipeline:2,*:3"; +//const char* kDefaultLogLevels = "GstEnginePipeline:2,*:3"; +const char* kDefaultLogLevels = "*:3"; static const char* kMessageHandlerMagic = "__logging_message__"; static const int kMessageHandlerMagicLength = strlen(kMessageHandlerMagic); diff --git a/gst/moodbar/gstfftwspectrum.c b/gst/moodbar/gstfftwspectrum.c index 8b32e93b8..23313a879 100644 --- a/gst/moodbar/gstfftwspectrum.c +++ b/gst/moodbar/gstfftwspectrum.c @@ -89,20 +89,28 @@ static GstStaticPadTemplate src_factory ( SPECTRUM_FREQ_CAPS ) ); -GST_BOILERPLATE (GstFFTWSpectrum, gst_fftwspectrum, GstElement, - GST_TYPE_ELEMENT); +G_DEFINE_TYPE(GstFFTWSpectrum, gst_fftwspectrum, GST_TYPE_ELEMENT); static void gst_fftwspectrum_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_fftwspectrum_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static gboolean gst_fftwspectrum_sink_event( + GstPad* pad, GstObject* parent, GstEvent* event); +static gboolean gst_fftwspectrum_src_event( + GstPad* pad, GstObject* parent, GstEvent* event); +static gboolean gst_fftwspectrum_src_query( + GstPad* pad, GstObject* parent, GstQuery* query); +static gboolean gst_fftwspectrum_sink_query( + GstPad* pad, GstObject* parent, GstQuery* query); static gboolean gst_fftwspectrum_set_sink_caps (GstPad *pad, GstCaps *caps); static gboolean gst_fftwspectrum_set_src_caps (GstPad *pad, GstCaps *caps); static void gst_fftwspectrum_fixatecaps (GstPad *pad, GstCaps *caps); static GstCaps *gst_fftwspectrum_getcaps (GstPad *pad); -static GstFlowReturn gst_fftwspectrum_chain (GstPad *pad, GstBuffer *buf); +static GstFlowReturn gst_fftwspectrum_chain( + GstPad *pad, GstObject* object, GstBuffer *buf); static GstStateChangeReturn gst_fftwspectrum_change_state (GstElement *element, GstStateChange transition); @@ -115,25 +123,6 @@ static GstStateChangeReturn gst_fftwspectrum_change_state (GstElement *element, /***************************************************************/ -static void -gst_fftwspectrum_base_init (gpointer gclass) -{ - static GstElementDetails element_details = - { - "FFTW-based Fourier transform", - "Filter/Converter/Spectrum", - "Convert a raw audio stream into a frequency spectrum", - "Joe Rabinoff " - }; - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &element_details); -} - /* initialize the plugin's class */ static void gst_fftwspectrum_class_init (GstFFTWSpectrumClass * klass) @@ -164,6 +153,18 @@ gst_fftwspectrum_class_init (GstFFTWSpectrumClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fftwspectrum_change_state); + + gst_element_class_add_pad_template (GST_ELEMENT_CLASS(klass), + gst_static_pad_template_get (&src_factory)); + gst_element_class_add_pad_template (GST_ELEMENT_CLASS(klass), + gst_static_pad_template_get (&sink_factory)); + + gst_element_class_set_static_metadata( + GST_ELEMENT_CLASS(klass), + "FFTW-based Fourier transform", + "Filter/Converter/Spectrum", + "Convert a raw audio stream into a frequency spectrum", + "Joe Rabinoff "); } /* initialize the new element @@ -172,30 +173,28 @@ gst_fftwspectrum_class_init (GstFFTWSpectrumClass * klass) * initialize structure */ static void -gst_fftwspectrum_init (GstFFTWSpectrum * conv, - GstFFTWSpectrumClass * gclass) +gst_fftwspectrum_init (GstFFTWSpectrum * conv) { - GstElementClass *klass = GST_ELEMENT_GET_CLASS (conv); + GstElementClass* klass = + G_TYPE_INSTANCE_GET_CLASS(conv, GST_ELEMENT_TYPE, GstElementClass); conv->sinkpad = gst_pad_new_from_template (gst_element_class_get_pad_template (klass, "sink"), "sink"); - gst_pad_set_setcaps_function (conv->sinkpad, - GST_DEBUG_FUNCPTR (gst_fftwspectrum_set_sink_caps)); - gst_pad_set_getcaps_function (conv->sinkpad, - GST_DEBUG_FUNCPTR (gst_fftwspectrum_getcaps)); - gst_pad_set_chain_function (conv->sinkpad, + gst_pad_set_event_function(conv->sinkpad, gst_fftwspectrum_sink_event); + gst_pad_set_query_function(conv->srcpad, gst_fftwspectrum_src_query); + + gst_pad_set_chain_function (conv->sinkpad, GST_DEBUG_FUNCPTR (gst_fftwspectrum_chain)); conv->srcpad = gst_pad_new_from_template (gst_element_class_get_pad_template (klass, "src"), "src"); - gst_pad_set_setcaps_function (conv->srcpad, - GST_DEBUG_FUNCPTR (gst_fftwspectrum_set_src_caps)); - gst_pad_set_getcaps_function (conv->srcpad, - GST_DEBUG_FUNCPTR (gst_fftwspectrum_getcaps)); - gst_pad_set_fixatecaps_function (conv->srcpad, - GST_DEBUG_FUNCPTR (gst_fftwspectrum_fixatecaps)); + gst_pad_set_event_function(conv->srcpad, gst_fftwspectrum_src_event); + gst_pad_set_query_function(conv->sinkpad, gst_fftwspectrum_sink_query); + + //gst_pad_set_fixatecaps_function (conv->srcpad, + // GST_DEBUG_FUNCPTR (gst_fftwspectrum_fixatecaps)); gst_element_add_pad (GST_ELEMENT (conv), conv->sinkpad); @@ -205,7 +204,7 @@ gst_fftwspectrum_init (GstFFTWSpectrum * conv, conv->rate = 0; conv->size = 0; conv->step = 0; - + /* These are set when we change to READY */ conv->fftw_in = NULL; conv->fftw_out = NULL; @@ -223,6 +222,65 @@ gst_fftwspectrum_init (GstFFTWSpectrum * conv, conv->hi_q = HIQUALITY_DEFAULT; } +static gboolean +gst_fftwspectrum_sink_event(GstPad* pad, GstObject* parent, GstEvent* event) +{ + GstFFTWSpectrum* conv = GST_FFTWSPECTRUM(parent); + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_CAPS: { + GstCaps* caps = NULL; + gst_event_parse_caps(event, &caps); + gst_fftwspectrum_set_sink_caps(pad, caps); + return gst_pad_push_event(conv->srcpad, event); + } + default: + return gst_pad_event_default(pad, parent, event); + } +} + +static gboolean +gst_fftwspectrum_src_event(GstPad* pad, GstObject* parent, GstEvent* event) +{ + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_CAPS: { + GstCaps* caps = NULL; + gst_event_parse_caps(event, &caps); + gst_fftwspectrum_set_src_caps(pad, caps); + } + // FALLTHROUGH + default: + return gst_pad_event_default(pad, parent, event); + } +} + +static gboolean +gst_fftwspectrum_src_query(GstPad* pad, GstObject* parent, GstQuery* query) +{ + switch (GST_QUERY_TYPE(query)) { + case GST_QUERY_CAPS: { + GstCaps* caps = gst_fftwspectrum_getcaps(pad); + gst_pad_set_caps(pad, caps); + } + // FALLTHROUGH + default: + return gst_pad_query_default(pad, parent, query); + } +} + +static gboolean +gst_fftwspectrum_sink_query(GstPad* pad, GstObject* parent, GstQuery* query) +{ + switch (GST_QUERY_TYPE(query)) { + case GST_QUERY_CAPS: { + GstCaps* caps = gst_fftwspectrum_getcaps(pad); + gst_pad_set_caps(pad, caps); + } + // FALLTHROUGH + default: + return gst_pad_query_default(pad, parent, query); + } +} + static void gst_fftwspectrum_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -362,7 +420,7 @@ gst_fftwspectrum_set_sink_caps (GstPad * pad, GstCaps * caps) /* Fixate the source caps with the given rate */ gst_caps_set_simple (newsrccaps, "rate", G_TYPE_INT, rate, NULL); - gst_pad_fixate_caps (conv->srcpad, newsrccaps); + //gst_pad_fixate_caps (conv->srcpad, newsrccaps); conv->rate = rate; res = gst_pad_set_caps (conv->srcpad, newsrccaps); if (!res) @@ -515,9 +573,10 @@ gst_fftwspectrum_change_state (GstElement * element, break; } - res = parent_class->change_state (element, transition); + res = GST_ELEMENT_CLASS(gst_fftwspectrum_parent_class) + ->change_state(element, transition); - switch (transition) + switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; @@ -545,15 +604,20 @@ gst_fftwspectrum_change_state (GstElement * element, static void push_samples (GstFFTWSpectrum *conv, GstBuffer *buf) { - gint newsamples = GST_BUFFER_SIZE (buf) / sizeof (gdouble); + GstMapInfo map; + gst_buffer_map(buf, &map, GST_MAP_READ); + + gint newsamples = map.size / sizeof (gdouble); gint oldsamples = conv->numsamples; conv->numsamples += newsamples; conv->samples = g_realloc (conv->samples, conv->numsamples * sizeof (gdouble)); - memcpy (&conv->samples[oldsamples], GST_BUFFER_DATA (buf), + memcpy (&conv->samples[oldsamples], map.data, newsamples * sizeof (gdouble)); - + /* GST_LOG ("Added %d samples", newsamples); */ + + gst_buffer_unmap(buf, &map); } /* This basically does the opposite of push_samples, but takes samples @@ -586,45 +650,78 @@ shift_samples (GstFFTWSpectrum *conv, gint toshift) * by conv->step. */ static GstFlowReturn -gst_fftwspectrum_chain (GstPad * pad, GstBuffer * buf) +gst_fftwspectrum_chain(GstPad* pad, GstObject* object, GstBuffer* buf) { - GstFFTWSpectrum *conv; + GstFFTWSpectrum *conv = GST_FFTWSPECTRUM(object); GstBuffer *outbuf; GstFlowReturn res = GST_FLOW_OK; - conv = GST_FFTWSPECTRUM (gst_pad_get_parent (pad)); - push_samples (conv, buf); gst_buffer_unref (buf); + GstQuery* query = gst_query_new_allocation(gst_pad_get_current_caps(pad), TRUE); + if (!gst_pad_peer_query(pad, query)) { + // Query failed, not a problem, we use the query defaults. + } + + GstBufferPool* pool = NULL; + guint size = 0; + guint min = 0; + guint max = 0; + if (gst_query_get_n_allocation_pools(query) > 0) { + gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max); + } + if (pool == NULL) { + pool = gst_buffer_pool_new(); + } + + GstStructure* config = gst_buffer_pool_get_config(pool); + gst_buffer_pool_config_set_params( + config, gst_pad_get_current_caps(pad), size, min, max); + gst_buffer_pool_set_config(pool, config); + + gst_buffer_pool_set_active(pool, TRUE); + while (conv->numsamples >= MAX (conv->size, conv->step)) { - res = gst_pad_alloc_buffer_and_set_caps - (conv->srcpad, conv->offset, OUTPUT_SIZE (conv), - GST_PAD_CAPS(conv->srcpad), &outbuf); + /* + res = gst_pad_alloc_buffer_and_set_caps( + conv->srcpad, + conv->offset, + OUTPUT_SIZE(conv), + GST_PAD_CAPS(conv->srcpad), + &outbuf); + */ + + res = gst_buffer_pool_acquire_buffer(pool, &outbuf, NULL); + if (res != GST_FLOW_OK) - break; - - GST_BUFFER_SIZE (outbuf) = OUTPUT_SIZE (conv); + break; + + gst_buffer_set_size(outbuf, OUTPUT_SIZE(conv)); GST_BUFFER_OFFSET (outbuf) = conv->offset; GST_BUFFER_OFFSET_END (outbuf) = conv->offset + conv->step; GST_BUFFER_TIMESTAMP (outbuf) = conv->timestamp; - GST_BUFFER_DURATION (outbuf) - = gst_util_uint64_scale_int (GST_SECOND, conv->step, conv->rate); - + GST_BUFFER_DURATION (outbuf) = + gst_util_uint64_scale_int (GST_SECOND, conv->step, conv->rate); + /* Do the Fourier transform */ memcpy (conv->fftw_in, conv->samples, conv->size * sizeof (double)); fftw_execute (conv->fftw_plan); { /* Normalize */ - gint i; - gfloat root = sqrtf (conv->size); - for (i = 0; i < 2*(conv->size/2+1); ++i) - conv->fftw_out[i] /= root; + gint i; + gfloat root = sqrtf (conv->size); + for (i = 0; i < 2*(conv->size/2+1); ++i) { + conv->fftw_out[i] /= root; + } } - memcpy (GST_BUFFER_DATA (outbuf), conv->fftw_out, OUTPUT_SIZE (conv)); - + GstMapInfo map; + gst_buffer_map(outbuf, &map, GST_MAP_WRITE); + memcpy (map.data, conv->fftw_out, OUTPUT_SIZE (conv)); + gst_buffer_unmap(outbuf, &map); + res = gst_pad_push (conv->srcpad, outbuf); - + shift_samples (conv, conv->step); if (res != GST_FLOW_OK) diff --git a/gst/moodbar/gstmoodbar.c b/gst/moodbar/gstmoodbar.c index da2f2e7b0..17da311ae 100644 --- a/gst/moodbar/gstmoodbar.c +++ b/gst/moodbar/gstmoodbar.c @@ -100,8 +100,7 @@ static GstStaticPadTemplate src_factory ) ); -GST_BOILERPLATE (GstMoodbar, gst_moodbar, GstElement, - GST_TYPE_ELEMENT); +G_DEFINE_TYPE(GstMoodbar, gst_moodbar, GST_TYPE_ELEMENT); static void gst_moodbar_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -109,9 +108,11 @@ static void gst_moodbar_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static gboolean gst_moodbar_set_sink_caps (GstPad *pad, GstCaps *caps); -static gboolean gst_moodbar_sink_event (GstPad *pad, GstEvent *event); +static gboolean gst_moodbar_sink_event ( + GstPad *pad, GstObject *parent, GstEvent *event); -static GstFlowReturn gst_moodbar_chain (GstPad *pad, GstBuffer *buf); +static GstFlowReturn gst_moodbar_chain ( + GstPad *pad, GstObject *object, GstBuffer *buf); static GstStateChangeReturn gst_moodbar_change_state (GstElement *element, GstStateChange transition); @@ -143,26 +144,6 @@ static const guint bark_bands[24] /* GObject boilerplate stuff */ /***************************************************************/ - -static void -gst_moodbar_base_init (gpointer gclass) -{ - static GstElementDetails element_details = - { - "Moodbar analyzer", - "Filter/Converter/Moodbar", - "Convert a spectrum into a stream of (uchar) rgb triples representing its \"mood\"", - "Joe Rabinoff " - }; - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &element_details); -} - /* initialize the plugin's class */ static void gst_moodbar_class_init (GstMoodbarClass * klass) @@ -178,16 +159,28 @@ gst_moodbar_class_init (GstMoodbarClass * klass) g_object_class_install_property (gobject_class, ARG_HEIGHT, g_param_spec_int ("height", "Image height", - "The height of the resulting raw image", - 1, G_MAXINT32, HEIGHT_DEFAULT, G_PARAM_READWRITE)); + "The height of the resulting raw image", + 1, G_MAXINT32, HEIGHT_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_MAX_WIDTH, g_param_spec_int ("max-width", "Image maximum width", - "The maximum width of the resulting raw image, or 0 for no rescaling", - 0, G_MAXINT32, MAX_WIDTH_DEFAULT, G_PARAM_READWRITE)); + "The maximum width of the resulting raw image, or 0 for no rescaling", + 0, G_MAXINT32, MAX_WIDTH_DEFAULT, G_PARAM_READWRITE)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_moodbar_change_state); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&src_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&sink_factory)); + + gst_element_class_set_static_metadata( + gstelement_class, + "Moodbar analyzer", + "Filter/Converter/Moodbar", + "Convert a spectrum into a stream of (uchar) rgb triples representing its \"mood\"", + "Joe Rabinoff "); } /* initialize the new element @@ -196,19 +189,17 @@ gst_moodbar_class_init (GstMoodbarClass * klass) * initialize structure */ static void -gst_moodbar_init (GstMoodbar *mood, GstMoodbarClass *gclass) +gst_moodbar_init (GstMoodbar *mood) { GstElementClass *klass = GST_ELEMENT_GET_CLASS (mood); mood->sinkpad = gst_pad_new_from_template (gst_element_class_get_pad_template (klass, "sink"), "sink"); - gst_pad_set_setcaps_function (mood->sinkpad, - GST_DEBUG_FUNCPTR (gst_moodbar_set_sink_caps)); gst_pad_set_event_function (mood->sinkpad, - GST_DEBUG_FUNCPTR (gst_moodbar_sink_event)); + GST_DEBUG_FUNCPTR (gst_moodbar_sink_event)); gst_pad_set_chain_function (mood->sinkpad, - GST_DEBUG_FUNCPTR (gst_moodbar_chain)); + GST_DEBUG_FUNCPTR (gst_moodbar_chain)); mood->srcpad = gst_pad_new_from_template @@ -222,7 +213,7 @@ gst_moodbar_init (GstMoodbar *mood, GstMoodbarClass *gclass) mood->rate = 0; mood->size = 0; mood->barkband_table = NULL; - + /* These are allocated when we change to PAUSED */ mood->r = NULL; mood->g = NULL; @@ -240,7 +231,7 @@ static void gst_moodbar_set_property (GObject *object, guint prop_id, { GstMoodbar *mood = GST_MOODBAR (object); - switch (prop_id) + switch (prop_id) { case ARG_HEIGHT: mood->height = (guint) g_value_get_int (value); @@ -252,7 +243,7 @@ static void gst_moodbar_set_property (GObject *object, guint prop_id, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } - + } @@ -352,16 +343,19 @@ gst_moodbar_set_sink_caps (GstPad *pad, GstCaps *caps) static gboolean -gst_moodbar_sink_event (GstPad *pad, GstEvent *event) +gst_moodbar_sink_event (GstPad *pad, GstObject *parent, GstEvent *event) { - GstMoodbar *mood; + GstMoodbar *mood = GST_MOODBAR(parent); gboolean res = TRUE; - mood = GST_MOODBAR (gst_pad_get_parent (pad)); - - if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { gst_moodbar_finish (mood); - + } else if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) { + GstCaps* caps = NULL; + gst_event_parse_caps(event, &caps); + gst_moodbar_set_sink_caps(pad, caps); + } + res = gst_pad_push_event (mood->srcpad, event); gst_object_unref (mood); @@ -397,7 +391,8 @@ gst_moodbar_change_state (GstElement *element, GstStateChange transition) break; } - res = parent_class->change_state (element, transition); + res = GST_ELEMENT_CLASS(gst_moodbar_parent_class) + ->change_state (element, transition); switch (transition) { @@ -457,27 +452,31 @@ allocate_another_frame (GstMoodbar *mood) * once we receive an EOS signal. */ static GstFlowReturn -gst_moodbar_chain (GstPad *pad, GstBuffer *buf) +gst_moodbar_chain (GstPad *pad, GstObject *parent, GstBuffer *buf) { - GstMoodbar *mood = GST_MOODBAR (gst_pad_get_parent (pad)); + GstMoodbar *mood = GST_MOODBAR (parent); guint i; gdouble amplitudes[24], rgb[3] = {0.f, 0.f, 0.f}; gdouble *out, real, imag; guint numfreqs = NUMFREQS (mood); - if (GST_BUFFER_SIZE (buf) != numfreqs * sizeof (gdouble) * 2) + GstMapInfo map; + gst_buffer_map(buf, &map, GST_MAP_READ); + + if (map.size != numfreqs * sizeof (gdouble) * 2) { + gst_buffer_unmap(buf, &map); gst_object_unref (mood); return GST_FLOW_ERROR; } - out = (gdouble *) GST_BUFFER_DATA (buf); + out = (gdouble *) map.data; if (!allocate_another_frame (mood)) return GST_FLOW_ERROR; /* Calculate total amplitudes for the different bark bands */ - + for (i = 0; i < 24; ++i) amplitudes[i] = 0.f; @@ -501,6 +500,7 @@ gst_moodbar_chain (GstPad *pad, GstBuffer *buf) mood->g[mood->numframes] = rgb[1]; mood->b[mood->numframes] = rgb[2]; + gst_buffer_unmap (buf, &map); gst_buffer_unref (buf); gst_object_unref (mood); @@ -624,9 +624,12 @@ gst_moodbar_finish (GstMoodbar *mood) (output_width * mood->height * 3 * sizeof (guchar)); if (!buf) return; + + GstMapInfo map; + gst_buffer_map(buf, &map, GST_MAP_READ); /* Don't set the timestamp, duration, etc. since it's irrelevant */ - GST_BUFFER_OFFSET (buf) = 0; - data = (guchar *) GST_BUFFER_DATA (buf); + map.memory->offset = 0; + data = (guchar *) map.data; gdouble r, g, b; guint i, j, n; @@ -634,40 +637,43 @@ gst_moodbar_finish (GstMoodbar *mood) for (line = 0; line < mood->height; ++line) { for (i = 0; i < output_width; ++i) - { - r = 0.f; g = 0.f; b = 0.f; - start = i * mood->numframes / output_width; - end = (i + 1) * mood->numframes / output_width; - if ( start == end ) - end = start + 1; + { + r = 0.f; g = 0.f; b = 0.f; + start = i * mood->numframes / output_width; + end = (i + 1) * mood->numframes / output_width; + if ( start == end ) + end = start + 1; - for( j = start; j < end; j++ ) - { - r += mood->r[j] * 255.f; - g += mood->g[j] * 255.f; - b += mood->b[j] * 255.f; - } + for( j = start; j < end; j++ ) + { + r += mood->r[j] * 255.f; + g += mood->g[j] * 255.f; + b += mood->b[j] * 255.f; + } - n = end - start; + n = end - start; - *(data++) = (guchar) (r / ((gdouble) n)); - *(data++) = (guchar) (g / ((gdouble) n)); - *(data++) = (guchar) (b / ((gdouble) n)); - } + *(data++) = (guchar) (r / ((gdouble) n)); + *(data++) = (guchar) (g / ((gdouble) n)); + *(data++) = (guchar) (b / ((gdouble) n)); + } } { /* Now we (finally) know the width of the image we're pushing */ - GstCaps *caps = gst_caps_copy (gst_pad_get_caps (mood->srcpad)); + GstCaps *caps = gst_caps_copy (gst_pad_get_current_caps (mood->srcpad)); gboolean res; gst_caps_set_simple (caps, "width", G_TYPE_INT, output_width, NULL); gst_caps_set_simple (caps, "height", G_TYPE_INT, mood->height, NULL); res = gst_pad_set_caps (mood->srcpad, caps); + /* if (res) gst_buffer_set_caps (buf, caps); + */ gst_caps_unref (caps); if (!res) return; } gst_pad_push (mood->srcpad, buf); + gst_buffer_unmap(buf, &map); } diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index 77ddd227d..20cbd1b87 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -122,7 +122,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString& filename) { SongLoader::Result SongLoader::LoadAudioCD() { #ifdef HAVE_AUDIOCD // Create gstreamer cdda element - GstElement* cdda = gst_element_make_from_uri (GST_URI_SRC, "cdda://", NULL); + GstElement* cdda = gst_element_make_from_uri (GST_URI_SRC, "cdda://", NULL, NULL); if (cdda == NULL) { qLog(Error) << "Error while creating CDDA GstElement"; return Error; @@ -460,7 +460,7 @@ SongLoader::Result SongLoader::LoadRemote() { // Create the source element automatically based on the URL GstElement* source = gst_element_make_from_uri( - GST_URI_SRC, url_.toEncoded().constData(), NULL); + GST_URI_SRC, url_.toEncoded().constData(), NULL, NULL); if (!source) { qLog(Warning) << "Couldn't create gstreamer source element for" << url_.toString(); return Error; @@ -476,12 +476,13 @@ SongLoader::Result SongLoader::LoadRemote() { // Connect callbacks GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline.get())); CHECKED_GCONNECT(typefind, "have-type", &TypeFound, this); - gst_bus_set_sync_handler(bus, BusCallbackSync, this); + gst_bus_set_sync_handler(bus, BusCallbackSync, this, NULL); gst_bus_add_watch(bus, BusCallback, this); // Add a probe to the sink so we can capture the data if it's a playlist GstPad* pad = gst_element_get_static_pad(fakesink, "sink"); - gst_pad_add_buffer_probe(pad, G_CALLBACK(DataReady), this); + gst_pad_add_probe( + pad, GST_PAD_PROBE_TYPE_BUFFER, &DataReady, this, NULL); gst_object_unref(pad); // Start "playing" @@ -511,16 +512,21 @@ void SongLoader::TypeFound(GstElement*, uint, GstCaps* caps, void* self) { instance->StopTypefindAsync(true); } -gboolean SongLoader::DataReady(GstPad*, GstBuffer* buf, void* self) { - SongLoader* instance = static_cast(self); +GstPadProbeReturn SongLoader::DataReady( + GstPad*, GstPadProbeInfo* info, gpointer self) { + SongLoader* instance = reinterpret_cast(self); if (instance->state_ == Finished) - return true; + return GST_PAD_PROBE_OK; + + GstBuffer* buffer = gst_pad_probe_info_get_buffer(info); + GstMapInfo map; + gst_buffer_map(buffer, &map, GST_MAP_READ); // Append the data to the buffer - instance->buffer_.append(reinterpret_cast(GST_BUFFER_DATA(buf)), - GST_BUFFER_SIZE(buf)); + instance->buffer_.append(reinterpret_cast(map.data), map.size); qLog(Debug) << "Received total" << instance->buffer_.size() << "bytes"; + gst_buffer_unmap(buffer, &map); if (instance->state_ == WaitingForMagic && (instance->buffer_.size() >= PlaylistParser::kMagicSize || @@ -529,7 +535,7 @@ gboolean SongLoader::DataReady(GstPad*, GstBuffer* buf, void* self) { instance->MagicReady(); } - return true; + return GST_PAD_PROBE_OK; } gboolean SongLoader::BusCallback(GstBus*, GstMessage* msg, gpointer self) { diff --git a/src/core/songloader.h b/src/core/songloader.h index 806e0378a..0c5d1cafc 100644 --- a/src/core/songloader.h +++ b/src/core/songloader.h @@ -100,7 +100,7 @@ private: // GStreamer callbacks static void TypeFound(GstElement* typefind, uint probability, GstCaps* caps, void* self); - static gboolean DataReady(GstPad*, GstBuffer* buf, void* self); + static GstPadProbeReturn DataReady(GstPad*, GstPadProbeInfo* buf, gpointer self); static GstBusSyncReply BusCallbackSync(GstBus*, GstMessage*, gpointer); static gboolean BusCallback(GstBus*, GstMessage*, gpointer); diff --git a/src/engines/gstengine.cpp b/src/engines/gstengine.cpp index 7131c8ce9..3dabfb3e0 100644 --- a/src/engines/gstengine.cpp +++ b/src/engines/gstengine.cpp @@ -200,24 +200,28 @@ void GstEngine::UpdateScope() { typedef Engine::Scope::value_type sample_type; // determine the number of channels + /* GstStructure* structure = gst_caps_get_structure( GST_BUFFER_CAPS(latest_buffer_), 0); + */ int channels = 2; - gst_structure_get_int(structure, "channels", &channels); + //gst_structure_get_int(structure, "channels", &channels); // scope does not support >2 channels if (channels > 2) return; - const sample_type* source = reinterpret_cast( - GST_BUFFER_DATA(latest_buffer_)); + GstMapInfo map; + gst_buffer_map(latest_buffer_, &map, GST_MAP_READ); + const sample_type* source = reinterpret_cast(map.data); sample_type* dest = scope_.data(); const int bytes = qMin( - static_cast(GST_BUFFER_SIZE(latest_buffer_)), + static_cast(map.size), scope_.size() * sizeof(sample_type)); memcpy(dest, source, bytes); + gst_buffer_unmap(latest_buffer_, &map); gst_buffer_unref(latest_buffer_); latest_buffer_ = NULL; } @@ -636,19 +640,21 @@ GstEngine::PluginDetailsList PluginDetailsList ret; - GstRegistry* registry = gst_registry_get_default(); + GstRegistry* registry = gst_registry_get(); GList* const features = gst_registry_get_feature_list(registry, GST_TYPE_ELEMENT_FACTORY); GList* p = features; while (p) { GstElementFactory* factory = GST_ELEMENT_FACTORY(p->data); - if (QString(factory->details.klass).contains(classname)) { + if (QString(gst_element_factory_get_klass(factory)).contains(classname)) { PluginDetails details; - details.name = QString::fromUtf8(GST_PLUGIN_FEATURE_NAME(p->data)); - details.long_name = QString::fromUtf8(factory->details.longname); - details.description = QString::fromUtf8(factory->details.description); - details.author = QString::fromUtf8(factory->details.author); + details.name = QString::fromUtf8(GST_OBJECT_NAME(p->data)); + details.long_name = + QString::fromUtf8(gst_element_factory_get_longname(factory)); + details.description = + QString::fromUtf8(gst_element_factory_get_description(factory)); + details.author = QString::fromUtf8(gst_element_factory_get_author(factory)); ret << details; } p = g_list_next(p); diff --git a/src/engines/gstenginepipeline.cpp b/src/engines/gstenginepipeline.cpp index 94f77a357..c05d754e5 100644 --- a/src/engines/gstenginepipeline.cpp +++ b/src/engines/gstenginepipeline.cpp @@ -285,7 +285,8 @@ bool GstEnginePipeline::Init() { // We do it here because we want pre-equalized and pre-volume samples // so that our visualization are not be affected by them. pad = gst_element_get_static_pad(event_probe, "src"); - gst_pad_add_event_probe(pad, G_CALLBACK(EventHandoffCallback), this); + gst_pad_add_probe( + pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, &EventHandoffCallback, this, NULL); gst_object_unref(pad); // Configure the fakesink properly @@ -296,7 +297,7 @@ bool GstEnginePipeline::Init() { int last_band_frequency = 0; for (int i=0 ; i(g_value_get_object(val)); - - GstTaskThreadCallbacks callbacks; - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.enter_thread = TaskEnterCallback; - - gst_task_set_thread_callbacks(task, &callbacks, this, NULL); + gst_task_set_enter_callback(task, &TaskEnterCallback, this, NULL); } } } @@ -666,8 +666,10 @@ void GstEnginePipeline::NewPadCallback(GstElement*, GstPad* pad, gpointer self) } } -bool GstEnginePipeline::HandoffCallback(GstPad*, GstBuffer* buf, gpointer self) { +GstPadProbeReturn GstEnginePipeline::HandoffCallback( + GstPad*, GstPadProbeInfo* info, gpointer self) { GstEnginePipeline* instance = reinterpret_cast(self); + GstBuffer* buf = gst_pad_probe_info_get_buffer(info); QList consumers; { @@ -724,20 +726,22 @@ bool GstEnginePipeline::HandoffCallback(GstPad*, GstBuffer* buf, gpointer self) instance->last_buffer_offset_ = GST_BUFFER_OFFSET(buf); - return true; + return GST_PAD_PROBE_OK; } -bool GstEnginePipeline::EventHandoffCallback(GstPad*, GstEvent* e, gpointer self) { +GstPadProbeReturn GstEnginePipeline::EventHandoffCallback( + GstPad*, GstPadProbeInfo* info, gpointer self) { GstEnginePipeline* instance = reinterpret_cast(self); + GstEvent* e = gst_pad_probe_info_get_event(info); qLog(Debug) << instance->id() << "event" << GST_EVENT_TYPE_NAME(e); - if (GST_EVENT_TYPE(e) == GST_EVENT_NEWSEGMENT && !instance->segment_start_received_) { + if (GST_EVENT_TYPE(e) == GST_EVENT_SEGMENT && !instance->segment_start_received_) { // The segment start time is used to calculate the proper offset of data // buffers from the start of the stream - gint64 start = 0; - gst_event_parse_new_segment(e, NULL, NULL, NULL, &start, NULL, NULL); - instance->segment_start_ = start; + const GstSegment* segment = NULL; + gst_event_parse_segment(e, &segment); + instance->segment_start_ = segment->start; instance->segment_start_received_ = true; if (instance->emit_track_ended_on_segment_start_) { @@ -748,7 +752,7 @@ bool GstEnginePipeline::EventHandoffCallback(GstPad*, GstEvent* e, gpointer self } } - return true; + return GST_PAD_PROBE_OK; } void GstEnginePipeline::SourceDrainedCallback(GstURIDecodeBin* bin, gpointer self) { @@ -836,17 +840,15 @@ void GstEnginePipeline::TransitionToNext() { } qint64 GstEnginePipeline::position() const { - GstFormat fmt = GST_FORMAT_TIME; gint64 value = 0; - gst_element_query_position(pipeline_, &fmt, &value); + gst_element_query_position(pipeline_, GST_FORMAT_TIME, &value); return value; } qint64 GstEnginePipeline::length() const { - GstFormat fmt = GST_FORMAT_TIME; gint64 value = 0; - gst_element_query_duration(pipeline_, &fmt, &value); + gst_element_query_duration(pipeline_, GST_FORMAT_TIME, &value); return value; } @@ -906,7 +908,8 @@ void GstEnginePipeline::UpdateEqualizer() { else gain *= 0.12; - GstObject* band = gst_child_proxy_get_child_by_index(GST_CHILD_PROXY(equalizer_), i); + GstObject* band = GST_OBJECT( + gst_child_proxy_get_child_by_index(GST_CHILD_PROXY(equalizer_), i)); g_object_set(G_OBJECT(band), "gain", gain, NULL); g_object_unref(G_OBJECT(band)); } diff --git a/src/engines/gstenginepipeline.h b/src/engines/gstenginepipeline.h index a1b8c9efb..da7bd5b92 100644 --- a/src/engines/gstenginepipeline.h +++ b/src/engines/gstenginepipeline.h @@ -126,8 +126,8 @@ class GstEnginePipeline : public QObject { static GstBusSyncReply BusCallbackSync(GstBus*, GstMessage*, gpointer); static gboolean BusCallback(GstBus*, GstMessage*, gpointer); static void NewPadCallback(GstElement*, GstPad*, gpointer); - static bool HandoffCallback(GstPad*, GstBuffer*, gpointer); - static bool EventHandoffCallback(GstPad*, GstEvent*, gpointer); + static GstPadProbeReturn HandoffCallback(GstPad*, GstPadProbeInfo*, gpointer); + static GstPadProbeReturn EventHandoffCallback(GstPad*, GstPadProbeInfo*, gpointer); static void SourceDrainedCallback(GstURIDecodeBin*, gpointer); static void SourceSetupCallback(GstURIDecodeBin*, GParamSpec *pspec, gpointer); static void TaskEnterCallback(GstTask*, GThread*, gpointer); diff --git a/src/moodbar/moodbarpipeline.cpp b/src/moodbar/moodbarpipeline.cpp index 835e52e79..2747c51f0 100644 --- a/src/moodbar/moodbarpipeline.cpp +++ b/src/moodbar/moodbarpipeline.cpp @@ -108,12 +108,13 @@ void MoodbarPipeline::Start() { // Connect signals CHECKED_GCONNECT(decodebin, "pad-added", &NewPadCallback, this); - gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), BusCallbackSync, this); + gst_bus_set_sync_handler( + gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), BusCallbackSync, this, NULL); // Set appsink callbacks GstAppSinkCallbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); - callbacks.new_buffer = NewBufferCallback; + callbacks.new_sample = NewBufferCallback; gst_app_sink_set_callbacks(reinterpret_cast(appsink), &callbacks, this, NULL); @@ -151,8 +152,12 @@ void MoodbarPipeline::NewPadCallback(GstElement*, GstPad* pad, gpointer data) { GstFlowReturn MoodbarPipeline::NewBufferCallback(GstAppSink* app_sink, gpointer data) { MoodbarPipeline* self = reinterpret_cast(data); - GstBuffer* buffer = gst_app_sink_pull_buffer(app_sink); - self->data_.append(reinterpret_cast(buffer->data), buffer->size); + GstSample* sample = gst_app_sink_pull_sample(app_sink); + GstBuffer* buffer = gst_sample_get_buffer(sample); + GstMapInfo map; + gst_buffer_map(buffer, &map, GST_MAP_READ); + self->data_.append(reinterpret_cast(map.data), map.size); + gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); return GST_FLOW_OK; @@ -187,7 +192,8 @@ void MoodbarPipeline::Cleanup() { Q_ASSERT(QThread::currentThread() != qApp->thread()); if (pipeline_) { - gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), NULL, NULL); + gst_bus_set_sync_handler( + gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), NULL, NULL, NULL); gst_element_set_state(pipeline_, GST_STATE_NULL); gst_object_unref(pipeline_); pipeline_ = NULL; diff --git a/src/musicbrainz/chromaprinter.cpp b/src/musicbrainz/chromaprinter.cpp index b3766b673..e7d1e6041 100644 --- a/src/musicbrainz/chromaprinter.cpp +++ b/src/musicbrainz/chromaprinter.cpp @@ -70,7 +70,7 @@ QString Chromaprinter::CreateFingerprint() { pipeline_ = gst_pipeline_new("pipeline"); GstElement* src = CreateElement("filesrc", pipeline_); - GstElement* decode = CreateElement("decodebin2", pipeline_); + GstElement* decode = CreateElement("decodebin", pipeline_); GstElement* convert = CreateElement("audioconvert", pipeline_); GstElement* resample = CreateElement("audioresample", pipeline_); GstElement* sink = CreateElement("appsink", pipeline_); @@ -85,10 +85,10 @@ QString Chromaprinter::CreateFingerprint() { gst_element_link_many(src, decode, NULL); gst_element_link_many(convert, resample, NULL); - // Chromaprint expects mono floats at a sample rate of 11025Hz. + // Chromaprint expects mono 16-bit ints at a sample rate of 11025Hz. GstCaps* caps = gst_caps_new_simple( - "audio/x-raw-int", - "width", G_TYPE_INT, 16, + "audio/x-raw", + "format", G_TYPE_STRING, "S16LE", "channels", G_TYPE_INT, kDecodeChannels, "rate", G_TYPE_INT, kDecodeRate, NULL); @@ -97,7 +97,7 @@ QString Chromaprinter::CreateFingerprint() { GstAppSinkCallbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); - callbacks.new_buffer = NewBufferCallback; + callbacks.new_sample = NewBufferCallback; gst_app_sink_set_callbacks(reinterpret_cast(sink), &callbacks, this, NULL); g_object_set(G_OBJECT(sink), "sync", FALSE, NULL); g_object_set(G_OBJECT(sink), "emit-signals", TRUE, NULL); @@ -106,8 +106,9 @@ QString Chromaprinter::CreateFingerprint() { g_object_set(src, "location", filename_.toUtf8().constData(), NULL); // Connect signals - CHECKED_GCONNECT(decode, "new-decoded-pad", &NewPadCallback, this); - gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), BusCallbackSync, this); + CHECKED_GCONNECT(decode, "pad-added", &NewPadCallback, this); + gst_bus_set_sync_handler( + gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), BusCallbackSync, this, NULL); guint bus_callback_id = gst_bus_add_watch(gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), BusCallback, this); QTime time; @@ -151,9 +152,10 @@ QString Chromaprinter::CreateFingerprint() { qLog(Debug) << "Decode time:" << decode_time << "Codegen time:" << codegen_time; // Cleanup - callbacks.new_buffer = NULL; + callbacks.new_sample = NULL; gst_app_sink_set_callbacks(reinterpret_cast(sink), &callbacks, this, NULL); - gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), NULL, NULL); + gst_bus_set_sync_handler( + gst_pipeline_get_bus(GST_PIPELINE(pipeline_)), NULL, NULL, NULL); g_source_remove(bus_callback_id); gst_element_set_state(pipeline_, GST_STATE_NULL); gst_object_unref(pipeline_); @@ -161,7 +163,7 @@ QString Chromaprinter::CreateFingerprint() { return fingerprint; } -void Chromaprinter::NewPadCallback(GstElement*, GstPad* pad, gboolean, gpointer data) { +void Chromaprinter::NewPadCallback(GstElement*, GstPad* pad, gpointer data) { Chromaprinter* instance = reinterpret_cast(data); GstPad* const audiopad = gst_element_get_static_pad( instance->convert_element_, "sink"); @@ -228,13 +230,16 @@ GstFlowReturn Chromaprinter::NewBufferCallback(GstAppSink* app_sink, gpointer se return GST_FLOW_OK; } - GstBuffer* buffer = gst_app_sink_pull_buffer(app_sink); - me->buffer_.write(reinterpret_cast(buffer->data), buffer->size); + GstSample* sample = gst_app_sink_pull_sample(app_sink); + GstBuffer* buffer = gst_sample_get_buffer(sample); + GstMapInfo map; + gst_buffer_map(buffer, &map, GST_MAP_READ); + me->buffer_.write(reinterpret_cast(map.data), map.size); + gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); gint64 pos = 0; - GstFormat format = GST_FORMAT_TIME; - gboolean ret = gst_element_query_position(me->pipeline_, &format, &pos); + gboolean ret = gst_element_query_position(me->pipeline_, GST_FORMAT_TIME, &pos); if (ret && pos > 30 * kNsecPerSec) { me->finishing_ = true; g_main_loop_quit(me->event_loop_); diff --git a/src/musicbrainz/chromaprinter.h b/src/musicbrainz/chromaprinter.h index a9c32265f..fa4933d4a 100644 --- a/src/musicbrainz/chromaprinter.h +++ b/src/musicbrainz/chromaprinter.h @@ -49,7 +49,7 @@ private: void ReportError(GstMessage* message); - static void NewPadCallback(GstElement*, GstPad* pad, gboolean, gpointer data); + static void NewPadCallback(GstElement*, GstPad* pad, gpointer data); static gboolean BusCallback(GstBus*, GstMessage* msg, gpointer data); static GstBusSyncReply BusCallbackSync(GstBus*, GstMessage* msg, gpointer data); static GstFlowReturn NewBufferCallback(GstAppSink* app_sink, gpointer self); diff --git a/src/transcoder/transcoder.cpp b/src/transcoder/transcoder.cpp index 487f975ff..774dc9969 100644 --- a/src/transcoder/transcoder.cpp +++ b/src/transcoder/transcoder.cpp @@ -100,7 +100,7 @@ GstElement* Transcoder::CreateElementForMimeType(const QString& element_type, // The caps we're trying to find GstCaps* target_caps = gst_caps_from_string(mime_type.toUtf8().constData()); - GstRegistry* registry = gst_registry_get_default(); + GstRegistry* registry = gst_registry_get(); GList* const features = gst_registry_get_feature_list(registry, GST_TYPE_ELEMENT_FACTORY); @@ -108,7 +108,7 @@ GstElement* Transcoder::CreateElementForMimeType(const QString& element_type, GstElementFactory* factory = GST_ELEMENT_FACTORY(p->data); // Is this the right type of plugin? - if (QString(factory->details.klass).contains(element_type)) { + if (QString(gst_element_factory_get_klass(factory)).contains(element_type)) { const GList* const templates = gst_element_factory_get_static_pad_templates(factory); for (const GList* p = templates ; p ; p = g_list_next(p)) { @@ -124,7 +124,7 @@ GstElement* Transcoder::CreateElementForMimeType(const QString& element_type, if (intersection) { if (!gst_caps_is_empty(intersection)) { int rank = gst_plugin_feature_get_rank(GST_PLUGIN_FEATURE(factory)); - QString name = GST_PLUGIN_FEATURE_NAME(factory); + QString name = GST_OBJECT_NAME(factory); if (name.startsWith("ffmux") || name.startsWith("ffenc")) rank = -1; // ffmpeg usually sucks @@ -451,7 +451,8 @@ bool Transcoder::StartJob(const Job &job) { state->convert_element_ = convert; CHECKED_GCONNECT(decode, "new-decoded-pad", &NewPadCallback, state.get()); - gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(state->pipeline_)), BusCallbackSync, state.get()); + gst_bus_set_sync_handler( + gst_pipeline_get_bus(GST_PIPELINE(state->pipeline_)), BusCallbackSync, state.get(), NULL); state->bus_callback_id_ = gst_bus_add_watch(gst_pipeline_get_bus(GST_PIPELINE(state->pipeline_)), BusCallback, state.get()); // Start the pipeline @@ -494,7 +495,7 @@ bool Transcoder::event(QEvent* e) { // Remove event handlers from the gstreamer pipeline so they don't get // called after the pipeline is shutting down gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE( - finished_event->state_->pipeline_)), NULL, NULL); + finished_event->state_->pipeline_)), NULL, NULL, NULL); g_source_remove(finished_event->state_->bus_callback_id_); // Remove it from the list - this will also destroy the GStreamer pipeline @@ -524,7 +525,7 @@ void Transcoder::Cancel() { // Remove event handlers from the gstreamer pipeline so they don't get // called after the pipeline is shutting down gst_bus_set_sync_handler(gst_pipeline_get_bus( - GST_PIPELINE(state->pipeline_)), NULL, NULL); + GST_PIPELINE(state->pipeline_)), NULL, NULL, NULL); g_source_remove(state->bus_callback_id_); // Stop the pipeline @@ -547,10 +548,9 @@ QMap Transcoder::GetProgress() const { gint64 position = 0; gint64 duration = 0; - GstFormat format = GST_FORMAT_TIME; - gst_element_query_position(state->pipeline_, &format, &position); - gst_element_query_duration(state->pipeline_, &format, &duration); + gst_element_query_position(state->pipeline_, GST_FORMAT_TIME, &position); + gst_element_query_duration(state->pipeline_, GST_FORMAT_TIME, &duration); ret[state->job_.input] = float(position) / duration; } diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index b4edfb485..1d9cb93f3 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -140,7 +140,9 @@ #include +#ifdef HAVE_AUDIOCD #include +#endif using boost::shared_ptr; using boost::scoped_ptr; diff --git a/src/visualisations/projectmvisualisation.cpp b/src/visualisations/projectmvisualisation.cpp index 536c5ccbe..0ee390f78 100644 --- a/src/visualisations/projectmvisualisation.cpp +++ b/src/visualisations/projectmvisualisation.cpp @@ -162,11 +162,15 @@ void ProjectMVisualisation::SetDuration(int seconds) { } void ProjectMVisualisation::ConsumeBuffer(GstBuffer* buffer, int) { - const int samples_per_channel = GST_BUFFER_SIZE(buffer) / sizeof(short) / 2; - const short* data = reinterpret_cast(GST_BUFFER_DATA(buffer)); + GstMapInfo map; + gst_buffer_map(buffer, &map, GST_MAP_READ); + const int samples_per_channel = map.size / sizeof(short) / 2; + const short* data = reinterpret_cast(map.data); if (projectm_) projectm_->pcm()->addPCM16Data(data, samples_per_channel); + + gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); }