Skip to content

Commit

Permalink
Remove the PlayerTimer class and run the player from TV::StartTV
Browse files Browse the repository at this point in the history
This is a further natural (and now obvious) improvement following the
threading changes in the player code. Instead of contriving playback
events to trigger the next frame, just loop inside the main event loop
in TV::StartTV and process other application events as needed.

There are almost certainly other simplifications possible here - notably
in the extensive use of timers; many of which can probably now be
removed.

Should almost certainly be a fix for #9223
  • Loading branch information
Mark Kendall committed Jan 10, 2011
1 parent b35ddbf commit c882551
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 72 deletions.
53 changes: 0 additions & 53 deletions mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -89,43 +89,6 @@ static unsigned dbg_ident(const MythPlayer*);
#define LOC_ERR QString("Player(%1), Error: ").arg(dbg_ident(this),0,36)
#define LOC_DEC QString("Player(%1): ").arg(dbg_ident(m_mp),0,36)

QEvent::Type PlayerTimer::kPlayerEventType =
(QEvent::Type) QEvent::registerEventType();

PlayerTimer::PlayerTimer(MythPlayer *player) : m_mp(player), m_queue_size(0)
{
if (!m_mp)
VERBOSE(VB_IMPORTANT, QString("PlayerTimer has no parent."));
PostNextEvent();
}

void PlayerTimer::PostNextEvent(void)
{
QEvent *event = new QEvent(kPlayerEventType);
qApp->postEvent(this, event);
m_queue_size++;
}

bool PlayerTimer::event(QEvent *e)
{
if (e->type() == kPlayerEventType)
{
// TODO this may fail if events are lost and the queue size is wrong
m_queue_size--;
uint max_queue = m_mp->GetFFRewSkip() == 1 ? 3 : 1;
while (m_queue_size < max_queue)
PostNextEvent();

if (m_mp && !m_mp->IsErrored())
{
m_mp->EventLoop();
m_mp->VideoLoop();
}
return true;
}
return false;
}

void DecoderThread::run(void)
{
if (!m_mp)
Expand Down Expand Up @@ -162,7 +125,6 @@ MythPlayer::MythPlayer(bool muted)
: decoder(NULL), decoder_change_lock(QMutex::Recursive),
videoOutput(NULL), player_ctx(NULL),
decoderThread(NULL), playerThread(NULL),
playerTimer(NULL),
no_hardware_decoders(false),
// Window stuff
parentWidget(NULL), embedid(0),
Expand Down Expand Up @@ -290,12 +252,6 @@ MythPlayer::~MythPlayer(void)
decoderThread = NULL;
}

if (playerTimer)
{
delete playerTimer;
playerTimer = NULL;
}

if (interactiveTV)
{
delete interactiveTV;
Expand Down Expand Up @@ -2549,9 +2505,6 @@ bool MythPlayer::StartPlaying(void)
InitialSeek();
VideoStart();

if (playerTimer)
delete playerTimer;
playerTimer = new PlayerTimer(this);
playerThread->setPriority(QThread::TimeCriticalPriority);
return !IsErrored();
}
Expand All @@ -2577,12 +2530,6 @@ void MythPlayer::StopPlaying()
VERBOSE(VB_PLAYBACK, LOC + QString("StopPlaying - begin"));
playerThread->setPriority(QThread::NormalPriority);

if (playerTimer)
{
delete playerTimer;
playerTimer = NULL;
}

DecoderEnd();
VideoEnd();
AudioEnd();
Expand Down
15 changes: 0 additions & 15 deletions mythtv/libs/libmythtv/mythplayer.h
Expand Up @@ -80,20 +80,6 @@ enum
kDisplayTeletextMenu = 0x100,
};

class PlayerTimer : public QObject
{
Q_OBJECT
public:
PlayerTimer(MythPlayer *mp);
void PostNextEvent(void);
virtual bool event(QEvent *e);
static enum QEvent::Type kPlayerEventType;

private:
MythPlayer *m_mp;
uint32_t m_queue_size;
};

class DecoderThread : public QThread
{
Q_OBJECT
Expand Down Expand Up @@ -533,7 +519,6 @@ class MPUBLIC MythPlayer
PlayerContext *player_ctx;
DecoderThread *decoderThread;
QThread *playerThread;
PlayerTimer *playerTimer;
bool no_hardware_decoders;

// Window stuff
Expand Down
23 changes: 19 additions & 4 deletions mythtv/libs/libmythtv/tv_play.cpp
Expand Up @@ -297,13 +297,28 @@ bool TV::StartTV(ProgramInfo *tvrec, uint flags)

while (true)
{
qApp->processEvents();
if (qApp->hasPendingEvents())
qApp->processEvents();

TVState state = tv->GetState(0);
bool is_err = kState_Error == state;
bool is_none = kState_None == state;
if (is_err || is_none)
if ((kState_Error == state) || (kState_None == state))
break;

if (kState_ChangingState == state)
continue;

const PlayerContext *mctx = tv->GetPlayerReadLock(0, __FILE__, __LINE__);
if (mctx)
{
mctx->LockDeletePlayer(__FILE__, __LINE__);
if (mctx->player && !mctx->player->IsErrored())
{
mctx->player->EventLoop();
mctx->player->VideoLoop();
}
}
mctx->UnlockDeletePlayer(__FILE__, __LINE__);
tv->ReturnPlayerLock(mctx);
}

VERBOSE(VB_PLAYBACK, LOC + "StartTV -- process events end");
Expand Down

0 comments on commit c882551

Please sign in to comment.