diff --git a/Makefile.am b/Makefile.am index c876e72592d751f787b57beb81d73ac1f4c0745f..ee4114e7b99dfe775f5715a433011240409a1d98 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,15 +67,7 @@ juk_SOURCES = \ tagguessertest_SOURCES = tagguessertest.cpp tagguesser.cpp mbtest_SOURCES = mbtest.cpp musicbrainzquery.cpp -INCLUDES= $(all_includes) -I$(arts_includes) $(taglib_includes) - -################################################## -# check to see if GStreamer is available -################################################## -if link_lib_GST -gstlibs = -lkdegst -lkdegstplay -endif -################################################## +INCLUDES= $(all_includes) -I$(arts_includes) $(taglib_includes) $(GST_CFLAGS) ################################################## # check to see if MusicBrainz is available @@ -85,7 +77,7 @@ mblibs = -lmusicbrainz -ltunepimp endif ################################################## -juk_LDADD = $(gstlibs) $(mblibs) -lartskde $(LIB_KIO) $(taglib_libs) +juk_LDADD = $(LIB_GST) $(mblibs) -lartskde $(LIB_KIO) $(taglib_libs) juk_LDFLAGS = $(all_libraries) $(KDE_RPATH) tagguessertest_LDADD = $(LIB_KDECORE) diff --git a/configure.in.bot b/configure.in.bot index 65e269dd1742954c93fecbc7c10ede31188f659a..40d9f75ef3bf8ab26e7d7f3cfb588428045c3745 100644 --- a/configure.in.bot +++ b/configure.in.bot @@ -7,7 +7,7 @@ if test "x$have_taglib" = "xfalse"; then echo "**************************************************" fi -if test "x$have_gst" = "xfalse"; then +if test "x$have_gst" = "xno"; then echo "**************************************************" echo "*" echo "* You do not seem to have GStreamer and the" diff --git a/configure.in.in b/configure.in.in index 6603ec807f762b57b84a0e09d51a3c0c0e8580e5..e3c27f638a1728e1d3d9d0b0bf3170a169448829 100644 --- a/configure.in.in +++ b/configure.in.in @@ -10,23 +10,6 @@ if test "x$build_arts" = "xno"; then DO_NOT_COMPILE="$DO_NOT_COMPILE juk" fi -AC_DEFUN([AC_HAVE_GST], -[ - AC_DEFINE(HAVE_GSTREAMER, 1, [have GStreamer]) - have_gst=true -]) - -AC_DEFUN([AC_NO_GST], -[ - AC_DEFINE(HAVE_GSTREAMER, 0, [don't have GStreamer]) - have_gst=false -]) - -KDE_CHECK_HEADER(kde/gst/gstreamer.h, - AC_HAVE_GST, - AC_NO_GST -) - AC_DEFUN([AC_HAVE_MUSICBRAINZ], [ AC_DEFINE(HAVE_MUSICBRAINZ, 1, [have MusicBrainz]) @@ -43,21 +26,119 @@ AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_MSG_CHECKING(for tunepimp) AC_TRY_COMPILE([ -#include + #include ], [ - tunepimp_t m_pimp; - tp_AddFile(m_pimp, "myfile"); - return 0; + tunepimp_t m_pimp; + tp_AddFile(m_pimp, "myfile"); + return 0; ], [ - AC_MSG_RESULT(yes) - AC_HAVE_MUSICBRAINZ + AC_MSG_RESULT(yes) + AC_HAVE_MUSICBRAINZ ], [ - AC_MSG_RESULT(no) - AC_NO_MUSICBRAINZ + AC_MSG_RESULT(no) + AC_NO_MUSICBRAINZ ]) AC_LANG_RESTORE -AM_CONDITIONAL(link_lib_GST, test x$have_gst = xtrue) AM_CONDITIONAL(link_lib_MB, test x$have_musicbrainz = xtrue) + +dnl ================================================================================ + +dnl KDE_PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error + +AC_DEFUN([KDE_PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + + +# check for pkg-config +AC_ARG_VAR(PKGCONFIGFOUND, [Path to pkg-config]) +AC_CHECK_PROG(PKGCONFIGFOUND, pkg-config,[yes]) + +if test "$PKGCONFIGFOUND" = "yes" ; then +# check for GStreamer + dnl Now we're ready to ask for gstreamer libs and cflags + dnl And we can also ask for the right version of gstreamer + have_gst=no + + dnl start with 0.8 + GST_MAJORMINOR=0.8 + GST_REQ=0.8.0 + KDE_PKG_CHECK_MODULES(GST, \ + gstreamer-$GST_MAJORMINOR >= $GST_REQ \ + gstreamer-control-$GST_MAJORMINOR >= $GST_REQ \ + gstreamer-libs-$GST_MAJORMINOR >= $GST_REQ, + have_gst=yes,have_gst=no) + + dnl Give error if we don't have gstreamer + if test "x$have_gst" = "xno"; then + LIB_GST="" + CFLAGS_GST="" + AC_MSG_WARN([GStreamer version >= $GST_REQ required.]) + AC_DEFINE(HAVE_GSTREAMER, 0, [have GStreamer]) + else + LIB_GST=$GST_LIBS + CFLAGS_GST=$GST_CFLAGS + AC_SUBST(LIB_GST) + AC_SUBST(CFLAGS_GST) + AC_MSG_NOTICE([GStreamer version >= $GST_REQ found.]) + AC_DEFINE(HAVE_GSTREAMER, 1, [have GStreamer]) + fi +else + have_gst=no + AC_DEFINE(HAVE_GSTREAMER, 0, [have GStreamer]) + AC_MSG_WARN([No pkg-config found, required for GStreamer]) +fi diff --git a/gstreamerplayer.cpp b/gstreamerplayer.cpp index f1f8debaffb1f8b66340c9ad5432533482b66db9..ab1255fa3fb13c382515c32494bf92728b1cbb12 100644 --- a/gstreamerplayer.cpp +++ b/gstreamerplayer.cpp @@ -1,7 +1,6 @@ /*************************************************************************** - begin : Sat Feb 9 2003 - copyright : (C) 2003 by Tim Jansen - email : tim@tjansen.de + copyright : (C) 2004 Scott Wheeler + email : wheeler@kde.org ***************************************************************************/ /*************************************************************************** @@ -13,145 +12,122 @@ * * ***************************************************************************/ -#include +#include "gstreamerplayer.h" #if HAVE_GSTREAMER #include +#include #include -#include "gstreamerplayer.h" - -using namespace KDE::GST; -using namespace KDE::GSTPlay; //////////////////////////////////////////////////////////////////////////////// // public methods //////////////////////////////////////////////////////////////////////////////// -GStreamerPlayer::GStreamerPlayer() : Player(), - m_positionNs(0), m_durationNs(0), m_currentVolume(1.0) +GStreamerPlayer::GStreamerPlayer() : Player() { - setupPlayer(); + static bool initialized = false; + if(!initialized) { + int argc = kapp->argc(); + char **argv = kapp->argv(); + gst_init(&argc, &argv); + initialized = true; + } + + m_pipeline = gst_thread_new("pipeline"); + m_source = gst_element_factory_make("filesrc", "source"); + m_decoder = gst_element_factory_make("spider", "decoder"); + m_volume = gst_element_factory_make("volume", "volume"); + m_sink = gst_element_factory_make("alsasink", "sink"); + + gst_bin_add_many(GST_BIN(m_pipeline), m_source, m_decoder, m_volume, m_sink, 0); + gst_element_link_many(m_source, m_decoder, m_volume, m_sink, 0); } GStreamerPlayer::~GStreamerPlayer() { - delete m_player; + stop(); + gst_object_unref(GST_OBJECT(m_pipeline)); } void GStreamerPlayer::play(const FileHandle &file) { - m_currentFile = file.absFilePath(); - m_positionNs = 0; - m_durationNs = 0; - - if(!file.isNull()) - m_player->setLocation(file.absFilePath()); - - if(m_player->getState() != Element::STATE_PLAYING) - m_player->setState(Element::STATE_PLAYING); + stop(); + g_object_set(G_OBJECT(m_source), "location", file.absFilePath().utf8().data(), 0); + gst_element_set_state(m_pipeline, GST_STATE_PLAYING); } void GStreamerPlayer::pause() { - if(m_player->getState() != Element::STATE_PAUSED) - m_player->setState(Element::STATE_PAUSED); + gst_element_set_state(m_pipeline, GST_STATE_PAUSED); } void GStreamerPlayer::stop() { - if(m_player->getState() != Element::STATE_NULL) - m_player->setState(Element::STATE_NULL); + gst_element_set_state(m_pipeline, GST_STATE_NULL); } void GStreamerPlayer::setVolume(float volume) { - // 1.0 is full volume - m_player->setVolume(volume); + g_object_set(G_OBJECT(m_volume), "volume", volume, 0); } float GStreamerPlayer::volume() const { - // 1.0 is full volume - return m_player->getVolume(); + gfloat value; + g_object_get(G_OBJECT(m_volume), "volume", &value, 0); + return value; } -///////////////////////////////////////////////////////////////////////////////// -// m_player status functions -///////////////////////////////////////////////////////////////////////////////// - bool GStreamerPlayer::playing() const { - // true if playing - return m_player->getState() == Element::STATE_PLAYING; + return gst_element_get_state(m_pipeline) == GST_STATE_PLAYING; } bool GStreamerPlayer::paused() const { - // true if paused - return m_player->getState() == Element::STATE_PAUSED; + return gst_element_get_state(m_pipeline) == GST_STATE_PAUSED; } int GStreamerPlayer::totalTime() const { - return m_durationNs / 1000000000L; + return time(GST_QUERY_TOTAL) / GST_SECOND; } int GStreamerPlayer::currentTime() const { - return m_positionNs / 1000000000L; + return time(GST_QUERY_POSITION) / GST_SECOND; } int GStreamerPlayer::position() const { - if (m_durationNs > 0) - return int((m_positionNs * 1000.0) / m_durationNs); - else - return 0; + long long total = time(GST_QUERY_TOTAL); + long long current = time(GST_QUERY_POSITION); + return total > 0 ? int((double(current) / double(total)) * double(1000)) : 0; } -///////////////////////////////////////////////////////////////////////////////// -// m_player seek functions -///////////////////////////////////////////////////////////////////////////////// - void GStreamerPlayer::seek(int seekTime) { - // seek time in seconds? - m_player->seekToTime(seekTime*1000000000); + int type = (GST_FORMAT_TIME | GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH); + gst_element_seek(m_sink, GstSeekType(type), seekTime * GST_SECOND); } void GStreamerPlayer::seekPosition(int position) { - // position unit is 1/1000th - if(m_durationNs > 0) - m_player->seekToTime(position * m_durationNs / 1000L); - else - m_player->seekToTime(0); - + long long total = time(GST_QUERY_TOTAL); + if(total > 0) + seek(double(position) / double(1000) * double(totalTime()) + 0.5); } -///////////////////////////////////////////////////////////////////////////////// -// private -///////////////////////////////////////////////////////////////////////////////// - -void GStreamerPlayer::setupPlayer() +long long GStreamerPlayer::time(GstQueryType type) const { - m_player = new Play(Play::PIPE_AUDIO_BUFFER_THREADED, this, "Play"); - connect(m_player, SIGNAL(timeTick(long long)), - SLOT(slotSetPosition(long long))); - connect(m_player, SIGNAL(streamLength(long long)), - SLOT(slotSetDuration(long long))); - connect(m_player, SIGNAL(streamEnd()), SLOT(slotStopIfNotPlaying())); -} - -void GStreamerPlayer::slotStopIfNotPlaying() -{ - if(!playing()) - stop(); + gint64 ns = 0; + GstFormat format = GST_FORMAT_TIME; + gst_element_query(m_sink, type, &format, &ns); + return ns; } #include "gstreamerplayer.moc" - #endif diff --git a/gstreamerplayer.h b/gstreamerplayer.h index 6c5bb1e452c9e0c12735782bbc9f761ad2b262d5..a6186c19a65b5c08a03043fb4c36be354ec2bdb7 100644 --- a/gstreamerplayer.h +++ b/gstreamerplayer.h @@ -1,7 +1,6 @@ /*************************************************************************** - begin : Sat Feb 9 2003 - copyright : (C) 2003 by Tim Jansen - email : tim@tjansen.de + copyright : (C) 2004 Scott Wheeler + email : wheeler@kde.org ***************************************************************************/ /*************************************************************************** @@ -17,11 +16,11 @@ #ifndef GSTREAMERPLAYER_H #define GSTREAMERPLAYER_H -#include +#include "config.h" #if HAVE_GSTREAMER -#include +#include #include @@ -54,24 +53,15 @@ public slots: void pause(); void stop(); -private slots: - void slotSetPosition(long long d) { m_positionNs = d; } - void slotSetDuration(long long d) { m_durationNs = d; } - void slotStopIfNotPlaying(); - private: - void setupPlayer(); - - KDE::GSTPlay::Play *m_player; - unsigned long long m_duration; + long long time(GstQueryType type) const; - long long m_positionNs; // in ns - long long m_durationNs; // in ns - - QString m_currentFile; - float m_currentVolume; + GstElement *m_pipeline; + GstElement *m_source; + GstElement *m_decoder; + GstElement *m_volume; + GstElement *m_sink; }; #endif - #endif