MythTV master
HLSReader.h
Go to the documentation of this file.
1#ifndef HLS_READER_H
2#define HLS_READER_H
3
4#include <QChar> // Fix Qt6 GCC SFINAE warning
5#include <QByteArray>
6#include <QMap>
7#include <QMutex>
8#include <QObject>
9#include <QString>
10#include <QTextStream>
11#include <QtGlobal> // Qt 5 for QtTypes and QtVersionChecks
12#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
13#include <QtTypes>
14#endif
15#include <QVector>
16#include <QWaitCondition>
17
19/*
20 Use MythSingleDownload.
21
22 MythDownloadManager leaks memory and QNetworkAccessManager can only
23 handle six simultaneous downloads. Each HLS stream can be
24 downloading the playlist and the segments at the same time, so the
25 limit of six could impact performance if recording more than three
26 HLS channels.
27*/
28
29#ifdef HLS_USE_MYTHDOWNLOADMANAGER
31#else
33#endif
34
35#include "libmythtv/mythtvexp.h"
36
37#include "HLSSegment.h"
38#include "HLSStream.h"
39#include "HLSStreamWorker.h"
40#include "HLSPlaylistWorker.h"
41
42
44{
45 friend class HLSStreamWorker;
46 friend class HLSPlaylistWorker;
47
48 public:
49 using StreamContainer = QMap<QString, HLSRecStream* >;
50 using SegmentContainer = QVector<HLSRecSegment>;
51
52 HLSReader(int inputId) : m_inputId(inputId) { };
53 ~HLSReader(void);
54
55 bool Open(const QString & m3u, int bitrate_index = 0);
56 void Close(bool quiet = false);
57 qint64 Read(uint8_t* buffer, qint64 len);
58 void Throttle(bool val);
59 bool IsThrottled(void) const { return m_throttle; }
60 bool IsOpen(const QString& url) const
61 { return m_curstream && m_m3u8 == url; }
62 bool FatalError(void) const { return m_fatal; }
63
64 bool LoadMetaPlaylists(MythSingleDownload& downloader);
65 void ResetStream(void)
66 { QMutexLocker lock(&m_streamLock); m_curstream = nullptr; }
67 void ResetSequence(void) { m_curSeq = -1; }
68
69 QString StreamURL(void) const
70 { return QString("%1").arg(m_curstream ? m_curstream->M3U8Url() : ""); }
71
72#ifdef HLS_USE_MYTHDOWNLOADMANAGER // MythDownloadManager leaks memory
73 static bool DownloadURL(const QString &url, QByteArray *buffer);
74#endif
75 static void CancelURL(const QString &url);
76 static void CancelURL(const QStringList &urls);
77
78 static bool IsValidPlaylist(QTextStream & text);
79
80 protected:
81 void Cancel(bool quiet = false);
82 bool LoadSegments(MythSingleDownload& downloader);
83 uint PercentBuffered(void) const;
84 std::chrono::seconds TargetDuration(void) const
85 { return (m_curstream ? m_curstream->TargetDuration() : 0s); }
86
87 void AllowPlaylistSwitch(void) { m_bandwidthCheck = true; }
88
89 void PlaylistGood(void);
90 void PlaylistRetrying(void);
91 int PlaylistRetryCount(void) const;
92
93 private:
94 bool ParseM3U8(const QByteArray & buffer, HLSRecStream* stream = nullptr);
95 void DecreaseBitrate(int progid);
96 void IncreaseBitrate(int progid);
97
98 // Downloading
99 int DownloadSegmentData(MythSingleDownload& downloader, HLSRecStream* hls,
100 HLSRecSegment& segment, int playlist_size);
101
102 // Debug
103 void EnableDebugging(void);
104
105 private:
106 QString m_m3u8;
110 HLSRecStream *m_curstream {nullptr};
111 int64_t m_curSeq {-1};
112 int m_bitrateIndex {0};
113
114 bool m_fatal {false};
115 bool m_cancel {false};
116 bool m_throttle {true};
117 // Only print one time that the media is encrypted
118 bool m_aesMsg {false};
119
120 HLSPlaylistWorker *m_playlistWorker {nullptr};
121 HLSStreamWorker *m_streamWorker {nullptr};
122
123 int m_playlistSize {0};
124 bool m_bandwidthCheck {false};
125 uint m_prebufferCnt {10};
126
127 QMutex m_seqLock;
128
129 mutable QMutex m_streamLock;
130
131 mutable QMutex m_workerLock;
132
134 QWaitCondition m_throttleCond;
135
136 bool m_debug {false};
137 int m_debugCnt {0};
138
139 // Downloading
140 int m_slowCnt {0};
141 QByteArray m_buffer;
142 QMutex m_bufLock;
143
144 // Log message
145 int m_inputId {0};
146};
147
148#endif // HLS_READER_H
void AllowPlaylistSwitch(void)
Definition: HLSReader.h:87
QWaitCondition m_throttleCond
Definition: HLSReader.h:134
QMutex m_bufLock
Definition: HLSReader.h:142
StreamContainer m_streams
Definition: HLSReader.h:108
QMutex m_seqLock
Definition: HLSReader.h:127
QMutex m_throttleLock
Definition: HLSReader.h:133
bool IsThrottled(void) const
Definition: HLSReader.h:59
QVector< HLSRecSegment > SegmentContainer
Definition: HLSReader.h:50
static void CancelURL(const QStringList &urls)
bool IsOpen(const QString &url) const
Definition: HLSReader.h:60
QMutex m_workerLock
Definition: HLSReader.h:131
QByteArray m_buffer
Definition: HLSReader.h:141
static void CancelURL(const QString &url)
SegmentContainer m_segments
Definition: HLSReader.h:109
std::chrono::seconds TargetDuration(void) const
Definition: HLSReader.h:84
HLSReader(int inputId)
Definition: HLSReader.h:52
void ResetStream(void)
Definition: HLSReader.h:65
QString StreamURL(void) const
Definition: HLSReader.h:69
QMap< QString, HLSRecStream * > StreamContainer
Definition: HLSReader.h:49
QMutex m_streamLock
Definition: HLSReader.h:129
void ResetSequence(void)
Definition: HLSReader.h:67
QString m_segmentBase
Definition: HLSReader.h:107
bool FatalError(void) const
Definition: HLSReader.h:62
QString m_m3u8
Definition: HLSReader.h:106
unsigned int uint
Definition: compat.h:60
#define MTV_PUBLIC
Definition: mythtvexp.h:8