Skip to content

Commit

Permalink
MythPlayer: Fix a Live TV channel change deadlock.
Browse files Browse the repository at this point in the history
This recognises that the decoder loop effectively has 3 different states
- running, partially paused and completely paused. The partial pause
state still allows the playback thread to decode a single frame on
demand, seek and perform position map syncs. Allowing these while the
decoder is changing adds various complications - hence add a new member
state variable, totalDecoderPause, that ensures the decoder loop does
nothing other than check its own pause state when completely paused.

Aside from fixing a deadlock on channel changes, this should also
speedup decoder changes under certain situations and probably prevents a
couple of even more obscure bugs (e.g. if a seek is triggered at the
same time as a channel change).
  • Loading branch information
mark-kendall committed Apr 17, 2011
1 parent bfa8827 commit 4693357
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 1 deletion.
12 changes: 11 additions & 1 deletion mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -130,7 +130,8 @@ MythPlayer::MythPlayer(bool muted)
parentWidget(NULL), embedid(0), parentWidget(NULL), embedid(0),
embx(-1), emby(-1), embw(-1), embh(-1), embx(-1), emby(-1), embw(-1), embh(-1),
// State // State
decoderPaused(false), pauseDecoder(false), unpauseDecoder(false), totalDecoderPause(false), decoderPaused(false),
pauseDecoder(false), unpauseDecoder(false),
killdecoder(false), decoderSeek(-1), decodeOneFrame(false), killdecoder(false), decoderSeek(-1), decodeOneFrame(false),
needNewPauseFrame(false), needNewPauseFrame(false),
bufferPaused(false), videoPaused(false), bufferPaused(false), videoPaused(false),
Expand Down Expand Up @@ -2779,6 +2780,12 @@ void MythPlayer::DecoderLoop(bool pause)
{ {
DecoderPauseCheck(); DecoderPauseCheck();


if (totalDecoderPause)
{
usleep(1000);
continue;
}

if (!decoder_change_lock.tryLock(1)) if (!decoder_change_lock.tryLock(1))
continue; continue;
if (decoder) if (decoder)
Expand Down Expand Up @@ -4493,6 +4500,7 @@ bool MythPlayer::SetVideoByComponentTag(int tag)
*/ */
void MythPlayer::SetDecoder(DecoderBase *dec) void MythPlayer::SetDecoder(DecoderBase *dec)
{ {
totalDecoderPause = true;
PauseDecoder(); PauseDecoder();


{ {
Expand All @@ -4509,6 +4517,8 @@ void MythPlayer::SetDecoder(DecoderBase *dec)
} }
decoder_change_lock.unlock(); decoder_change_lock.unlock();
} }

totalDecoderPause = false;
} }


bool MythPlayer::PosMapFromEnc(unsigned long long start, bool MythPlayer::PosMapFromEnc(unsigned long long start,
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/mythplayer.h
Expand Up @@ -532,6 +532,7 @@ class MPUBLIC MythPlayer
QWaitCondition decoderThreadUnpause; QWaitCondition decoderThreadUnpause;
mutable QMutex decoderPauseLock; mutable QMutex decoderPauseLock;
mutable QMutex decoderSeekLock; mutable QMutex decoderSeekLock;
bool totalDecoderPause;
bool decoderPaused; bool decoderPaused;
bool pauseDecoder; bool pauseDecoder;
bool unpauseDecoder; bool unpauseDecoder;
Expand Down

0 comments on commit 4693357

Please sign in to comment.