diff -rup mythtv.orig/libs/libmythtv/RingBuffer.cpp mythtv/libs/libmythtv/RingBuffer.cpp
old
|
new
|
using namespace std; |
42 | 42 | |
43 | 43 | const uint RingBuffer::kBufferSize = 3 * 1024 * 1024; |
44 | 44 | |
45 | | #define CHUNK 32768 /* readblocksize increments */ |
| 45 | #define DEF_CHUNK 32768 /* default readblocksize increments */ |
46 | 46 | |
47 | 47 | #define PNG_MIN_SIZE 20 /* header plus one empty chunk */ |
48 | 48 | #define NUV_MIN_SIZE 204 /* header size? */ |
… |
… |
RingBuffer::RingBuffer(const QString &lf |
96 | 96 | readsallowed(false), wantseek(false), setswitchtonext(false), |
97 | 97 | rawbitrate(4000), playspeed(1.0f), |
98 | 98 | fill_threshold(65536), fill_min(-1), |
99 | | readblocksize(CHUNK), wanttoread(0), |
| 99 | readblocksize(DEF_CHUNK), wanttoread(0), |
100 | 100 | numfailures(0), commserror(false), |
101 | 101 | dvdPriv(NULL), oldfile(false), |
102 | 102 | livetvchain(NULL), ignoreliveeof(false), |
… |
… |
RingBuffer::RingBuffer(const QString &lf |
118 | 118 | return; |
119 | 119 | } |
120 | 120 | |
| 121 | int io_multiplier = gContext->GetNumSetting("ReadWriteMultiplier", 5); |
| 122 | |
| 123 | read_chunk_size = (2<<(io_multiplier - 1)) * 1024; |
| 124 | max_read_size = 640 / (32 / (2<<(io_multiplier - 1))) * 1024; |
| 125 | |
| 126 | VERBOSE(VB_GENERAL, LOC + QString("Using io multiplier %1, chunk/max = " |
| 127 | "%2/%3") |
| 128 | .arg(io_multiplier) |
| 129 | .arg(read_chunk_size) |
| 130 | .arg(max_read_size)); |
| 131 | |
121 | 132 | if (read_retries != (uint)-1) |
122 | 133 | OpenFile(filename, read_retries); |
123 | 134 | } |
… |
… |
void RingBuffer::CalcReadAheadThresh(voi |
531 | 542 | pthread_rwlock_wrlock(&rwlock); |
532 | 543 | wantseek = false; |
533 | 544 | readsallowed = false; |
534 | | readblocksize = CHUNK; |
| 545 | readblocksize = read_chunk_size; |
535 | 546 | |
536 | 547 | // loop without sleeping if the buffered data is less than this |
537 | | fill_threshold = CHUNK * 2; |
| 548 | fill_threshold = read_chunk_size * 2; |
538 | 549 | fill_min = 1; |
539 | 550 | |
540 | 551 | #ifdef USING_FRONTEND |
… |
… |
int RingBuffer::ReadBufAvail(void) const |
606 | 617 | void RingBuffer::ResetReadAhead(long long newinternal) |
607 | 618 | { |
608 | 619 | readAheadLock.lock(); |
609 | | readblocksize = CHUNK; |
| 620 | readblocksize = read_chunk_size; |
610 | 621 | rbrpos = 0; |
611 | 622 | rbwpos = 0; |
612 | 623 | internalreadpos = newinternal; |
… |
… |
void RingBuffer::ReadAheadThread(void) |
720 | 731 | |
721 | 732 | struct timeval lastread, now; |
722 | 733 | gettimeofday(&lastread, NULL); |
723 | | const int KB640 = 640*1024; |
724 | 734 | int readtimeavg = 300; |
725 | 735 | int readinterval; |
726 | 736 | |
727 | 737 | pausereadthread = false; |
728 | 738 | |
729 | | readAheadBuffer = new char[kBufferSize + KB640]; |
| 739 | readAheadBuffer = new char[kBufferSize + max_read_size]; |
730 | 740 | |
731 | 741 | ResetReadAhead(0); |
732 | 742 | totfree = ReadBufFree(); |
… |
… |
void RingBuffer::ReadAheadThread(void) |
777 | 787 | |
778 | 788 | readtimeavg = (readtimeavg * 9 + readinterval) / 10; |
779 | 789 | |
780 | | if (readtimeavg < 200 && readblocksize < KB640) |
| 790 | if (readtimeavg < 200 && readblocksize < max_read_size) |
781 | 791 | { |
782 | | readblocksize += CHUNK; |
| 792 | readblocksize += read_chunk_size; |
783 | 793 | //VERBOSE(VB_PLAYBACK, |
784 | 794 | // QString("Avg read interval was %1 msec. %2K block size") |
785 | 795 | // .arg(readtimeavg).arg(readblocksize/1024)); |
786 | 796 | readtimeavg = 300; |
787 | 797 | } |
788 | | else if (readtimeavg > 400 && readblocksize > CHUNK) |
| 798 | else if (readtimeavg > 400 && readblocksize > read_chunk_size) |
789 | 799 | { |
790 | | readblocksize -= CHUNK; |
| 800 | readblocksize -= read_chunk_size; |
791 | 801 | //VERBOSE(VB_PLAYBACK, |
792 | 802 | // QString("Avg read interval was %1 msec. %2K block size") |
793 | 803 | // .arg(readtimeavg).arg(readblocksize/1024)); |
diff -rup mythtv.orig/libs/libmythtv/RingBuffer.h mythtv/libs/libmythtv/RingBuffer.h
old
|
new
|
class MPUBLIC RingBuffer |
126 | 126 | long long readpos; |
127 | 127 | long long writepos; |
128 | 128 | |
| 129 | int read_chunk_size; |
| 130 | int max_read_size; |
| 131 | |
129 | 132 | bool stopreads; |
130 | 133 | |
131 | 134 | mutable pthread_rwlock_t rwlock; |
diff -rup mythtv.orig/libs/libmythtv/ThreadedFileWriter.cpp mythtv/libs/libmythtv/ThreadedFileWriter.cpp
old
|
new
|
|
22 | 22 | #define LOC_ERR QString("TFW, Error: ") |
23 | 23 | |
24 | 24 | const uint ThreadedFileWriter::TFW_DEF_BUF_SIZE = 2*1024*1024; |
25 | | const uint ThreadedFileWriter::TFW_MAX_WRITE_SIZE = TFW_DEF_BUF_SIZE / 4; |
26 | | const uint ThreadedFileWriter::TFW_MIN_WRITE_SIZE = TFW_DEF_BUF_SIZE / 32; |
| 25 | const uint ThreadedFileWriter::TFW_MAX_WRITE_SIZE = TFW_DEF_BUF_SIZE / |
| 26 | (128 / (2<<(5-1))); |
| 27 | const uint ThreadedFileWriter::TFW_MIN_WRITE_SIZE = TFW_DEF_BUF_SIZE / |
| 28 | (1024 / (2<<(5-1))); |
27 | 29 | |
28 | 30 | /** \class ThreadedFileWriter |
29 | 31 | * \brief This class supports the writing of recordings to disk. |
… |
… |
bool ThreadedFileWriter::Open(void) |
148 | 150 | bzero(buf, TFW_DEF_BUF_SIZE + 64); |
149 | 151 | |
150 | 152 | tfw_buf_size = TFW_DEF_BUF_SIZE; |
151 | | tfw_min_write_size = TFW_MIN_WRITE_SIZE; |
| 153 | int io_multiplier = gContext->GetNumSetting("ReadWriteMultiplier", 5); |
| 154 | |
| 155 | tfw_min_write_size = TFW_DEF_BUF_SIZE / (1024 / (2<<(io_multiplier - 1))); |
| 156 | tfw_max_write_size = TFW_DEF_BUF_SIZE / (128 / (2<<(io_multiplier - 1))); |
| 157 | |
| 158 | VERBOSE(VB_RECORD, LOC + QString("Using io multiplier %1, " |
| 159 | "min/max = %2/%3") |
| 160 | .arg(io_multiplier) |
| 161 | .arg(tfw_min_write_size) |
| 162 | .arg(tfw_max_write_size)); |
| 163 | |
152 | 164 | pthread_create(&writer, NULL, boot_writer, this); |
153 | 165 | pthread_create(&syncer, NULL, boot_syncer, this); |
154 | 166 | return true; |
… |
… |
void ThreadedFileWriter::DiskLoop(void) |
364 | 376 | buffer is valid, and we try to write all of it at once which |
365 | 377 | takes a long time. During this time, the other thread fills up |
366 | 378 | the 10% that was free... */ |
367 | | size = (size > TFW_MAX_WRITE_SIZE) ? TFW_MAX_WRITE_SIZE : size; |
| 379 | size = (size > tfw_max_write_size) ? tfw_max_write_size : size; |
368 | 380 | |
369 | 381 | bool write_ok; |
370 | 382 | if (ignore_writes) |
diff -rup mythtv.orig/libs/libmythtv/ThreadedFileWriter.h mythtv/libs/libmythtv/ThreadedFileWriter.h
old
|
new
|
class ThreadedFileWriter |
48 | 48 | bool in_dtor; |
49 | 49 | bool ignore_writes; |
50 | 50 | long long tfw_min_write_size; |
| 51 | long long tfw_max_write_size; |
51 | 52 | |
52 | 53 | // buffer position state |
53 | 54 | uint rpos; ///< points to end of data written to disk |
diff -rup mythtv.orig/programs/mythtv-setup/backendsettings.cpp mythtv/programs/mythtv-setup/backendsettings.cpp
old
|
new
|
static GlobalSpinBox *HDRingbufferSize() |
171 | 171 | return bs; |
172 | 172 | } |
173 | 173 | |
| 174 | static GlobalSpinBox *ReadWriteMultiplier() |
| 175 | { |
| 176 | GlobalSpinBox *bs = new GlobalSpinBox( |
| 177 | "ReadWriteMultiplier", 2, 6, 1); |
| 178 | bs->setLabel(QObject::tr("File read & write size multiplier")); |
| 179 | bs->setHelpText(QObject::tr("This fine tunes filesystem reads & writes " |
| 180 | "for differently performing storage " |
| 181 | "systems. Use caution when adjusting from the default of " |
| 182 | "5 as this may negatively impact LiveTV and recordings.")); |
| 183 | bs->setValue(5); |
| 184 | return bs; |
| 185 | } |
| 186 | |
174 | 187 | static HostLineEdit *MiscStatusScript() |
175 | 188 | { |
176 | 189 | HostLineEdit *he = new HostLineEdit("MiscStatusScript"); |
… |
… |
BackendSettings::BackendSettings() { |
760 | 773 | fm->addChild(DeletesFollowLinks()); |
761 | 774 | fm->addChild(TruncateDeletes()); |
762 | 775 | fm->addChild(HDRingbufferSize()); |
| 776 | fm->addChild(ReadWriteMultiplier()); |
763 | 777 | group2->addChild(fm); |
764 | 778 | VerticalConfigurationGroup* misc = new VerticalConfigurationGroup(false); |
765 | 779 | misc->addChild(MiscStatusScript()); |