Hello community,
here is the log from the commit of package amarok
checked in at Sat Apr 15 11:42:08 CEST 2006.
--------
--- KDE/amarok/amarok.changes 2006-04-13 12:53:18.000000000 +0200
+++ STABLE/amarok/amarok.changes 2006-04-13 20:11:02.000000000 +0200
@@ -1,0 +2,11 @@
+Thu Apr 13 20:06:49 CEST 2006 - bk@suse.de
+
+- make scope (visualisation) work with the helix wrapper on 64-bit
+
+-------------------------------------------------------------------
+Thu Apr 13 16:29:59 CEST 2006 - bk@suse.de
+
+- helix/x86_64: when playing streams, we didn't show any track info
+- fix build of last change (ChangeLog didn't apply, file was moved)
+
+-------------------------------------------------------------------
New:
----
helix-wrapper-metadata.diff
helix-wrapper-scope.diff
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ amarok.spec ++++++
--- /var/tmp/diff_new_pack.9C4HUz/_old 2006-04-15 11:41:52.000000000 +0200
+++ /var/tmp/diff_new_pack.9C4HUz/_new 2006-04-15 11:41:52.000000000 +0200
@@ -19,7 +19,7 @@
Group: Productivity/Multimedia/Sound/Players
Summary: Media Player for KDE
Version: 1.3.8
-Release: 26
+Release: 28
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define rversion 1.3.8
%define mversion 0.5
@@ -45,6 +45,8 @@
Patch15: konqsidebar-translation.diff
Patch16: helix-memleak-fix.patch
Patch17: amarok-skip-hidden-dirs.diff
+Patch18: helix-wrapper-metadata.diff
+Patch19: helix-wrapper-scope.diff
%description
amaroK is a media player for all kinds of media supported by aRts or
@@ -216,6 +218,8 @@
%patch15
%patch16
%patch17
+%patch18
+%patch19
cp %{S:10} amarok/src/engine/helix/
. /etc/opt/kde3/common_options
update_admin --no-unsermake
@@ -346,6 +350,11 @@
/opt/kde3/bin/amarok_libvisual
%changelog -n amarok
+* Thu Apr 13 2006 - bk@suse.de
+- make scope (visualisation) work with the helix wrapper on 64-bit
+* Thu Apr 13 2006 - bk@suse.de
+- helix/x86_64: when playing streams, we didn't show any track info
+- fix build of last change (ChangeLog didn't apply, file was moved)
* Thu Apr 13 2006 - dmueller@suse.de
- Readd fix to avoid scanning hidden dirs
* Wed Apr 12 2006 - cthiel@suse.de
++++++ amarok-helix-helper.cpp ++++++
--- KDE/amarok/amarok-helix-helper.cpp 2006-04-10 18:19:34.000000000 +0200
+++ STABLE/amarok/amarok-helix-helper.cpp 2006-04-13 20:30:21.000000000 +0200
@@ -3,10 +3,36 @@
#include <string>
#include <iostream>
#include <fstream>
+#include // for fcntl(pipefd, F_SETFL, flags|O_NONBLOCK|O_WRONLY)
using namespace std;
-int main()
+int scopebuf2sendbuffer(DelayQueue *item, char *buf)
+{
+ int len;
+
+ memcpy(buf, &item->len, sizeof(int) ); len = sizeof(int);
+ memcpy(&buf[len], &item->time, sizeof(unsigned long) ); len += sizeof(unsigned long);
+ memcpy(&buf[len], &item->etime, sizeof(unsigned long) ); len += sizeof(unsigned long);
+ memcpy(&buf[len], &item->nchan, sizeof(int) ); len += sizeof(int);
+ memcpy(&buf[len], &item->bps, sizeof(int) ); len += sizeof(int);
+ memcpy(&buf[len], &item->tps, sizeof(double) ); len += sizeof(double);
+ memcpy(&buf[len], &item->spb, sizeof(int) ); len += sizeof(int);
+ memcpy(&buf[len], item->buf, item->len ); len += item->len;
+
+ return len;
+}
+
+void makenonblocking(int pipefd)
+{
+ int flags = fcntl(pipefd, F_GETFL);
+ if (fcntl(pipefd, F_SETFL, flags|O_NONBLOCK|O_WRONLY)) {
+ perror("fcntl to set O_NONBLOCK");
+ exit(8);
+ }
+}
+
+int main(int argc, char *argv[])
{
string in, coredir, pluginsdir, codecsdir, tmp;
HelixSimplePlayer player;
@@ -15,6 +41,18 @@
int retval;
fd_set rfds;
+ // variables for sending new stream metadata as updates to amarokapp:
+
+ bool isLocal = true; // initialisation, we only have to send stream info
+ HelixSimplePlayer::metaData saved_md;
+ memset(&saved_md, 0, sizeof(saved_md)); // the saved metadata is empty
+ char sendscopebuf[65536], *sendscopeptr = NULL;
+ size_t towrite = 0;
+
+ int pipefd = atoi(argv[argc-1]); // It's the last argument which we get
+
+ makenonblocking(pipefd); // make the received pipe fd nonblocking
+
while ( true ) {
FD_ZERO(&rfds);
FD_SET(0, &rfds);
@@ -26,7 +64,37 @@
if (retval >= 0 && numPlayers) {
player.dispatch();
+ if (pipefd) {
+ if (!sendscopeptr) {
+ DelayQueue * scopebuf = player.getScopeBuf();
+ if (scopebuf) {
+ sendscopeptr = sendscopebuf;
+ towrite = scopebuf2sendbuffer(scopebuf, sendscopeptr);
+ delete scopebuf;
+ }
+ }
+ if (sendscopeptr) {
+ int written = write(pipefd, sendscopeptr, towrite);
+ if (written > 0) {
+ towrite -= written;
+ sendscopeptr += written;
+ }
+ if (towrite <= 0)
+ sendscopeptr = NULL;
+ }
+ } else
player.clearScopeQ();
+
+ // If the source is non-local, check MetaData and send updates:
+
+ HelixSimplePlayer::metaData *md = player.getMetaData(0);
+ if (!isLocal && (strcmp(saved_md.title, md->title)
+ || strcmp(saved_md.artist, md->artist))) {
+ memcpy(&saved_md, md, sizeof(saved_md));
+ cout << "###TITLE:" << saved_md.title << endl;
+ cout << "###ARTIST:" << saved_md.artist << endl;
+ cout << "###BITRATE:" << saved_md.bitrate << endl << flush;
+ }
}
if(retval == 1) {
@@ -62,7 +130,8 @@
getline(cin, tmp);
int nr = atoi(tmp.c_str());
getline(cin, tmp);
- bool isLocal = atoi(tmp.c_str()) != 0;
+ isLocal = atoi(tmp.c_str()) != 0;
+ // (-> now saves the info if we play a local file or a stream)
player.setURL( file.c_str(), nr, isLocal );
}
++++++ amarok-skip-hidden-dirs.diff ++++++
--- /var/tmp/diff_new_pack.9C4HUz/_old 2006-04-15 11:41:53.000000000 +0200
+++ /var/tmp/diff_new_pack.9C4HUz/_new 2006-04-15 11:41:53.000000000 +0200
@@ -6,18 +6,6 @@
BUG: 115478
------------------------------------------------------------------------
-Index: amarok/ChangeLog
-===================================================================
---- amarok/ChangeLog (revision 529213)
-+++ amarok/ChangeLog (revision 529214)
-@@ -8,6 +8,7 @@ VERSION 1.3.9:
- * Support for libtunepimp 0.4. (BR 94988)
-
- BUGFIXES:
-+ * Skip hidden directories while scanning the collection. (BR115478)
- * Fix leak of file descriptors with embedded cover art. Patch by Shane
- King . (BR 123472)
- * Stop collection folders being automatically removed. Instead, allow
Index: amarok/src/collectionreader.cpp
===================================================================
--- amarok/src/collectionreader.cpp (revision 529213)
++++++ helix-wrapper-metadata.diff ++++++
--- amarok/src/engine/helix/helix-engine.cpp
+++ amarok/src/engine/helix/helix-engine.cpp
@@ -82,6 +82,16 @@
m_duration[l[1].toInt()] = l[2].toInt();
} else if(l[0].startsWith("###DODONE")) {
m_done[l[1].toInt()] = l[2].toInt();
+ // Reveive song title, artist and bitrate from helper:
+ } else if(l[0].startsWith("###TITLE")) {
+ strncpy(m_md.title, l[1].latin1(), sizeof(m_md.title)-1);
+ m_md.title[sizeof(m_md.title)] = '\0';
+ } else if(l[0].startsWith("###ARTIST")) {
+ strncpy(m_md.artist, l[1].latin1(), sizeof(m_md.artist)-1);
+ m_md.artist[sizeof(m_md.artist)] = '\0';
+ } else if(l[0].startsWith("###BITRATE")) {
+ m_md.bitrate = l[1].toLong();
+ m_newMetaData = true; // got all, flag that we have new metadata
}
}
@@ -384,6 +393,7 @@
m_pluginsdir(HELIX_LIBS "/plugins"),
m_codecsdir(HELIX_LIBS "/codecs"),
m_inited(false),
+ m_newMetaData(false), // initialisation to false (no new metadata)
m_item(0),
#ifdef DEBUG_PURPOSES_ONLY
m_fps(0.0),m_fcount(0),m_ftime(0.0),m_scopebufwaste(0), m_scopebufnone(0), m_scopebuftotal(0),
@@ -868,6 +878,11 @@
(strcmp(m_md.title, md->title) || strcmp(m_md.artist, md->artist)))
{
memcpy(&m_md, md, sizeof(m_md));
+#else // #ifdef USE_HELIX_WRAPPER:
+ if (m_isStream && m_newMetaData) // We are streaming and have new metadata:
+ {
+ m_newMetaData = false; // we are going to process it, but only once ;)
+#endif // moved here, now we can use the function always to pass the metadata:
//debug() << "Title: " << md->title << " Artist: " << md->artist << " Bitrate: " << md->bitrate << endl;
@@ -896,7 +911,6 @@
bndl.bitrate = QString::number( m_md.bitrate / 1000 );
emit EngineBase::metaData( bndl );
}
-#endif
}
--- amarok/src/engine/helix/helix-engine.h
+++ amarok/src/engine/helix/helix-engine.h
@@ -174,6 +174,7 @@
bool m_isStream;
HelixSimplePlayer::metaData m_md;
+ bool m_newMetaData;
DelayQueue *m_item;
#ifdef DEBUG_PURPOSES_ONLY
++++++ helix-wrapper-scope.diff ++++++
--- amarok/src/engine/helix/helix-engine.cpp
+++ amarok/src/engine/helix/helix-engine.cpp
@@ -12,6 +12,8 @@
#include
#include
#include
+#include // for fcntl(m_scopefd, F_SETFL, flags|O_NONBLOCK)
+#include // for EAGAIN to handle nonblocking reads
#include <climits>
#include <cmath>
#include
@@ -86,6 +94,7 @@
HelixSimplePlayer::HelixSimplePlayer()
: m_error(0), m_volume(0), m_enabledEQ(false), m_preamp(0), m_scopecount(0)
+ , scopebufhead(0), scopebuftail(0)
{
m_duration[0] = m_duration[1] = 0;
m_where[0] = m_where[1] = 0;
@@ -104,6 +115,45 @@
void HelixSimplePlayer::dispatch()
{
+ static char *buf = NULL;
+ static int offset = 0, bufsz = 0;
+ DelayQueue *item;
+ int len;
+
+#define MAXSCOPEDATA 17632 // max. supported package size, no scope if larger
+
+ if (!buf)
+ buf = (char *)malloc(MAXSCOPEDATA);
+
+ while(1) {
+ if (offset >= MAXSCOPEDATA) // safety measure against overflow
+ offset = 0;
+
+ int nbytesread = read(m_scopefd, buf+offset, MAXSCOPEDATA-offset);
+
+ if (nbytesread == -1 && errno == EAGAIN)
+ return; // no data was immediately available for reading
+
+ if (!offset) // We are at the start of a new packet, read its size:
+ memcpy(&bufsz, buf, 4);
+
+ if (nbytesread + offset != bufsz + 32) {
+ offset += nbytesread;
+ return; // We didn't get all data, update offset and return
+ } else
+ offset = 0; // We read the whole package now
+
+ item = new DelayQueue(bufsz);
+ memcpy(&item->time, &buf[len=4], 4);
+ memcpy(&item->etime, &buf[len+=4], 4);
+ memcpy(&item->nchan, &buf[len+=4], 4);
+ memcpy(&item->bps, &buf[len+=4], 4);
+ memcpy(&item->tps, &buf[len+=4], sizeof(double));
+ memcpy(&item->spb, &buf[len +=sizeof(double)], 4);
+ memcpy(item->buf, &buf[len+=4], item->len);
+
+ addScopeBuf(item);
+ }
}
void HelixSimplePlayer::tearDown()
@@ -113,8 +161,51 @@
DelayQueue* HelixSimplePlayer::getScopeBuf()
{
+ dispatch();
+ pthread_mutex_lock(&m_scope_m);
+
+ struct DelayQueue *item = scopebufhead;
+
+ if (item)
+ {
+ scopebufhead = item->fwd;
+ m_scopecount--;
+ if (!scopebufhead)
+ scopebuftail = 0;
+ }
+
+ pthread_mutex_unlock(&m_scope_m);
+
+ return item;
- return 0;
}
+
+void HelixSimplePlayer::addScopeBuf(struct DelayQueue *item)
+{
+ pthread_mutex_lock(&m_scope_m);
+
+ if (scopebuftail)
+ {
+ item->fwd = 0;
+ scopebuftail->fwd = item;
+ scopebuftail = item;
+ m_scopecount++;
+ }
+ else
+ {
+ item->fwd = 0;
+ scopebufhead = item;
+ scopebuftail = item;
+ m_scopecount = 1;
+ }
+ pthread_mutex_unlock(&m_scope_m);
+}
+
+void HelixSimplePlayer::clearScopeQ()
+{
+ struct DelayQueue *item;
+ while ((item = getScopeBuf()))
+ delete item;
+}
void HelixSimplePlayer::init( const QCString& m_coredir, const QCString& m_pluginsdir,
const QCString& m_codecsdir, int nr)
@@ -240,6 +341,10 @@
int HelixSimplePlayer::peekScopeTime(unsigned long& t)
{
+ if (scopebufhead)
+ t = scopebufhead->time;
+ else
+ return -1;
return 0;
}
@@ -296,6 +403,18 @@
#ifdef USE_HELIX_WRAPPER
connect(&helper, SIGNAL(readyReadStdout()), this, SLOT(slotHandleHelper()));
+ int pipe_fds[2];
+ if (pipe(pipe_fds) == -1) {
+ perror("pipe");
+ exit(5);
+ }
+ m_scopefd = pipe_fds[0]; // use one side of the pipe ourselfes
+ int flags = fcntl(m_scopefd, F_GETFL);
+ if (fcntl(m_scopefd, F_SETFL, flags|O_NONBLOCK)) {
+ perror("fcntl to set O_NONBLOCK");
+ exit(8);
+ }
+ helper.addArgument(QString::number(pipe_fds[1])); // and pass the other
helper.start();
#endif
}
@@ -812,7 +937,7 @@
const Engine::Scope &HelixEngine::scope()
{
-#ifndef USE_HELIX_WRAPPER
+#ifndef USE_HELIX_WRAPPER_this_function_now_passes_the_scope_to_visualisation
int i;
unsigned long t;
@@ -938,7 +1063,7 @@
void
HelixEngine::resetScope()
{
-#ifndef USE_HELIX_WRAPPER
+#ifndef USE_HELIX_WRAPPER_this_function_is_now_needed_to_clear_the__scope
// make sure the scope is clear of old buffers
clearScopeQ();
m_scopeindex = 0;
--- amarok/src/engine/helix/helix-engine.h
+++ amarok/src/engine/helix/helix-engine.h
@@ -63,6 +63,8 @@
int getScopeCount() { return m_scopecount; }
int peekScopeTime(unsigned long&t);
DelayQueue *getScopeBuf();
+ void addScopeBuf(struct DelayQueue *item);
+ void clearScopeQ();
int getPluginInfo(int index,
const char *&description,
const char *©right,
@@ -98,6 +101,10 @@
bool m_enabledEQ;
int m_preamp;
int m_scopecount;
+ int m_scopefd;
+ pthread_mutex_t m_scope_m;
+ struct DelayQueue *scopebufhead;
+ struct DelayQueue *scopebuftail;
std::vector<int> m_equalizerGains;
QProcess helper;
private:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...