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