00001
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
00022 #define NUV_MIN_SIZE 204
00023 #define MPEG_MIN_SIZE 376
00024
00025
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
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
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
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
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);
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
00126 void Pause(void);
00127 void Unpause(void);
00128 void WaitForPause(void);
00129
00130
00131 void Start(void);
00132 void StopReads(void);
00133 void StartReads(void);
00134
00135
00136 bool LiveMode(void) const;
00137 void SetLiveMode(LiveTVChain *chain);
00138 void IgnoreLiveEOF(bool ignore);
00139
00140
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);
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;
00182 long long writepos;
00183 long long internalreadpos;
00184 long long ignorereadpos;
00185 mutable QReadWriteLock rbrlock;
00186 int rbrpos;
00187 mutable QReadWriteLock rbwlock;
00188 int rbwpos;
00189
00190
00191
00192 volatile bool stopreads;
00193
00194 mutable QReadWriteLock rwlock;
00195
00196 QString safefilename;
00197 QString filename;
00198 QString subtitlefilename;
00199
00200 ThreadedFileWriter *tfw;
00201 int fd2;
00202
00203 bool writemode;
00204
00205 RemoteFile *remotefile;
00206
00207 uint bufferSize;
00208 bool low_buffers;
00209 bool fileismatroska;
00210 bool unknownbitrate;
00211 bool startreadahead;
00212 char *readAheadBuffer;
00213 bool readaheadrunning;
00214 bool reallyrunning;
00215 bool request_pause;
00216 bool paused;
00217 bool ateof;
00218 bool readsallowed;
00219 bool setswitchtonext;
00220 uint rawbitrate;
00221 float playspeed;
00222 int fill_threshold;
00223 int fill_min;
00224 int readblocksize;
00225 int wanttoread;
00226 int numfailures;
00227 bool commserror;
00228
00229 bool oldfile;
00230
00231 LiveTVChain *livetvchain;
00232 bool ignoreliveeof;
00233
00234 long long readAdjust;
00235
00236
00237 bool bitrateMonitorEnabled;
00238 QMutex decoderReadLock;
00239 QMap<qint64, uint64_t> decoderReads;
00240 QMutex storageReadLock;
00241 QMap<qint64, uint64_t> storageReads;
00242
00243
00244
00245
00246
00247
00248
00250 QWaitCondition generalWait;
00251
00252 public:
00253 static QMutex subExtLock;
00254 static QStringList subExt;
00255 static QStringList subExtNoCheck;
00256 };
00257
00258 #endif // _RINGBUFFER_H_