⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.c

📁 linux TV 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		int hiband = (p.frequency >= SWITCHFREQ);		setup_switch (frontend_fd,			      switch_pos,			      t->polarisation == POLARISATION_VERTICAL ? 0 : 1,			      hiband);		usleep(50000);		if (hiband)			p.frequency -= LOF_HI;		else			p.frequency -= LOF_LO;	}	if (ioctl(frontend_fd, FE_SET_FRONTEND, &p) == -1) {		errorn("Setting frontend parameters failed");		return -1;	}	for (i = 0; i < 10; i++) {		usleep (200000);		if (ioctl(frontend_fd, FE_READ_STATUS, &s) == -1) {			errorn("FE_READ_STATUS failed");			return -1;		}		verbose(">>> tuning status == 0x%02x\n", s);		if (s & FE_HAS_LOCK) {			t->last_tuning_failed = 0;			return 0;		}	}	warning(">>> tuning failed!!!\n");	t->last_tuning_failed = 1;	return -1;}static int tune_to_transponder (int frontend_fd, struct transponder *t){	/* move TP from "new" to "scanned" list */	list_del_init(&t->list);	list_add_tail(&t->list, &scanned_transponders);	t->scan_done = 1;	if (t->type != fe_info.type) {		/* ignore cable descriptors in sat NIT and vice versa */		t->last_tuning_failed = 1;		return -1;	}	if (__tune_to_transponder (frontend_fd, t) == 0)		return 0;	return __tune_to_transponder (frontend_fd, t);}static int tune_to_next_transponder (int frontend_fd){	struct list_head *pos, *tmp;	struct transponder *t;	list_for_each_safe(pos, tmp, &new_transponders) {		t = list_entry (pos, struct transponder, list);retry:		if (tune_to_transponder (frontend_fd, t) == 0)			return 0;		if (t->other_frequency_flag &&				t->other_f &&				t->n_other_f) {			t->param.frequency = t->other_f[t->n_other_f - 1];			t->n_other_f--;			info("retrying with f=%d\n", t->param.frequency);			goto retry;		}	}	return -1;}struct strtab {	const char *str;	int val;};static int str2enum(const char *str, const struct strtab *tab, int deflt){	while (tab->str) {		if (!strcmp(tab->str, str))			return tab->val;		tab++;	}	error("invalid enum value '%s'\n", str);	return deflt;}static enum fe_code_rate str2fec(const char *fec){	struct strtab fectab[] = {		{ "NONE", FEC_NONE },		{ "1/2",  FEC_1_2 },		{ "2/3",  FEC_2_3 },		{ "3/4",  FEC_3_4 },		{ "4/5",  FEC_4_5 },		{ "5/6",  FEC_5_6 },		{ "6/7",  FEC_6_7 },		{ "7/8",  FEC_7_8 },		{ "8/9",  FEC_8_9 },		{ "AUTO", FEC_AUTO },		{ NULL, 0 }	};	return str2enum(fec, fectab, FEC_AUTO);}static enum fe_modulation str2qam(const char *qam){	struct strtab qamtab[] = {		{ "QPSK",   QPSK },		{ "QAM16",  QAM_16 },		{ "QAM32",  QAM_32 },		{ "QAM64",  QAM_64 },		{ "QAM128", QAM_128 },		{ "QAM256", QAM_256 },		{ "AUTO",   QAM_AUTO },		{ NULL, 0 }	};	return str2enum(qam, qamtab, QAM_AUTO);}static enum fe_bandwidth str2bandwidth(const char *bw){	struct strtab bwtab[] = {		{ "8MHz", BANDWIDTH_8_MHZ },		{ "7MHz", BANDWIDTH_7_MHZ },		{ "6MHz", BANDWIDTH_6_MHZ },		{ "AUTO", BANDWIDTH_AUTO },		{ NULL, 0 }	};	return str2enum(bw, bwtab, BANDWIDTH_AUTO);}static enum fe_transmit_mode str2mode(const char *mode){	struct strtab modetab[] = {		{ "2k",   TRANSMISSION_MODE_2K },		{ "8k",   TRANSMISSION_MODE_8K },		{ "AUTO", TRANSMISSION_MODE_AUTO },		{ NULL, 0 }	};	return str2enum(mode, modetab, TRANSMISSION_MODE_AUTO);}static enum fe_guard_interval str2guard(const char *guard){	struct strtab guardtab[] = {		{ "1/32", GUARD_INTERVAL_1_32 },		{ "1/16", GUARD_INTERVAL_1_16 },		{ "1/8",  GUARD_INTERVAL_1_8 },		{ "1/4",  GUARD_INTERVAL_1_4 },		{ "AUTO", GUARD_INTERVAL_AUTO },		{ NULL, 0 }	};	return str2enum(guard, guardtab, GUARD_INTERVAL_AUTO);}static enum fe_hierarchy str2hier(const char *hier){	struct strtab hiertab[] = {		{ "NONE", HIERARCHY_NONE },		{ "1",    HIERARCHY_1 },		{ "2",    HIERARCHY_2 },		{ "4",    HIERARCHY_4 },		{ "AUTO", HIERARCHY_AUTO },		{ NULL, 0 }	};	return str2enum(hier, hiertab, HIERARCHY_AUTO);}static int tune_initial (int frontend_fd, const char *initial){	FILE *inif;	unsigned int f, sr;	char buf[200];	char pol[20], fec[20], qam[20], bw[20], fec2[20], mode[20], guard[20], hier[20];	struct transponder *t;	inif = fopen(initial, "r");	if (!inif) {		error("cannot open '%s': %d %m\n", initial, errno);		return -1;	}	while (fgets(buf, sizeof(buf), inif)) {		if (buf[0] == '#' || buf[0] == '\n')			;		else if (sscanf(buf, "S %u %1[HV] %u %4s\n", &f, pol, &sr, fec) == 4) {			t = alloc_transponder(f);			t->type = FE_QPSK;			t->polarisation = pol[0] == 'H' ? POLARISATION_HORIZONTAL :							  POLARISATION_VERTICAL;			t->param.inversion = spectral_inversion;			t->param.u.qpsk.symbol_rate = sr;			t->param.u.qpsk.fec_inner = str2fec(fec);			info("initial transponder %u %c %u %d\n",					t->param.frequency,					pol[0], sr,					t->param.u.qpsk.fec_inner);		}		else if (sscanf(buf, "C %u %u %4s %6s\n", &f, &sr, fec, qam) == 4) {			t = alloc_transponder(f);			t->type = FE_QAM;			t->param.inversion = spectral_inversion;			t->param.u.qam.symbol_rate = sr;			t->param.u.qam.fec_inner = str2fec(fec);			t->param.u.qam.modulation = str2qam(qam);			info("initial transponder %u %u %d %d\n",					t->param.frequency,					sr,					t->param.u.qam.fec_inner,					t->param.u.qam.modulation);		}		else if (sscanf(buf, "T %u %4s %4s %4s %7s %4s %4s %4s\n",					&f, bw, fec, fec2, qam, mode, guard, hier) == 8) {			t = alloc_transponder(f);			t->type = FE_OFDM;			t->param.inversion = spectral_inversion;			t->param.u.ofdm.bandwidth = str2bandwidth(bw);			t->param.u.ofdm.code_rate_HP = str2fec(fec);			t->param.u.ofdm.code_rate_LP = str2fec(fec2);			t->param.u.ofdm.constellation = str2qam(qam);			t->param.u.ofdm.transmission_mode = str2mode(mode);			t->param.u.ofdm.guard_interval = str2guard(guard);			t->param.u.ofdm.hierarchy_information = str2hier(hier);			info("initial transponder %u %d %d %d %d %d %d %d\n",					t->param.frequency,					t->param.u.ofdm.bandwidth,					t->param.u.ofdm.code_rate_HP,					t->param.u.ofdm.code_rate_LP,					t->param.u.ofdm.constellation,					t->param.u.ofdm.transmission_mode,					t->param.u.ofdm.guard_interval,					t->param.u.ofdm.hierarchy_information);		}		else			error("cannot parse'%s'\n", buf);	}	fclose(inif);	return tune_to_next_transponder(frontend_fd);}static void scan_tp (void){	struct section_buf s0;	struct section_buf s1;	struct section_buf s2;	struct section_buf s3;	/**	 *  filter timeouts > min repetition rates specified in ETR211	 */	setup_filter (&s0, demux_devname, 0x00, 0x00, 1, 0, 5); /* PAT */	setup_filter (&s1, demux_devname, 0x11, 0x42, 1, 0, 5); /* SDT */	add_filter (&s0);	add_filter (&s1);	if (!current_tp_only || output_format != OUTPUT_PIDS) {		setup_filter (&s2, demux_devname, 0x10, 0x40, 1, 0, 15); /* NIT */		add_filter (&s2);		if (get_other_nits) {			/* get NIT-others			 * Note: There is more than one NIT-other: one per			 * network, separated by the network_id.			 */			setup_filter (&s3, demux_devname, 0x10, 0x41, 1, 1, 15);			add_filter (&s3);		}	}	do {		read_filters ();	} while (!(list_empty(&running_filters) &&		   list_empty(&waiting_filters)));}static void scan_network (int frontend_fd, const char *initial){	if (tune_initial (frontend_fd, initial) < 0) {		error("initial tuning failed\n");		return;	}	do {		scan_tp();	} while (tune_to_next_transponder(frontend_fd) == 0);}static void pids_dump_service_parameter_set(FILE *f, struct service *s){        int i;	fprintf(f, "%-24.24s (0x%04x) %02x: ", s->service_name, s->service_id, s->type);	if (!s->pcr_pid || (s->type > 2))		fprintf(f, "           ");	else if (s->pcr_pid == s->video_pid)		fprintf(f, "PCR == V   ");	else if ((s->audio_num == 1) && (s->pcr_pid == s->audio_pid[0]))		fprintf(f, "PCR == A   ");	else		fprintf(f, "PCR 0x%04x ", s->pcr_pid);	if (s->video_pid)		fprintf(f, "V 0x%04x", s->video_pid);	else		fprintf(f, "        ");	if (s->audio_num)		fprintf(f, " A");        for (i = 0; i < s->audio_num; i++) {		fprintf(f, " 0x%04x", s->audio_pid[i]);		if (s->audio_lang[i][0])			fprintf(f, " (%.3s)", s->audio_lang[i]);		else if (s->audio_num == 1)			fprintf(f, "      ");	}	if (s->teletext_pid)		fprintf(f, " TT 0x%04x", s->teletext_pid);	if (s->ac3_pid)		fprintf(f, " AC3 0x%04x", s->ac3_pid);	if (s->subtitling_pid)		fprintf(f, " SUB 0x%04x", s->subtitling_pid);	fprintf(f, "\n");}static char sat_polarisation (struct transponder *t){	return t->polarisation == POLARISATION_VERTICAL ? 'v' : 'h';}static int sat_number (struct transponder *t){	return switch_pos;}static void dump_lists (void){	struct list_head *p1, *p2;	struct transponder *t;	struct service *s;	int n = 0;	char sn[20];	list_for_each(p1, &scanned_transponders) {		t = list_entry(p1, struct transponder, list);		list_for_each(p2, &t->services) {			n++;		}	}	info("dumping lists (%d services)\n", n);	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_name) {				/* not in SDT */				snprintf(sn, sizeof(sn), "[%04x]", s->service_id);				s->service_name = strdup(sn);			}			if (s->video_pid && !(serv_select & 1))				continue; /* no TV services */			if (!s->video_pid && s->audio_num && !(serv_select & 2))				continue; /* no radio services */			if (!s->video_pid && !s->audio_num && !(serv_select & 4))				continue; /* no data/other services */			if (s->scrambled && !ca_select)				continue; /* FTA only */			switch (output_format)			{			  case OUTPUT_PIDS:				pids_dump_service_parameter_set (stdout, s);				break;			  case OUTPUT_VDR:				vdr_dump_service_parameter_set (stdout,						    s->service_name,						    s->provider_name,						    t->type,						    &t->param,						    sat_polarisation(t),						    s->video_pid,						    s->pcr_pid,						    s->audio_pid,						    //FIXME: s->audio_lang						    s->audio_num,						    s->teletext_pid,						    s->scrambled,						    //FIXME: s->subtitling_pid						    s->ac3_pid,						    s->service_id,						    t->network_id,						    s->transport_stream_id,						    t->orbital_pos,						    t->we_flag,						    vdr_dump_provider,						    ca_select,						    vdr_version);				break;			  case OUTPUT_ZAP:				zap_dump_service_parameter_set (stdout,						    s->service_name,						    t->type,						    &t->param,						    sat_polarisation(t),						    sat_number(t),						    s->video_pid,						    s->audio_pid,						    s->service_id);			  default:				break;			  }		}	}	info("Done.\n");}static void handle_sigint(int sig){	error("interrupted by SIGINT, dumping partial result...\n");	dump_lists();	exit(2);}static const char *usage = "\n"	"usage: %s [options...] [-c | initial-tuning-data-file]\n"	"	scan doesn't do frequency scans, hence it needs initial\n"	"	tuning data for at least one transponder/channel.\n"	"	-c	scan on currently tuned transponder only\n"	"	-v 	verbose (repeat for more)\n"	"	-q 	quiet (repeat for less)\n"	"	-a N	use DVB /dev/dvb/adapterN/\n"	"	-f N	use DVB /dev/dvb/adapter?/frontendN\n"	"	-d N	use DVB /dev/dvb/adapter?/demuxN\n"	"	-s N	use DiSEqC switch position N (DVB-S only)\n"	"	-i N	spectral inversion setting (0: off, 1: on, 2: auto [default])\n"	"	-n	evaluate NIT-other for full network scan (slow!)\n"	"	-5	multiply all filter timeouts by factor 5\n"	"		for non-DVB-compliant section repitition rates\n"	"	-o fmt	output format: 'zap' (default), 'vdr' or 'pids' (default with -c)\n"	"	-x N	Conditional Axcess, (default 1)\n"	"		N=0 gets only FTA channels\n"	"		N=xxx sets ca field in vdr output to :xxx:\n"	"	-t N	Service select, Combined bitfield parameter.\n"	"		1 = TV, 2 = Radio, 4 = Other, (default 7)\n"	"	-p	for vdr output format: dump provider name\n"	"	-e N	VDR version, default 2 for VDR-1.2.x\n"	"		ANYTHING ELSE GIVES NONZERO NIT and TID\n";int main (int argc, char **argv){	char frontend_devname [80];	int adapter = 0, frontend = 0, demux = 0;	int opt, i;	int frontend_fd;	int fe_open_mode;	const char *initial = NULL;	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:vq")) != -1) {		switch (opt) {		case 'a':			adapter = strtoul(optarg, NULL, 0);			break;		case 'c':			current_tp_only = 1;			output_format = OUTPUT_PIDS;			break;		case 'n':			get_other_nits = 1;			break;		case 'd':			demux = strtoul(optarg, NULL, 0);			break;		case 'f':			frontend = strtoul(optarg, NULL, 0);			break;		case 'p':			vdr_dump_provider = 1;			break;		case 's':			switch_pos = strtoul(optarg, NULL, 0);			break;		case 'o':                        if      (strcmp(optarg, "zap") == 0) output_format = OUTPUT_ZAP;                        else if (strcmp(optarg, "vdr") == 0) output_format = OUTPUT_VDR;                        else if (strcmp(optarg, "pids") == 0) output_format = OUTPUT_PIDS;                        else {				fprintf (stderr, usage, argv[0]);				return -1;			}			break;		case '5':			long_timeout = 1;			break;		case 'x':			ca_select = strtoul(optarg, NULL, 0);			break;		case 'e':			vdr_version = strtoul(optarg, NULL, 0);			break;		case 't':			serv_select = strtoul(optarg, NULL, 0);			break;		case 'i':			spectral_inversion = strtoul(optarg, NULL, 0);			break;		case 'v':			verbosity++;			break;		case 'q':			if (--verbosity < 0)				verbosity = 0;			break;		default:			fprintf (stderr, usage, argv[0]);			return -1;		};	}	if (optind < argc)		initial = argv[optind];	if ((!initial && !current_tp_only) || (initial && current_tp_only) ||			(spectral_inversion > 2)) {		fprintf (stderr, usage, argv[0]);		return -1;	}	if (switch_pos >= 4) {		fprintf (stderr, "switch position needs to be < 4!\n");		return -1;	}	if (initial)		info("scanning %s\n", initial);	snprintf (frontend_devname, sizeof(frontend_devname),		  "/dev/dvb/adapter%i/frontend%i", adapter, frontend);	snprintf (demux_devname, sizeof(demux_devname),		  "/dev/dvb/adapter%i/demux%i", adapter, demux);	info("using '%s' and '%s'\n", frontend_devname, demux_devname);	for (i = 0; i < MAX_RUNNING; i++)		poll_fds[i].fd = -1;	fe_open_mode = current_tp_only ? O_RDONLY : O_RDWR;	if ((frontend_fd = open (frontend_devname, fe_open_mode)) < 0)		fatal("failed to open '%s': %d %m\n", frontend_devname, errno);	/* determine FE type and caps */	if (ioctl(frontend_fd, FE_GET_INFO, &fe_info) == -1)		fatal("FE_GET_INFO failed: %d %m\n", errno);	if ((spectral_inversion == INVERSION_AUTO ) &&	    !(fe_info.caps & FE_CAN_INVERSION_AUTO)) {		info("Frontend can not do INVERSION_AUTO, trying INVERSION_OFF instead\n");		spectral_inversion = INVERSION_OFF;	}	signal(SIGINT, handle_sigint);	if (current_tp_only) {		current_tp = alloc_transponder(0); /* dummy */		/* move TP from "new" to "scanned" list */		list_del_init(&current_tp->list);		list_add_tail(&current_tp->list, &scanned_transponders);		current_tp->scan_done = 1;		scan_tp ();	}	else		scan_network (frontend_fd, initial);	close (frontend_fd);	dump_lists ();	return 0;}static void dump_dvb_parameters (FILE *f, struct transponder *t){	switch (output_format) {		case OUTPUT_PIDS:		case OUTPUT_VDR:			vdr_dump_dvb_parameters(f, t->type, &t->param,					sat_polarisation (t), t->orbital_pos, t->we_flag);			break;		case OUTPUT_ZAP:			zap_dump_dvb_parameters (f, t->type, &t->param,					sat_polarisation (t), sat_number (t));			break;		default:			break;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -