MythTV master
iptvtuningdata.h
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2#ifndef IPTV_TUNING_DATA_H
3#define IPTV_TUNING_DATA_H
4
5#include <array>
6
7// Qt headers
8#include <QApplication>
9#include <QString>
10#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
11#include <QStringConverter>
12#endif
13#include <QUrl>
14
15// MythTV headers
17#include "libmythtv/mythtvexp.h"
19
21{
22 public:
23 enum FECType : std::uint8_t
24 {
29 };
30
31 enum IPTVType : std::uint8_t
32 {
33 kData = 1,
40 };
41
42 enum IPTVProtocol : std::uint8_t
43 {
44 inValid = 0,
49 http_hls
50 };
51
53 {
54 m_bitrate.fill(0);
55 }
56
57 IPTVTuningData(const QString &data_url, IPTVProtocol protocol) :
58 m_dataUrl(data_url), m_protocol(protocol)
59 {
60 m_bitrate.fill(0);
61 }
62
63 IPTVTuningData(const QString &data_url, uint data_bitrate,
64 const FECType fec_type,
65 const QString &fec_url0, uint fec_bitrate0,
66 const QString &fec_url1, uint fec_bitrate1) :
67 m_dataUrl(data_url),
68 m_fecType(fec_type), m_fecUrl0(fec_url0), m_fecUrl1(fec_url1)
69 {
70 GuessProtocol();
71 m_bitrate[0] = data_bitrate;
72 m_bitrate[1] = fec_bitrate0;
73 m_bitrate[2] = fec_bitrate1;
74 }
75
76 IPTVTuningData(const QString &data_url, uint data_bitrate,
77 const QString &fec_type,
78 const QString &fec_url0, uint fec_bitrate0,
79 const QString &fec_url1, uint fec_bitrate1,
80 const IPTVProtocol protocol) :
81 m_dataUrl(data_url),
82 m_fecUrl0(fec_url0), m_fecUrl1(fec_url1),
83 m_protocol(protocol)
84 {
85 m_bitrate[0] = data_bitrate;
86 m_bitrate[1] = fec_bitrate0;
87 m_bitrate[2] = fec_bitrate1;
88 if (fec_type.toLower() == "rfc2733")
89 m_fecType = kRFC2733;
90 else if (fec_type.toLower() == "rfc5109")
91 m_fecType = kRFC5109;
92 else if (fec_type.toLower() == "smpte2022")
93 m_fecType = kSMPTE2022;
94 else
95 {
96 m_fecUrl0.clear();
97 m_fecUrl1.clear();
98 }
99 }
100
101 QString GetDeviceKey(void) const
102 {
103 const QUrl u = GetDataURL();
104 if (IsHLS())
105 return QString("%1(%2)").arg(u.toString()).arg(GetBitrate(0));
106 if (IsHTTPTS() || IsRTSP())
107 return QString("%1").arg(u.toString());
108 return QString("%1:%2:%3")
109 .arg(u.host(),u.userInfo(),QString::number(u.port())).toLower();
110 }
111
112 QString GetDeviceName(void) const
113 {
114 return QString("[data]%1[fectype]%2[fec0]%3[fec1]%4%5")
115 .arg(GetDataURL().toString(),
116 GetFECTypeString(1),
117 GetFECURL1().toString(),
118 GetFECURL1().toString(),
119 GetBitrate(0) ? QString("-%1").arg(GetBitrate(0)) : "");
120 }
121
122 bool operator==(const IPTVTuningData &other) const
123 {
124 return GetDeviceName() == other.GetDeviceName();
125 }
126
127 bool operator!=(const IPTVTuningData &other) const
128 {
129 return GetDeviceName() != other.GetDeviceName();
130 }
131
132 void SetDataURL(const QUrl &url)
133 {
134 m_dataUrl = url;
135 GuessProtocol();
136 }
137
138 QUrl GetDataURL(void) const { return m_dataUrl; }
139 QUrl GetFECURL0(void) const { return m_fecUrl0; }
140 QUrl GetFECURL1(void) const { return m_fecUrl1; }
141 QUrl GetURL(uint i) const
142 {
143 if (0 == i)
144 return GetDataURL();
145 if (1 == i)
146 return GetFECURL0();
147 if (2 == i)
148 return GetFECURL1();
149 return {};
150 }
151 uint GetBitrate(uint i) const { return m_bitrate[i]; }
152
153 FECType GetFECType(void) const { return m_fecType; }
154
155 QString GetFECTypeString(uint i) const
156 {
157 if (0 == i)
158 return "data";
159 switch (m_fecType)
160 {
161 case kNone: return {};
162 case kRFC2733: return QString("rfc2733-%1").arg(i);
163 case kRFC5109: return QString("rfc5109-%1").arg(i);
164 case kSMPTE2022: return QString("smpte2022-%1").arg(i);
165 }
166 return {};
167 }
168
169 static uint GetURLCount(void) { return 3; }
170
171 bool IsValid(void) const;
172
173 bool IsUDP(void) const
174 {
175 return (m_protocol == udp);
176 }
177
178 bool IsRTP(void) const
179 {
180 return (m_protocol == rtp);
181 }
182
183 bool IsRTSP(void) const
184 {
185 return (m_protocol == rtsp);
186 }
187
188 bool IsHLS() const
189 {
190 return (m_protocol == http_hls);
191 }
192
193 bool IsHTTPTS() const
194 {
195 return (m_protocol == http_ts);
196 }
197
198 // An HLSPlaylist URL is identified as http_ts if download fails.
199 void GuessProtocol(void)
200 {
201 if (!m_dataUrl.isValid())
202 m_protocol = IPTVTuningData::inValid; // NOLINT(bugprone-branch-clone)
203 else if (m_dataUrl.scheme() == "udp")
204 m_protocol = IPTVTuningData::udp;
205 else if (m_dataUrl.scheme() == "rtp")
206 m_protocol = IPTVTuningData::rtp;
207 else if (m_dataUrl.scheme() == "rtsp")
208 m_protocol = IPTVTuningData::rtsp;
209 else if ((m_dataUrl.scheme() == "http") || (m_dataUrl.scheme() == "https"))
210 {
211 QByteArray buffer;
212 if (CanReadHTTP(buffer))
213 {
214 if (IsHLSPlaylist(buffer))
215 m_protocol = IPTVTuningData::http_hls;
216 else
217 m_protocol = IPTVTuningData::http_ts;
218 }
219 else
220 {
221 m_protocol = IPTVTuningData::http_ts; // Breaks the unit test if set to inValid
222 }
223 }
224 else
225 {
226 m_protocol = IPTVTuningData::inValid;
227 }
228 }
229
231 {
232 return m_protocol;
233 }
234
235 protected:
236
237 // Read first part of the http(s) URL.
238 // This is done to test if we can download from this URL
239 // and 2000 bytes is enough to determine in IsHLSPlaylist
240 // if the file is an HLS playlist or not.
241 //
242 bool CanReadHTTP(QByteArray &buffer) const;
243
244 static bool IsHLSPlaylist(QByteArray &buffer)
245 {
246 QTextStream text(&buffer);
247#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
248 text.setCodec("UTF-8");
249#else
250 text.setEncoding(QStringConverter::Utf8);
251#endif
252 return (HLSReader::IsValidPlaylist(text));
253 }
254
255 protected:
257 FECType m_fecType {kNone};
260 std::array<uint,3> m_bitrate {};
261 IPTVProtocol m_protocol {inValid};
262};
263
264#endif // IPTV_TUNING_DATA_H
static bool IsValidPlaylist(QTextStream &text)
Definition: HLSReader.cpp:267
QString GetFECTypeString(uint i) const
QUrl GetDataURL(void) const
QString GetDeviceKey(void) const
FECType GetFECType(void) const
bool operator==(const IPTVTuningData &other) const
static uint GetURLCount(void)
QUrl GetFECURL0(void) const
bool IsRTP(void) const
void SetDataURL(const QUrl &url)
QUrl GetFECURL1(void) const
IPTVTuningData(const QString &data_url, uint data_bitrate, const QString &fec_type, const QString &fec_url0, uint fec_bitrate0, const QString &fec_url1, uint fec_bitrate1, const IPTVProtocol protocol)
bool IsHLS() const
IPTVProtocol GetProtocol(void) const
static bool IsHLSPlaylist(QByteArray &buffer)
bool IsHTTPTS() const
bool IsRTSP(void) const
bool IsUDP(void) const
IPTVTuningData(const QString &data_url, IPTVProtocol protocol)
uint GetBitrate(uint i) const
QString GetDeviceName(void) const
void GuessProtocol(void)
QUrl GetURL(uint i) const
IPTVTuningData(const QString &data_url, uint data_bitrate, const FECType fec_type, const QString &fec_url0, uint fec_bitrate0, const QString &fec_url1, uint fec_bitrate1)
bool operator!=(const IPTVTuningData &other) const
unsigned int uint
Definition: freesurround.h:24
#define MTV_PUBLIC
Definition: mythtvexp.h:15
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93