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 <array>
8 #include <unistd.h>
9 
10 #include <QMutex>
11 #include <QWaitCondition>
12 #include <QString>
13 
14 #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  using pipe_fd_array = std::array<int,2>;
88  using pipe_flag_array = std::array<long,2>;
89  static void setup_pipe(pipe_fd_array& mypipe, pipe_flag_array& myflags);
90 
91  QString m_videoDevice;
92  int m_streamFd {-1};
93  mutable pipe_fd_array m_wakePipe {-1,-1};
95 
97 
98  // Data for managing the device ringbuffer
99  mutable QMutex m_lock;
100  volatile bool m_doRun {false};
101  bool m_eof {false};
102  mutable bool m_error {false};
103  bool m_requestPause {false};
104  bool m_paused {false};
105  bool m_usingPoll {true};
106  bool m_pollTimeoutIsError {true};
107  std::chrono::milliseconds m_maxPollWait {2500ms};
108 
109  size_t m_size {0};
110  size_t m_used {0};
111  size_t m_readQuanta {0};
112  size_t m_devBufferCount {1};
113  size_t m_devReadSize {0};
114  size_t m_readThreshold {0};
115  unsigned char *m_buffer {nullptr};
116  unsigned char *m_readPtr {nullptr};
117  unsigned char *m_writePtr {nullptr};
118  unsigned char *m_endPtr {nullptr};
119 
120  mutable QWaitCondition m_dataWait;
121  QWaitCondition m_runWait;
122  QWaitCondition m_pauseWait;
123  QWaitCondition m_unpauseWait;
124 
125  // statistics
126  size_t m_maxUsed {0};
127  size_t m_avgUsed {0};
128  size_t m_avgBufWriteCnt {0};
129  size_t m_avgBufReadCnt {0};
130  size_t m_avgBufSleepCnt {0};
132 };
133 
134 #endif // DEVICEREADBUFFER_H
135 
136 /*
137  * vim:ts=4:sw=4:ai:et:si:sts=4
138  */
DeviceReadBuffer::m_streamFd
int m_streamFd
Definition: DeviceReadBuffer.h:92
DeviceReadBuffer::m_devReadSize
size_t m_devReadSize
Definition: DeviceReadBuffer.h:113
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
DeviceReadBuffer::m_readPtr
unsigned char * m_readPtr
Definition: DeviceReadBuffer.h:116
DeviceReadBuffer::m_pauseWait
QWaitCondition m_pauseWait
Definition: DeviceReadBuffer.h:122
DeviceReadBuffer::m_maxUsed
size_t m_maxUsed
Definition: DeviceReadBuffer.h:126
DeviceReadBuffer::Start
void Start(void)
Definition: DeviceReadBuffer.cpp:149
DeviceReadBuffer::m_used
size_t m_used
Definition: DeviceReadBuffer.h:110
DeviceReadBuffer::WakePoll
void WakePoll(void) const
Definition: DeviceReadBuffer.cpp:224
DeviceReadBuffer::Setup
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
Definition: DeviceReadBuffer.cpp:92
DeviceReaderCB::~DeviceReaderCB
virtual ~DeviceReaderCB()=default
DeviceReadBuffer::m_wakePipeFlags
pipe_flag_array m_wakePipeFlags
Definition: DeviceReadBuffer.h:94
DeviceReadBuffer::m_devBufferCount
size_t m_devBufferCount
Definition: DeviceReadBuffer.h:112
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:253
DeviceReadBuffer::WaitForPaused
bool WaitForPaused(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:259
DeviceReadBuffer::m_runWait
QWaitCondition m_runWait
Definition: DeviceReadBuffer.h:121
DeviceReadBuffer::WaitForUsed
uint WaitForUsed(uint needed, std::chrono::milliseconds max_wait) const
Definition: DeviceReadBuffer.cpp:727
DeviceReadBuffer::Read
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
Definition: DeviceReadBuffer.cpp:659
DeviceReadBuffer::m_avgBufWriteCnt
size_t m_avgBufWriteCnt
Definition: DeviceReadBuffer.h:128
DeviceReadBuffer::m_wakePipe
pipe_fd_array m_wakePipe
Definition: DeviceReadBuffer.h:93
DeviceReadBuffer::IsPauseRequested
bool IsPauseRequested(void) const
Definition: DeviceReadBuffer.cpp:279
DeviceReadBuffer
Buffers reads from device files.
Definition: DeviceReadBuffer.h:35
DeviceReadBuffer::WaitForUnpause
bool WaitForUnpause(unsigned long timeout)
Definition: DeviceReadBuffer.cpp:269
DeviceReaderCB
Definition: DeviceReadBuffer.h:19
DeviceReadBuffer::GetContiguousUnused
uint GetContiguousUnused(void) const
Definition: DeviceReadBuffer.cpp:315
DeviceReadBuffer::m_requestPause
bool m_requestPause
Definition: DeviceReadBuffer.h:103
DeviceReaderCB::ReaderPaused
virtual void ReaderPaused(int fd)=0
DeviceReadBuffer::m_eof
bool m_eof
Definition: DeviceReadBuffer.h:101
DeviceReadBuffer::setup_pipe
static void setup_pipe(pipe_fd_array &mypipe, pipe_flag_array &myflags)
Definition: DeviceReadBuffer.cpp:22
DeviceReadBuffer::WaitForUnused
uint WaitForUnused(uint needed) const
Definition: DeviceReadBuffer.cpp:701
DeviceReadBuffer::pipe_fd_array
std::array< int, 2 > pipe_fd_array
Definition: DeviceReadBuffer.h:87
DeviceReadBuffer::CheckForErrors
bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt)
Definition: DeviceReadBuffer.cpp:578
DeviceReadBuffer::m_pollTimeoutIsError
bool m_pollTimeoutIsError
Definition: DeviceReadBuffer.h:106
DeviceReadBuffer::m_doRun
volatile bool m_doRun
Definition: DeviceReadBuffer.h:100
DeviceReadBuffer::m_readerCB
DeviceReaderCB * m_readerCB
Definition: DeviceReadBuffer.h:96
DeviceReadBuffer::m_readQuanta
size_t m_readQuanta
Definition: DeviceReadBuffer.h:111
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:207
DeviceReadBuffer::m_videoDevice
QString m_videoDevice
Definition: DeviceReadBuffer.h:91
DeviceReadBuffer::IsRunning
bool IsRunning(void) const
Definition: DeviceReadBuffer.cpp:297
DeviceReadBuffer::m_usingPoll
bool m_usingPoll
Definition: DeviceReadBuffer.h:105
tspacket.h
DeviceReadBuffer::m_buffer
unsigned char * m_buffer
Definition: DeviceReadBuffer.h:115
DeviceReadBuffer::IsOpen
bool IsOpen(void) const
Definition: DeviceReadBuffer.h:79
DeviceReadBuffer::Stop
void Stop(void)
Definition: DeviceReadBuffer.cpp:192
DeviceReadBuffer::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: DeviceReadBuffer.h:123
DeviceReadBuffer::m_readThreshold
size_t m_readThreshold
Definition: DeviceReadBuffer.h:114
DeviceReadBuffer::ClosePipes
void ClosePipes(void) const
Definition: DeviceReadBuffer.cpp:240
DeviceReaderCB::PriorityEvent
virtual void PriorityEvent(int fd)=0
DeviceReadBuffer::m_lock
QMutex m_lock
Definition: DeviceReadBuffer.h:99
DeviceReadBuffer::m_size
size_t m_size
Definition: DeviceReadBuffer.h:109
DeviceReadBuffer::m_avgUsed
size_t m_avgUsed
Definition: DeviceReadBuffer.h:127
DeviceReadBuffer::pipe_flag_array
std::array< long, 2 > pipe_flag_array
Definition: DeviceReadBuffer.h:88
DeviceReadBuffer::GetUnused
uint GetUnused(void) const
Definition: DeviceReadBuffer.cpp:303
DeviceReadBuffer::~DeviceReadBuffer
~DeviceReadBuffer() override
Definition: DeviceReadBuffer.cpp:82
DeviceReadBuffer::ReportStats
void ReportStats(void)
Definition: DeviceReadBuffer.cpp:744
DeviceReadBuffer::SetPaused
void SetPaused(bool val)
Definition: DeviceReadBuffer.cpp:213
DeviceReadBuffer::m_maxPollWait
std::chrono::milliseconds m_maxPollWait
Definition: DeviceReadBuffer.h:107
DeviceReadBuffer::m_writePtr
unsigned char * m_writePtr
Definition: DeviceReadBuffer.h:117
DeviceReadBuffer::Poll
bool Poll(void) const
Definition: DeviceReadBuffer.cpp:452
DeviceReadBuffer::HandlePausing
bool HandlePausing(void)
Definition: DeviceReadBuffer.cpp:432
DeviceReadBuffer::DeviceReadBuffer
DeviceReadBuffer(DeviceReaderCB *cb, bool use_poll=true, bool error_exit_on_poll_timeout=true)
Definition: DeviceReadBuffer.cpp:64
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:130
mthread.h
DeviceReadBuffer::m_error
bool m_error
Definition: DeviceReadBuffer.h:102
DeviceReadBuffer::IsErrored
bool IsErrored(void) const
Definition: DeviceReadBuffer.cpp:285
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:346
DeviceReadBuffer::IncrWritePointer
void IncrWritePointer(uint len)
Definition: DeviceReadBuffer.cpp:321
mythtimer.h
DeviceReadBuffer::m_avgBufReadCnt
size_t m_avgBufReadCnt
Definition: DeviceReadBuffer.h:129
DeviceReadBuffer::IsEOF
bool IsEOF(void) const
Definition: DeviceReadBuffer.cpp:291
DeviceReadBuffer::m_paused
bool m_paused
Definition: DeviceReadBuffer.h:104
DeviceReadBuffer::SetRequestPause
void SetRequestPause(bool request)
Definition: DeviceReadBuffer.cpp:206
DeviceReadBuffer::m_dataWait
QWaitCondition m_dataWait
Definition: DeviceReadBuffer.h:120
DeviceReadBuffer::m_lastReport
MythTimer m_lastReport
Definition: DeviceReadBuffer.h:131
DeviceReadBuffer::IncrReadPointer
void IncrReadPointer(uint len)
Definition: DeviceReadBuffer.cpp:335
DeviceReadBuffer::m_endPtr
unsigned char * m_endPtr
Definition: DeviceReadBuffer.h:118
DeviceReadBuffer::Reset
void Reset(const QString &streamName, int streamfd)
Definition: DeviceReadBuffer.cpp:177
uint
unsigned int uint
Definition: freesurround.h:24
DeviceReadBuffer::GetUsed
uint GetUsed(void) const
Definition: DeviceReadBuffer.cpp:309