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