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 "libmythtv/mythtvexp.h"
13#include "libmythbase/mthread.h"
15
16// FFmpeg
17extern "C" {
18#include "libavcodec/avcodec.h"
19}
20
21// Size of PNG header plus one empty chunk
22static constexpr qint64 kReadTestSize { 20 };
23
24// about one second at 35Mb
25static constexpr uint32_t BUFFER_SIZE_MINIMUM { 4 * 1024 * 1024 };
26static constexpr uint8_t BUFFER_FACTOR_NETWORK { 2 };
27static constexpr uint8_t BUFFER_FACTOR_BITRATE { 2 };
28static constexpr uint8_t BUFFER_FACTOR_MATROSKA { 2 };
29
30static constexpr int32_t DEFAULT_CHUNK_SIZE { 32768 };
31
32static inline QString seek2string(int Whence)
33{
34 if (SEEK_SET == Whence)
35 return "SEEK_SET";
36 if (SEEK_CUR == Whence)
37 return "SEEK_CUR";
38 return "SEEK_END";
39}
40
42class MythDVDBuffer;
43class MythBDBuffer;
44class LiveTVChain;
45class RemoteFile;
46
47enum MythBufferType : std::uint8_t
48{
56};
57
59{
61
62 public:
63 static MythMediaBuffer *Create(const QString &Filename, bool Write,
64 bool UseReadAhead = true,
65 std::chrono::milliseconds Timeout = kDefaultOpenTimeout,
66 bool StreamOnly = false);
67 ~MythMediaBuffer() override = 0;
68 MythBufferType GetType() const;
69
70 static constexpr std::chrono::milliseconds kDefaultOpenTimeout { 2s };
71 static constexpr std::chrono::milliseconds kLiveTVOpenTimeout { 10s };
72 static QString BitrateToString (uint64_t Rate, bool Hz = false);
73 static void AVFormatInitNetwork (void);
74
75 void SetOldFile (bool Old);
76 void UpdateRawBitrate (uint RawBitrate);
77 void UpdatePlaySpeed (float PlaySpeed);
78 void EnableBitrateMonitor (bool Enable);
79 void SetBufferSizeFactors (bool EstBitrate, bool Matroska);
80 void SetWaitForWrite (void);
81 QString GetSafeFilename (void);
82 QString GetFilename (void) const;
83 QString GetSubtitleFilename (void) const;
84 QString GetLastError (void) const;
85 bool GetCommsError (void) const;
86 void ResetCommsError (void);
87 bool GetStopReads (void) const;
88 QString GetDecoderRate (void);
89 QString GetStorageRate (void);
90 QString GetAvailableBuffer (void);
91 uint GetBufferSize (void) const;
92 bool IsNearEnd (double Framerate, uint Frames) const;
93 long long GetWritePosition (void) const;
94 long long GetRealFileSize (void) const;
95 bool IsDisc (void) const;
96 bool IsDVD (void) const;
97 bool IsBD (void) const;
98 const MythDVDBuffer *DVD (void) const;
99 MythDVDBuffer *DVD (void);
100 const MythBDBuffer *BD (void) const;
101 MythBDBuffer *BD (void);
102 int Read (void *Buffer, int Count);
103 int Peek (void *Buffer, int Count);
104 int Peek (std::vector<char>& Buffer);
105 void Reset (bool Full = false, bool ToAdjust = false, bool ResetInternal = false);
106 void Pause (void);
107 void Unpause (void);
108 void WaitForPause (void);
109 void Start (void);
110 void StopReads (void);
111 void StartReads (void);
112 long long Seek (long long Position, int Whence, bool HasLock = false);
113 long long SetAdjustFilesize (void);
114
115 // LiveTV used utilities
116 int GetReadBufAvail (void) const;
117 bool SetReadInternalMode (bool Mode);
118 bool IsReadInternalMode (void) const;
119 bool LiveMode (void) const;
120 void SetLiveMode (LiveTVChain *Chain);
121 void IgnoreLiveEOF (bool Ignore);
122
123 // ThreadedFileWriter proxies
124 int Write (const void *Buffer, uint Count);
125 bool IsIOBound (void) const;
126 void WriterFlush (void);
127 void Sync (void);
128 long long WriterSeek (long long Position, int Whence, bool HasLock = false);
129 bool WriterSetBlocking (bool Lock = true);
130
131 virtual long long GetReadPosition (void) const = 0;
132 virtual bool IsOpen (void) const = 0;
133 virtual bool IsStreamed (void) { return LiveMode(); }
134 virtual bool IsSeekingAllowed (void) { return true; }
135 virtual bool IsBookmarkAllowed (void) { return true; }
136 virtual int BestBufferSize (void) { return DEFAULT_CHUNK_SIZE; }
137 virtual bool StartFromBeginning(void) { return true; }
138 virtual void IgnoreWaitStates (bool /*Ignore*/) { }
139 virtual bool IsInMenu (void) const { return false; }
140 virtual bool IsInStillFrame (void) const { return false; }
141 virtual bool IsInDiscMenuOrStillFrame(void) const { return IsInMenu() || IsInStillFrame(); }
142 virtual bool HandleAction (const QStringList &/*Action*/, mpeg::chrono::pts /*Pts*/) { return false; }
143 virtual bool OpenFile (const QString &Filename, std::chrono::milliseconds Retry = kDefaultOpenTimeout) = 0;
144 virtual bool ReOpen (const QString& /*Filename*/ = "") { return false; }
145
146 protected:
147 explicit MythMediaBuffer(MythBufferType Type);
148
149 void run(void) override;
150 void CreateReadAheadBuffer (void);
151 void CalcReadAheadThresh (void);
152 bool PauseAndWait (void);
153 int ReadPriv (void *Buffer, int Count, bool Peek);
154 int ReadDirect (void *Buffer, int Count, bool Peek);
155 bool WaitForReadsAllowed (void);
156 int WaitForAvail (int Count, std::chrono::milliseconds Timeout);
157 int ReadBufFree (void) const;
158 int ReadBufAvail (void) const;
159 void ResetReadAhead (long long NewInternal);
160 void KillReadAheadThread (void);
161 uint64_t UpdateDecoderRate (uint64_t Latest = 0);
162 uint64_t UpdateStorageRate (uint64_t Latest = 0);
163
164 virtual int SafeRead (void *Buffer, uint Size) = 0;
165 virtual long long GetRealFileSizeInternal(void) const { return -1; }
166 virtual long long SeekInternal (long long Position, int Whence) = 0;
167
168
169 protected:
171
172 mutable QReadWriteLock m_posLock;
173 long long m_readPos { 0 };
174 long long m_writePos { 0 };
175 long long m_internalReadPos { 0 };
176 long long m_ignoreReadPos { -1 };
177
178 mutable QReadWriteLock m_rbrLock;
179 int m_rbrPos { 0 };
180
181 mutable QReadWriteLock m_rbwLock;
182 int m_rbwPos { 0 };
183
184 // note should not go under rwLock..
185 // this is used to break out of read_safe where rwLock is held
186 volatile bool m_stopReads {false};
187
188 // unprotected (for debugging)
190
191 mutable QReadWriteLock m_rwLock;
192 QString m_filename;
194 QString m_lastError;
196 int m_fd2 { -1 };
197 bool m_writeMode { false };
200 bool m_lowBuffers { false };
201 bool m_fileIsMatroska { false };
202 bool m_unknownBitrate { false };
203 bool m_startReadAhead { false };
204 char *m_readAheadBuffer { nullptr };
205 bool m_readAheadRunning { false };
206 bool m_reallyRunning { false };
207 bool m_requestPause { false };
208 bool m_paused { false };
209 bool m_ateof { false };
210 bool m_waitForWrite { false };
211 bool m_beingWritten { false };
212 bool m_readsAllowed { false };
213 bool m_readsDesired { false };
214 volatile bool m_recentSeek { true }; // not protected by rwLock
215 bool m_setSwitchToNext { false };
217 float m_playSpeed { 1.0F };
218 int m_fillThreshold { 65536 };
219 int m_fillMin { -1 };
221 int m_wantToRead { 0 };
222 int m_numFailures { 0 }; // (see note 1)
223 bool m_commsError { false };
224 bool m_oldfile { false };
226 bool m_ignoreLiveEOF { false };
227 long long m_readAdjust { 0 };
228 int m_readOffset { 0 };
229 bool m_readInternalMode { false };
230 // End of section protected by rwLock
231
234 QMap<std::chrono::milliseconds, uint64_t> m_decoderReads;
236 QMap<std::chrono::milliseconds, uint64_t> m_storageReads;
237
238 // note 1: numfailures is modified with only a read lock in the
239 // read ahead thread, but this is safe since all other places
240 // that use it are protected by a write lock. But this is a
241 // fragile state of affairs and care must be taken when modifying
242 // code or locking around this variable.
243
245 QWaitCondition m_generalWait; // protected by rwLock
246
247 private:
248 bool m_bitrateInitialized { false };
249};
250#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:313
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: compat.h:60
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:8
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
Mode
Definition: synaesthesia.h:20