Skip to content

Commit

Permalink
Allow user to force a specific HLS bitrate to record. Right now there…
Browse files Browse the repository at this point in the history
… is no

UI to make this easy, and I have mostly used it as a debugging tool.

To use this, the channel and iptv_channel tables need to be updated.

In the channel table, create a separate channel entry for each bitrate.  In other
words, instead of just having a SKYNEWS channel and allowing myth to auto
select the best bitrate for the available bandwidth, create three separate
SKYNEWS channels:  SKYNEWS-1, SKYNEWS-2, SKYNEWS-3.

INSERT INTO `channel` (`chanid`, `channum`, `freqid`, `sourceid`,
`callsign`, `name`, `icon`, `finetune`, `videofilters`, `xmltvid`,
`recpriority`, `contrast`, `brightness`, `colour`, `hue`, `tvformat`,
`visible`, `outputfilters`, `useonairguide`, `mplexid`, `serviceid`,
`tmoffset`, `atsc_major_chan`, `atsc_minor_chan`, `last_record`,
`default_authority`, `commmethod`, `iptvid`) VALUES
(5051,'5-1',NULL,5,'SKYNEWS-1','SKYNEWS-1','',NULL,'','19572',0,32768,32768,32768,32768,'Default',1,'',0,NULL,0,0,0,0,'2014-02-20 21:40:47','',-1,NULL),
(5052,'5-2',NULL,5,'SKYNEWS-2','SKYNEWS-2','',NULL,'','19572',0,32768,32768,32768,32768,'Default',1,'',0,NULL,0,0,0,0,'2014-02-20 21:40:47','',-1,NULL),
(5053,'5-3',NULL,5,'SKYNEWS-3','SKYNEWS-3','',NULL,'','19572',0,32768,32768,32768,32768,'Default',1,'',0,NULL,0,0,0,0,'2014-02-20
21:40:47','',-1,NULL);

In the iptv_channel table, also create a separate channel entry for each
bitrate, and set the 'bitrate' column to be the index of the desired
bitrate.

INSERT INTO `iptv_channel` (`chanid`, `url`, `type`, `bitrate`)
VALUES
(5051,'http://skynews-1.ml.llnwd.net/skynews_sd/smil:mbr_alpha.smil/playlist.m3u8','data',1),
(5052,'http://skynews-1.ml.llnwd.net/skynews_sd/smil:mbr_alpha.smil/playlist.m3u8','data',2),
(5053,'http://skynews-1.ml.llnwd.net/skynews_sd/smil:mbr_alpha.smil/playlist.m3u8','data',3);

I may change this from using an index to the actual desired bitrate.  If the
feed suddenly changes the bitrates they offer, though, that could cause it
to suddenly stop working.

If users find value in being able to select a specific bitrate, a UI will
have to be developed.
  • Loading branch information
jpoet committed Apr 20, 2014
1 parent 6f246c0 commit 391bf8f
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
7 changes: 4 additions & 3 deletions mythtv/libs/libmythtv/iptvtuningdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,19 @@ class MTV_PUBLIC IPTVTuningData
{
const QUrl u = GetDataURL();
if (IsHLS())
return u.toString();
return QString("%1(%2)").arg(u.toString()).arg(GetBitrate(0));
return QString("%1:%2:%3")
.arg(u.host()).arg(u.userInfo()).arg(u.port()).toLower();
}

QString GetDeviceName(void) const
{
return QString("[data]%1[fectype]%2[fec0]%3[fec1]%4")
return QString("[data]%1[fectype]%2[fec0]%3[fec1]%4%5")
.arg(GetDataURL().toString())
.arg(GetFECTypeString(1))
.arg(GetFECURL1().toString())
.arg(GetFECURL1().toString());
.arg(GetFECURL1().toString())
.arg(GetBitrate(0) ? QString("-%1").arg(GetBitrate(0)) : "");
}

bool operator==(const IPTVTuningData &other) const
Expand Down
44 changes: 33 additions & 11 deletions mythtv/libs/libmythtv/recorders/HLS/HLSReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ static uint64_t MDate(void)
}

HLSReader::HLSReader(void)
: m_curstream(NULL), m_cur_seq(-1), m_fatal(false), m_cancel(false),
: m_curstream(NULL), m_cur_seq(-1), m_bitrate_index(0),
m_fatal(false), m_cancel(false),
m_throttle(true), m_aesmsg(false),
m_playlistworker(NULL), m_streamworker(NULL),
m_playlist_size(0), m_bandwidthcheck(false), m_prebuffer_cnt(10),
Expand All @@ -28,10 +29,12 @@ HLSReader::~HLSReader(void)
LOG(VB_RECORD, LOG_INFO, LOC + "dtor -- end");
}

