Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HLS recorder got removed following the IPTV branch merge a few months ago. Re-implement it using new framework Construct it as a derivative of existing IPTV Stream Handler. Extend IPTVChannel so it doesn't close immediately the stream handler. Instead we mark it for deletion and only delete it 5s later, re-use it if we attempt to use it again within that delay. This is done to speed up startup as the HLS ring buffer can take a long time to start, and the signal monitor attempts to close the stream handler causing too much delay.
- Loading branch information
Showing
6 changed files
with
349 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/** -*- Mode: c++ -*- | ||
* HLSStreamHandler | ||
* Copyright (c) 2013 Bubblestuff Pty Ltd | ||
* based on IPTVStreamHandler | ||
* Distributed as part of MythTV under GPL v2 and later. | ||
*/ | ||
|
||
// MythTV headers | ||
#include "hlsstreamhandler.h" | ||
#include "mythlogging.h" | ||
#include "HLS/httplivestreambuffer.h" | ||
|
||
#define LOC QString("HLSSH(%1): ").arg(_device) | ||
|
||
// BUFFER_SIZE is a multiple of TS_SIZE | ||
#define TS_SIZE 188 | ||
#define BUFFER_SIZE (128 * TS_SIZE) | ||
|
||
QMap<QString,HLSStreamHandler*> HLSStreamHandler::s_handlers; | ||
QMap<QString,uint> HLSStreamHandler::s_handlers_refcnt; | ||
QMutex HLSStreamHandler::s_handlers_lock; | ||
|
||
HLSStreamHandler* HLSStreamHandler::Get(const IPTVTuningData& tuning) | ||
{ | ||
QMutexLocker locker(&s_handlers_lock); | ||
|
||
QString devkey = tuning.GetDeviceKey(); | ||
|
||
QMap<QString,HLSStreamHandler*>::iterator it = s_handlers.find(devkey); | ||
|
||
if (it == s_handlers.end()) | ||
{ | ||
HLSStreamHandler* newhandler = new HLSStreamHandler(tuning); | ||
newhandler->Start(); | ||
s_handlers[devkey] = newhandler; | ||
s_handlers_refcnt[devkey] = 1; | ||
|
||
LOG(VB_RECORD, LOG_INFO, | ||
QString("HLSSH: Creating new stream handler %1 for %2") | ||
.arg(devkey).arg(tuning.GetDeviceName())); | ||
} | ||
else | ||
{ | ||
s_handlers_refcnt[devkey]++; | ||
uint rcount = s_handlers_refcnt[devkey]; | ||
LOG(VB_RECORD, LOG_INFO, | ||
QString("HLSSH: Using existing stream handler %1 for %2") | ||
.arg(devkey).arg(tuning.GetDeviceName()) + | ||
QString(" (%1 in use)").arg(rcount)); | ||
} | ||
|
||
return s_handlers[devkey]; | ||
} | ||
|
||
void HLSStreamHandler::Return(HLSStreamHandler* & ref) | ||
{ | ||
QMutexLocker locker(&s_handlers_lock); | ||
|
||
QString devname = ref->_device; | ||
|
||
QMap<QString,uint>::iterator rit = s_handlers_refcnt.find(devname); | ||
if (rit == s_handlers_refcnt.end()) | ||
return; | ||
|
||
LOG(VB_RECORD, LOG_INFO, QString("HLSSH: Return(%1) has %2 handlers") | ||
.arg(devname).arg(*rit)); | ||
|
||
if (*rit > 1) | ||
{ | ||
ref = NULL; | ||
(*rit)--; | ||
return; | ||
} | ||
|
||
QMap<QString,HLSStreamHandler*>::iterator it = s_handlers.find(devname); | ||
if ((it != s_handlers.end()) && (*it == ref)) | ||
{ | ||
LOG(VB_RECORD, LOG_INFO, QString("HLSSH: Closing handler for %1") | ||
.arg(devname)); | ||
ref->Stop(); | ||
LOG(VB_RECORD, LOG_DEBUG, QString("HLSSH: handler for %1 stopped") | ||
.arg(devname)); | ||
delete *it; | ||
s_handlers.erase(it); | ||
} | ||
else | ||
{ | ||
LOG(VB_GENERAL, LOG_ERR, | ||
QString("HLSSH Error: Couldn't find handler for %1") | ||
.arg(devname)); | ||
} | ||
|
||
s_handlers_refcnt.erase(rit); | ||
ref = NULL; | ||
} | ||
|
||
HLSStreamHandler::HLSStreamHandler(const IPTVTuningData& tuning) : | ||
IPTVStreamHandler(tuning), | ||
m_tuning(tuning) | ||
{ | ||
m_hls = new HLSRingBuffer(m_tuning.GetURL(0).toString(), false); | ||
m_buffer = new uint8_t[BUFFER_SIZE]; | ||
} | ||
|
||
HLSStreamHandler::~HLSStreamHandler(void) | ||
{ | ||
Stop(); | ||
m_hls->Interrupt(); | ||
delete m_hls; | ||
delete[] m_buffer; | ||
} | ||
|
||
void HLSStreamHandler::run(void) | ||
{ | ||
RunProlog(); | ||
|
||
LOG(VB_GENERAL, LOG_INFO, LOC + "run()"); | ||
|
||
SetRunning(true, false, false); | ||
|
||
// TODO Error handling.. | ||
|
||
if (!m_hls->IsOpen()) | ||
{ | ||
m_hls->OpenFile(m_tuning.GetURL(0).toString()); | ||
} | ||
|
||
while (m_hls->IsOpen() && _running_desired) | ||
{ | ||
int size = m_hls->Read((void*)m_buffer, BUFFER_SIZE); | ||
|
||
if (size < 0) | ||
{ | ||
break; // error | ||
} | ||
if (m_buffer[0] != 0x47) | ||
{ | ||
LOG(VB_RECORD, LOG_INFO, LOC + | ||
QString("Packet not starting with SYNC Byte (got 0x%1)") | ||
.arg((char)m_buffer[0], 2, QLatin1Char('0'))); | ||
} | ||
|
||
int remainder = 0; | ||
{ | ||
QMutexLocker locker(&_listener_lock); | ||
HLSStreamHandler::StreamDataList::const_iterator sit; | ||
sit = _stream_data_list.begin(); | ||
for (; sit != _stream_data_list.end(); ++sit) | ||
{ | ||
remainder = sit.key()->ProcessData(m_buffer, size); | ||
} | ||
} | ||
|
||
if (remainder != 0) | ||
{ | ||
LOG(VB_RECORD, LOG_INFO, LOC + | ||
QString("data_length = %1 remainder = %2") | ||
.arg(size).arg(remainder)); | ||
} | ||
} | ||
|
||
SetRunning(false, false, false); | ||
RunEpilog(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** -*- Mode: c++ -*- | ||
* HLSStreamHandler | ||
* Copyright (c) 2013 Bubblestuff Pty Ltd | ||
* based on IPTVStreamHandler | ||
* Distributed as part of MythTV under GPL v2 and later. | ||
*/ | ||
|
||
#ifndef _HLSSTREAMHANDLER_H_ | ||
#define _HLSSTREAMHANDLER_H_ | ||
|
||
#include <vector> | ||
using namespace std; | ||
|
||
#include <QString> | ||
#include <QMutex> | ||
#include <QMap> | ||
|
||
#include "channelutil.h" | ||
#include "iptvstreamhandler.h" | ||
|
||
class MPEGStreamData; | ||
class HLSRingBuffer; | ||
|
||
class HLSStreamHandler : public IPTVStreamHandler | ||
{ | ||
public: | ||
static HLSStreamHandler* Get(const IPTVTuningData& tuning); | ||
static void Return(HLSStreamHandler* & ref); | ||
|
||
protected: | ||
HLSStreamHandler(const IPTVTuningData &tuning); | ||
virtual ~HLSStreamHandler(void); | ||
|
||
virtual void run(void); // MThread | ||
|
||
protected: | ||
IPTVTuningData m_tuning; | ||
HLSRingBuffer* m_hls; | ||
uint8_t* m_buffer; | ||
|
||
// for implementing Get & Return | ||
static QMutex s_handlers_lock; | ||
static QMap<QString, HLSStreamHandler*> s_handlers; | ||
static QMap<QString, uint> s_handlers_refcnt; | ||
}; | ||
|
||
#endif // _HLSSTREAMHANDLER_H_ |
Oops, something went wrong.