|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 00003 #ifndef _RINGBUFFER_H_ 00004 #define _RINGBUFFER_H_ 00005 00006 #include <QReadWriteLock> 00007 #include <QWaitCondition> 00008 #include <QString> 00009 #include <QMutex> 00010 #include <QMap> 00011 00012 #include "mythconfig.h" 00013 #include "mthread.h" 00014 00015 extern "C" { 00016 #include "libavcodec/avcodec.h" 00017 } 00018 00019 #include "mythtvexp.h" 00020 00021 #define PNG_MIN_SIZE 20 /* header plus one empty chunk */ 00022 #define NUV_MIN_SIZE 204 /* header size? */ 00023 #define MPEG_MIN_SIZE 376 /* 2 TS packets */ 00024 00025 /* should be minimum of the above test sizes */ 00026 #define kReadTestSize PNG_MIN_SIZE 00027 00028 class ThreadedFileWriter; 00029 class DVDRingBuffer; 00030 class BDRingBuffer; 00031 class LiveTVChain; 00032 class RemoteFile; 00033 00034 enum RingBufferType 00035 { 00036 kRingBuffer_Unknown = 0, 00037 kRingBuffer_File, 00038 kRingBuffer_DVD, 00039 kRingBuffer_BD, 00040 kRingBuffer_HTTP, 00041 kRingBuffer_HLS, 00042 }; 00043 00044 class MTV_PUBLIC RingBuffer : protected MThread 00045 { 00046 public: 00047 static RingBuffer *Create(const QString &lfilename, bool write, 00048 bool usereadahead = true, 00049 int timeout_ms = kDefaultOpenTimeout, 00050 bool stream_only = false); 00051 virtual ~RingBuffer(); 00052 00053 // Sets 00054 void SetWriteBufferSize(int newSize); 00055 void SetWriteBufferMinWriteSize(int newMinSize); 00056 void SetOldFile(bool is_old); 00057 void UpdateRawBitrate(uint rawbitrate); 00058 void UpdatePlaySpeed(float playspeed); 00059 void EnableBitrateMonitor(bool enable) { bitrateMonitorEnabled = enable; } 00060 void SetBufferSizeFactors(bool estbitrate, bool matroska); 00061 00062 // Gets 00063 QString GetSafeFilename(void) { return safefilename; } 00064 QString GetFilename(void) const; 00065 QString GetSubtitleFilename(void) const; 00068 bool GetStopReads(void) const { return stopreads; } 00069 bool isPaused(void) const; 00071 virtual long long GetReadPosition(void) const = 0; 00072 QString GetDecoderRate(void); 00073 QString GetStorageRate(void); 00074 QString GetAvailableBuffer(void); 00075 uint GetBufferSize(void) { return bufferSize; } 00076 long long GetWritePosition(void) const; 00079 virtual long long GetRealFileSize(void) const { return -1; } 00080 bool IsNearEnd(double fps, uint vvf) const; 00082 virtual bool IsOpen(void) const = 0; 00083 virtual bool IsStreamed(void) { return LiveMode(); } 00084 virtual bool IsSeekingAllowed(void) { return true; } 00085 virtual bool IsBookmarkAllowed(void) { return true; } 00086 virtual int BestBufferSize(void) { return 32768; } 00087 static QString BitrateToString(uint64_t rate, bool hz = false); 00088 00089 // DVD and bluray methods 00090 bool IsDisc(void) const { return IsDVD() || IsBD(); } 00091 bool IsDVD(void) const { return type == kRingBuffer_DVD; } 00092 bool IsBD(void) const { return type == kRingBuffer_BD; } 00093 const DVDRingBuffer *DVD(void) const; 00094 const BDRingBuffer *BD(void) const; 00095 DVDRingBuffer *DVD(void); 00096 BDRingBuffer *BD(void); 00097 virtual bool StartFromBeginning(void) { return true; } 00098 virtual void IgnoreWaitStates(bool ignore) { } 00099 virtual bool IsInDiscMenuOrStillFrame(void) const { return false; } 00100 virtual bool HandleAction(const QStringList &, int64_t) { return false; } 00101 00102 // General Commands 00103 00110 virtual bool OpenFile(const QString &lfilename, 00111 uint retry_ms = kDefaultOpenTimeout) = 0; 00112 virtual bool ReOpen(QString newFilename = "") { return false; } 00113 00114 int Read(void *buf, int count); 00115 int Peek(void *buf, int count); // only works with readahead 00116 00117 void Reset(bool full = false, 00118 bool toAdjust = false, 00119 bool resetInternal = false); 00120 00122 virtual long long Seek( 00123 long long pos, int whence, bool has_lock = false) = 0; 00124 00125 // Pause commands 00126 void Pause(void); 00127 void Unpause(void); 00128 void WaitForPause(void); 00129 00130 // Start/Stop commands 00131 void Start(void); 00132 void StopReads(void); 00133 void StartReads(void); 00134 00135 // LiveTVChain support 00136 bool LiveMode(void) const; 00137 void SetLiveMode(LiveTVChain *chain); 00138 void IgnoreLiveEOF(bool ignore); 00139 00140 // ThreadedFileWriter proxies 00141 int Write(const void *buf, uint count); 00142 bool IsIOBound(void) const; 00143 void WriterFlush(void); 00144 void Sync(void); 00145 long long WriterSeek(long long pos, int whence, bool has_lock = false); 00146 00147 long long SetAdjustFilesize(void); 00148 00150 void SetTimeout(bool is_old) MDEPRECATED { SetOldFile(is_old); } 00151 00152 static const int kDefaultOpenTimeout; 00153 static const int kLiveTVOpenTimeout; 00154 00155 protected: 00156 RingBuffer(RingBufferType rbtype); 00157 00158 void run(void); // MThread 00159 void CreateReadAheadBuffer(void); 00160 void CalcReadAheadThresh(void); 00161 bool PauseAndWait(void); 00162 virtual int safe_read(void *data, uint sz) = 0; 00163 00164 int ReadPriv(void *buf, int count, bool peek); 00165 int ReadDirect(void *buf, int count, bool peek); 00166 bool WaitForReadsAllowed(void); 00167 bool WaitForAvail(int count); 00168 00169 int ReadBufFree(void) const; 00170 int ReadBufAvail(void) const; 00171 00172 void ResetReadAhead(long long newinternal); 00173 void KillReadAheadThread(void); 00174 00175 uint64_t UpdateDecoderRate(uint64_t latest = 0); 00176 uint64_t UpdateStorageRate(uint64_t latest = 0); 00177 00178 protected: 00179 RingBufferType type; 00180 mutable QReadWriteLock poslock; 00181 long long readpos; // protected by poslock 00182 long long writepos; // protected by poslock 00183 long long internalreadpos; // protected by poslock 00184 long long ignorereadpos; // protected by poslock 00185 mutable QReadWriteLock rbrlock; 00186 int rbrpos; // protected by rbrlock 00187 mutable QReadWriteLock rbwlock; 00188 int rbwpos; // protected by rbwlock 00189 00190 // note should not go under rwlock.. 00191 // this is used to break out of read_safe where rwlock is held 00192 volatile bool stopreads; 00193 00194 mutable QReadWriteLock rwlock; 00195 00196 QString safefilename; // unprotected (for debugging) 00197 QString filename; // protected by rwlock 00198 QString subtitlefilename; // protected by rwlock 00199 00200 ThreadedFileWriter *tfw; // protected by rwlock 00201 int fd2; // protected by rwlock 00202 00203 bool writemode; // protected by rwlock 00204 00205 RemoteFile *remotefile; // protected by rwlock 00206 00207 uint bufferSize; // protected by rwlock 00208 bool low_buffers; // protected by rwlock 00209 bool fileismatroska; // protected by rwlock 00210 bool unknownbitrate; // protected by rwlock 00211 bool startreadahead; // protected by rwlock 00212 char *readAheadBuffer; // protected by rwlock 00213 bool readaheadrunning; // protected by rwlock 00214 bool reallyrunning; // protected by rwlock 00215 bool request_pause; // protected by rwlock 00216 bool paused; // protected by rwlock 00217 bool ateof; // protected by rwlock 00218 bool readsallowed; // protected by rwlock 00219 bool setswitchtonext; // protected by rwlock 00220 uint rawbitrate; // protected by rwlock 00221 float playspeed; // protected by rwlock 00222 int fill_threshold; // protected by rwlock 00223 int fill_min; // protected by rwlock 00224 int readblocksize; // protected by rwlock 00225 int wanttoread; // protected by rwlock 00226 int numfailures; // protected by rwlock (see note 1) 00227 bool commserror; // protected by rwlock 00228 00229 bool oldfile; // protected by rwlock 00230 00231 LiveTVChain *livetvchain; // protected by rwlock 00232 bool ignoreliveeof; // protected by rwlock 00233 00234 long long readAdjust; // protected by rwlock 00235 00236 // bitrate monitors 00237 bool bitrateMonitorEnabled; 00238 QMutex decoderReadLock; 00239 QMap<qint64, uint64_t> decoderReads; 00240 QMutex storageReadLock; 00241 QMap<qint64, uint64_t> storageReads; 00242 00243 // note 1: numfailures is modified with only a read lock in the 00244 // read ahead thread, but this is safe since all other places 00245 // that use it are protected by a write lock. But this is a 00246 // fragile state of affairs and care must be taken when modifying 00247 // code or locking around this variable. 00248 00250 QWaitCondition generalWait; // protected by rwlock 00251 00252 public: 00253 static QMutex subExtLock; 00254 static QStringList subExt; 00255 static QStringList subExtNoCheck; 00256 }; 00257 00258 #endif // _RINGBUFFER_H_
1.7.6.1