mirror of
https://github.com/rofafor/vdr-plugin-satip.git
synced 2023-10-10 13:37:42 +02:00
Add preliminary support for DVBViewer CI.
This commit is contained in:
parent
9c91e01a87
commit
e7c9b04ad2
7
device.c
7
device.c
@ -469,6 +469,13 @@ int cSatipDevice::GetCISlot(void)
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString cSatipDevice::GetTnrParameterString(void)
|
||||||
|
{
|
||||||
|
if (channelM.Ca())
|
||||||
|
return GetTnrUrlParameters(&channelM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool cSatipDevice::IsIdle(void)
|
bool cSatipDevice::IsIdle(void)
|
||||||
{
|
{
|
||||||
return !Receiving();
|
return !Receiving();
|
||||||
|
1
device.h
1
device.h
@ -110,6 +110,7 @@ public:
|
|||||||
virtual int GetId(void);
|
virtual int GetId(void);
|
||||||
virtual int GetPmtPid(void);
|
virtual int GetPmtPid(void);
|
||||||
virtual int GetCISlot(void);
|
virtual int GetCISlot(void);
|
||||||
|
virtual cString GetTnrParameterString(void);
|
||||||
virtual bool IsIdle(void);
|
virtual bool IsIdle(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ public:
|
|||||||
virtual int GetId(void) = 0;
|
virtual int GetId(void) = 0;
|
||||||
virtual int GetPmtPid(void) = 0;
|
virtual int GetPmtPid(void) = 0;
|
||||||
virtual int GetCISlot(void) = 0;
|
virtual int GetCISlot(void) = 0;
|
||||||
|
virtual cString GetTnrParameterString(void) = 0;
|
||||||
virtual bool IsIdle(void) = 0;
|
virtual bool IsIdle(void) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
310
param.c
310
param.c
@ -194,3 +194,313 @@ cString GetTransponderUrlParameters(const cChannel *channelP)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString GetTnrUrlParameters(const cChannel *channelP)
|
||||||
|
{
|
||||||
|
if (channelP) {
|
||||||
|
cDvbTransponderParameters dtp(channelP->Parameters());
|
||||||
|
eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
|
||||||
|
|
||||||
|
// TunerType: Byte;
|
||||||
|
// 0 = cable, 1 = satellite, 2 = terrestrial, 3 = atsc, 4 = iptv, 5 = stream (URL, DVBViewer GE)
|
||||||
|
int TunerType = 0;
|
||||||
|
if (channelP->IsCable())
|
||||||
|
TunerType = 0;
|
||||||
|
else if (channelP->IsSat())
|
||||||
|
TunerType = 1;
|
||||||
|
else if (channelP->IsTerr())
|
||||||
|
TunerType = 2;
|
||||||
|
else if (channelP->IsAtsc())
|
||||||
|
TunerType = 3;
|
||||||
|
|
||||||
|
// Frequency: DWord;
|
||||||
|
// DVB-S: MHz if < 1000000, kHz if >= 1000000
|
||||||
|
// DVB-T/C, ATSC: kHz
|
||||||
|
// IPTV: IP address Byte3.Byte2.Byte1.Byte0
|
||||||
|
int Frequency = channelP->Frequency() / 1000;
|
||||||
|
|
||||||
|
// Symbolrate: DWord;
|
||||||
|
// DVB S/C: in kSym/s
|
||||||
|
// DVB-T, ATSC: 0
|
||||||
|
// IPTV: Port
|
||||||
|
int Symbolrate = (channelP->IsSat() || channelP->IsCable()) ? channelP->Srate() : 0;
|
||||||
|
|
||||||
|
// LNB_LOF: Word;
|
||||||
|
// DVB-S: Local oscillator frequency of the LNB
|
||||||
|
// DVB-T/C, ATSC: 0
|
||||||
|
// IPTV: Byte0 and Byte1 of Source IP
|
||||||
|
int LNB_LOF = channelP->IsSat() ? Setup.LnbSLOF : 0;
|
||||||
|
|
||||||
|
// Tone: Byte;
|
||||||
|
// 0 = off, 1 = 22 khz
|
||||||
|
int Tone = (channelP->Frequency() < Setup.LnbSLOF) ? 0 : 1;
|
||||||
|
|
||||||
|
// Polarity: Byte;
|
||||||
|
// DVB-S polarity: 0 = horizontal, 1 = vertical, 2 = circular left, 3 = circular right
|
||||||
|
// DVB-C modulation: 0 = Auto, 1 = 16QAM, 2 = 32QAM, 3 = 64QAM, 4 = 128QAM, 5 = 256 QAM
|
||||||
|
// DVB-T bandwidth: 0 = 6 MHz, 1 = 7 MHz, 2 = 8 MHz
|
||||||
|
// IPTV: Byte3 of SourceIP
|
||||||
|
int Polarity = 0;
|
||||||
|
if (channelP->IsSat()) {
|
||||||
|
switch (tolower(dtp.Polarization())) {
|
||||||
|
case 'h':
|
||||||
|
Polarity = 0;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
Polarity = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
Polarity = 2;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
Polarity = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channelP->IsCable()) {
|
||||||
|
switch (dtp.Modulation()) {
|
||||||
|
case 999:
|
||||||
|
Polarity = 0;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
Polarity = 1;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
Polarity = 2;
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
Polarity = 3;
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
Polarity = 4;
|
||||||
|
break;
|
||||||
|
case 256:
|
||||||
|
Polarity = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channelP->IsTerr()) {
|
||||||
|
switch (dtp.Bandwidth()) {
|
||||||
|
case 6:
|
||||||
|
Polarity = 0;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
Polarity = 1;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
Polarity = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DiSEqC: Byte;
|
||||||
|
// 0 = None
|
||||||
|
// 1 = Pos A (mostly translated to PosA/OptA)
|
||||||
|
// 2 = Pos B (mostly translated to PosB/OptA)
|
||||||
|
// 3 = PosA/OptA
|
||||||
|
// 4 = PosB/OptA
|
||||||
|
// 5 = PosA/OptB
|
||||||
|
// 6 = PosB/OptB
|
||||||
|
// 7 = Preset Position (DiSEqC 1.2, see DiSEqCExt)
|
||||||
|
// 8 = Angular Position (DiSEqC 1.2, see DiSEqCExt)
|
||||||
|
// 9 = DiSEqC Command Sequence (see DiSEqCExt)
|
||||||
|
int DiSEqC = 0;
|
||||||
|
|
||||||
|
// FEC: Byte;
|
||||||
|
// 0 = Auto
|
||||||
|
// 1 = 1/2
|
||||||
|
// 2 = 2/3
|
||||||
|
// 3 = 3/4
|
||||||
|
// 4 = 5/6
|
||||||
|
// 5 = 7/8
|
||||||
|
// 6 = 8/9
|
||||||
|
// 7 = 3/5
|
||||||
|
// 8 = 4/5
|
||||||
|
// 9 = 9/10
|
||||||
|
// IPTV: Byte2 of SourceIP
|
||||||
|
// DVB C/T, ATSC: 0
|
||||||
|
int FEC = 0;
|
||||||
|
if (channelP->IsSat()) {
|
||||||
|
switch (dtp.CoderateH()) {
|
||||||
|
case 999:
|
||||||
|
FEC = 0;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
FEC = 1;
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
FEC = 2;
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
FEC = 3;
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
FEC = 4;
|
||||||
|
break;
|
||||||
|
case 78:
|
||||||
|
FEC = 5;
|
||||||
|
break;
|
||||||
|
case 89:
|
||||||
|
FEC = 6;
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
FEC = 7;
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
FEC = 8;
|
||||||
|
break;
|
||||||
|
case 910:
|
||||||
|
FEC = 9;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio_PID: Word;
|
||||||
|
int Audio_PID = channelP->Apid(0);
|
||||||
|
if (IS_AUDIO_TRACK(track))
|
||||||
|
Audio_PID = channelP->Apid(int(track - ttAudioFirst));
|
||||||
|
else if (IS_DOLBY_TRACK(track))
|
||||||
|
Audio_PID = channelP->Dpid(int(track - ttDolbyFirst));
|
||||||
|
|
||||||
|
// Video_PID: Word;
|
||||||
|
int Video_PID = channelP->Vpid();
|
||||||
|
|
||||||
|
// PMT_PID: Word;
|
||||||
|
int PMT_PID = channelP->Ppid();
|
||||||
|
|
||||||
|
// Service_ID: Word;
|
||||||
|
int Service_ID = channelP->Sid();
|
||||||
|
|
||||||
|
// SatModulation: Byte;
|
||||||
|
// Bit 0..1: satellite modulation. 0 = Auto, 1 = QPSK, 2 = 8PSK, 3 = 16QAM or APSK for DVB-S2
|
||||||
|
// Bit 2: modulation system. 0 = DVB-S/T/C, 1 = DVB-S2/T2/C2
|
||||||
|
// Bit 3..4: DVB-S2: roll-off. 0 = 0.35, 1 = 0.25, 2 = 0.20, 3 = reserved
|
||||||
|
// Bit 5..6: spectral inversion, 0 = undefined, 1 = auto, 2 = normal, 3 = inverted
|
||||||
|
// Bit 7: DVB-S2: pilot symbols, 0 = off, 1 = on
|
||||||
|
// DVB-T2: DVB-T2 Lite, 0 = off, 1 = on
|
||||||
|
int SatModulation = 0;
|
||||||
|
if (channelP->IsSat() && dtp.System()) {
|
||||||
|
switch (dtp.Modulation()) {
|
||||||
|
case 999:
|
||||||
|
SatModulation |= (0 & 0x3) << 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
SatModulation |= (1 & 0x3) << 0;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
SatModulation |= (2 & 0x3) << 0;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
SatModulation |= (3 & 0x3) << 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SatModulation |= (dtp.System() & 0x1) << 2;
|
||||||
|
if (channelP->IsSat() && dtp.System()) {
|
||||||
|
switch (dtp.RollOff()) {
|
||||||
|
case 35:
|
||||||
|
SatModulation |= (0 & 0x3) << 3;
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
SatModulation |= (1 & 0x3) << 3;
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
SatModulation |= (2 & 0x3) << 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (dtp.Inversion()) {
|
||||||
|
case 999:
|
||||||
|
SatModulation |= (1 & 0x3) << 5;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
SatModulation |= (2 & 0x3) << 5;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
SatModulation |= (3 & 0x3) << 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (channelP->IsSat() && dtp.System()) {
|
||||||
|
switch (dtp.Pilot()) {
|
||||||
|
case 0:
|
||||||
|
SatModulation |= (0 & 0x1) << 7;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
SatModulation |= (1 & 0x1) << 7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DiSEqCExt: Word;
|
||||||
|
// DiSEqC Extension, meaning depends on DiSEqC
|
||||||
|
// DiSEqC = 0..6: 0
|
||||||
|
// DiSEqC = 7: Preset Position (DiSEqC 1.2)
|
||||||
|
// DiSEqC = 8: Orbital Position (DiSEqC 1.2, USALS, for calculating motor angle)
|
||||||
|
// Same format as OrbitalPos above
|
||||||
|
// DiSEQC = 9: Orbital Position referencing DiSEqC sequence defined in DiSEqC.xml/ini
|
||||||
|
// Same format as OrbitalPos above
|
||||||
|
int DiSEqCExt = 0;
|
||||||
|
|
||||||
|
// Flags: Byte;
|
||||||
|
// Bit 0: 1 = encrypted channel
|
||||||
|
// Bit 1: reserved, set to 0
|
||||||
|
// Bit 2: 1 = channel broadcasts RDS data
|
||||||
|
// Bit 3: 1 = channel is a video service (even if the Video PID is temporarily = 0)
|
||||||
|
// Bit 4: 1 = channel is an audio service (even if the Audio PID is temporarily = 0)
|
||||||
|
// Bit 5: 1 = audio has a different samplerate than 48 KHz
|
||||||
|
// Bit 6: 1 = bandstacking, internally polarisation is always set to H
|
||||||
|
// Bit 7: 1 = channel entry is an additional audio track of the preceding
|
||||||
|
// channel with bit 7 = 0
|
||||||
|
int Flags = (channelP->Ca() > 0xFF) ? 1 : 0;
|
||||||
|
|
||||||
|
// ChannelGroup: Byte;
|
||||||
|
// 0 = Group A, 1 = Group B, 2 = Group C etc.
|
||||||
|
int ChannelGroup = 0;
|
||||||
|
|
||||||
|
// TransportStream_ID: Word;
|
||||||
|
int TransportStream_ID = channelP->Tid();
|
||||||
|
|
||||||
|
// OriginalNetwork_ID: Word;
|
||||||
|
int OriginalNetwork_ID = channelP->Nid();
|
||||||
|
|
||||||
|
// Substream: Word;
|
||||||
|
// DVB-S/C/T, ATSC, IPTV: 0
|
||||||
|
// DVB-T2: 0 = PLP_ID not set, 1..256: PLP_ID + 1, 257... reserved
|
||||||
|
int Substream = (channelP->IsTerr() && dtp.System()) ? dtp.StreamId() - 1 : 0;
|
||||||
|
|
||||||
|
// OrbitalPos: Word;
|
||||||
|
// DVB-S: orbital position x 10, 0 = undefined, 1..1800 east, 1801..3599 west (1°W = 3599)
|
||||||
|
// DVB-C: 4000..4999
|
||||||
|
// DVB-T: 5000..5999
|
||||||
|
// ATSC: 6000..6999
|
||||||
|
// IPTV: 7000..7999
|
||||||
|
// Stream: 8000..8999
|
||||||
|
int OrbitalPos = 0;
|
||||||
|
if (channelP->IsSat()) {
|
||||||
|
OrbitalPos = cSource::Position(channelP->Source());
|
||||||
|
if (OrbitalPos != 3600)
|
||||||
|
OrbitalPos += 1800;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cString::sprintf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
|
||||||
|
TunerType, Frequency, Symbolrate, LNB_LOF, Tone, Polarity, DiSEqC, FEC, Audio_PID, Video_PID, PMT_PID, Service_ID,
|
||||||
|
SatModulation, DiSEqCExt, Flags, ChannelGroup, TransportStream_ID, OriginalNetwork_ID, Substream, OrbitalPos);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
1
param.h
1
param.h
@ -11,5 +11,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
cString GetTransponderUrlParameters(const cChannel *channelP);
|
cString GetTransponderUrlParameters(const cChannel *channelP);
|
||||||
|
cString GetTnrUrlParameters(const cChannel *channelP);
|
||||||
|
|
||||||
#endif // __SATIP_PARAM_H
|
#endif // __SATIP_PARAM_H
|
||||||
|
18
server.c
18
server.c
@ -146,12 +146,26 @@ cSatipServer::cSatipServer(const char *addressP, const int portP, const char *mo
|
|||||||
quirkM |= eSatipQuirkForceLock;
|
quirkM |= eSatipQuirkForceLock;
|
||||||
quirksM = cString::sprintf("%s%sForceLock", *quirksM, isempty(*quirksM) ? "" : ",");
|
quirksM = cString::sprintf("%s%sForceLock", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
}
|
}
|
||||||
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
|
||||||
}
|
|
||||||
// These devices support the X_PMT protocol extension
|
// These devices support the X_PMT protocol extension
|
||||||
if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet
|
if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet
|
||||||
strstr(*descriptionM, "minisatip") // minisatip server
|
strstr(*descriptionM, "minisatip") // minisatip server
|
||||||
) {
|
) {
|
||||||
|
quirkM |= eSatipQuirkCiXpmt;
|
||||||
|
quirksM = cString::sprintf("%s%sCiXpmt", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
|
}
|
||||||
|
// These devices support the TNR protocol extension
|
||||||
|
if (strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
||||||
|
) {
|
||||||
|
quirkM |= eSatipQuirkCiTnr;
|
||||||
|
quirksM = cString::sprintf("%s%sCiTnr", *quirksM, isempty(*quirksM) ? "" : ",");
|
||||||
|
}
|
||||||
|
debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM);
|
||||||
|
}
|
||||||
|
// These devices support external CI
|
||||||
|
if (strstr(*descriptionM, "OctopusNet") || // Digital Devices OctopusNet
|
||||||
|
strstr(*descriptionM, "minisatip") || // minisatip server
|
||||||
|
strstr(*descriptionM, "DVBViewer") // DVBViewer Media Server
|
||||||
|
) {
|
||||||
hasCiM = true;
|
hasCiM = true;
|
||||||
}
|
}
|
||||||
char *s, *p = strdup(*modelM);
|
char *s, *p = strdup(*modelM);
|
||||||
|
4
server.h
4
server.h
@ -79,7 +79,9 @@ public:
|
|||||||
eSatipQuirkPlayPids = 0x02,
|
eSatipQuirkPlayPids = 0x02,
|
||||||
eSatipQuirkForceLock = 0x04,
|
eSatipQuirkForceLock = 0x04,
|
||||||
eSatipQuirkRtpOverTcp = 0x08,
|
eSatipQuirkRtpOverTcp = 0x08,
|
||||||
eSatipQuirkMask = 0x0F
|
eSatipQuirkCiXpmt = 0x10,
|
||||||
|
eSatipQuirkCiTnr = 0x20,
|
||||||
|
eSatipQuirkMask = 0xFF
|
||||||
};
|
};
|
||||||
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP);
|
cSatipServer(const char *addressP, const int portP, const char *modelP, const char *filtersP, const char *descriptionP);
|
||||||
virtual ~cSatipServer();
|
virtual ~cSatipServer();
|
||||||
|
12
tuner.c
12
tuner.c
@ -25,6 +25,7 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
|
|||||||
rtcpM(*this),
|
rtcpM(*this),
|
||||||
streamAddrM(""),
|
streamAddrM(""),
|
||||||
streamParamM(""),
|
streamParamM(""),
|
||||||
|
tnrParamM(""),
|
||||||
streamPortM(SATIP_DEFAULT_RTSP_PORT),
|
streamPortM(SATIP_DEFAULT_RTSP_PORT),
|
||||||
currentServerM(NULL, deviceP.GetId(), 0),
|
currentServerM(NULL, deviceP.GetId(), 0),
|
||||||
nextServerM(NULL, deviceP.GetId(), 0),
|
nextServerM(NULL, deviceP.GetId(), 0),
|
||||||
@ -210,6 +211,7 @@ bool cSatipTuner::Connect(void)
|
|||||||
|
|
||||||
if (!isempty(*streamAddrM)) {
|
if (!isempty(*streamAddrM)) {
|
||||||
cString connectionUri = GetBaseUrl(*streamAddrM, streamPortM);
|
cString connectionUri = GetBaseUrl(*streamAddrM, streamPortM);
|
||||||
|
tnrParamM = "";
|
||||||
// Just retune
|
// Just retune
|
||||||
if (streamIdM >= 0) {
|
if (streamIdM >= 0) {
|
||||||
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
|
cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM);
|
||||||
@ -445,6 +447,7 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids());
|
uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids());
|
||||||
}
|
}
|
||||||
if (useci) {
|
if (useci) {
|
||||||
|
if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkCiXpmt)) {
|
||||||
// CI extension parameters:
|
// CI extension parameters:
|
||||||
// - x_pmt : specifies the PMT of the service you want the CI to decode
|
// - x_pmt : specifies the PMT of the service you want the CI to decode
|
||||||
// - x_ci : specfies which CI slot (1..n) to use
|
// - x_ci : specfies which CI slot (1..n) to use
|
||||||
@ -460,6 +463,15 @@ bool cSatipTuner::UpdatePids(bool forceP)
|
|||||||
}
|
}
|
||||||
pmtPidM = pid;
|
pmtPidM = pid;
|
||||||
}
|
}
|
||||||
|
else if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkCiTnr)) {
|
||||||
|
// CI extension parameters:
|
||||||
|
// - tnr : specifies a channel config entry
|
||||||
|
cString param = deviceM->GetTnrParameterString();
|
||||||
|
if (!isempty(*param) && strcmp(*tnrParamM, *param) != 0)
|
||||||
|
uri = cString::sprintf("%s&tnr=%s", *uri, *param);
|
||||||
|
tnrParamM = param;
|
||||||
|
}
|
||||||
|
}
|
||||||
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
pidUpdateCacheM.Set(ePidUpdateIntervalMs);
|
||||||
if (!rtspM.Play(*uri))
|
if (!rtspM.Play(*uri))
|
||||||
return false;
|
return false;
|
||||||
|
1
tuner.h
1
tuner.h
@ -99,6 +99,7 @@ private:
|
|||||||
cSatipRtcp rtcpM;
|
cSatipRtcp rtcpM;
|
||||||
cString streamAddrM;
|
cString streamAddrM;
|
||||||
cString streamParamM;
|
cString streamParamM;
|
||||||
|
cString tnrParamM;
|
||||||
int streamPortM;
|
int streamPortM;
|
||||||
cSatipTunerServer currentServerM;
|
cSatipTunerServer currentServerM;
|
||||||
cSatipTunerServer nextServerM;
|
cSatipTunerServer nextServerM;
|
||||||
|
Loading…
Reference in New Issue
Block a user