Commit cbece874 authored by Scott Wheeler's avatar Scott Wheeler

GStreamer 0.8 backend. It still causes some weirdness when I switch from

GStreamer to aRts and back to GStreamer (hangs), but it's fair enough to
be in CVS now.  I may do some weird backporting where it still supports 0.6
in the branch or this depending on what it finds once it's a bit more stable.

BUG:72877
BUG:88464

svn path=/trunk/kdemultimedia/juk/; revision=360596
parent 98561d3b
......@@ -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)
......
......@@ -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"
......
......@@ -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 <tunepimp/tp_c.h>
#include <tunepimp/tp_c.h>
], [
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
/***************************************************************************
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 <config.h>
#include "gstreamerplayer.h"
#if HAVE_GSTREAMER
#include <kdebug.h>
#include <kapplication.h>
#include <qfile.h>
#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
/***************************************************************************
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 <config.h>
#include "config.h"
#if HAVE_GSTREAMER
#include <kde/gstplay/play.h>
#include <gst/gst.h>
#include <qstring.h>
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment