diff --git a/mythtv/libs/libmythtv/HLS/httplivestreambuffer.cpp b/mythtv/libs/libmythtv/HLS/httplivestreambuffer.cpp index 3efd8a3a944..39f11798cd4 100644 --- a/mythtv/libs/libmythtv/HLS/httplivestreambuffer.cpp +++ b/mythtv/libs/libmythtv/HLS/httplivestreambuffer.cpp @@ -1455,7 +1455,8 @@ HLSRingBuffer::HLSRingBuffer(const QString &lfilename) : m_playback(new HLSPlayback()), m_meta(false), m_error(false), m_aesmsg(false), m_startup(0), m_bitrate(0), m_seektoend(false), - m_streamworker(NULL), m_playlistworker(NULL), m_fd(NULL) + m_streamworker(NULL), m_playlistworker(NULL), m_fd(NULL), + m_interrupted(false) { startreadahead = false; OpenFile(lfilename); @@ -2532,7 +2533,7 @@ void HLSRingBuffer::WaitUntilBuffered(void) m_streamworker->Wakeup(); m_streamworker->Lock(); int retries = 0; - while (!m_error && + while (!m_error && !m_interrupted && (m_streamworker->CurrentPlaybackBuffer(false) < 2) && (live || (!live && !m_streamworker->IsAtEnd()))) { @@ -2550,6 +2551,13 @@ int HLSRingBuffer::safe_read(void *data, uint sz) int used = 0; int i_read = sz; + WaitUntilBuffered(); + if (m_interrupted) + { + LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("interrupted")); + return 0; + } + do { int segnum = m_playback->Segment(); @@ -2605,9 +2613,10 @@ int HLSRingBuffer::safe_read(void *data, uint sz) i_read -= len; segment->Unlock(); } - while (i_read > 0); + while (i_read > 0 && !m_interrupted); - WaitUntilBuffered(); + if (m_interrupted) + LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("interrupted")); m_playback->AddOffset(used); return used; @@ -2738,14 +2747,17 @@ long long HLSRingBuffer::Seek(long long pos, int whence, bool has_lock) // see if we've already got the segment, and at least 2 buffered after // then no need to wait for streamworker - while (!m_error && + while (!m_error && !m_interrupted && (!m_streamworker->GotBufferedSegments(segnum, 2) && (m_streamworker->CurrentPlaybackBuffer(false) < 2) && !m_streamworker->IsAtEnd())) { - m_streamworker->WaitForSignal(); //1000); + m_streamworker->WaitForSignal(1000); retries++; } + if (m_interrupted) + LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("interrupted")); + m_streamworker->Unlock(); // now seek within found segment @@ -2780,3 +2792,21 @@ bool HLSRingBuffer::IsOpen(void) const { return !m_error && !m_streams.isEmpty() && NumSegments() > 0; } + +void HLSRingBuffer::Interrupt(void) +{ + QMutexLocker lock(&m_lock); + + // segment didn't get downloaded (timeout?) + LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("requesting interrupt")); + m_interrupted = true; +} + +void HLSRingBuffer::Continue(void) +{ + QMutexLocker lock(&m_lock); + + // segment didn't get downloaded (timeout?) + LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("requesting restart")); + m_interrupted = false; +} diff --git a/mythtv/libs/libmythtv/HLS/httplivestreambuffer.h b/mythtv/libs/libmythtv/HLS/httplivestreambuffer.h index 340d6c764b1..ead70fffc8c 100644 --- a/mythtv/libs/libmythtv/HLS/httplivestreambuffer.h +++ b/mythtv/libs/libmythtv/HLS/httplivestreambuffer.h @@ -60,6 +60,8 @@ class HLSRingBuffer : public RingBuffer bool SaveToDisk(QString filename, int segstart = 0, int segend = -1); int NumStreams(void) const; int Read(void *data, uint i_read) { return safe_read(data, i_read); } + void Interrupt(void); + void Continue(void); protected: virtual int safe_read(void *data, uint i_read); @@ -126,6 +128,7 @@ class HLSRingBuffer : public RingBuffer friend class PlaylistWorker; PlaylistWorker *m_playlistworker; FILE *m_fd; + bool m_interrupted; }; #endif diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederhls.cpp b/mythtv/libs/libmythtv/iptv/iptvfeederhls.cpp index a2701be9819..8b1bcf4e357 100644 --- a/mythtv/libs/libmythtv/iptv/iptvfeederhls.cpp +++ b/mythtv/libs/libmythtv/iptv/iptvfeederhls.cpp @@ -72,12 +72,19 @@ void IPTVFeederHLS::Run(void) m_interrupted = false; m_lock.unlock(); + m_hls->Continue(); while (!m_interrupted) { if (m_hls == NULL) break; m_lock.lock(); uint size = m_hls->Read((void *)m_buffer, BUFFER_SIZE); + if (size < 0) + { + m_lock.unlock(); + break; + } + if (m_buffer[0] != 0x47) { LOG(VB_RECORD, LOG_INFO, LOC + @@ -103,8 +110,12 @@ void IPTVFeederHLS::Stop(void) { LOG(VB_RECORD, LOG_INFO, LOC + "Stop() -- begin"); QMutexLocker locker(&m_lock); + m_interrupted = true; + if (m_hls) + m_hls->Interrupt(); + while (m_running) m_waitcond.wait(&m_lock, 500);