Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
  • Loading branch information...
commit 588cc6e2b3818d1c9c9af97b233b28914c226ea6 1 parent 208e2f5
@jyavenard jyavenard authored
View
11 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;
+}
View
1  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;
View
34 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))
View
8 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())
{
Please sign in to comment.
Something went wrong with that request. Please try again.