Permalink
Browse files

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
  • Loading branch information...
1 parent 211d0b8 commit 38814153bd41c5b87ab5296b89d3db24462ef7b2 @jyavenard jyavenard committed Dec 14, 2010
@@ -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;
+}
@@ -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;
@@ -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))
@@ -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())
{

0 comments on commit 3881415

Please sign in to comment.