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

📄 scan.c

📁 dvb在linux下搜索电台的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/** *  Simple MPEG parser to achieve network/service information. * *  refered standards: * *    ETSI EN 300 468 *    ETSI TR 101 211 *    ETSI ETR 211 *    ITU-T H.222.0 * * ############################################################################## This is tool is derived from the dvb scan tool  (linuxtv-dvb-apps-1.1.0/utils/scan)  Differencies: - command line options - detects dvb card automatically - no need for initial tuning data, but therefore up to now no DVB-S support - some adaptions for VDR syntax have phun, wirbel 2006/02/16 ############################################################################## */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include <errno.h>#include <signal.h>#include <assert.h>//#include <linux/dvb/frontend.h>#include <linux/videodev.h>#include <linux/dvb/dmx.h>#include "list.h"#include "dump-vdr.h"#include "dump-xine.h"#include "dump-dvbscan.h"#include "dump-kaffeine.h"#include "scan.h"static char demux_devname[80];static struct dvb_frontend_info fe_info = {	.type = -1};uint version = 20080105;int verbosity = 2;static int long_timeout;static int tuning_speed = 1;static int current_tp_only=1;static int get_other_nits = 0;static int add_frequencies = 0;static int vdr_dump_provider;static int vdr_dump_channum;static int ca_select = 1;static int serv_select = 3;	// 20080106: radio and tv as default (no service/other).static int vdr_version = 4;static int qam_no_auto = 0;	// 20060705static enum fe_spectral_inversion caps_inversion	= INVERSION_AUTO;static enum fe_code_rate caps_fec 			= FEC_AUTO;static enum fe_modulation caps_qam			= QAM_AUTO;static enum fe_modulation this_qam			= QAM_64;static enum fe_transmit_mode caps_transmission_mode 	= TRANSMISSION_MODE_AUTO;static enum fe_guard_interval caps_guard_interval	= GUARD_INTERVAL_AUTO;static enum fe_hierarchy caps_hierarchy			= HIERARCHY_AUTO;enum table_type {	PAT,	PMT,	SDT,	NIT};enum format {        OUTPUT_VDR,	OUTPUT_PIDS,	OUTPUT_XINE,	OUTPUT_DVBSCAN_TUNING_DATA,	OUTPUT_KAFFEINE};static enum format output_format = OUTPUT_VDR;enum running_mode {	RM_NOT_RUNNING = 0x01,	RM_STARTS_SOON = 0x02,	RM_PAUSING     = 0x03,	RM_RUNNING     = 0x04};#define AUDIO_CHAN_MAX (32)#define CA_SYSTEM_ID_MAX (16)struct service {	struct list_head list;	int transport_stream_id;	int service_id;	char *provider_name;	char *service_name;	uint16_t pmt_pid;	uint16_t pcr_pid;	uint16_t video_pid;	uint16_t audio_pid[AUDIO_CHAN_MAX];	char audio_lang[AUDIO_CHAN_MAX][4];	int audio_num;	uint16_t ca_id[CA_SYSTEM_ID_MAX];	int ca_num;	uint16_t teletext_pid;	uint16_t subtitling_pid;	uint16_t ac3_pid;	unsigned int type         : 8;	unsigned int scrambled	  : 1;	enum running_mode running;	void *priv;	int channel_num;};struct transponder {	struct list_head list;	struct list_head services;	int network_id;	int original_network_id;                /* onid patch by Hartmut Birr */	int transport_stream_id;	enum fe_type type;	struct dvb_frontend_parameters param;	unsigned int scan_done		  : 1;	unsigned int last_tuning_failed	  : 1;	unsigned int other_frequency_flag : 1;	/* DVB-T */	int n_other_f;	uint32_t *other_f;			/* DVB-T frequency-list descriptor */};struct section_buf {	struct list_head list;	const char *dmx_devname;	unsigned int run_once  : 1;	unsigned int segmented : 1;	/* segmented by table_id_ext */	int fd;	int pid;	int table_id;	int table_id_ext;	int section_version_number;	uint8_t section_done[32];	int sectionfilter_done;	unsigned char buf[1024];	time_t timeout;	time_t start_time;	time_t running_time;	struct section_buf *next_seg;	/* this is used to handle segmented tables (like NIT-other) */};static LIST_HEAD(scanned_transponders);static LIST_HEAD(new_transponders);static struct transponder *current_tp;static void dump_dvb_parameters (FILE *f, struct transponder *p);static void setup_filter (struct section_buf* s, const char *dmx_devname,		          int pid, int tid, int run_once, int segmented, int timeout);static void add_filter (struct section_buf *s);/* According to the DVB standards, the combination of network_id and * transport_stream_id should be unique, but in real life the satellite * operators and broadcasters don't care enough to coordinate * the numbering. Thus we identify TPs by frequency (scan handles only * one satellite at a time). Further complication: Different NITs on * one satellite sometimes list the same TP with slightly different * frequencies, so we have to search within some bandwidth. */static struct transponder *alloc_transponder(uint32_t frequency){	struct transponder *tp = calloc(1, sizeof(*tp));	tp->param.frequency = frequency;	INIT_LIST_HEAD(&tp->list);	INIT_LIST_HEAD(&tp->services);	list_add_tail(&tp->list, &new_transponders);	return tp;}static int is_same_transponder(uint32_t f1, uint32_t f2){	uint32_t diff;	if (f1 == f2)		return 1;	diff = (f1 > f2) ? (f1 - f2) : (f2 - f1);	//FIXME: use symbolrate etc. to estimate bandwidth	if (diff < 2000) {		debug("f1 = %u is same TP as f2 = %u\n", f1, f2);		return 1;	}	return 0;}static struct transponder *find_transponder(uint32_t frequency){	struct list_head *pos;	struct transponder *tp;	list_for_each(pos, &scanned_transponders) {		tp = list_entry(pos, struct transponder, list);		if (is_same_transponder(tp->param.frequency, frequency))			return tp;	}	list_for_each(pos, &new_transponders) {		tp = list_entry(pos, struct transponder, list);		if (is_same_transponder(tp->param.frequency, frequency))			return tp;	}	return NULL;}static void copy_transponder(struct transponder *d, struct transponder *s){	d->network_id = s->network_id;	d->original_network_id = s->original_network_id;  /* onid patch by Hartmut Birr */	d->transport_stream_id = s->transport_stream_id;	d->type = s->type;	memcpy(&d->param, &s->param, sizeof(d->param));	d->scan_done = s->scan_done;	d->last_tuning_failed = s->last_tuning_failed;	d->other_frequency_flag = s->other_frequency_flag;	d->n_other_f = s->n_other_f;	if (d->n_other_f) {		d->other_f = calloc(d->n_other_f, sizeof(uint32_t));		memcpy(d->other_f, s->other_f, d->n_other_f * sizeof(uint32_t));	} 	else		d->other_f = NULL;}/* service_ids are guaranteed to be unique within one TP * (the DVB standards say theay should be unique within one * network, but in real life...) */static struct service *alloc_service(struct transponder *tp, int service_id){	struct service *s = calloc(1, sizeof(*s));	INIT_LIST_HEAD(&s->list);	s->service_id = service_id;	list_add_tail(&s->list, &tp->services);	return s;}static struct service *find_service(struct transponder *tp, int service_id){	struct list_head *pos;	struct service *s;	list_for_each(pos, &tp->services) {		s = list_entry(pos, struct service, list);		if (s->service_id == service_id)			return s;	}	return NULL;}static void parse_ca_identifier_descriptor (const unsigned char *buf,				     struct service *s) {  unsigned char len = buf [1];  int i;  buf += 2;  if (len > sizeof(s->ca_id)) {    len = sizeof(s->ca_id);    warning("too many CA system ids\n");    }  memcpy(s->ca_id, buf, len);  s->ca_num=0;  for (i = 0; i < len / sizeof(s->ca_id[0]); i++) {    int id = ((s->ca_id[i] & 0x00FF) << 8) + ((s->ca_id[i] & 0xFF00) >> 8);    s->ca_id[i] = id;    moreverbose("  CA ID     : PID 0x%04x\n", s->ca_id[i]);    s->ca_num++;    }}static void parse_ca_descriptor (const unsigned char *buf, struct service *s) { unsigned char descriptor_length = buf [1]; int CA_system_ID; // int CA_PID;		// not needed for VDR int found=0; int i; buf += 2; if (descriptor_length < 4) return; CA_system_ID = (buf[0] << 8) | buf[1]; for (i=0; i<s->ca_num; i++)   if (s->ca_id[i] == CA_system_ID)     found++; if (!found) {   if (s->ca_num + 1 >= CA_SYSTEM_ID_MAX)     warning("TOO MANY CA SYSTEM IDs.\n");   else {      moreverbose("  CA ID     : PID 0x%04x\n", CA_system_ID);      s->ca_id[s->ca_num]=CA_system_ID;      s->ca_num++;      }    } 	} static void parse_iso639_language_descriptor (const unsigned char *buf, struct service *s){	unsigned char len = buf [1];	buf += 2;	if (len >= 4) {		debug("    LANG=%.3s %d\n", buf, buf[3]);		memcpy(s->audio_lang[s->audio_num], buf, 3);#if 0		/* seems like the audio_type is wrong all over the place */		//if (buf[3] == 0) -> normal		if (buf[3] == 1)			s->audio_lang[s->audio_num][3] = '!'; /* clean effects (no language) */		else if (buf[3] == 2)			s->audio_lang[s->audio_num][3] = '?'; /* for the hearing impaired */		else if (buf[3] == 3)			s->audio_lang[s->audio_num][3] = '+'; /* visually impaired commentary */#endif	}}static void parse_network_name_descriptor (const unsigned char *buf, void *dummy){	unsigned char len = buf [1];	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){	return ((b0 >> 4) & 0x0f) * 10000000 + (b0 & 0x0f) * 1000000 +	       ((b1 >> 4) & 0x0f) * 100000   + (b1 & 0x0f) * 10000 +	       ((b2 >> 4) & 0x0f) * 1000     + (b2 & 0x0f) * 100 +	       ((b3 >> 4) & 0x0f) * 10       + (b3 & 0x0f);}static const fe_code_rate_t fec_tab [8] = {	FEC_AUTO, FEC_1_2, FEC_2_3, FEC_3_4,	FEC_5_6, FEC_7_8, FEC_NONE, FEC_NONE};static const fe_modulation_t qam_tab [7] = {	QAM_AUTO, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256};static void parse_cable_delivery_system_descriptor (const unsigned char *buf,					     struct transponder *t){	if (!t) {		warning("cable_delivery_system_descriptor outside transport stream definition (ignored)\n");		return;	}	t->type = FE_QAM;	t->param.frequency = bcd32_to_cpu (buf[2], buf[3], buf[4], buf[5]);	t->param.frequency *= 100;	t->param.u.qam.fec_inner = fec_tab[buf[12] & 0x07];	t->param.u.qam.symbol_rate = 10 * bcd32_to_cpu (buf[9],							buf[10],							buf[11],							buf[12] & 0xf0);	if ((buf[8] & 0x0f) > 5)		t->param.u.qam.modulation = QAM_AUTO;	else

⌨️ 快捷键说明

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