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 "libmythbase/mthread.h"
15 #include "libmythbase/mythtimer.h"
16 
17 #include "mpeg/tspacket.h"
18 
20 {
21  protected:
22  virtual ~DeviceReaderCB() = default;
23  public:
24  virtual void ReaderPaused(int fd) = 0;
25  virtual void PriorityEvent(int fd) = 0;
26 };
27 
35 class DeviceReadBuffer : protected MThread
36 {
37  public:
38  explicit DeviceReadBuffer(DeviceReaderCB *cb,
39  bool use_poll = true,
40  bool error_exit_on_poll_timeout = true);
41  ~DeviceReadBuffer() override;
42 
43  bool Setup(const QString &streamName,
44  int streamfd,
45  uint readQuanta = sizeof(TSPacket),
46  uint deviceBufferSize = 0,
47  uint deviceBufferCount = 1);
48 
49  void Start(void);
50  void Reset(const QString &streamName, int streamfd);
51  void Stop(void);
52 
53  void SetRequestPause(bool request);
54  bool IsPaused(void) const;
55  bool WaitForUnpause(unsigned long timeout);
56  bool WaitForPaused(unsigned long timeout);
57 
58  bool IsErrored(void) const;
59  bool IsEOF(void) const;
60  bool IsRunning(void) const;
61 
62  uint Read(unsigned char *buf, uint count);
63  uint GetUsed(void) const;
64 
65  private:
66  void run(void) override; // MThread
67 
68  void SetPaused(bool val);
69  void IncrWritePointer(uint len);
70  void IncrReadPointer(uint len);
71 
72  bool HandlePausing(void);
73  bool Poll(void) const;
74  void WakePoll(void) const;
75  uint WaitForUnused(uint needed) const;
76  uint WaitForUsed (uint needed, std::chrono::milliseconds max_wait) const;
77 
78  bool IsPauseRequested(void) const;
79  bool IsOpen(void) const { return m_streamFd >= 0; }
80  void ClosePipes(void) const;
81  uint GetUnused(void) const;
82  uint GetContiguousUnused(void) const;
83 
84  bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt);
85  void ReportStats(void);
86 
87  QString m_videoDevice;
88  int m_streamFd {-1};
89  mutable pipe_fd_array m_wakePipe {-1,-1};
91 
93 
94  // Data for managing the device ringbuffer
95  mutable QMutex m_lock;
96  volatile bool m_doRun {false};
97  bool m_eof {false};
98  mutable bool m_error {false};
99  bool m_requestPause {false};
100  bool m_paused {false};
101  bool m_usingPoll {true};
102  bool m_pollTimeoutIsError {true};
103  std::chrono::milliseconds m_maxPollWait {2500ms};
104 
105  size_t m_size {0};
106  size_t m_used {0};
107  size_t m_readQuanta {0};
108  size_t m_devBufferCount {1};
109  size_t m_devReadSize {0};
110  size_t m_readThreshold {0};
111  unsigned char *m_buffer {nullptr};
112  unsigned char *m_readPtr {nullptr};
113  unsigned char *m_writePtr {nullptr};
114  unsigned char *m_endPtr {nullptr};
115 
116  mutable QWaitCondition m_dataWait;
117  QWaitCondition m_runWait;
118  QWaitCondition m_pauseWait;
119  QWaitCondition m_unpauseWait;
120 
121  // statistics
122  size_t m_maxUsed {0};
123  size_t m_avgUsed {0};
124  size_t m_avgBufWriteCnt {0};
125  size_t m_avgBufReadCnt {0};
126  size_t m_avgBufSleepCnt {0};
128 };
129 
130 #endif // DEVICEREADBUFFER_H
131 
132 /*
133  * vim:ts=4:sw=4:ai:et:si:sts=4
134  */
DeviceReadBuffer::m_streamFd
int m_streamFd
Definition: DeviceReadBuffer.h:88
DeviceReadBuffer::m_devReadSize
size_t m_devReadSize
Definition: DeviceReadBuffer.h:109
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
DeviceReadBuffer::m_readPtr
unsigned char * m_readPtr
Definition: DeviceReadBuffer.h:112
DeviceReadBuffer::m_pauseWait
QWaitCondition m_pauseWait
Definition: DeviceReadBuffer.h:118
DeviceReadBuffer::m_maxUsed
size_t m_maxUsed
Definition: DeviceReadBuffer.h:122
DeviceReadBuffer::Start
void Start(void)
Definition: DeviceReadBuffer.cpp:106
DeviceReadBuffer::m_used
size_t m_used
Definition: DeviceReadBuffer.h:106
DeviceReadBuffer::WakePoll
void WakePoll(void) const
Definition: DeviceReadBuffer.cpp:181
DeviceReadBuffer::Setup
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
Definition: DeviceReadBuffer.cpp:49
DeviceReaderCB::~DeviceReaderCB
virtual ~DeviceReaderCB()=default
DeviceReadBuffer::m_wakePipeFlags
pipe_flag_array m_wakePipeFlags
Definition: DeviceReadBuffer.h:90
DeviceReadBuffer::m_devBufferCount
size_t m_devBufferCount
Definition: DeviceReadBuffer.h:108
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:210
DeviceReadBuffer::WaitForPaused
bool WaitForPaused(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:216
DeviceReadBuffer::m_runWait
QWaitCondition m_runWait
Definition: DeviceReadBuffer.h:117
DeviceReadBuffer::WaitForUsed
uint WaitForUsed(uint needed, std::chrono::milliseconds max_wait) const
Definition: DeviceReadBuffer.cpp:684
DeviceReadBuffer::Read
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
Definition: DeviceReadBuffer.cpp:616
DeviceReadBuffer::m_avgBufWriteCnt
size_t m_avgBufWriteCnt
Definition: DeviceReadBuffer.h:124
DeviceReadBuffer::m_wakePipe
pipe_fd_array m_wakePipe
Definition: DeviceReadBuffer.h:89
DeviceReadBuffer::IsPauseRequested
bool IsPauseRequested(void) const
Definition: DeviceReadBuffer.cpp:236
DeviceReadBuffer
Buffers reads from device files.
Definition: DeviceReadBuffer.h:35
DeviceReadBuffer::WaitForUnpause
bool WaitForUnpause(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:226
DeviceReaderCB
Definition: DeviceReadBuffer.h:19
DeviceReadBuffer::GetContiguousUnused
uint GetContiguousUnused(void) const
Definition: DeviceReadBuffer.cpp:272
DeviceReadBuffer::m_requestPause
bool m_requestPause
Definition: DeviceReadBuffer.h:99
DeviceReaderCB::ReaderPaused
virtual void ReaderPaused(int fd)=0
DeviceReadBuffer::m_eof
bool m_eof
Definition: DeviceReadBuffer.h:97
DeviceReadBuffer::WaitForUnused
uint WaitForUnused(uint needed) const
Definition: DeviceReadBuffer.cpp:658
DeviceReadBuffer::CheckForErrors
bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt)
Definition: DeviceReadBuffer.cpp:535
DeviceReadBuffer::m_pollTimeoutIsError
bool m_pollTimeoutIsError
Definition: DeviceReadBuffer.h:102
DeviceReadBuffer::m_doRun
volatile bool m_doRun
Definition: DeviceReadBuffer.h:96
DeviceReadBuffer::m_readerCB
DeviceReaderCB * m_readerCB
Definition: DeviceReadBuffer.h:92
DeviceReadBuffer::m_readQuanta
size_t m_readQuanta
Definition: DeviceReadBuffer.h:107
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:171
DeviceReadBuffer::m_videoDevice
QString m_videoDevice
Definition: DeviceReadBuffer.h:87
DeviceReadBuffer::IsRunning
bool IsRunning(void) const
Definition: DeviceReadBuffer.cpp:254
DeviceReadBuffer::m_usingPoll
bool m_usingPoll
Definition: DeviceReadBuffer.h:101
tspacket.h
DeviceReadBuffer::m_buffer
unsigned char * m_buffer
Definition: DeviceReadBuffer.h:111
DeviceReadBuffer::IsOpen
bool IsOpen(void) const
Definition: DeviceReadBuffer.h:79
DeviceReadBuffer::Stop
void Stop(void)
Definition: DeviceReadBuffer.cpp:149
DeviceReadBuffer::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: DeviceReadBuffer.h:119
pipe_flag_array
std::array< long, 2 > pipe_flag_array
Definition: mythbaseutil.h:17
DeviceReadBuffer::m_readThreshold
size_t m_readThreshold
Definition: DeviceReadBuffer.h:110
uint
unsigned int uint
Definition: compat.h:79
DeviceReadBuffer::ClosePipes
void ClosePipes(void) const
Definition: DeviceReadBuffer.cpp:197
DeviceReaderCB::PriorityEvent
virtual void PriorityEvent(int fd)=0
DeviceReadBuffer::m_lock
QMutex m_lock
Definition: DeviceReadBuffer.h:95
DeviceReadBuffer::m_size
size_t m_size
Definition: DeviceReadBuffer.h:105
mythbaseutil.h
DeviceReadBuffer::m_avgUsed
size_t m_avgUsed
Definition: DeviceReadBuffer.h:123
DeviceReadBuffer::GetUnused
uint GetUnused(void) const
Definition: DeviceReadBuffer.cpp:260
DeviceReadBuffer::~DeviceReadBuffer
~DeviceReadBuffer() override
Definition: DeviceReadBuffer.cpp:39
DeviceReadBuffer::ReportStats
void ReportStats(void)
Definition: DeviceReadBuffer.cpp:701
DeviceReadBuffer::SetPaused
void SetPaused(bool val)
Definition: DeviceReadBuffer.cpp:170
DeviceReadBuffer::m_maxPollWait
std::chrono::milliseconds m_maxPollWait
Definition: DeviceReadBuffer.h:103
DeviceReadBuffer::m_writePtr
unsigned char * m_writePtr
Definition: DeviceReadBuffer.h:113
DeviceReadBuffer::Poll
bool Poll(void) const
Definition: DeviceReadBuffer.cpp:409
DeviceReadBuffer::HandlePausing
bool HandlePausing(void)
Definition: DeviceReadBuffer.cpp:389
DeviceReadBuffer::DeviceReadBuffer
DeviceReadBuffer(DeviceReaderCB *cb, bool use_poll=true, bool error_exit_on_poll_timeout=true)
Definition: DeviceReadBuffer.cpp:21
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:126
mthread.h
DeviceReadBuffer::m_error
bool m_error
Definition: DeviceReadBuffer.h:98
DeviceReadBuffer::IsErrored
bool IsErrored(void) const
Definition: DeviceReadBuffer.cpp:242
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:303
DeviceReadBuffer::IncrWritePointer
void IncrWritePointer(uint len)
Definition: DeviceReadBuffer.cpp:278
mythtimer.h
DeviceReadBuffer::m_avgBufReadCnt
size_t m_avgBufReadCnt
Definition: DeviceReadBuffer.h:125
DeviceReadBuffer::IsEOF
bool IsEOF(void) const
Definition: DeviceReadBuffer.cpp:248
DeviceReadBuffer::m_paused
bool m_paused
Definition: DeviceReadBuffer.h:100
DeviceReadBuffer::SetRequestPause
void SetRequestPause(bool request)
Definition: DeviceReadBuffer.cpp:163
DeviceReadBuffer::m_dataWait
QWaitCondition m_dataWait
Definition: DeviceReadBuffer.h:116
pipe_fd_array
std::array< int, 2 > pipe_fd_array
Definition: mythbaseutil.h:16
DeviceReadBuffer::m_lastReport
MythTimer m_lastReport
Definition: DeviceReadBuffer.h:127
DeviceReadBuffer::IncrReadPointer
void IncrReadPointer(uint len)
Definition: DeviceReadBuffer.cpp:292
DeviceReadBuffer::m_endPtr
unsigned char * m_endPtr
Definition: DeviceReadBuffer.h:114
DeviceReadBuffer::Reset
void Reset(const QString &streamName, int streamfd)
Definition: DeviceReadBuffer.cpp:134
DeviceReadBuffer::GetUsed
uint GetUsed(void) const
Definition: DeviceReadBuffer.cpp:266