bool HLSReader::Open(const QString & m3u)
bool HLSReader::Open(const QString & m3u, int bitrate_index)
{
LOG(VB_RECORD, LOG_INFO, LOC + QString("Opening '%1'").arg(m3u));

m_bitrate_index = bitrate_index;

if (IsOpen(m3u))
{
LOG(VB_RECORD, LOG_ERR, LOC + "Already open");
Expand Down Expand Up @@ -77,18 +80,37 @@ bool HLSReader::Open(const QString & m3u)
if (!ParseM3U8(buffer))
return false;

// Select the highest bitrate stream
StreamContainer::iterator Istream;
for (Istream = m_streams.begin(); Istream != m_streams.end(); ++Istream)
if (m_bitrate_index == 0)
{
if (m_curstream == NULL ||
(*Istream)->Bitrate() > m_curstream->Bitrate())
m_curstream = *Istream;
// Select the highest bitrate stream
StreamContainer::iterator Istream;
for (Istream = m_streams.begin(); Istream != m_streams.end(); ++Istream)
{
if (m_curstream == NULL ||
(*Istream)->Bitrate() > m_curstream->Bitrate())
m_curstream = *Istream;
}
}
else
{
if (m_streams.size() < m_bitrate_index)
{
LOG(VB_RECORD, LOG_ERR, LOC +
QString("Open '%1': Only %2 bitrates, %3 is not a valid index")
.arg(m3u)
.arg(m_streams.size())
.arg(m_bitrate_index));
m_fatal = true;
return false;
}

m_curstream = *(m_streams.begin() + (m_bitrate_index - 1));
}

if (!m_curstream)
{
LOG(VB_RECORD, LOG_ERR, LOC + QString("No stream selected"));
m_fatal = true;
return false;
}
LOG(VB_RECORD, LOG_INFO, LOC +
Expand Down Expand Up @@ -967,7 +989,7 @@ bool HLSReader::ParseM3U8(const QByteArray& buffer, HLSRecStream* stream)
EnableDebugging();
Iseg = m_segments.begin() + (behind - max_behind);
m_segments.erase(m_segments.begin(), Iseg);
m_bandwidthcheck = true;
m_bandwidthcheck = (m_bitrate_index == 0);
}
else if (m_debug_cnt > 0)
--m_debug_cnt;
Expand Down Expand Up @@ -1125,7 +1147,7 @@ bool HLSReader::LoadSegments(MythSingleDownload& downloader)
if (!m_curstream)
{
LOG(VB_RECORD, LOG_ERR, LOC + "LoadSegment: current stream not set.");
m_bandwidthcheck = true;
m_bandwidthcheck = (m_bitrate_index == 0);
return false;
}

Expand Down Expand Up @@ -1213,7 +1235,7 @@ bool HLSReader::LoadSegments(MythSingleDownload& downloader)

if (m_prebuffer_cnt == 0)
{
m_bandwidthcheck = true;
m_bandwidthcheck = (m_bitrate_index == 0);
m_prebuffer_cnt = 2;
}
else
Expand Down
5 changes: 3 additions & 2 deletions mythtv/libs/libmythtv/recorders/HLS/HLSReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ class HLSReader
HLSReader(void);
~HLSReader(void);

bool Open(const QString & uri);
bool Open(const QString & uri, int bitrate_index = 0);
void Close(bool quiet = false);
int Read(uint8_t* buffer, int len);
void Throttle(bool val);
bool IsThrottled(void) const { return m_throttle; }
bool IsOpen(const QString& url) const
{ return m_curstream && m_m3u8 == url; }
bool FatalError(void) const { return m_fatal; }

bool LoadMetaPlaylists(MythSingleDownload& downloader);
void ResetStream(void)
Expand All @@ -66,7 +67,6 @@ class HLSReader
static QString RelativeURI(const QString surl, const QString spath);

protected:
bool FatalError(void) const { return m_fatal; }
void Cancel(bool quiet = false);
bool LoadSegments(MythSingleDownload& downloader);
uint PercentBuffered(void) const;
Expand Down Expand Up @@ -128,6 +128,7 @@ class HLSReader
SegmentContainer m_segments;
HLSRecStream *m_curstream;
int64_t m_cur_seq;
int m_bitrate_index;

bool m_fatal;
bool m_cancel;
Expand Down
4 changes: 3 additions & 1 deletion mythtv/libs/libmythtv/recorders/hlsstreamhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ void HLSStreamHandler::run(void)
{
if (!m_hls->IsOpen(url))
{
if (!m_hls->Open(url))
if (!m_hls->Open(url, m_tuning.GetBitrate(0)))
{
if (m_hls->FatalError())
break;
usleep(open_sleep);
if (open_sleep < 20000000)
open_sleep += 500000;
Expand Down
3 changes: 3 additions & 0 deletions mythtv/libs/libmythtv/recorders/iptvchannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ bool IPTVChannel::Tune(const IPTVTuningData &tuning, bool scanning)

m_firsttune = false;

LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Tuned to (%1)")
.arg(tuning.GetDeviceName()));

return true;
}

Expand Down

0 comments on commit 391bf8f

Please sign in to comment.