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 "mythtimer.h"
14 #include "tspacket.h"
15 #include "mthread.h"
16 
18 {
19  protected:
20  virtual ~DeviceReaderCB() = default;
21  public:
22  virtual void ReaderPaused(int fd) = 0;
23  virtual void PriorityEvent(int fd) = 0;
24 };
25 
33 class DeviceReadBuffer : protected MThread
34 {
35  public:
36  explicit DeviceReadBuffer(DeviceReaderCB *cb,
37  bool use_poll = true,
38  bool error_exit_on_poll_timeout = true);
39  ~DeviceReadBuffer() override;
40 
41  bool Setup(const QString &streamName,
42  int streamfd,
43  uint readQuanta = sizeof(TSPacket),
44  uint deviceBufferSize = 0,
45  uint deviceBufferCount = 1);
46 
47  void Start(void);
48  void Reset(const QString &streamName, int streamfd);
49  void Stop(void);
50 
51  void SetRequestPause(bool request);
52  bool IsPaused(void) const;
53  bool WaitForUnpause(unsigned long timeout);
54  bool WaitForPaused(unsigned long timeout);
55 
56  bool IsErrored(void) const;
57  bool IsEOF(void) const;
58  bool IsRunning(void) const;
59 
60  uint Read(unsigned char *buf, uint count);
61  uint GetUsed(void) const;
62 
63  private:
64  void run(void) override; // MThread
65 
66  void SetPaused(bool val);
67  void IncrWritePointer(uint len);
68  void IncrReadPointer(uint len);
69 
70  bool HandlePausing(void);
71  bool Poll(void) const;
72  void WakePoll(void) const;
73  uint WaitForUnused(uint needed) const;
74  uint WaitForUsed (uint needed, uint max_wait /*ms*/) const;
75 
76  bool IsPauseRequested(void) const;
77  bool IsOpen(void) const { return m_streamFd >= 0; }
78  void ClosePipes(void) const;
79  uint GetUnused(void) const;
80  uint GetContiguousUnused(void) const;
81 
82  bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt);
83  void ReportStats(void);
84 
85  QString m_videoDevice;
86  int m_streamFd {-1};
87  mutable int m_wakePipe[2] {-1,-1};
88  mutable long m_wakePipeFlags[2] {0,0};
89 
91 
92  // Data for managing the device ringbuffer
93  mutable QMutex m_lock;
94  volatile bool m_doRun {false};
95  bool m_eof {false};
96  mutable bool m_error {false};
97  bool m_requestPause {false};
98  bool m_paused {false};
99  bool m_usingPoll {true};
100  bool m_pollTimeoutIsError {true};
101  uint m_maxPollWait {2500 /*ms*/};
102 
103  size_t m_size {0};
104  size_t m_used {0};
105  size_t m_readQuanta {0};
106  size_t m_devBufferCount {1};
107  size_t m_devReadSize {0};
108  size_t m_readThreshold {0};
109  unsigned char *m_buffer {nullptr};
110  unsigned char *m_readPtr {nullptr};
111  unsigned char *m_writePtr {nullptr};
112  unsigned char *m_endPtr {nullptr};
113 
114  mutable QWaitCondition m_dataWait;
115  QWaitCondition m_runWait;
116  QWaitCondition m_pauseWait;
117  QWaitCondition m_unpauseWait;
118 
119  // statistics
120  size_t m_maxUsed {0};
121  size_t m_avgUsed {0};
122  size_t m_avgBufWriteCnt {0};
123  size_t m_avgBufReadCnt {0};
124  size_t m_avgBufSleepCnt {0};
126 };
127 
128 #endif // _DEVICEREADBUFFER_H_
129 
130 /*
131  * vim:ts=4:sw=4:ai:et:si:sts=4
132  */
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
QWaitCondition m_unpauseWait
DeviceReadBuffer(DeviceReaderCB *cb, bool use_poll=true, bool error_exit_on_poll_timeout=true)
bool IsRunning(void) const
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
QWaitCondition m_dataWait
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
~DeviceReadBuffer() override
virtual ~DeviceReaderCB()=default
bool IsEOF(void) const
volatile bool m_doRun
void ClosePipes(void) const
uint GetContiguousUnused(void) const
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
bool IsOpen(void) const
void WakePoll(void) const
unsigned char * m_buffer
void IncrReadPointer(uint len)
unsigned char * m_writePtr
bool IsErrored(void) const
bool IsPaused(void) const
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
virtual void ReaderPaused(int fd)=0
uint WaitForUsed(uint needed, uint max_wait) const
bool WaitForPaused(unsigned long timeout)
void SetRequestPause(bool request)
uint WaitForUnused(uint needed) const
virtual void PriorityEvent(int fd)=0
bool WaitForUnpause(unsigned long timeout)
unsigned char * m_endPtr
unsigned int uint
Definition: compat.h:140
DeviceReaderCB * m_readerCB
bool Poll(void) const
bool CheckForErrors(ssize_t read_len, size_t requested_len, uint &errcnt)
void IncrWritePointer(uint len)
QWaitCondition m_runWait
void Reset(const QString &streamName, int streamfd)
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
Buffers reads from device files.
uint GetUsed(void) const
uint GetUnused(void) const
QWaitCondition m_pauseWait
void SetPaused(bool val)
unsigned char * m_readPtr
bool IsPauseRequested(void) const