MythTV master
mythmediabuffer.h
Go to the documentation of this file.
1#ifndef MYTHMEDIABUFFER_H
2#define MYTHMEDIABUFFER_H
3
4// Qt
5#include <QReadWriteLock>
6#include <QWaitCondition>
7#include <QString>
8#include <QMutex>
9#include <QMap>
10
11// MythTV
12#include "libmythbase/mythconfig.h"
13#include "libmythtv/mythtvexp.h"
14#include "libmythbase/mthread.h"
16
17// FFmpeg
18extern "C" {
19#include "libavcodec/avcodec.h"
20}
21
22// Size of PNG header plus one empty chunk
23static constexpr qint64 kReadTestSize { 20 };
24
25// about one second at 35Mb
26static constexpr uint32_t BUFFER_SIZE_MINIMUM { 4 * 1024 * 1024 };
27static constexpr uint8_t BUFFER_FACTOR_NETWORK { 2 };
28static constexpr uint8_t BUFFER_FACTOR_BITRATE { 2 };
29static constexpr uint8_t BUFFER_FACTOR_MATROSKA { 2 };
30
31static constexpr int32_t DEFAULT_CHUNK_SIZE { 32768 };
32
33static inline QString seek2string(int Whence)
34{
35 if (SEEK_SET == Whence)
36 return "SEEK_SET";
37 if (SEEK_CUR == Whence)
38 return "SEEK_CUR";
39 return "SEEK_END";
40}
41
43class MythDVDBuffer;
44class MythBDBuffer;
45class LiveTVChain;
46class RemoteFile;
47
48enum MythBufferType : std::uint8_t
49{
57};
58
60{
62
63 public:
64 static MythMediaBuffer *Create(const QString &Filename, bool Write,
65 bool UseReadAhead = true,
66 std::chrono::milliseconds Timeout = kDefaultOpenTimeout,
67 bool StreamOnly = false);
68 ~MythMediaBuffer() override = 0;
69 MythBufferType GetType() const;
70
71 static constexpr std::chrono::milliseconds kDefaultOpenTimeout { 2s };
72 static constexpr std::chrono::milliseconds kLiveTVOpenTimeout { 10s };
73 static QString BitrateToString (uint64_t Rate, bool Hz = false);
74 static void AVFormatInitNetwork (void);
75
76 void SetOldFile (bool Old);
77 void UpdateRawBitrate (uint RawBitrate);
78 void UpdatePlaySpeed (float PlaySpeed);
79 void EnableBitrateMonitor (bool Enable);
80 void SetBufferSizeFactors (bool EstBitrate, bool Matroska);
81 void SetWaitForWrite (void);
82 QString GetSafeFilename (void);
83 QString GetFilename (void) const;
84 QString GetSubtitleFilename (void) const;
85 QString GetLastError (void) const;
86 bool GetCommsError (void) const;
87 void ResetCommsError (void);
88 bool GetStopReads (void) const;
89 QString GetDecoderRate (void);
90 QString GetStorageRate (void);
91 QString GetAvailableBuffer (void);
92 uint GetBufferSize (void) const;
93 bool IsNearEnd (double Framerate, uint Frames) const;
94 long long GetWritePosition (void) const;
95 long long GetRealFileSize (void) const;
96 bool IsDisc (void) const;
97 bool IsDVD (void) const;
98 bool IsBD (void) const;
99 const MythDVDBuffer *DVD (void) const;
100 MythDVDBuffer *DVD (void);
101 const MythBDBuffer *BD (void) const;
102 MythBDBuffer *BD (void);
103 int Read (void *Buffer, int Count);
104 int Peek (void *Buffer, int Count);
105 int Peek (std::vector<char>& Buffer);
106 void Reset (bool Full = false, bool ToAdjust = false, bool ResetInternal = false);
107 void Pause (void);
108 void Unpause (void);
109 void WaitForPause (void);
110 void Start (void);
111 void StopReads (void);
112 void StartReads (void);
113 long long Seek (long long Position, int Whence, bool HasLock = false);
114 long long SetAdjustFilesize (void);
115
116 // LiveTV used utilities
117 int GetReadBufAvail (void) const;
118 bool SetReadInternalMode (bool Mode);
119 bool IsReadInternalMode (void) const;
120 bool LiveMode (void) const;
121 void SetLiveMode (LiveTVChain *Chain);
122 void IgnoreLiveEOF (bool Ignore);
123
124 // ThreadedFileWriter proxies
125 int Write (const void *Buffer, uint Count);
126 bool IsIOBound (void) const;
127 void WriterFlush (void);
128 void Sync (void);
129 long long WriterSeek (long long Position, int Whence, bool HasLock = false);
130 bool WriterSetBlocking (bool Lock = true);
131
132 virtual long long GetReadPosition (void) const = 0;
133 virtual bool IsOpen (void) const = 0;
134 virtual bool IsStreamed (void) { return LiveMode(); }
135 virtual bool IsSeekingAllowed (void) { return true; }
136 virtual bool IsBookmarkAllowed (void) { return true; }
137 virtual int BestBufferSize (void) { return DEFAULT_CHUNK_SIZE; }
138 virtual bool StartFromBeginning(void) { return true; }
139 virtual void IgnoreWaitStates (bool /*Ignore*/) { }
140 virtual bool IsInMenu (void) const { return false; }
141 virtual bool IsInStillFrame (void) const { return false; }
142 virtual bool IsInDiscMenuOrStillFrame(void) const { return IsInMenu() || IsInStillFrame(); }
143 virtual bool HandleAction (const QStringList &/*Action*/, mpeg::chrono::pts /*Pts*/) { return false; }
144 virtual bool OpenFile (const QString &Filename, std::chrono::milliseconds Retry = kDefaultOpenTimeout) = 0;
145 virtual bool ReOpen (const QString& /*Filename*/ = "") { return false; }
146
147 protected:
148 explicit MythMediaBuffer(MythBufferType Type);
149
150 void run(void) override;
151 void CreateReadAheadBuffer (void);
152 void CalcReadAheadThresh (void);
153 bool PauseAndWait (void);
154 int ReadPriv (void *Buffer, int Count, bool Peek);
155 int ReadDirect (void *Buffer, int Count, bool Peek);
156 bool WaitForReadsAllowed (void);
157 int WaitForAvail (int Count, std::chrono::milliseconds Timeout);
158 int ReadBufFree (void) const;
159 int ReadBufAvail (void) const;
160 void ResetReadAhead (long long NewInternal);
161 void KillReadAheadThread (void);
162 uint64_t UpdateDecoderRate (uint64_t Latest = 0);
163 uint64_t UpdateStorageRate (uint64_t Latest = 0);
164
165 virtual int SafeRead (void *Buffer, uint Size) = 0;
166 virtual long long GetRealFileSizeInternal(void) const { return -1; }
167 virtual long long SeekInternal (long long Position, int Whence) = 0;
168
169
170 protected:
172
173 mutable QReadWriteLock m_posLock;
174 long long m_readPos { 0 };
175 long long m_writePos { 0 };
176 long long m_internalReadPos { 0 };
177 long long m_ignoreReadPos { -1 };
178
179 mutable QReadWriteLock m_rbrLock;
180 int m_rbrPos { 0 };
181
182 mutable QReadWriteLock m_rbwLock;
183 int m_rbwPos { 0 };
184
185 // note should not go under rwLock..
186 // this is used to break out of read_safe where rwLock is held
187 volatile bool m_stopReads {false};
188
189 // unprotected (for debugging)
191
192 mutable QReadWriteLock m_rwLock;
193 QString m_filename;
195 QString m_lastError;
197 int m_fd2 { -1 };
198 bool m_writeMode { false };
201 bool m_lowBuffers { false };
202 bool m_fileIsMatroska { false };
203 bool m_unknownBitrate { false };
204 bool m_startReadAhead { false };
205 char *m_readAheadBuffer { nullptr };
206 bool m_readAheadRunning { false };
207 bool m_reallyRunning { false };
208 bool m_requestPause { false };
209 bool m_paused { false };
210 bool m_ateof { false };
211 bool m_waitForWrite { false };
212 bool m_beingWritten { false };
213 bool m_readsAllowed { false };
214 bool m_readsDesired { false };
215 volatile bool m_recentSeek { true }; // not protected by rwLock
216 bool m_setSwitchToNext { false };
218 float m_playSpeed { 1.0F };
219 int m_fillThreshold { 65536 };
220 int m_fillMin { -1 };
222 int m_wantToRead { 0 };
223 int m_numFailures { 0 }; // (see note 1)
224 bool m_commsError { false };
225 bool m_oldfile { false };
227 bool m_ignoreLiveEOF { false };
228 long long m_readAdjust { 0 };
229 int m_readOffset { 0 };
230 bool m_readInternalMode { false };
231 // End of section protected by rwLock
232
235 QMap<std::chrono::milliseconds, uint64_t> m_decoderReads;
237 QMap<std::chrono::milliseconds, uint64_t> m_storageReads;
238
239 // note 1: numfailures is modified with only a read lock in the
240 // read ahead thread, but this is safe since all other places
241 // that use it are protected by a write lock. But this is a
242 // fragile state of affairs and care must be taken when modifying
243 // code or locking around this variable.
244
246 QWaitCondition m_generalWait; // protected by rwLock
247
248 private:
249 bool m_bitrateInitialized { false };
250};
251#endif
Keeps track of recordings in a current LiveTV instance.
Definition: livetvchain.h:33
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:49
virtual void run(void)
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: mthread.cpp:315
A class to allow a MythMediaBuffer to read from BDs.
Definition: mythbdbuffer.h:20
long long GetRealFileSize(void) const
QString GetStorageRate(void)
void Reset(bool Full=false, bool ToAdjust=false, bool ResetInternal=false)
Resets the read-ahead thread and our position in the file.
MythBufferType GetType() const
void ResetCommsError(void)
virtual long long GetRealFileSizeInternal(void) const
void KillReadAheadThread(void)
Stops the read-ahead thread, and waits for it to stop.
long long GetWritePosition(void) const
Returns how far into a ThreadedFileWriter file we have written.
bool GetCommsError(void) const
void SetLiveMode(LiveTVChain *Chain)
Assigns a LiveTVChain to this RingBuffer.
void UpdateRawBitrate(uint RawBitrate)
Set the raw bit rate, to allow RingBuffer adjust effective bitrate.
long long m_internalReadPos
void IgnoreLiveEOF(bool Ignore)
Tells RingBuffer whether to ignore the end-of-file.
QReadWriteLock m_rbwLock
int ReadDirect(void *Buffer, int Count, bool Peek)
int Peek(void *Buffer, int Count)
long long m_ignoreReadPos
bool WriterSetBlocking(bool Lock=true)
Calls ThreadedFileWriter::SetBlocking(bool)
virtual void IgnoreWaitStates(bool)
virtual bool IsInStillFrame(void) const
QString GetSafeFilename(void)
QString GetLastError(void) const
bool WaitForReadsAllowed(void)
QReadWriteLock m_rbrLock
bool IsDisc(void) const
void SetBufferSizeFactors(bool EstBitrate, bool Matroska)
Tells RingBuffer that the raw bitrate may be inaccurate and the underlying container is matroska,...
MythMediaBuffer(MythBufferType Type)
void EnableBitrateMonitor(bool Enable)
virtual bool IsInMenu(void) const
MythBufferType m_type
LiveTVChain * m_liveTVChain
virtual bool HandleAction(const QStringList &, mpeg::chrono::pts)
void SetOldFile(bool Old)
Tell RingBuffer if this is an old file or not.
virtual bool OpenFile(const QString &Filename, std::chrono::milliseconds Retry=kDefaultOpenTimeout)=0
int ReadBufFree(void) const
Returns number of bytes available for reading into buffer.
uint64_t UpdateDecoderRate(uint64_t Latest=0)
int ReadPriv(void *Buffer, int Count, bool Peek)
When possible reads from the read-ahead buffer, otherwise reads directly from the device.
virtual bool IsBookmarkAllowed(void)
void Pause(void)
Pauses the read-ahead thread.
volatile bool m_recentSeek
void Start(void)
Starts the read-ahead thread.
void WaitForPause(void)
Waits for Pause(void) to take effect.
virtual bool IsStreamed(void)
virtual bool ReOpen(const QString &="")
QString m_subtitleFilename
volatile bool m_stopReads
uint GetBufferSize(void) const
void WriterFlush(void)
Calls ThreadedFileWriter::Flush(void)
uint64_t UpdateStorageRate(uint64_t Latest=0)
bool IsDVD(void) const
int ReadBufAvail(void) const
Returns number of bytes available for reading from buffer.
QString GetAvailableBuffer(void)
bool IsIOBound(void) const
virtual int BestBufferSize(void)
long long m_readAdjust
virtual bool StartFromBeginning(void)
int Read(void *Buffer, int Count)
This is the public method for reading from a file, it calls the appropriate read method if the file i...
QString GetDecoderRate(void)
bool PauseAndWait(void)
int WaitForAvail(int Count, std::chrono::milliseconds Timeout)
virtual bool IsOpen(void) const =0
void Sync(void)
Calls ThreadedFileWriter::Sync(void)
void UpdatePlaySpeed(float PlaySpeed)
Set the play speed, to allow RingBuffer adjust effective bitrate.
bool SetReadInternalMode(bool Mode)
static MythMediaBuffer * Create(const QString &Filename, bool Write, bool UseReadAhead=true, std::chrono::milliseconds Timeout=kDefaultOpenTimeout, bool StreamOnly=false)
Creates a RingBuffer instance.
ThreadedFileWriter * m_tfw
RemoteFile * m_remotefile
void SetWaitForWrite(void)
QReadWriteLock m_posLock
long long Seek(long long Position, int Whence, bool HasLock=false)
virtual bool IsSeekingAllowed(void)
QMap< std::chrono::milliseconds, uint64_t > m_decoderReads
long long WriterSeek(long long Position, int Whence, bool HasLock=false)
Calls ThreadedFileWriter::Seek(long long,int).
static QString BitrateToString(uint64_t Rate, bool Hz=false)
const MythDVDBuffer * DVD(void) const
bool GetStopReads(void) const
long long SetAdjustFilesize(void)
int Write(const void *Buffer, uint Count)
Writes buffer to ThreadedFileWriter::Write(const void*,uint)
virtual bool IsInDiscMenuOrStillFrame(void) const
const MythBDBuffer * BD(void) const
void CreateReadAheadBuffer(void)
void Unpause(void)
Unpauses the read-ahead thread.
virtual long long GetReadPosition(void) const =0
~MythMediaBuffer() override=0
Deletes.
virtual long long SeekInternal(long long Position, int Whence)=0
static void AVFormatInitNetwork(void)
int GetReadBufAvail(void) const
Returns number of bytes available for reading from buffer.
QString GetSubtitleFilename(void) const
bool IsBD(void) const
long long m_writePos
QMap< std::chrono::milliseconds, uint64_t > m_storageReads
QReadWriteLock m_rwLock
static constexpr std::chrono::milliseconds kDefaultOpenTimeout
bool IsReadInternalMode(void) const
bool IsNearEnd(double Framerate, uint Frames) const
static constexpr std::chrono::milliseconds kLiveTVOpenTimeout
void ResetReadAhead(long long NewInternal)
Restart the read-ahead thread at the 'newinternal' position.
virtual int SafeRead(void *Buffer, uint Size)=0
bool LiveMode(void) const
Returns true if this RingBuffer has been assigned a LiveTVChain.
void CalcReadAheadThresh(void)
Calculates m_fillMin, m_fillThreshold, and m_readBlockSize from the estimated effective bitrate of th...
QString GetFilename(void) const
QWaitCondition m_generalWait
Condition to signal that the read ahead thread is running.
This class supports the writing of recordings to disk.
unsigned int uint
Definition: freesurround.h:24
static QString seek2string(int Whence)
MythBufferType
@ kMythBufferFile
@ kMythBufferDVD
@ kMythBufferBD
@ kMythBufferUnknown
@ kMythBufferHTTP
@ kMythBufferMHEG
@ kMythBufferHLS
static constexpr int32_t DEFAULT_CHUNK_SIZE
static constexpr uint32_t BUFFER_SIZE_MINIMUM
static constexpr uint8_t BUFFER_FACTOR_MATROSKA
static constexpr uint8_t BUFFER_FACTOR_BITRATE
static constexpr qint64 kReadTestSize
static constexpr uint8_t BUFFER_FACTOR_NETWORK
#define MTV_PUBLIC
Definition: mythtvexp.h:15
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
Mode
Definition: synaesthesia.h:23