MythTV  master
HLSStreamWorker.cpp
Go to the documentation of this file.
1 #include "HLSReader.h"
2 #include "HLSStreamWorker.h"
3 
4 #define LOC QString("%1 worker: ").arg(m_parent->StreamURL().isEmpty() ? "Stream" : m_parent->StreamURL())
5 
7  : MThread("HLSStream"),
8  m_parent(parent)
9 {
10  LOG(VB_RECORD, LOG_DEBUG, LOC + "ctor");
11 }
12 
14 {
15  LOG(VB_RECORD, LOG_DEBUG, LOC + "dtor");
16 }
17 
19 {
20  LOG(VB_RECORD, LOG_INFO, LOC + "Cancel -- begin");
21  m_cancel = true;
22  Wakeup();
24  wait();
25  LOG(VB_RECORD, LOG_INFO, LOC + "Cancel -- end");
26 }
27 
29 {
30  QMutexLocker locker(&m_downloader_lock);
31  if (m_downloader)
33 }
34 
36 {
37  LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
38  RunProlog();
39 
40  m_downloader_lock.lock();
42  m_downloader_lock.unlock();
43 
44  uint64_t delay;
45  int retries = 0;
46  while (!m_cancel)
47  {
48  if (m_parent->FatalError())
49  {
50  LOG(VB_GENERAL, LOG_CRIT, LOC + "Fatal error detected");
51  break;
52  }
54  {
55  LOG(VB_RECORD, LOG_WARNING, LOC +
56  QString("download failed, retry #%1").arg(++retries));
57 
58  // Asking QNetworkAccessManager to redownload after a
59  // failure seems to result in another failure, even if the
60  // segment is now available. So, create a new instance.
61  m_downloader_lock.lock();
62  delete m_downloader;
64  m_downloader_lock.unlock();
65 
66  if (retries == 1) // first error
67  continue; // will retry immediately
68  if (retries > 2)
70  if (retries == 10)
72 
73  delay = (uint64_t)500 * retries * retries;
74  if (delay > 20000)
75  delay = 20000;
76  }
77  else
78  {
79  retries = 0;
80  delay = 11000;
81  }
82 
83  m_lock.lock();
84  if (!m_wokenup && !m_cancel)
85  {
86  if (delay < 1000)
87  LOG(VB_RECORD, LOG_WARNING, LOC + "waiting to retry");
88  else
89  LOG(VB_RECORD, LOG_DEBUG, LOC + "waiting for work");
90  m_waitcond.wait(&m_lock, delay);
91  }
92  m_wokenup = false;
93  m_lock.unlock();
94  }
95 
97  delete m_downloader;
98  m_downloader = nullptr;
99 
100  LOG(VB_RECORD, LOG_INFO, LOC + "run -- end");
101  RunEpilog();
102 }
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
void EnableDebugging(void)
Definition: HLSReader.cpp:1020
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:311
bool LoadSegments(MythSingleDownload &downloader)
Definition: HLSReader.cpp:759
QMutex m_downloader_lock
MythSingleDownload * m_downloader
bool FatalError(void) const
Definition: HLSReader.h:53
HLSStreamWorker(HLSReader *parent)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
void Wakeup(void)
#define LOC
void ResetSequence(void)
Definition: HLSReader.h:58
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
HLSReader * m_parent
void CancelCurrentDownload(void)
QWaitCondition m_waitcond
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:202