Ticket #10658: 10658-v1.patch
File 10658-v1.patch, 8.0 KB (added by , 12 years ago) |
---|
-
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) 14 14 AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data; 15 15 16 16 if (!avfr) 17 return 0; 17 return AVERROR(EBADF); 18 19 int ret = avfr->GetRingBuffer()->Read(buf, buf_size); 18 20 19 return avfr->GetRingBuffer()->Read(buf, buf_size);21 return (ret < 0) ? AVERROR(errno) : ret; 20 22 } 21 23 22 24 static 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) 24 26 AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data; 25 27 26 28 if (!avfr) 27 return 0;29 return AVERROR(EBADF); 28 30 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; 30 34 } 31 35 32 36 static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence) … … static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence) 34 38 AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data; 35 39 36 40 if (!avfr) 37 return 0;41 return AVERROR(EBADF); 38 42 39 43 if (whence == AVSEEK_SIZE) 40 44 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) 1008 1008 return ret; 1009 1009 } 1010 1010 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) 1011 int RingBuffer::WaitForAvail(int count, int how_long_ms) 1038 1012 { 1039 1013 int avail = ReadBufAvail(); 1014 if (avail >= count) 1015 return avail; 1016 1040 1017 count = (ateof && avail < count) ? avail : count; 1041 1018 1042 1019 if (livetvchain && setswitchtonext && avail < count) … … bool RingBuffer::WaitForAvail(int count) 1044 1021 LOG(VB_GENERAL, LOG_INFO, LOC + 1045 1022 "Checking to see if there's a new livetv program to switch to.."); 1046 1023 livetvchain->ReloadAll(); 1047 return false;1024 return avail; 1048 1025 } 1049 1026 1050 1027 // Make sure that if the read ahead thread is sleeping and … … bool RingBuffer::WaitForAvail(int count) 1061 1038 !request_pause && !commserror && readaheadrunning) 1062 1039 { 1063 1040 wanttoread = count; 1064 generalWait.wait(&rwlock, 250);1041 generalWait.wait(&rwlock, max(10, min(250, how_long_ms - t.elapsed()))); 1065 1042 avail = ReadBufAvail(); 1066 1043 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; 1097 1050 } 1098 1051 1099 1052 wanttoread = 0; 1100 1053 1101 return avail >= count;1054 return avail; 1102 1055 } 1103 1056 1104 1057 int RingBuffer::ReadDirect(void *buf, int count, bool peek) … … int RingBuffer::ReadDirect(void *buf, int count, bool peek) 1171 1124 * \param buf Pointer to where data will be written 1172 1125 * \param count Number of bytes to read 1173 1126 * \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 1175 1132 */ 1176 1133 int RingBuffer::ReadPriv(void *buf, int count, bool peek) 1177 1134 { … … int RingBuffer::ReadPriv(void *buf, int count, bool peek) 1222 1179 rwlock.lockForRead(); 1223 1180 } 1224 1181 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) 1226 1187 { 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()))); 1234 1189 } 1235 1236 if (!WaitForAvail(count)) 1190 if (!readsallowed) 1237 1191 { 1238 LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": !WaitForAvail()");1239 1192 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; 1246 1195 } 1247 1196 1248 count = min(ReadBufAvail(), count); 1197 int avail = WaitForAvail(count, max(timeout_ms - t.elapsed(), 1)); 1198 count = min(avail, count); 1249 1199 1250 1200 if (count <= 0) 1251 1201 { … … int RingBuffer::ReadPriv(void *buf, int count, bool peek) 1253 1203 // notable is an exit from the read ahead thread or 1254 1204 // the end of the file stream has been reached. 1255 1205 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 } 1258 1217 } 1259 1218 1260 1219 if (peek) … … int RingBuffer::Read(void *buf, int count) 1306 1265 poslock.lockForWrite(); 1307 1266 readpos += ret; 1308 1267 poslock.unlock(); 1268 UpdateDecoderRate(ret); 1309 1269 } 1310 1270 1311 UpdateDecoderRate(ret);1312 1271 return ret; 1313 1272 } 1314 1273 -
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 162 162 163 163 int ReadPriv(void *buf, int count, bool peek); 164 164 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); 167 166 168 167 int ReadBufFree(void) const; 169 168 int ReadBufAvail(void) const;