Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] UK DVB-T Freeview channel numbering



Hi,

I'm wondering if the "scan" developers are considering incorporating automatic channel numbering (for applications such as VDR) in the near future for those services that support it? 

If so, I have attached a small patch (created against the CVS dvb-apps tree) to retrieve the channel numbers for the UK terrestrial "Freeview" service for use in VDR 1.2.xx. The channel numbers can be found in the NIT table as the user-defined descriptor 0x83 and each channel number has a corresponding Service ID which is included in the descriptor. My coding skills are not excellent, so please feel free to amend the code if necessary.

Short example of VDR output:

:@20
f tn:825833:I0B8C34D0M16T2G32Y0:T:27500:301:302,304:0:0:25856:0:0:0
:@21
TMF:825833:I0B8C34D0M16T2G32Y0:T:27500:201:202,204:0:0:25728:0:0:0

Cheers,

John


diff --unified --recursive --new-file dvb-apps/util/scan/dump-vdr.c dvb-apps-new/util/scan/dump-vdr.c
--- dvb-apps/util/scan/dump-vdr.c	2004-01-19 00:30:27.301710936 +0000
+++ dvb-apps-new/util/scan/dump-vdr.c	2004-01-19 00:37:16.109562696 +0000
@@ -126,11 +126,15 @@
 				 int we_flag,
 				 int dump_provider,
 				 int ca_select,
-				 int vdr_version)
+				 int vdr_version,
+				 int dump_channum,
+				 int channel_num)
 {
         int i;
 
 	if ((video_pid || audio_pid[0]) && ((ca_select > 0) || ((ca_select == 0) && (scrambled == 0)))) {
+		if ((dump_channum == 1) && (channel_num > 0))
+			fprintf(f, ":@%i\n", channel_num);
 		if (dump_provider == 1)
 			fprintf (f, "%s - ", provider_name);
 		fprintf (f, "%s:", service_name);
diff --unified --recursive --new-file dvb-apps/util/scan/dump-vdr.h dvb-apps-new/util/scan/dump-vdr.h
--- dvb-apps/util/scan/dump-vdr.h	2004-01-19 00:30:27.530676128 +0000
+++ dvb-apps-new/util/scan/dump-vdr.h	2004-01-19 00:37:21.581730800 +0000
@@ -30,7 +30,9 @@
 				 int we_flag,
 				 int dump_provider,
 				 int ca_select,
-				 int vdr_version);
+				 int vdr_version,
+				 int dump_channum,
+				 int channel_num);
 
 #endif
 
diff --unified --recursive --new-file dvb-apps/util/scan/scan.c dvb-apps-new/util/scan/scan.c
--- dvb-apps/util/scan/scan.c	2004-01-19 00:30:35.191511504 +0000
+++ dvb-apps-new/util/scan/scan.c	2004-01-19 00:47:52.760777000 +0000
@@ -46,6 +46,7 @@
 static int current_tp_only;
 static int get_other_nits;
 static int vdr_dump_provider;
+static int vdr_dump_channum;
 static int ca_select = 1;
 static int serv_select = 7;
 static int vdr_version = 2;
@@ -106,6 +107,7 @@
 	unsigned int scrambled	  : 1;
 	enum running_mode running;
 	void *priv;
+	int channel_num;
 };
 
 struct transponder {
@@ -305,6 +307,36 @@
 	info("Network Name '%.*s'\n", len, buf + 2);
 }
 
+static void parse_terrestrial_uk_channel_number (const unsigned char *buf, void *dummy)
+{
+	int i, n, channel_num, service_id;
+	struct list_head *p1, *p2;
+	struct transponder *t;
+	struct service *s;
+	
+	// 32 bits per record
+	n = buf[1] / 4;
+	if (n < 1)
+		return;
+
+	// desc id, desc len, (service id, service number)
+	buf += 2;
+	for (i = 0; i < n; i++) {
+		service_id = (buf[0]<<8)|(buf[1]&0xff);
+		channel_num = (buf[2]&0x03<<8)|(buf[3]&0xff);
+		debug("Service ID 0x%x has channel number %d ", service_id, channel_num);
+		list_for_each(p1, &scanned_transponders) {
+			t = list_entry(p1, struct transponder, list);
+			list_for_each(p2, &t->services) {
+				s = list_entry(p2, struct service, list);
+				if (s->service_id == service_id)
+					s->channel_num = channel_num;
+			}
+		}
+		buf += 4;
+	}
+}
+
 
 static long bcd32_to_cpu (const int b0, const int b1, const int b2, const int b3)
 {
@@ -601,6 +633,11 @@
 			if (t == NIT)
 				parse_frequency_list_descriptor (buf, data);
 			break;
+		
+		case 0x83:
+			if (t == NIT)
+				parse_terrestrial_uk_channel_number (buf, data);
+			break;
 
 		default:
 			verbosedebug("skip descriptor 0x%02x\n", descriptor_tag);
@@ -1633,7 +1670,9 @@
 						    t->we_flag,
 						    vdr_dump_provider,
 						    ca_select,
-						    vdr_version);
+						    vdr_version,
+						    vdr_dump_channum,
+						    s->channel_num);
 				break;
 			  case OUTPUT_ZAP:
 				zap_dump_service_parameter_set (stdout,
@@ -1685,7 +1724,8 @@
 	"	-e N	VDR version, default 2 for VDR-1.2.x\n"
 	"		ANYTHING ELSE GIVES NONZERO NIT and TID\n"
 	"	-l lnb-type (DVB-S Only) (use -l help to print types) or \n"
-	"	-l low[,high[,switch]] in Mhz\n";
+	"	-l low[,high[,switch]] in Mhz\n"
+	"	-u      UK DVB-T Freeview channel numbering for VDR\n";
 
 void
 bad_usage(char *pname, int prlnb)
@@ -1720,7 +1760,7 @@
 
 	/* start with default lnb type */
 	lnb_type = *lnb_enum(0);
-	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vq")) != -1) {
+	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vq:u")) != -1) {
 		switch (opt) {
 		case 'a':
 			adapter = strtoul(optarg, NULL, 0);
@@ -1781,6 +1821,9 @@
 			if (--verbosity < 0)
 				verbosity = 0;
 			break;
+		case 'u':
+			vdr_dump_channum = 1;
+			break;
 		default:
 			bad_usage(argv[0], 0);
 			return -1;


Home | Main Index | Thread Index