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_stream_lock); m_curstream = nullptr; }
58  void ResetSequence(void) { m_cur_seq = -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_segment_base;
102  HLSRecStream *m_curstream {nullptr};
103  int64_t m_cur_seq {-1};
104  int m_bitrate_index {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_playlist_size {0};
116  bool m_bandwidthcheck {false};
117  uint m_prebuffer_cnt {10};
118  QMutex m_seq_lock;
119  mutable QMutex m_stream_lock;
120  mutable QMutex m_worker_lock;
122  QWaitCondition m_throttle_cond;
123  bool m_debug {false};
124  int m_debug_cnt {0};
125 
126  // Downloading
127  int m_slow_cnt {0};
128  QByteArray m_buffer;
129  QMutex m_buflock;
130 };
131 
132 #endif
QWaitCondition m_throttle_cond
Definition: HLSReader.h:122
QMutex m_throttle_lock
Definition: HLSReader.h:121
StreamContainer m_streams
Definition: HLSReader.h:100
SegmentContainer m_segments
Definition: HLSReader.h:101
bool IsThrottled(void) const
Definition: HLSReader.h:50
QMutex m_stream_lock
Definition: HLSReader.h:119
bool FatalError(void) const
Definition: HLSReader.h:53
QMutex m_seq_lock
Definition: HLSReader.h:118
void AllowPlaylistSwitch(void)
Definition: HLSReader.h:78
QMutex m_buflock
Definition: HLSReader.h:129
#define MTV_PUBLIC
Definition: mythtvexp.h:15
QString StreamURL(void) const
Definition: HLSReader.h:60
QByteArray m_buffer
Definition: HLSReader.h:128
unsigned int uint
Definition: compat.h:140
int TargetDuration(void) const
Definition: HLSReader.h:75
QString m_segment_base
Definition: HLSReader.h:99
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
QMutex m_worker_lock
Definition: HLSReader.h:120
QString m_m3u8
Definition: HLSReader.h:98
bool IsOpen(const QString &url) const
Definition: HLSReader.h:51