Ticket #3045: jerky_video.patch

File jerky_video.patch, 10.9 KB (added by support@…, 19 years ago)

Fix for jerky video on channel changes due to WarpTimecode

  • libs/libmythtv/nuppeldecoder.cpp

     
    547547    if (usingextradata && extradata.video_fourcc == MKTAG('D', 'I', 'V', 'X'))
    548548        setreadahead = true;
    549549
    550     ringBuffer->UpdateRawBitrate(0);
     550    bitrate = 0;
     551    ringBuffer->UpdateRawBitrate(GetRawBitrate());
    551552
    552553    videosizetotal = 0;
    553554    videoframesread = 0;
     
    10991100                {
    11001101                    videosizetotal /= videoframesread;
    11011102
    1102                     float bps = videosizetotal * 8.0 / 1024 * video_frame_rate;
    1103                     bps = bps * 3 / 2;
     1103                    float bps = (videosizetotal * 8.0f / 1024.0f *
     1104                                 video_frame_rate);
     1105                    bitrate = (uint) (bps * 1.5f);
    11041106
    1105                     ringBuffer->UpdateRawBitrate((uint) bps);
     1107                    ringBuffer->UpdateRawBitrate(GetRawBitrate());
    11061108                    setreadahead = true;
    11071109                }
    11081110            }
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    28442844        return;
    28452845    }
    28462846
     2847    // the bitrate is reset by ringBuffer->OpenFile()...
     2848    ringBuffer->UpdateRawBitrate(GetDecoder()->GetRawBitrate());
     2849
    28472850    ringBuffer->Unpause();
    28482851
    28492852    if (discontinuity || newtype)
     
    29492952        return;
    29502953    }
    29512954
     2955    // the bitrate is reset by ringBuffer->OpenFile()...
     2956    ringBuffer->UpdateRawBitrate(GetDecoder()->GetRawBitrate());
     2957
    29522958    ringBuffer->Unpause();
    29532959    ringBuffer->IgnoreLiveEOF(false);
    29542960
     
    34643470
    34653471    timecode += tc_wrap[tc_type];
    34663472
     3473#define DOTCWRAP 0
     3474#if DOTCWRAP
    34673475    // wrapped
    34683476    if (timecode < tc_lastval[tc_type] - 10000)
    34693477    {
     
    35003508            tc_avcheck_framecounter = 0;
    35013509        }
    35023510    }
     3511#endif
    35033512}
    35043513
    35053514/** \fn NuppelVideoPlayer::AddAudioData(char*,int,long long)
  • libs/libmythtv/avformatdecoder.cpp

     
    266266      ic(NULL),
    267267      frame_decoded(0),             decoded_video_frame(NULL),
    268268      directrendering(false),       drawband(false),
    269       bitrate(0),
    270269      gopset(false),                seen_gop(false),
    271270      seq_count(0),                 firstgoppos(0),
    272271      prevgoppos(0),                gotvideo(false),
  • libs/libmythtv/decoderbase.h

     
    7979
    8080    virtual QString GetEncodingType(void) const = 0;
    8181    virtual double  GetFPS(void) const { return fps; }
     82    /// Returns the estimated bitrate if the video were played at normal speed.
     83    uint GetRawBitrate(void) const { return bitrate; }
    8284
    8385    virtual void UpdateFramesPlayed(void);
    8486    long long GetFramesRead(void) const { return framesRead; };
     
    163165    int current_height;
    164166    float current_aspect;
    165167    double fps;
     168    uint bitrate;
    166169
    167170    long long framesPlayed;
    168171    long long framesRead;
  • libs/libmythtv/RingBuffer.cpp

     
    77// POSIX C headers
    88#include <sys/types.h>
    99#include <sys/stat.h>
     10#include <sys/time.h>
    1011#include <unistd.h>
    1112#include <fcntl.h>
    1213#include <pthread.h>
     
    3940#define O_LARGEFILE 0
    4041#endif
    4142
    42 const uint RingBuffer::kBufferSize = 10 * 256 * 1024;
     43const uint RingBuffer::kBufferSize = 3 * 1024 * 1024;
    4344
     45#define CHUNK 32768 /* readblocksize increments */
     46
    4447#define PNG_MIN_SIZE   20 /* header plus one empty chunk */
    4548#define NUV_MIN_SIZE  204 /* header size? */
    4649#define MPEG_MIN_SIZE 376 /* 2 TS packets */
     
    9295      internalreadpos(0),       ateof(false),
    9396      readsallowed(false),      wantseek(false), setswitchtonext(false),
    9497      rawbitrate(4000),         playspeed(1.0f),
    95       fill_threshold(-1),       fill_min(-1),
    96       readblocksize(128000),    wanttoread(0),
     98      fill_threshold(65536),    fill_min(-1),
     99      readblocksize(CHUNK),     wanttoread(0),
    97100      numfailures(0),           commserror(false),
    98101      dvdPriv(NULL),            oldfile(false),
    99102      livetvchain(NULL),        ignoreliveeof(false),
     
    534537 */
    535538void RingBuffer::CalcReadAheadThresh(void)
    536539{
    537     const uint KB32  =  32*1024;
    538     const uint KB64  =  64*1024;
    539     const uint KB128 = 128*1024;
    540     const uint KB256 = 256*1024;
    541     const uint KB512 = 512*1024;
    542540    uint estbitrate;
    543541
    544     wantseek = true;
    545542    pthread_rwlock_wrlock(&rwlock);
    546 
    547     estbitrate     = (uint) max(abs(rawbitrate * playspeed), 0.5f * rawbitrate);
    548     estbitrate     = min(rawbitrate * 3, estbitrate);
    549543    wantseek       = false;
    550544    readsallowed   = false;
     545    readblocksize  = CHUNK;
     546
     547    // loop without sleeping if the buffered data is less than this
     548    fill_threshold = CHUNK * 2;
    551549    fill_min       = 1;
    552     readblocksize  = (estbitrate > 2500)  ? KB64  : KB32;
    553     readblocksize  = (estbitrate > 5000)  ? KB128 : readblocksize;
    554     readblocksize  = (estbitrate > 9000)  ? KB256 : readblocksize;
    555     readblocksize  = (estbitrate > 18000) ? KB512 : readblocksize;
    556550
    557     uint  secs_thr = 300; // seconds of buffering desired
    558     float secs_min = 0.1; // minumum seconds of buffering before allowing read
     551#ifdef USING_FRONTEND
     552    if (dvdPriv)
     553    {
     554        const uint KB32  =  32*1024;
     555        const uint KB64  =  64*1024;
     556        const uint KB128 = 128*1024;
     557        const uint KB256 = 256*1024;
     558        const uint KB512 = 512*1024;
    559559
    560     // set basic fill_threshold based on bitrate
    561     fill_threshold = (estbitrate * secs_thr) >> 3; // >>3 => bits -> bytes
    562     // extra buffering for remote files
    563     fill_threshold = fill_threshold + ((remotefile) ? KB256 : 0);
    564     // make the fill_threshold at least one block
    565     fill_threshold = max(readblocksize, fill_threshold);
     560        estbitrate     = (uint) max(abs(rawbitrate * playspeed),
     561                                    0.5f * rawbitrate);
     562        estbitrate     = min(rawbitrate * 3, estbitrate);
     563        readblocksize  = (estbitrate > 2500)  ? KB64  : KB32;
     564        readblocksize  = (estbitrate > 5000)  ? KB128 : readblocksize;
     565        readblocksize  = (estbitrate > 9000)  ? KB256 : readblocksize;
     566        readblocksize  = (estbitrate > 18000) ? KB512 : readblocksize;
    566567
    567     // set the minimum buffering before allowing ffmpeg read
    568     fill_min        = (uint) ((estbitrate * secs_min) * 0.125f);
    569     // make this a multiple of ffmpeg block size..
    570     fill_min        = ((fill_min / KB32) + 1) * KB32;
     568        // minumum seconds of buffering before allowing read
     569        float secs_min = 0.1;
    571570
     571        // set the minimum buffering before allowing ffmpeg read
     572        fill_min        = (uint) ((estbitrate * secs_min) * 0.125f);
     573        // make this a multiple of ffmpeg block size..
     574        fill_min        = ((fill_min / KB32) + 1) * KB32;
     575    }
     576#endif // USING_FRONTEND   
     577
     578    pthread_rwlock_unlock(&rwlock);
     579
    572580    VERBOSE(VB_PLAYBACK, LOC +
    573581            QString("CalcReadAheadThresh(%1 KB)\n\t\t\t -> "
    574582                    "threshhold(%2 KB) min read(%3 KB) blk size(%4 KB)")
    575583            .arg(estbitrate).arg(fill_threshold/1024)
    576584            .arg(fill_min/1024).arg(readblocksize/1024));
    577 
    578     pthread_rwlock_unlock(&rwlock);
    579585}
    580586
    581587/** \fn RingBuffer::ReadBufFree(void) const
     
    611617void RingBuffer::ResetReadAhead(long long newinternal)
    612618{
    613619    readAheadLock.lock();
     620    readblocksize = CHUNK;
    614621    rbrpos = 0;
    615622    rbwpos = 0;
    616623    internalreadpos = newinternal;
     
    722729    int used = 0;
    723730    int loops = 0;
    724731
     732    struct timeval lastread, now;
     733    gettimeofday(&lastread, NULL);
     734    const int KB640 = 640*1024;
     735    int readtimeavg = 300;
     736    int readinterval;
     737
    725738    pausereadthread = false;
    726739
    727     readAheadBuffer = new char[kBufferSize + 256000];
     740    readAheadBuffer = new char[kBufferSize + KB640];
    728741
    729742    ResetReadAhead(0);
    730743    totfree = ReadBufFree();
     
    768781            // limit the read size
    769782            totfree = readblocksize;
    770783
     784            // adapt blocksize
     785            gettimeofday(&now, NULL);
     786            readinterval = (now.tv_sec  - lastread.tv_sec ) * 1000 +
     787                           (now.tv_usec - lastread.tv_usec) / 1000;
     788
     789            readtimeavg = (readtimeavg * 9 + readinterval) / 10;
     790
     791            if (readtimeavg < 200 && readblocksize < KB640)
     792            {
     793                readblocksize += CHUNK;
     794                VERBOSE(VB_PLAYBACK,
     795                    QString("Avg read interval was %1 msec. %2K block size")
     796                            .arg(readtimeavg).arg(readblocksize/1024));
     797                readtimeavg = 300;
     798            }
     799            else if (readtimeavg > 400 && readblocksize > CHUNK)
     800            {
     801                readblocksize -= CHUNK;
     802                VERBOSE(VB_PLAYBACK,
     803                    QString("Avg read interval was %1 msec. %2K block size")
     804                            .arg(readtimeavg).arg(readblocksize/1024));
     805                readtimeavg = 300;
     806            }
     807            lastread = now;
     808
    771809            if (rbwpos + totfree > kBufferSize)
    772810                totfree = kBufferSize - rbwpos;
    773811
  • libs/libmythtv/decoderbase.cpp

     
    2323
    2424      current_width(640), current_height(480),
    2525      current_aspect(1.33333), fps(29.97),
     26      bitrate(4000),
    2627
    2728      framesPlayed(0), framesRead(0), lastKey(0), keyframedist(-1),
    2829      indexOffset(0),
  • libs/libmythtv/avformatdecoder.h

     
    204204    bool directrendering;
    205205    bool drawband;
    206206
    207     int bitrate;
    208 
    209207    bool gopset;
    210208    /// A flag to indicate that we've seen a GOP frame.  Used in junction with seq_count.
    211209    bool seen_gop;
  • libs/libmythtv/ivtvdecoder.cpp

     
    4949{
    5050    lastResetTime.start();
    5151    fps = 29.97f;
     52    bitrate = 8000;
    5253    lastKey = 0;
    5354}
    5455
     
    277278
    278279    fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
    279280
    280     ringBuffer->UpdateRawBitrate(8000);
     281    ringBuffer->UpdateRawBitrate(GetRawBitrate());
    281282
    282283    if (m_playbackinfo || livetv || watchingrecording)
    283284    {