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
20 #include "mythdownloadmanager.h"
21 #else
22 #include "mythsingledownload.h"
23 #endif
24 
25 #include "mythlogging.h"
26 #include "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 = QList<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  int Read(uint8_t* buffer, int 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  int TargetDuration(void) const
76  { return (m_curstream ? m_curstream->TargetDuration() : 0); }
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  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
QMutex m_streamLock
Definition: HLSReader.h:119
QMutex m_throttleLock
Definition: HLSReader.h:121
QMutex m_bufLock
Definition: HLSReader.h:129
StreamContainer m_streams
Definition: HLSReader.h:100
SegmentContainer m_segments
Definition: HLSReader.h:101
bool IsThrottled(void) const
Definition: HLSReader.h:50
bool FatalError(void) const
Definition: HLSReader.h:53
QString m_segmentBase
Definition: HLSReader.h:99
void AllowPlaylistSwitch(void)
Definition: HLSReader.h:78
#define MTV_PUBLIC
Definition: mythtvexp.h:15
QMutex m_seqLock
Definition: HLSReader.h:118
QString StreamURL(void) const
Definition: HLSReader.h:60
QWaitCondition m_throttleCond
Definition: HLSReader.h:122
QByteArray m_buffer
Definition: HLSReader.h:128
unsigned int uint
Definition: compat.h:140
int TargetDuration(void) const
Definition: HLSReader.h:75
void ResetSequence(void)
Definition: HLSReader.h:58
QList< HLSRecSegment > SegmentContainer
Definition: HLSReader.h:41
QMap< QString, HLSRecStream * > StreamContainer
Definition: HLSReader.h:40
void ResetStream(void)
Definition: HLSReader.h:56
QString m_m3u8
Definition: HLSReader.h:98
QMutex m_workerLock
Definition: HLSReader.h:120
bool IsOpen(const QString &url) const
Definition: HLSReader.h:51