summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormark-kendall <mkendall@mythtv.org>2011-04-17 02:28:08 (GMT)
committer mark-kendall <mkendall@mythtv.org>2011-04-17 02:28:08 (GMT)
commitc42834e19857c4e79bd5600bd7c1768f34072d1d (patch)
treef71f0f2a559205f163fb24c0afe336b0886ab6e0
parent1650de344341987575e389a8dc4600d5348f849b (diff)
MythPlayer: Fix a Live TV channel change deadlock.
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).
-rw-r--r--mythtv/libs/libmythtv/mythplayer.cpp12
-rw-r--r--mythtv/libs/libmythtv/mythplayer.h1
2 files changed, 12 insertions, 1 deletions
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index b2a991b..8be3a7a 100644
--- a/mythtv/libs/libmythtv/mythplayer.cpp
+++ b/mythtv/libs/libmythtv/mythplayer.cpp
@@ -130,7 +130,8 @@ MythPlayer::MythPlayer(bool muted)
parentWidget(NULL), embedid(0),
embx(-1), emby(-1), embw(-1), embh(-1),
// State
- decoderPaused(false), pauseDecoder(false), unpauseDecoder(false),
+ totalDecoderPause(false), decoderPaused(false),
+ pauseDecoder(false), unpauseDecoder(false),
killdecoder(false), decoderSeek(-1), decodeOneFrame(false),
needNewPauseFrame(false),
bufferPaused(false), videoPaused(false),
@@ -2836,6 +2837,12 @@ void MythPlayer::DecoderLoop(bool pause)
{
DecoderPauseCheck();
+ if (totalDecoderPause)
+ {
+ usleep(1000);
+ continue;
+ }
+
if (forcePositionMapSync)
{
if (!decoder_change_lock.tryLock(1))
@@ -4573,6 +4580,7 @@ bool MythPlayer::SetVideoByComponentTag(int tag)
*/
void MythPlayer::SetDecoder(DecoderBase *dec)
{
+ totalDecoderPause = true;
PauseDecoder();
{
@@ -4589,6 +4597,8 @@ void MythPlayer::SetDecoder(DecoderBase *dec)
}
decoder_change_lock.unlock();
}
+
+ totalDecoderPause = false;
}
bool MythPlayer::PosMapFromEnc(unsigned long long start,
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
index 8415fca..e905d55 100644
--- a/mythtv/libs/libmythtv/mythplayer.h
+++ b/mythtv/libs/libmythtv/mythplayer.h
@@ -545,6 +545,7 @@ class MTV_PUBLIC MythPlayer
QWaitCondition decoderThreadUnpause;
mutable QMutex decoderPauseLock;
mutable QMutex decoderSeekLock;
+ bool totalDecoderPause;
bool decoderPaused;
bool pauseDecoder;
bool unpauseDecoder;