summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Yves Avenard <jyavenard@mythtv.org>2010-12-14 05:10:35 (GMT)
committer Jean-Yves Avenard <jyavenard@mythtv.org>2010-12-14 14:53:57 (GMT)
commit38814153bd41c5b87ab5296b89d3db24462ef7b2 (patch)
tree7a8a936ab4a6990215b305a3dfcfcc2daf845820
parent211d0b8dbb1f2f98c15c1a08a8d717b26220ce24 (diff)
Fix potential deadlocks resulting in "Waited 100ms for video buffers"
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 5a012f5..27f6f79 100644
--- a/mythtv/libs/libmythtv/audioplayer.cpp
+++ b/mythtv/libs/libmythtv/audioplayer.cpp
@@ -367,3 +367,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 29b637d..a966d99 100644
--- a/mythtv/libs/libmythtv/audioplayer.h
+++ b/mythtv/libs/libmythtv/audioplayer.h
@@ -55,6 +55,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 8cca1a4..655c36f 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -3638,11 +3638,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);
@@ -3814,26 +3811,6 @@ bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
total_decoded_audio += data_size;
allowedquit |= ringBuffer->IsInDiscMenuOrStillFrame();
- // 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;
@@ -3872,12 +3849,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 1705794..9067c12 100644
--- a/mythtv/libs/libmythtv/mythplayer.cpp
+++ b/mythtv/libs/libmythtv/mythplayer.cpp
@@ -1934,6 +1934,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())
{