Permalink
Browse files

Add playback registration handling

It is an unfortunate fact that you can only do one playback at a time within a frontend; usually because you can only open one audio session at a time.
This commit provides a mechanism for playback objects (such as TV, AirPlay, RAOP, MythMusic) to register themselves as a player and request playback; in which case all other registered player will be asked to close.
  • Loading branch information...
jyavenard committed Jul 15, 2012
1 parent ea944e6 commit ae61cb983197112c51730063a4e57653f64dd78a
Showing with 75 additions and 0 deletions.
  1. +70 −0 mythtv/libs/libmythbase/mythcorecontext.cpp
  2. +5 −0 mythtv/libs/libmythbase/mythcorecontext.h
@@ -87,6 +87,9 @@ class MythCoreContextPrivate : public QObject
MythScheduler *m_scheduler;
bool m_blockingClient;
QMap<QObject *, QByteArray> m_playbackClients;
QMutex m_playbackLock;
};
MythCoreContextPrivate::MythCoreContextPrivate(MythCoreContext *lparent,
@@ -1364,4 +1367,71 @@ void MythCoreContext::WaitUntilSignals(const char *signal1, ...)
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
}
/**
* \fn void MythCoreContext::RegisterForPlayback(QObject *sender, const char *method)
* Register sender for TVPlaybackAboutToStart signal. Method will be called upon
* the signal being emitted.
* sender must call MythCoreContext::UnregisterForPlayback upon deletion
*/
void MythCoreContext::RegisterForPlayback(QObject *sender, const char *method)
{
QMutexLocker lock(&d->m_playbackLock);
if (!d->m_playbackClients.contains(sender))
{
d->m_playbackClients.insert(sender, QByteArray(method));
connect(this, SIGNAL(TVPlaybackAboutToStart()),
sender, method,
Qt::BlockingQueuedConnection);
}
}
/**
* \fn void MythCoreContext::UnregisterForPlayback(QObject *sender)
* Unregister sender from being called when TVPlaybackAboutToStart signal
* is emitted
*/
void MythCoreContext::UnregisterForPlayback(QObject *sender)
{
QMutexLocker lock(&d->m_playbackLock);
if (d->m_playbackClients.contains(sender))
{
QByteArray ba = d->m_playbackClients.value(sender);
const char *method = ba.constData();
disconnect(this, SIGNAL(TVPlaybackAboutToStart()),
sender, method);
d->m_playbackClients.remove(sender);
}
}
/**
* \fn void MythCoreContext::WantingPlayback(QObject *sender)
* All the objects that have registered using MythCoreContext::RegisterForPlayback
* but sender will be called. The objet's registered method will be called
* in a blocking fashion, each of them being called one after the other
*/
void MythCoreContext::WantingPlayback(QObject *sender)
{
QMutexLocker lock(&d->m_playbackLock);
bool found = false;
QByteArray ba;
const char *method;
if (d->m_playbackClients.contains(sender))
{
found = true;
ba = d->m_playbackClients.value(sender);
method = ba.constData();
disconnect(this, SIGNAL(TVPlaybackAboutToStart()), sender, method);
}
emit TVPlaybackAboutToStart();
if (found)
{
connect(this, SIGNAL(TVPlaybackAboutToStart()),
sender, method,
Qt::BlockingQueuedConnection);
}
}
/* vim: set expandtab tabstop=4 shiftwidth=4: */
@@ -169,6 +169,10 @@ class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ
QString GetLanguageAndVariant(void);
void ResetLanguage(void);
void RegisterForPlayback(QObject *sender, const char *method);
void UnregisterForPlayback(QObject *sender);
void WantingPlayback(QObject *sender);
// signal related methods
void WaitUntilSignals(const char *signal1, ...);
void emitTVPlaybackStarted(void) { emit TVPlaybackStarted(); }
@@ -185,6 +189,7 @@ class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ
void TVPlaybackPaused(void);
void TVPlaybackUnpaused(void);
void TVPlaybackAborted(void);
void TVPlaybackAboutToStart(void);
private:
MythCoreContextPrivate *d;

0 comments on commit ae61cb9

Please sign in to comment.