MythTV master
ExternalStreamHandler.h
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2
3#ifndef EXTERNAL_STREAMHANDLER_H
4#define EXTERNAL_STREAMHANDLER_H
5
6// POSIX
7#include <sys/types.h> // for pid_t
8
9#include <cstdint>
10#include <vector>
11
12#include <QString>
13#include <QAtomicInt>
14#include <QByteArray>
15#include <QFileInfo>
16#include <QMutex>
17#include <QMap>
18#include <QVariantMap>
19#include <QStringList>
20#include <QTextStream>
21
23
24#include "streamhandler.h"
25
27class ExternalChannel;
28
30{
31 static constexpr uint8_t kMaxErrorCnt { 20 };
32
33 public:
34 ExternIO(const QString & app, const QStringList & args);
35 ~ExternIO(void);
36
37 bool Ready(int fd, std::chrono::milliseconds timeout, const QString & what);
38 int Read(QByteArray & buffer, int maxlen, std::chrono::milliseconds timeout = 2500ms);
39 QByteArray GetStatus(std::chrono::milliseconds timeout = 2500ms);
40 int Write(const QByteArray & buffer);
41 bool Run(void);
42 bool Error(void) const { return !m_error.isEmpty(); }
43 QString ErrorString(void) const { return m_error; }
44 void ClearError(void) { m_error.clear(); }
45
46 static bool KillIfRunning(const QString & cmd);
47
48 private:
49 void Fork(void);
50
51 QFileInfo m_app;
52 QStringList m_args;
53 int m_appIn {-1};
54 int m_appOut {-1};
55 int m_appErr {-1};
56 pid_t m_pid {-1};
57 QString m_error;
58
59 int m_bufSize {0};
60 char *m_buffer {nullptr};
61
62 QString m_statusBuf;
63 QTextStream m_status;
64 int m_errCnt {0};
65};
66
67// Note : This class always uses a TS reader.
68
70{
75
76 public:
77 static ExternalStreamHandler *Get(const QString &devname,
78 int inputid, int majorid);
79 static void Return(ExternalStreamHandler * & ref, int inputid);
80
81 public:
82 explicit ExternalStreamHandler(const QString & path, int inputid,
83 int majorid);
84 ~ExternalStreamHandler(void) override { CloseApp(); }
85
86 void run(void) override; // MThread
87 void PriorityEvent(int fd) override; // DeviceReaderCB
88
89 QString GetDescription(void) { return m_loc; }
90 QString UpdateDescription(void);
91 bool IsDamaged(void) const { return m_damaged; }
92 void ClearDamaged(void) { m_damaged = false; }
93 bool IsAppOpen(void);
94 bool IsTSOpen(void);
95 bool HasTuner(void) const { return m_hasTuner; }
96 bool HasPictureAttributes(void) const { return m_hasPictureAttributes; }
97
98 bool RestartStream(void);
99
100 void LockReplay(void) { m_replayLock.lock(); }
101 void UnlockReplay(bool enable_replay = false)
102 { m_replay = enable_replay; m_replayLock.unlock(); }
103 void ReplayStream(void);
104 bool StartStreaming(void);
105 bool StopStreaming(void);
106
107 bool CheckForError(void);
108
109 void PurgeBuffer(void);
110
111 bool ProcessCommand(const QString & cmd, QString & result,
112 std::chrono::milliseconds timeout = 4s,
113 uint retry_cnt = 3);
114 bool ProcessVer1(const QString & cmd, QString & result,
115 std::chrono::milliseconds timeout, uint retry_cnt);
116 bool ProcessVer2(const QString & command, QString & result,
117 std::chrono::milliseconds timeout, uint retry_cnt);
118 bool ProcessJson(const QVariantMap & vmsg,
119 QVariantMap & elements,
120 QByteArray & response,
121 std::chrono::milliseconds timeout = 4s,
122 uint retry_cnt = 3);
123 int APIVersion(void) const { return m_apiVersion; }
124
125 private:
126 int StreamingCount(void) const;
127 bool SetAPIVersion(void);
128 bool OpenApp(void);
129 void CloseApp(void);
130
131 QString m_loc;
133 QMutex m_ioLock;
134 ExternIO *m_io {nullptr};
135 QStringList m_args;
136 QString m_app;
137 bool m_tsOpen {false};
138 int m_ioErrCnt {0};
139 bool m_pollMode {false};
140
143 bool m_hasTuner {false};
145
146 QByteArray m_replayBuffer;
147 bool m_replay {false};
148 bool m_xon {false};
149 bool m_damaged {false};
150
151 // for implementing Get & Return
152 static QMutex s_handlersLock;
153 static QMap<int, ExternalStreamHandler*> s_handlers;
154 static QMap<int, uint> s_handlersRefCnt;
155
156 QAtomicInt m_streamingCnt;
160};
161
162#endif // EXTERNAL_STREAMHANDLER_H
This class is intended to detect the presence of needed tables.
QStringList m_args
bool Ready(int fd, std::chrono::milliseconds timeout, const QString &what)
int Write(const QByteArray &buffer)
static bool KillIfRunning(const QString &cmd)
int Read(QByteArray &buffer, int maxlen, std::chrono::milliseconds timeout=2500ms)
void ClearError(void)
static constexpr uint8_t kMaxErrorCnt
QByteArray GetStatus(std::chrono::milliseconds timeout=2500ms)
QTextStream m_status
bool Error(void) const
ExternIO(const QString &app, const QStringList &args)
QString ErrorString(void) const
-*- Mode: c++ -*-
bool ProcessVer1(const QString &cmd, QString &result, std::chrono::milliseconds timeout, uint retry_cnt)
static ExternalStreamHandler * Get(const QString &devname, int inputid, int majorid)
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
bool HasPictureAttributes(void) const
~ExternalStreamHandler(void) override
ExternalStreamHandler(const QString &path, int inputid, int majorid)
bool ProcessVer2(const QString &command, QString &result, std::chrono::milliseconds timeout, uint retry_cnt)
static QMap< int, uint > s_handlersRefCnt
bool ProcessCommand(const QString &cmd, QString &result, std::chrono::milliseconds timeout=4s, uint retry_cnt=3)
static QMap< int, ExternalStreamHandler * > s_handlers
bool ProcessJson(const QVariantMap &vmsg, QVariantMap &elements, QByteArray &response, std::chrono::milliseconds timeout=4s, uint retry_cnt=3)
void UnlockReplay(bool enable_replay=false)
void PriorityEvent(int fd) override
static void Return(ExternalStreamHandler *&ref, int inputid)
unsigned int uint
Definition: freesurround.h:24