Ticket #10658: 10658-v1.patch

File 10658-v1.patch, 8.0 KB (added by danielk, 12 years ago)

Initial patch

  • mythtv/libs/libmythtv/avfringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/avfringbuffer.cpp b/mythtv/libs/libmythtv/avfringbuffer.cpp
    index cdb04f7..c8bc1f1 100644
    a b static int AVF_Read(URLContext *h, uint8_t *buf, int buf_size) 
    1414    AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
    1515
    1616    if (!avfr)
    17         return 0;
     17        return AVERROR(EBADF);
     18
     19    int ret = avfr->GetRingBuffer()->Read(buf, buf_size);
    1820
    19     return avfr->GetRingBuffer()->Read(buf, buf_size);
     21    return (ret < 0) ? AVERROR(errno) : ret;
    2022}
    2123
    2224static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
    static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size) 
    2426    AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
    2527
    2628    if (!avfr)
    27         return 0;
     29        return AVERROR(EBADF);
    2830
    29     return avfr->GetRingBuffer()->Write(buf, buf_size);
     31    int ret = avfr->GetRingBuffer()->Write(buf, buf_size);
     32   
     33    return (ret < 0) ? AVERROR(errno) : ret;
    3034}
    3135
    3236static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence)
    static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence) 
    3438    AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
    3539
    3640    if (!avfr)
    37         return 0;
     41        return AVERROR(EBADF);
    3842
    3943    if (whence == AVSEEK_SIZE)
    4044        return avfr->GetRingBuffer()->GetRealFileSize();
  • mythtv/libs/libmythtv/ringbuffer.cpp

    diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
    index 5e720c2..8623137 100644
    a b int RingBuffer::Peek(void *buf, int count) 
    10081008    return ret;
    10091009}
    10101010
    1011 bool RingBuffer::WaitForReadsAllowed(void)
    1012 {
    1013     MythTimer t;
    1014     t.start();
    1015 
    1016     while (!readsallowed && !stopreads &&
    1017            !request_pause && !commserror && readaheadrunning)
    1018     {
    1019         generalWait.wait(&rwlock, 1000);
    1020         if (!readsallowed && t.elapsed() > 1000)
    1021         {
    1022             LOG(VB_GENERAL, LOG_WARNING, LOC +
    1023                 "Taking too long to be allowed to read..");
    1024 
    1025             if (t.elapsed() > 10000)
    1026             {
    1027                 LOG(VB_GENERAL, LOG_ERR, LOC + "Took more than 10 seconds to "
    1028                                                "be allowed to read, aborting.");
    1029                 return false;
    1030             }
    1031         }
    1032     }
    1033 
    1034     return readsallowed;
    1035 }
    1036 
    1037 bool RingBuffer::WaitForAvail(int count)
     1011int RingBuffer::WaitForAvail(int count, int how_long_ms)
    10381012{
    10391013    int avail = ReadBufAvail();
     1014    if (avail >= count)
     1015        return avail;
     1016
    10401017    count = (ateof && avail < count) ? avail : count;
    10411018
    10421019    if (livetvchain && setswitchtonext && avail < count)
    bool RingBuffer::WaitForAvail(int count) 
    10441021        LOG(VB_GENERAL, LOG_INFO, LOC +
    10451022            "Checking to see if there's a new livetv program to switch to..");
    10461023        livetvchain->ReloadAll();
    1047         return false;
     1024        return avail;
    10481025    }
    10491026
    10501027    // Make sure that if the read ahead thread is sleeping and
    bool RingBuffer::WaitForAvail(int count) 
    10611038           !request_pause && !commserror && readaheadrunning)
    10621039    {
    10631040        wanttoread = count;
    1064         generalWait.wait(&rwlock, 250);
     1041        generalWait.wait(&rwlock, max(10, min(250, how_long_ms - t.elapsed())));
    10651042        avail = ReadBufAvail();
    10661043
    1067         if (ateof && avail < count)
    1068             count = avail;
    1069 
    1070         if (avail < count)
    1071         {
    1072             int elapsed = t.elapsed();
    1073             if (elapsed > 500 && low_buffers && avail >= fill_min)
    1074                 count = avail;
    1075             else if  (((elapsed > 250) && (elapsed < 500))  ||
    1076                      ((elapsed >  500) && (elapsed < 750))  ||
    1077                      ((elapsed > 1000) && (elapsed < 1250)) ||
    1078                      ((elapsed > 2000) && (elapsed < 2250)) ||
    1079                      ((elapsed > 4000) && (elapsed < 4250)) ||
    1080                      ((elapsed > 8000) && (elapsed < 8250)) ||
    1081                      ((elapsed > 9000)))
    1082             {
    1083                 LOG(VB_GENERAL, LOG_INFO, LOC + "Waited " +
    1084                     QString("%1").arg((elapsed / 250) * 0.25f, 3, 'f', 1) +
    1085                     " seconds for data \n\t\t\tto become available..." +
    1086                     QString(" %2 < %3") .arg(avail).arg(count));
    1087             }
    1088 
    1089             if (elapsed > 16000)
    1090             {
    1091                 LOG(VB_GENERAL, LOG_ERR, LOC + "Waited " +
    1092                     QString("%1").arg(elapsed/1000) +
    1093                     " seconds for data, aborting.");
    1094                 return false;
    1095             }
    1096         }
     1044        if (ateof)
     1045            break;
     1046        if (low_buffers && avail >= fill_min)
     1047            break;
     1048        if (t.elapsed() > how_long_ms)
     1049            break;
    10971050    }
    10981051
    10991052    wanttoread = 0;
    11001053
    1101     return avail >= count;
     1054    return avail;
    11021055}
    11031056
    11041057int RingBuffer::ReadDirect(void *buf, int count, bool peek)
    int RingBuffer::ReadDirect(void *buf, int count, bool peek) 
    11711124 *  \param buf   Pointer to where data will be written
    11721125 *  \param count Number of bytes to read
    11731126 *  \param peek  If true, don't increment read count
    1174  *  \return Returns number of bytes read
     1127 *
     1128 *  \note If we return a -1, errno will be set as if the C
     1129 *        read function had been called on a file.
     1130 *
     1131 *  \return Returns number of bytes read, or -1 on error
    11751132 */
    11761133int RingBuffer::ReadPriv(void *buf, int count, bool peek)
    11771134{
    int RingBuffer::ReadPriv(void *buf, int count, bool peek) 
    12221179        rwlock.lockForRead();
    12231180    }
    12241181
    1225     if (!WaitForReadsAllowed())
     1182    // Wait for reads allowed
     1183    MythTimer t; t.start();
     1184    const int timeout_ms = 100;
     1185    while ((t.elapsed() < timeout_ms) && !readsallowed && !stopreads &&
     1186           !request_pause && !commserror && readaheadrunning)
    12261187    {
    1227         LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": !WaitForReadsAllowed()");
    1228         rwlock.unlock();
    1229         stopreads = true; // this needs to be outside the lock
    1230         rwlock.lockForWrite();
    1231         wanttoread = 0;
    1232         rwlock.unlock();
    1233         return 0;
     1188        generalWait.wait(&rwlock, max(1, min(100, timeout_ms - t.elapsed())));
    12341189    }
    1235 
    1236     if (!WaitForAvail(count))
     1190    if (!readsallowed)
    12371191    {
    1238         LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": !WaitForAvail()");
    12391192        rwlock.unlock();
    1240         stopreads = true; // this needs to be outside the lock
    1241         rwlock.lockForWrite();
    1242         ateof = true;
    1243         wanttoread = 0;
    1244         rwlock.unlock();
    1245         return 0;
     1193        errno = EAGAIN;
     1194        return -1;
    12461195    }
    12471196
    1248     count = min(ReadBufAvail(), count);
     1197    int avail = WaitForAvail(count, max(timeout_ms - t.elapsed(), 1));
     1198    count = min(avail, count);
    12491199
    12501200    if (count <= 0)
    12511201    {
    int RingBuffer::ReadPriv(void *buf, int count, bool peek) 
    12531203        // notable is an exit from the read ahead thread or
    12541204        // the end of the file stream has been reached.
    12551205        LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": ReadBufAvail() == 0");
    1256         rwlock.unlock();
    1257         return count;
     1206        if (ateof)
     1207        {
     1208            rwlock.unlock();
     1209            return 0;
     1210        }
     1211        else
     1212        {
     1213            rwlock.unlock();
     1214            errno = EAGAIN;
     1215            return -1;
     1216        }
    12581217    }
    12591218
    12601219    if (peek)
    int RingBuffer::Read(void *buf, int count) 
    13061265        poslock.lockForWrite();
    13071266        readpos += ret;
    13081267        poslock.unlock();
     1268        UpdateDecoderRate(ret);
    13091269    }
    13101270
    1311     UpdateDecoderRate(ret);
    13121271    return ret;
    13131272}
    13141273
  • mythtv/libs/libmythtv/ringbuffer.h

    diff --git a/mythtv/libs/libmythtv/ringbuffer.h b/mythtv/libs/libmythtv/ringbuffer.h
    index 45bd956..ecbf64a 100644
    a b class MTV_PUBLIC RingBuffer : protected MThread 
    162162
    163163    int ReadPriv(void *buf, int count, bool peek);
    164164    int ReadDirect(void *buf, int count, bool peek);
    165     bool WaitForReadsAllowed(void);
    166     bool WaitForAvail(int count);
     165    int WaitForAvail(int count, int how_long_ms);
    167166
    168167    int ReadBufFree(void) const;
    169168    int ReadBufAvail(void) const;