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(int inputId) { m_inputId = inputId; };
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  void SetDiscontinuitySequence(int s) { m_sequence = s; }
60 
61  QString StreamURL(void) const
62  { return QString("%1").arg(m_curstream ? m_curstream->M3U8Url() : ""); }
63 
64 #ifdef HLS_USE_MYTHDOWNLOADMANAGER // MythDownloadManager leaks memory
65  static bool DownloadURL(const QString &url, QByteArray *buffer);
66 #endif
67  static void CancelURL(const QString &url);
68  static void CancelURL(const QStringList &urls);
69 
70  static bool IsValidPlaylist(QTextStream & text);
71 
72  protected:
73  void Cancel(bool quiet = false);
74  bool LoadSegments(MythSingleDownload& downloader);
75  uint PercentBuffered(void) const;
76  std::chrono::seconds TargetDuration(void) const
77  { return (m_curstream ? m_curstream->TargetDuration() : 0s); }
78 
79  void AllowPlaylistSwitch(void) { m_bandwidthCheck = true; }
80 
81  void PlaylistGood(void);
82  void PlaylistRetrying(void);
83  int PlaylistRetryCount(void) const;
84 
85  private:
86  bool ParseM3U8(const QByteArray & buffer, HLSRecStream* stream = nullptr);
87  void DecreaseBitrate(int progid);
88  void IncreaseBitrate(int progid);
89 
90  // Downloading
91  bool LoadSegments(HLSRecStream & hlsstream);
92  int DownloadSegmentData(MythSingleDownload& downloader, HLSRecStream* hls,
93  const HLSRecSegment& segment, int playlist_size);
94 
95  // Debug
96  void EnableDebugging(void);
97 
98  private:
99  QString m_m3u8;
100  QString m_segmentBase;
103  HLSRecStream *m_curstream {nullptr};
104  int64_t m_curSeq {-1};
105  int m_bitrateIndex {0};
106 
107  bool m_fatal {false};
108  bool m_cancel {false};
109  bool m_throttle {true};
110  // Only print one time that the media is encrypted
111  bool m_aesMsg {false};
112 
113  HLSPlaylistWorker *m_playlistWorker {nullptr};
114  HLSStreamWorker *m_streamWorker {nullptr};
115 
116  int m_playlistSize {0};
117  bool m_bandwidthCheck {false};
118  uint m_prebufferCnt {10};
119  QMutex m_seqLock;
120  mutable QMutex m_streamLock;
121  mutable QMutex m_workerLock;
123  QWaitCondition m_throttleCond;
124  bool m_debug {false};
125  int m_debugCnt {0};
126 
127  // Downloading
128  int m_slowCnt {0};
129  QByteArray m_buffer;
130  QMutex m_bufLock;
131 
132  int m_sequence {0}; // Discontinuity sequence number
133 
134  // Log message
135  int m_inputId {0};
136 };
137 
138 #endif // HLS_READER_H
HLSPlaylistWorker
Definition: HLSPlaylistWorker.h:11
HLSStreamWorker.h
HLSReader::m_seqLock
QMutex m_seqLock
Definition: HLSReader.h:119
HLSReader::FatalError
bool FatalError(void) const
Definition: HLSReader.h:53
HLSReader::TargetDuration
std::chrono::seconds TargetDuration(void) const
Definition: HLSReader.h:76
HLSReader::m_segments
SegmentContainer m_segments
Definition: HLSReader.h:102
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:101
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
HLSReader::SetDiscontinuitySequence
void SetDiscontinuitySequence(int s)
Definition: HLSReader.h:59
mythsingledownload.h
HLSReader::StreamURL
QString StreamURL(void) const
Definition: HLSReader.h:61
HLSRecStream
Definition: HLSStream.h:15
HLSReader::m_workerLock
QMutex m_workerLock
Definition: HLSReader.h:121
HLSReader::m_bufLock
QMutex m_bufLock
Definition: HLSReader.h:130
mythlogging.h
HLSStream.h
HLSReader::m_m3u8
QString m_m3u8
Definition: HLSReader.h:99
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:79
HLSReader::m_throttleCond
QWaitCondition m_throttleCond
Definition: HLSReader.h:123
HLSReader::m_segmentBase
QString m_segmentBase
Definition: HLSReader.h:100
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:129
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:122
mythdownloadmanager.h
HLSReader::HLSReader
HLSReader(int inputId)
Definition: HLSReader.h:43
HLSReader::m_streamLock
QMutex m_streamLock
Definition: HLSReader.h:120