summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Yves Avenard <jyavenard@mythtv.org>2010-12-14 08:55:56 (GMT)
committer Jean-Yves Avenard <jyavenard@mythtv.org>2010-12-14 08:55:56 (GMT)
commit588cc6e2b3818d1c9c9af97b233b28914c226ea6 (patch)
tree145adef6ab2a5579884f66dda08f27e82fec2b46
parent208e2f58682b374cdfe18c154e69cbc537e7e81d (diff)
Fix potential deadlocks resulting in "Waited 100ms for video buffers"
[backport to fixes/0.24] When we are waiting for video the video buffers to fill up, if the audio buffer is almost full, reset it. Collaborative effort between tralph@mythtv.org mkendall@mythtv.org and jyavenard@mythtv.org
-rw-r--r--mythtv/libs/libmythtv/audioplayer.cpp11
-rw-r--r--mythtv/libs/libmythtv/audioplayer.h1
-rw-r--r--mythtv/libs/libmythtv/avformatdecoder.cpp34
-rw-r--r--mythtv/libs/libmythtv/mythplayer.cpp8
4 files changed, 23 insertions, 31 deletions
diff --git a/mythtv/libs/libmythtv/audioplayer.cpp b/mythtv/libs/libmythtv/audioplayer.cpp
index f922676..b4a1ca6 100644
--- a/mythtv/libs/libmythtv/audioplayer.cpp
+++ b/mythtv/libs/libmythtv/audioplayer.cpp
@@ -351,3 +351,14 @@ bool AudioPlayer::GetBufferStatus(uint &fill, uint &total)
m_audioOutput->GetBufferStatus(fill, total);
return true;
}
+
+bool AudioPlayer::IsBufferAlmostFull(void)
+{
+ uint ofill = 0, ototal = 0, othresh = 0;
+ if (GetBufferStatus(ofill, ototal))
+ {
+ othresh = ((ototal>>1) + (ototal>>2));
+ return ofill > othresh;
+ }
+ return false;
+}
diff --git a/mythtv/libs/libmythtv/audioplayer.h b/mythtv/libs/libmythtv/audioplayer.h
index 68a7284..62446d8 100644
--- a/mythtv/libs/libmythtv/audioplayer.h
+++ b/mythtv/libs/libmythtv/audioplayer.h
@@ -53,6 +53,7 @@ class MPUBLIC AudioPlayer
void AddAudioData(char *buffer, int len, int64_t timecode);
bool GetBufferStatus(uint &fill, uint &total);
+ bool IsBufferAlmostFull(void);
private:
MythPlayer *m_parent;
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index bf28f7ce..5bfab27 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -3929,11 +3929,8 @@ bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
avcodeclock->unlock();
uint ofill = 0, ototal = 0, othresh = 0, total_decoded_audio = 0;
- if (m_audio->GetBufferStatus(ofill, ototal))
- {
- othresh = ((ototal>>1) + (ototal>>2));
- allowedquit = (!(decodetype & kDecodeAudio)) && (ofill > othresh);
- }
+ allowedquit = (!(decodetype & kDecodeAudio)) &&
+ m_audio->IsBufferAlmostFull();
if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
@@ -4098,26 +4095,6 @@ bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
total_decoded_audio += data_size;
allowedquit |= ringBuffer->InDVDMenuOrStillFrame();
- // Audio can expand by a factor of 6 in audiooutputbase's audiobuffer
- allowedquit |= !(decodetype & kDecodeVideo) &&
- ((ofill + total_decoded_audio * 6) > othresh);
-
- // top off audio buffers initially in audio only mode
- if (!allowedquit && !(decodetype & kDecodeVideo))
- {
- uint fill, total;
- if (m_audio->GetBufferStatus(fill, total))
- {
- total /= 6; // Possible expansion in aobase (upmix, float conv)
- allowedquit = fill == 0 || fill > total>>1 ||
- total - fill < (uint)(data_size) ||
- ofill + total_decoded_audio > total>>2 ||
- total - fill < (uint)(data_size<<1);
- }
- else
- VERBOSE(VB_IMPORTANT, LOC_ERR + "GetFrame() : Failed to top off "
- "buffers in audio only mode");
- }
tmp_pkt.data += ret;
tmp_pkt.size -= ret;
@@ -4156,12 +4133,7 @@ bool AvFormatDecoder::GetFrame(DecodeType decodetype)
skipaudio = false;
}
- uint ofill = 0, ototal = 0, othresh = 0;
- if (m_audio->GetBufferStatus(ofill, ototal))
- {
- othresh = ((ototal>>1) + (ototal>>2));
- allowedquit = ofill > othresh;
- }
+ allowedquit = m_audio->IsBufferAlmostFull();
if (private_dec && private_dec->HasBufferedFrames() &&
(selectedTrack[kTrackTypeVideo].av_stream_index > -1))
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index 4fe3bf2..5b13fbc 100644
--- a/mythtv/libs/libmythtv/mythplayer.cpp
+++ b/mythtv/libs/libmythtv/mythplayer.cpp
@@ -1920,6 +1920,14 @@ bool MythPlayer::PrebufferEnoughFrames(bool pause_audio, int min_buffers)
VERBOSE(VB_IMPORTANT, LOC +
QString("Waited 100ms for video buffers %1")
.arg(videoOutput->GetFrameStatus()));
+ if (audio.IsBufferAlmostFull())
+ {
+ // We are likely to enter this condition
+ // if the audio buffer was too full during GetFrame in AVFD
+ VERBOSE(VB_AUDIO, LOC +
+ QString("Resetting audio buffer"));
+ audio.Reset();
+ }
}
if ((waited_for > 500) && !videoOutput->EnoughFreeFrames())
{