Skip to content

Commit

Permalink
Merge pull request #382 from ksooo/rds-support-dyn
Browse files Browse the repository at this point in the history
Create RDS stream only if audio stream actually contains RDS data.
  • Loading branch information
ksooo authored Oct 25, 2018
2 parents db8e489 + bda6b76 commit 8bad7e9
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 17 deletions.
2 changes: 1 addition & 1 deletion pvr.hts/addon.xml.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.hts"
version="4.4.0"
version="4.4.1"
name="Tvheadend HTSP Client"
provider-name="Adam Sutton, Sam Stenvall, Lars Op den Kamp, Kai Sommerfeld">
<requires>@ADDON_DEPENDS@</requires>
Expand Down
3 changes: 3 additions & 0 deletions pvr.hts/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
4.4.1
- Fix creation of RDS streams. Must only be done if audio stream actually contains RDS data.

4.4.0
- Add support for Radio Data System (RDS)
- Enable async EPG data transfer by default
Expand Down
74 changes: 60 additions & 14 deletions src/tvheadend/HTSPDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,21 @@ void HTSPDemuxer::ProcessRDS(uint32_t idx, const void* bin, size_t binlen)
uint8_t rdslen = data[offset - 1];
if (rdslen > 0)
{
const uint32_t rdsIdx = idx - TVH_STREAM_INDEX_OFFSET;
if (m_streamStat.find(rdsIdx) == m_streamStat.end())
{
// No RDS stream yet. Create and announce it.
if (!AddRDSStream(idx, rdsIdx))
return;

// Update streams.
Logger::Log(LogLevel::LEVEL_DEBUG, "demux stream change");

DemuxPacket* pktSpecial = PVR->AllocateDemuxPacket(0);
pktSpecial->iStreamId = DMX_SPECIALID_STREAMCHANGE;
m_pktBuffer.Push(pktSpecial);
}

DemuxPacket* pkt = PVR->AllocateDemuxPacket(rdslen);
if (!pkt)
return;
Expand All @@ -415,7 +430,7 @@ void HTSPDemuxer::ProcessRDS(uint32_t idx, const void* bin, size_t binlen)

memcpy(pkt->pData, rdsdata, rdslen);
pkt->iSize = rdslen;
pkt->iStreamId = idx - TVH_STREAM_INDEX_OFFSET;
pkt->iStreamId = rdsIdx;

m_pktBuffer.Push(pkt);
delete [] rdsdata;
Expand Down Expand Up @@ -513,10 +528,50 @@ void HTSPDemuxer::ParseMuxPacket ( htsmsg_t *m )
PVR->FreeDemuxPacket(pkt);
}

bool HTSPDemuxer::AddStream(const char* type, uint32_t idx, htsmsg_field_t *f)
bool HTSPDemuxer::AddRDSStream(uint32_t audioIdx, uint32_t rdsIdx)
{
CodecDescriptor codecDescriptor = CodecDescriptor::GetCodecByName(type);
xbmc_codec_t codec = codecDescriptor.Codec();
for (const auto& stream : m_streams)
{
if (stream.iPID != audioIdx)
continue;

// Found the stream with the embedded RDS data. Create corresponding RDS stream.
const CodecDescriptor codecDescriptor = CodecDescriptor::GetCodecByName("rds");
const xbmc_codec_t codec = codecDescriptor.Codec();

if (codec.codec_type == XBMC_CODEC_TYPE_UNKNOWN)
return false;

m_streamStat[rdsIdx] = 0;

PVR_STREAM_PROPERTIES::PVR_STREAM rdsStream = {};
rdsStream.iCodecType = codec.codec_type;
rdsStream.iCodecId = codec.codec_id;
rdsStream.iPID = rdsIdx;
strncpy(rdsStream.strLanguage, stream.strLanguage, sizeof(rdsStream.strLanguage) - 1);

// We can only use PVR_STREAM_MAX_STREAMS streams
if (m_streams.size() < PVR_STREAM_MAX_STREAMS)
{
Logger::Log(LogLevel::LEVEL_DEBUG, " id: %d, type rds, codec: %u", rdsIdx, rdsStream.iCodecId);
m_streams.emplace_back(rdsStream);
return true;
}
else
{
Logger::Log(LogLevel::LEVEL_INFO, "Maximum stream limit reached ignoring id: %d, type rds, codec: %u",
rdsIdx, rdsStream.iCodecId);
return false;
}
}
// stream with embedded RDS data not found
return false;
}

bool HTSPDemuxer::AddTVHStream(uint32_t idx, const char* type, htsmsg_field_t *f)
{
const CodecDescriptor codecDescriptor = CodecDescriptor::GetCodecByName(type);
const xbmc_codec_t codec = codecDescriptor.Codec();

if (codec.codec_type == XBMC_CODEC_TYPE_UNKNOWN)
return false;
Expand Down Expand Up @@ -555,15 +610,6 @@ bool HTSPDemuxer::AddStream(const char* type, uint32_t idx, htsmsg_field_t *f)
stream.iSampleRate = htsmsg_get_u32_or_default(&f->hmf_msg, "rate", 48000);
}

/* RDS data */
if (stream.iCodecType == XBMC_CODEC_TYPE_AUDIO &&
!strcmp("MPEG2AUDIO", type))
{
// Add RDS stream for the mpeg2 audio stream. It can contain embedded RDS data.
if (!AddStream("rds", idx - TVH_STREAM_INDEX_OFFSET, f))
return false;
}

/* Video */
if (stream.iCodecType == XBMC_CODEC_TYPE_VIDEO)
{
Expand Down Expand Up @@ -639,7 +685,7 @@ void HTSPDemuxer::ParseSubscriptionStart ( htsmsg_t *m )
continue;

idx += TVH_STREAM_INDEX_OFFSET;
AddStream(type, idx, f);
AddTVHStream(idx, type, f);
}

/* Update streams */
Expand Down
4 changes: 2 additions & 2 deletions src/tvheadend/HTSPDemuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ class HTSPDemuxer
void ParseTimeshiftStatus(htsmsg_t *m);
void ParseDescrambleInfo(htsmsg_t *m);

bool AddStream(const char* type, uint32_t idx, htsmsg_field_t *f);

bool AddTVHStream(uint32_t idx, const char* type, htsmsg_field_t *f);
bool AddRDSStream(uint32_t audioIdx, uint32_t rdsIdx);
void ProcessRDS(uint32_t idx, const void* bin, size_t binlen);

mutable P8PLATFORM::CMutex m_mutex;
Expand Down

0 comments on commit 8bad7e9

Please sign in to comment.