/
streamhandler.h
128 lines (103 loc) · 4.04 KB
/
streamhandler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// -*- Mode: c++ -*-
#ifndef _STREAM_HANDLER_H_
#define _STREAM_HANDLER_H_
#include <vector>
using namespace std;
#include <QWaitCondition>
#include <QString>
#include <QMutex>
#include <QMap>
#include "DeviceReadBuffer.h" // for ReaderPausedCB
#include "mpegstreamdata.h" // for PIDPriority
#include "mthread.h"
#include "mythdate.h"
//#define DEBUG_PID_FILTERS
class PIDInfo
{
public:
PIDInfo() :
_pid(0xffffffff), filter_fd(-1), streamType(0), pesType(-1) {;}
PIDInfo(uint pid) :
_pid(pid), filter_fd(-1), streamType(0), pesType(-1) {;}
PIDInfo(uint pid, uint stream_type, int pes_type) :
_pid(pid), filter_fd(-1),
streamType(stream_type), pesType(pes_type) {;}
virtual ~PIDInfo() {;}
virtual bool Open(const QString &dev, bool use_section_reader)
{ return false; }
virtual bool Close(const QString &dev) { return false; }
bool IsOpen(void) const { return filter_fd >= 0; }
uint _pid;
int filter_fd; ///< Input filter file descriptor
uint streamType; ///< StreamID
int pesType; ///< PESStreamID
};
// Please do not change this to hash or other unordered container.
// HDHRStreamHandler::UpdateFilters() relies on the forward
// iterator returning these in order of ascending pid number.
typedef QMap<uint,PIDInfo*> PIDInfoMap;
// locking order
// _pid_lock -> _listener_lock
// _add_rm_lock -> _listener_lock
// -> _start_stop_lock
class StreamHandler : protected MThread, public DeviceReaderCB
{
public:
virtual void AddListener(MPEGStreamData *data,
bool allow_section_reader = false,
bool needs_drb = false,
QString output_file = QString());
virtual void RemoveListener(MPEGStreamData *data);
bool IsRunning(void) const;
protected:
StreamHandler(const QString &device);
~StreamHandler();
void Start(void);
void Stop(void);
void SetRunning(bool running,
bool using_buffering,
bool using_section_reader);
bool AddPIDFilter(PIDInfo *info);
bool RemovePIDFilter(uint pid);
bool RemoveAllPIDFilters(void);
void UpdateListeningForEIT(void);
bool UpdateFiltersFromStreamData(void);
virtual bool UpdateFilters(void) { return true; }
virtual void CycleFiltersByPriority() {}
PIDPriority GetPIDPriority(uint pid) const;
// DeviceReaderCB
virtual void ReaderPaused(int fd) { (void) fd; }
virtual void PriorityEvent(int fd) { (void) fd; }
virtual PIDInfo *CreatePIDInfo(uint pid, uint stream_type, int pes_type)
{ return new PIDInfo(pid, stream_type, pes_type); }
protected:
/// Called with _listener_lock locked just after adding new output file.
virtual void AddNamedOutputFile(const QString &filename) {}
/// Called with _listener_lock locked just before removing old output file.
virtual void RemoveNamedOutputFile(const QString &filename) {}
/// At minimum this sets _running_desired, this may also send
/// signals to anything that might be blocking the run() loop.
/// \note: The _start_stop_lock must be held when this is called.
void SetRunningDesired(bool desired);
protected:
QString _device;
bool _needs_buffering;
bool _allow_section_reader;
QMutex _add_rm_lock;
mutable QMutex _start_stop_lock;
volatile bool _running_desired;
volatile bool _error;
bool _running;
bool _using_buffering;
bool _using_section_reader;
QWaitCondition _running_state_changed;
mutable QMutex _pid_lock;
vector<uint> _eit_pids;
PIDInfoMap _pid_info;
uint _open_pid_filters;
MythTimer _cycle_timer;
typedef QMap<MPEGStreamData*,QString> StreamDataList;
mutable QMutex _listener_lock;
StreamDataList _stream_data_list;
};
#endif // _STREAM_HANDLER_H_