MythTV  master
DeviceReadBuffer.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 /* Device Buffer written by John Poet */
3 
4 #ifndef DEVICEREADBUFFER_H
5 #define DEVICEREADBUFFER_H
6 
7 #include <unistd.h>
8 
9 #include <QMutex>
10 #include <QWaitCondition>
11 #include <QString>
12 
13 #include "mythbaseutil.h"
14 #include "mythtimer.h"
15 #include "tspacket.h"
16 #include "mthread.h"
17 
19 {
20  protected:
21  virtual ~DeviceReaderCB() = default;
22  public:
23  virtual void ReaderPaused(int fd) = 0;
24  virtual void PriorityEvent(int fd) = 0;
25 };
26 
34 class DeviceReadBuffer : protected MThread
35 {
36  public:
37  explicit DeviceReadBuffer(DeviceReaderCB *cb,
38  bool use_poll = true,
39  bool error_exit_on_poll_timeout = true);
40  ~DeviceReadBuffer() override;
41 
42  bool Setup(const QString &streamName,
43  int streamfd,
44  uint readQuanta = sizeof(TSPacket),
45  uint deviceBufferSize = 0,
46  uint deviceBufferCount = 1);
47 
48  void Start(void);
49  void Reset(const QString &streamName, int streamfd);
50  void Stop(void);
51 
52  void SetRequestPause(bool request);
53  bool IsPaused(void) const;
54  bool WaitForUnpause(unsigned long timeout);
55  bool WaitForPaused(unsigned long timeout);
56 
57  bool IsErrored(void) const;
58  bool IsEOF(void) const;
59  bool IsRunning(void) const;
60 
61  uint Read(unsigned char *buf, uint count);
62  uint GetUsed(void) const;
63 
64  private:
65  void run(void) override; // MThread
66 
67  void SetPaused(bool val);
68  void IncrWritePointer(uint len);
69  void IncrReadPointer(uint len);
70 
71  bool HandlePausing(void);
72  bool Poll(void) const;
73  void WakePoll(void) const;
74  uint WaitForUnused(uint needed) const;
75  uint WaitForUsed (uint needed, std::chrono::milliseconds max_wait) const;
76 
77  bool IsPauseRequested(void) const;
78  bool IsOpen(void) const { return m_streamFd >= 0; }
79  void ClosePipes(void) const;
80  uint GetUnused(void) const;
81  uint GetContiguousUnused(void) const;
82 
83  bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt);
84  void ReportStats(void);
85 
86  QString m_videoDevice;
87  int m_streamFd {-1};
88  mutable pipe_fd_array m_wakePipe {-1,-1};
90 
92 
93  // Data for managing the device ringbuffer
94  mutable QMutex m_lock;
95  volatile bool m_doRun {false};
96  bool m_eof {false};
97  mutable bool m_error {false};
98  bool m_requestPause {false};
99  bool m_paused {false};
100  bool m_usingPoll {true};
101  bool m_pollTimeoutIsError {true};
102  std::chrono::milliseconds m_maxPollWait {2500ms};
103 
104  size_t m_size {0};
105  size_t m_used {0};
106  size_t m_readQuanta {0};
107  size_t m_devBufferCount {1};
108  size_t m_devReadSize {0};
109  size_t m_readThreshold {0};
110  unsigned char *m_buffer {nullptr};
111  unsigned char *m_readPtr {nullptr};
112  unsigned char *m_writePtr {nullptr};
113  unsigned char *m_endPtr {nullptr};
114 
115  mutable QWaitCondition m_dataWait;
116  QWaitCondition m_runWait;
117  QWaitCondition m_pauseWait;
118  QWaitCondition m_unpauseWait;
119 
120  // statistics
121  size_t m_maxUsed {0};
122  size_t m_avgUsed {0};
123  size_t m_avgBufWriteCnt {0};
124  size_t m_avgBufReadCnt {0};
125  size_t m_avgBufSleepCnt {0};
127 };
128 
129 #endif // DEVICEREADBUFFER_H
130 
131 /*
132  * vim:ts=4:sw=4:ai:et:si:sts=4
133  */
DeviceReadBuffer::m_streamFd
int m_streamFd
Definition: DeviceReadBuffer.h:87
DeviceReadBuffer::m_devReadSize
size_t m_devReadSize
Definition: DeviceReadBuffer.h:108
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
DeviceReadBuffer::m_readPtr
unsigned char * m_readPtr
Definition: DeviceReadBuffer.h:111
DeviceReadBuffer::m_pauseWait
QWaitCondition m_pauseWait
Definition: DeviceReadBuffer.h:117
DeviceReadBuffer::m_maxUsed
size_t m_maxUsed
Definition: DeviceReadBuffer.h:121
DeviceReadBuffer::Start
void Start(void)
Definition: DeviceReadBuffer.cpp:104
DeviceReadBuffer::m_used
size_t m_used
Definition: DeviceReadBuffer.h:105
DeviceReadBuffer::WakePoll
void WakePoll(void) const
Definition: DeviceReadBuffer.cpp:179
DeviceReadBuffer::Setup
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
Definition: DeviceReadBuffer.cpp:47
DeviceReaderCB::~DeviceReaderCB
virtual ~DeviceReaderCB()=default
DeviceReadBuffer::m_wakePipeFlags
pipe_flag_array m_wakePipeFlags
Definition: DeviceReadBuffer.h:89
DeviceReadBuffer::m_devBufferCount
size_t m_devBufferCount
Definition: DeviceReadBuffer.h:107
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
DeviceReadBuffer::IsPaused
bool IsPaused(void) const
Definition: DeviceReadBuffer.cpp:208
DeviceReadBuffer::WaitForPaused
bool WaitForPaused(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:214
DeviceReadBuffer::m_runWait
QWaitCondition m_runWait
Definition: DeviceReadBuffer.h:116
DeviceReadBuffer::WaitForUsed
uint WaitForUsed(uint needed, std::chrono::milliseconds max_wait) const
Definition: DeviceReadBuffer.cpp:682
DeviceReadBuffer::Read
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
Definition: DeviceReadBuffer.cpp:614
DeviceReadBuffer::m_avgBufWriteCnt
size_t m_avgBufWriteCnt
Definition: DeviceReadBuffer.h:123
DeviceReadBuffer::m_wakePipe
pipe_fd_array m_wakePipe
Definition: DeviceReadBuffer.h:88
DeviceReadBuffer::IsPauseRequested
bool IsPauseRequested(void) const
Definition: DeviceReadBuffer.cpp:234
DeviceReadBuffer
Buffers reads from device files.
Definition: DeviceReadBuffer.h:34
DeviceReadBuffer::WaitForUnpause
bool WaitForUnpause(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:224
DeviceReaderCB
Definition: DeviceReadBuffer.h:18
DeviceReadBuffer::GetContiguousUnused
uint GetContiguousUnused(void) const
Definition: DeviceReadBuffer.cpp:270
DeviceReadBuffer::m_requestPause
bool m_requestPause
Definition: DeviceReadBuffer.h:98
DeviceReaderCB::ReaderPaused
virtual void ReaderPaused(int fd)=0
DeviceReadBuffer::m_eof
bool m_eof
Definition: DeviceReadBuffer.h:96
DeviceReadBuffer::WaitForUnused
uint WaitForUnused(uint needed) const
Definition: DeviceReadBuffer.cpp:656
DeviceReadBuffer::CheckForErrors
bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt)
Definition: DeviceReadBuffer.cpp:533
DeviceReadBuffer::m_pollTimeoutIsError
bool m_pollTimeoutIsError
Definition: DeviceReadBuffer.h:101
DeviceReadBuffer::m_doRun
volatile bool m_doRun
Definition: DeviceReadBuffer.h:95
DeviceReadBuffer::m_readerCB
DeviceReaderCB * m_readerCB
Definition: DeviceReadBuffer.h:91
DeviceReadBuffer::m_readQuanta
size_t m_readQuanta
Definition: DeviceReadBuffer.h:106
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:169
DeviceReadBuffer::m_videoDevice
QString m_videoDevice
Definition: DeviceReadBuffer.h:86
DeviceReadBuffer::IsRunning
bool IsRunning(void) const
Definition: DeviceReadBuffer.cpp:252
DeviceReadBuffer::m_usingPoll
bool m_usingPoll
Definition: DeviceReadBuffer.h:100
tspacket.h
DeviceReadBuffer::m_buffer
unsigned char * m_buffer
Definition: DeviceReadBuffer.h:110
DeviceReadBuffer::IsOpen
bool IsOpen(void) const
Definition: DeviceReadBuffer.h:78
DeviceReadBuffer::Stop
void Stop(void)
Definition: DeviceReadBuffer.cpp:147
DeviceReadBuffer::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: DeviceReadBuffer.h:118
pipe_flag_array
std::array< long, 2 > pipe_flag_array
Definition: mythbaseutil.h:17
DeviceReadBuffer::m_readThreshold
size_t m_readThreshold
Definition: DeviceReadBuffer.h:109
uint
unsigned int uint
Definition: compat.h:144
DeviceReadBuffer::ClosePipes
void ClosePipes(void) const
Definition: DeviceReadBuffer.cpp:195
DeviceReaderCB::PriorityEvent
virtual void PriorityEvent(int fd)=0
DeviceReadBuffer::m_lock
QMutex m_lock
Definition: DeviceReadBuffer.h:94
DeviceReadBuffer::m_size
size_t m_size
Definition: DeviceReadBuffer.h:104
mythbaseutil.h
DeviceReadBuffer::m_avgUsed
size_t m_avgUsed
Definition: DeviceReadBuffer.h:122
DeviceReadBuffer::GetUnused
uint GetUnused(void) const
Definition: DeviceReadBuffer.cpp:258
DeviceReadBuffer::~DeviceReadBuffer
~DeviceReadBuffer() override
Definition: DeviceReadBuffer.cpp:37
DeviceReadBuffer::ReportStats
void ReportStats(void)
Definition: DeviceReadBuffer.cpp:699
DeviceReadBuffer::SetPaused
void SetPaused(bool val)
Definition: DeviceReadBuffer.cpp:168
DeviceReadBuffer::m_maxPollWait
std::chrono::milliseconds m_maxPollWait
Definition: DeviceReadBuffer.h:102
DeviceReadBuffer::m_writePtr
unsigned char * m_writePtr
Definition: DeviceReadBuffer.h:112
DeviceReadBuffer::Poll
bool Poll(void) const
Definition: DeviceReadBuffer.cpp:407
DeviceReadBuffer::HandlePausing
bool HandlePausing(void)
Definition: DeviceReadBuffer.cpp:387
DeviceReadBuffer::DeviceReadBuffer
DeviceReadBuffer(DeviceReaderCB *cb, bool use_poll=true, bool error_exit_on_poll_timeout=true)
Definition: DeviceReadBuffer.cpp:19
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:48
DeviceReadBuffer::m_avgBufSleepCnt
size_t m_avgBufSleepCnt
Definition: DeviceReadBuffer.h:125
mthread.h
DeviceReadBuffer::m_error
bool m_error
Definition: DeviceReadBuffer.h:97
DeviceReadBuffer::IsErrored
bool IsErrored(void) const
Definition: DeviceReadBuffer.cpp:240
DeviceReadBuffer::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: DeviceReadBuffer.cpp:301
DeviceReadBuffer::IncrWritePointer
void IncrWritePointer(uint len)
Definition: DeviceReadBuffer.cpp:276
mythtimer.h
DeviceReadBuffer::m_avgBufReadCnt
size_t m_avgBufReadCnt
Definition: DeviceReadBuffer.h:124
DeviceReadBuffer::IsEOF
bool IsEOF(void) const
Definition: DeviceReadBuffer.cpp:246
DeviceReadBuffer::m_paused
bool m_paused
Definition: DeviceReadBuffer.h:99
DeviceReadBuffer::SetRequestPause
void SetRequestPause(bool request)
Definition: DeviceReadBuffer.cpp:161
DeviceReadBuffer::m_dataWait
QWaitCondition m_dataWait
Definition: DeviceReadBuffer.h:115
pipe_fd_array
std::array< int, 2 > pipe_fd_array
Definition: mythbaseutil.h:16
DeviceReadBuffer::m_lastReport
MythTimer m_lastReport
Definition: DeviceReadBuffer.h:126
DeviceReadBuffer::IncrReadPointer
void IncrReadPointer(uint len)
Definition: DeviceReadBuffer.cpp:290
DeviceReadBuffer::m_endPtr
unsigned char * m_endPtr
Definition: DeviceReadBuffer.h:113
DeviceReadBuffer::Reset
void Reset(const QString &streamName, int streamfd)
Definition: DeviceReadBuffer.cpp:132
DeviceReadBuffer::GetUsed
uint GetUsed(void) const
Definition: DeviceReadBuffer.cpp:264