Ticket #9824: 0042-RingBuffer-CalcReadAheadThresh-mods-for-low-bit-rate.patch

File 0042-RingBuffer-CalcReadAheadThresh-mods-for-low-bit-rate.patch, 4.7 KB (added by Lawrence Rust <lvr@…>, 8 years ago)
  • mythtv/libs/libmythtv/RingBuffer.cpp

    From 373eada6ff187bf59e33c2d3b8e33c2ca1581f30 Mon Sep 17 00:00:00 2001
    From: Lawrence Rust <lvr@softsystem.co.uk>
    Date: Fri, 3 Jun 2011 15:08:57 +0200
    Subject: [PATCH 42/42] RingBuffer: CalcReadAheadThresh mods for low bit rate (radio) streams
    
    The existing readahead block size is too large for 64/128 kBps audio streams
    and can cause audio underruns.
    
    Make WaitFailAvail return the bytes available if less than that requested
    for low bit rate streams (where fill_min is < 32kB).
    
    Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
    ---
     mythtv/libs/libmythtv/RingBuffer.cpp |   54 ++++++++++++++++++++++-----------
     1 files changed, 36 insertions(+), 18 deletions(-)
    
    diff --git a/mythtv/libs/libmythtv/RingBuffer.cpp b/mythtv/libs/libmythtv/RingBuffer.cpp
    index 95fb96b..eda425a 100644
    a b void RingBuffer::OpenFile(const QString &lfilename, uint retry_ms) 
    540540    commserror = false;
    541541    numfailures = 0;
    542542
    543     rawbitrate = 8000;
     543    rawbitrate = 2500;
    544544    CalcReadAheadThresh();
    545545
    546546    rwlock.unlock();
    void RingBuffer::CalcReadAheadThresh(void) 
    806806    // loop without sleeping if the buffered data is less than this
    807807    fill_threshold = kBufferSize / 8;
    808808
    809     const uint KB32  =  32*1024;
    810     const uint KB64  =  64*1024;
    811     const uint KB128 = 128*1024;
    812     const uint KB256 = 256*1024;
    813     const uint KB512 = 512*1024;
     809    const int KB1   =  1024;
     810    const int KB2   =  2*1024;
     811    const int KB4   =  4*1024;
     812    const int KB8   =  8*1024;
     813    const int KB16  =  16*1024;
     814    const int KB32  =  32*KB1;
     815    const int KB64  =  64*KB1;
     816    const int KB128 = 128*KB1;
     817    const int KB256 = 256*KB1;
     818    const int KB512 = 512*KB1;
    814819
    815820    estbitrate     = (uint) max(abs(rawbitrate * playspeed),
    816821                                0.5f * rawbitrate);
    817822    estbitrate     = min(rawbitrate * 3, estbitrate);
    818     int rbs        = (estbitrate > 2500)  ? KB64  : KB32;
    819     rbs            = (estbitrate > 5000)  ? KB128 : rbs;
    820     rbs            = (estbitrate > 9000)  ? KB256 : rbs;
    821     rbs            = (estbitrate > 18000) ? KB512 : rbs;
    822     readblocksize  = max(rbs,readblocksize);
     823
     824    int const rbs = estbitrate > 18000 ? KB512 :
     825                    estbitrate > 9000 ? KB256 :
     826                    estbitrate > 5000 ? KB128 :
     827                    estbitrate > 2500 ? KB64 :
     828                    estbitrate > 1000 ? KB32 :
     829                    estbitrate > 500 ? KB16 :
     830                    estbitrate > 250 ? KB8 :
     831                    estbitrate > 125 ? KB4 :
     832                    KB2;
     833    if (rbs < CHUNK)
     834        readblocksize = rbs;
     835    else
     836        readblocksize = max(rbs,readblocksize);
    823837
    824838    // minumum seconds of buffering before allowing read
    825     float secs_min = 0.25;
     839    float const secs_min = 0.25f;
    826840    // set the minimum buffering before allowing ffmpeg read
    827     fill_min        = (uint) ((estbitrate * secs_min) * 0.125f);
     841    fill_min = (uint) (estbitrate * ((KB1 / 8) * secs_min));
    828842    // make this a multiple of ffmpeg block size..
    829     fill_min        = ((fill_min / KB32) + 1) * KB32;
     843    if (fill_min > CHUNK)
     844        fill_min = (fill_min / CHUNK) * CHUNK;
    830845
    831846    VERBOSE(VB_FILE, LOC +
    832847            QString("CalcReadAheadThresh(%1 Kb)\n\t\t\t -> "
    833848                    "threshhold(%2 KB) min read(%3 KB) blk size(%4 KB)")
    834             .arg(estbitrate).arg(fill_threshold/1024)
    835             .arg(fill_min/1024).arg(readblocksize/1024));
     849            .arg(estbitrate).arg(fill_threshold/KB1)
     850            .arg(fill_min/KB1).arg(readblocksize/KB1));
    836851}
    837852
    838853bool RingBuffer::IsNearEnd(double fps, uint vvf) const
    void RingBuffer::run(void) 
    11821197                    (now.tv_usec - lastread.tv_usec) / 1000;
    11831198                readtimeavg = (readtimeavg * 9 + readinterval) / 10;
    11841199
    1185                 if (readtimeavg < 150 && (uint)readblocksize < (kBufferSize>>2))
     1200                if (readtimeavg < 150 && (uint)readblocksize < (kBufferSize>>2) && readblocksize >= CHUNK)
    11861201                {
    11871202                    int old_block_size = readblocksize;
    11881203                    readblocksize = 3 * readblocksize / 2;
    bool RingBuffer::WaitForAvail(int count) 
    14311446        if (avail < count)
    14321447        {
    14331448            int elapsed = t.elapsed();
    1434             if  (((elapsed > 250)  && (elapsed < 500))  ||
     1449            // Return avail for low bitrate audio streams to avoid underrun
     1450            if (elapsed >= 500 && fill_min < CHUNK && avail >= fill_min)
     1451                count = avail;
     1452            else if  (((elapsed > 250)  && (elapsed < 500))  ||
    14351453                 ((elapsed > 500)  && (elapsed < 750))  ||
    14361454                 ((elapsed > 1000) && (elapsed < 1250)) ||
    14371455                 ((elapsed > 2000) && (elapsed < 2250)) ||