summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY2
-rw-r--r--nit.c81
-rw-r--r--nit.h16
3 files changed, 96 insertions, 3 deletions
diff --git a/HISTORY b/HISTORY
index dee12d0a..76cf574f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -2606,3 +2606,5 @@ Video Disk Recorder Revision History
and satellite transponders.
- Added 'libsi' include files to the 'include' directory, so that plugins can
use them (thanks to Marcel Wiesweg).
+- Now only processing NITs that contain the transponder they are actually
+ broadcast on.
diff --git a/nit.c b/nit.c
index 652b03af..f236be9f 100644
--- a/nit.c
+++ b/nit.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: nit.c 1.3 2004/01/18 10:09:47 kls Exp $
+ * $Id: nit.c 1.4 2004/01/18 16:31:08 kls Exp $
*/
#include "nit.h"
@@ -17,12 +17,16 @@
cNitFilter::cNitFilter(void)
{
+ numNits = 0;
+ networkId = 0;
Set(0x10, 0x40); // NIT
}
void cNitFilter::SetStatus(bool On)
{
cFilter::SetStatus(On);
+ numNits = 0;
+ networkId = 0;
sectionSyncer.Reset();
}
@@ -31,7 +35,59 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
SI::NIT nit(Data, false);
if (!nit.CheckCRCAndParse())
return;
- if (!sectionSyncer.Sync(nit.getVersionNumber(), nit.getSectionNumber(), nit.getLastSectionNumber()))
+ // Some broadcasters send more than one NIT, with no apparent way of telling which
+ // one is the right one to use. This is an attempt to find the NIT that contains
+ // the transponder it was transmitted on and use only that one:
+ int ThisNIT = -1;
+ if (!networkId) {
+ for (int i = 0; i < numNits; i++) {
+ if (nits[i].networkId == nit.getNetworkId()) {
+ if (nit.getSectionNumber() == 0) {
+ // all NITs have passed by
+ for (int j = 0; j < numNits; j++) {
+ if (nits[j].hasTransponder) {
+ networkId = nits[j].networkId;
+ //printf("taking NIT with network ID %d\n", networkId);
+ //XXX what if more than one NIT contaisn this transponder???
+ break;
+ }
+ }
+ if (!networkId) {
+ //printf("none of the NITs contains transponder %d\n", Transponder());
+ return;
+ }
+ }
+ else {
+ ThisNIT = i;
+ break;
+ }
+ }
+ }
+ if (!networkId && ThisNIT < 0 && numNits < MAXNITS) {
+ if (nit.getSectionNumber() == 0) {
+ *nits[numNits].name = 0;
+ SI::Descriptor *d;
+ for (SI::Loop::Iterator it; (d = nit.commonDescriptors.getNext(it)); ) {
+ switch (d->getDescriptorTag()) {
+ case SI::NetworkNameDescriptorTag: {
+ SI::NetworkNameDescriptor *nnd = (SI::NetworkNameDescriptor *)d;
+ nnd->name.getText(nits[numNits].name);
+ }
+ break;
+ default: ;
+ }
+ }
+ nits[numNits].networkId = nit.getNetworkId();
+ nits[numNits].hasTransponder = false;
+ //printf("NIT[%d] %5d '%s'\n", numNits, nits[numNits].networkId, nits[numNits].name);
+ ThisNIT = numNits;
+ numNits++;
+ }
+ }
+ }
+ else if (networkId != nit.getNetworkId())
+ return; // ignore all other NITs
+ else if (!sectionSyncer.Sync(nit.getVersionNumber(), nit.getSectionNumber(), nit.getLastSectionNumber()))
return;
if (!Channels.Lock(true, 10))
return;
@@ -49,6 +105,13 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
int CodeRate = CodeRates[sd->getFecInner()];
int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
+ if (ThisNIT >= 0) {
+ if (ISTRANSPONDER(Frequency, Transponder())) {
+ nits[ThisNIT].hasTransponder = true;
+ //printf("has transponder %d\n", Transponder());
+ }
+ break;
+ }
bool found = false;
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
@@ -77,6 +140,13 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
int Modulation = Modulations[min(sd->getModulation(), 6)];
int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
+ if (ThisNIT >= 0) {
+ if (ISTRANSPONDER(Frequency / 1000, Transponder())) {
+ nits[ThisNIT].hasTransponder = true;
+ //printf("has transponder %d\n", Transponder());
+ }
+ break;
+ }
bool found = false;
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
@@ -112,6 +182,13 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
int GuardInterval = GuardIntervals[sd->getGuardInterval()];
static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO };
int TransmissionMode = TransmissionModes[sd->getTransmissionMode()];
+ if (ThisNIT >= 0) {
+ if (ISTRANSPONDER(Frequency / 1000000, Transponder())) {
+ nits[ThisNIT].hasTransponder = true;
+ //printf("has transponder %d\n", Transponder());
+ }
+ break;
+ }
bool found = false;
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
diff --git a/nit.h b/nit.h
index e7d987df..018902c3 100644
--- a/nit.h
+++ b/nit.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: nit.h 1.1 2004/01/11 14:31:05 kls Exp $
+ * $Id: nit.h 1.2 2004/01/18 16:31:08 kls Exp $
*/
#ifndef __NIT_H
@@ -12,9 +12,23 @@
#include "filter.h"
+#define MAXNITS 16
+#define MAXNETWORKNAME 256
+
class cNitFilter : public cFilter {
private:
+
+ class cNit {
+ public:
+ u_short networkId;
+ char name[MAXNETWORKNAME];
+ bool hasTransponder;
+ };
+
cSectionSyncer sectionSyncer;
+ cNit nits[MAXNITS];
+ u_short networkId;
+ int numNits;
protected:
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
public: