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

📄 scan.c

📁 dvb在linux下搜索电台的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		case 0x09://ITU-T Rec. H.222.0 | ISO/IEC 13818-1/11172-1 auxiliary 			moreverbose("  ITU-T Rec. H.222.0 | ISO/IEC 13818-1/11172-1 auxiliary : PID 0x%04x\n", elementary_pid);			break;		case 0x0A://ISO/IEC 13818-6 Multiprotocol encapsulation 			moreverbose("  ISO/IEC 13818-6 Multiprotocol encapsulation    : PID 0x%04x\n", elementary_pid);			break; 		case 0x0B:                        /*			Digital storage media command and control (DSM-CC) is a toolkit for control channels associated			with MPEG-1 and MPEG-2 streams. It is defined in part 6 of the MPEG-2 standard (Extensions for DSM-CC).			DSM-CC may be used for controlling the video reception, providing features normally found			on VCR (fast-forward, rewind, pause, etc). It may also be used for a wide variety of other purposes			including packet data transport. MPEG-2 ISO/IEC 13818-6 (part 6 of the MPEG-2 standard).			DSM-CC defines or extends five distinct protocols:			* User-User 			* User-Network 			* MPEG transport profiles (profiles to the standard MPEG transport protocol ISO/IEC 13818-1 to allow				transmission of event, synchronization, download, and other information in the MPEG transport stream)			* Download 			* Switched Digital Broadcast-Channel Change Protocol (SDB/CCP)				Enables a client to remotely switch from channel to channel in a broadcast environment.				Used to attach a client to a continuous-feed session (CFS) or other broadcast feed. Sometimes used in pay-per-view.			*/ 			moreverbose("  DSM-CC U-N Messages : PID 0x%04x\n", elementary_pid); 			break;		case 0x0C://ISO/IEC 13818-6 Stream Descriptors 			moreverbose("  ISO/IEC 13818-6 Stream Descriptors : PID 0x%04x\n", elementary_pid);			break;		case 0x0D://ISO/IEC 13818-6 Sections (any type, including private data) 			moreverbose("  ISO/IEC 13818-6 Sections (any type, including private data) : PID 0x%04x\n", elementary_pid);			break;		case 0x0E://ISO/IEC 13818-1 auxiliary 			moreverbose("  ISO/IEC 13818-1 auxiliary : PID 0x%04x\n", elementary_pid);			break; 		case 0x0F:			moreverbose("  ADTS Audio Stream (usually AAC) : PID 0x%04x\n", elementary_pid);			if (output_format == OUTPUT_VDR) break; /* not supported by VDR up to now. */			if (s->audio_num < AUDIO_CHAN_MAX) {				s->audio_pid[s->audio_num] = elementary_pid;				parse_descriptors (PMT, buf + 5, ES_info_len, s);				s->audio_num++;			}			else				warning("more than %i audio channels, truncating\n",				     AUDIO_CHAN_MAX);			break;		case 0x10://ISO/IEC 14496-2 Visual 			moreverbose("  ISO/IEC 14496-2 Visual : PID 0x%04x\n", elementary_pid);			break; 		case 0x11:			moreverbose("  ISO/IEC 14496-3 Audio with LATM transport syntax as def. in ISO/IEC 14496-3/AMD1 : PID 0x%04x\n", elementary_pid);			if (output_format == OUTPUT_VDR) break; /* not supported by VDR up to now. */			if (s->audio_num < AUDIO_CHAN_MAX) {				s->audio_pid[s->audio_num] = elementary_pid;				parse_descriptors (PMT, buf + 5, ES_info_len, s);				s->audio_num++;			}			else				warning("more than %i audio channels, truncating\n",				     AUDIO_CHAN_MAX);			break; 		case 0x12:			moreverbose("  ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets : PID 0x%04x\n", elementary_pid);			break; 		case 0x13:			moreverbose("  ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC 14496 sections : PID 0x%04x\n", elementary_pid);			break; 		case 0x14:			moreverbose("  ISO/IEC 13818-6 DSM-CC synchronized download protocol : PID 0x%04x\n", elementary_pid);			break;		case 0x15:			moreverbose("  Metadata carried in PES packets using the Metadata Access Unit Wrapper : PID 0x%04x\n", elementary_pid);			break; 		case 0x16:			moreverbose("  Metadata carried in metadata_sections : PID 0x%04x\n", elementary_pid);			break; 		case 0x17:			moreverbose("  Metadata carried in ISO/IEC 13818-6 (DSM-CC) Data Carousel : PID 0x%04x\n", elementary_pid);			break; 		case 0x18:			moreverbose("  Metadata carried in ISO/IEC 13818-6 (DSM-CC) Object Carousel : PID 0x%04x\n", elementary_pid);			break; 		case 0x19:			moreverbose("  Metadata carried in ISO/IEC 13818-6 Synchronized Download Protocol using the Metadata Access Unit Wrapper : PID 0x%04x\n", elementary_pid);			break; 		case 0x1A:			moreverbose("  IPMP stream (defined in ISO/IEC 13818-11, MPEG-2 IPMP) : PID 0x%04x\n", elementary_pid);			break;		case 0x1B:			moreverbose("  AVC Video stream, ITU-T Rec. H.264 | ISO/IEC 14496-10 : PID 0x%04x\n", elementary_pid);			if (s->video_pid == 0) {				if (output_format == OUTPUT_VDR)					//Offsets of 10000 are used to indicate special video codings inside VDR					s->video_pid = (elementary_pid + 10000);				else					s->video_pid = elementary_pid;				}			break; 		case 0x81:			moreverbose("  Audio per ATSC A/53B [2] Annex B : PID 0x%04x\n", elementary_pid);			if (output_format == OUTPUT_VDR) break; /* not supported by VDR up to now. */			if (s->audio_num < AUDIO_CHAN_MAX) {				s->audio_pid[s->audio_num] = elementary_pid;				parse_descriptors (PMT, buf + 5, ES_info_len, s);				s->audio_num++;			}			else				warning("more than %i audio channels, truncating\n",				     AUDIO_CHAN_MAX);			break;		default:			moreverbose("  OTHER     : PID 0x%04x TYPE 0x%02x\n", elementary_pid, buf[0]);		};		buf += ES_info_len + 5;		section_length -= ES_info_len + 5;	};        tmp = msg_buf;        tmp += sprintf(tmp, "0x%04x (%.4s)", s->audio_pid[0], s->audio_lang[0]);	if (s->audio_num > AUDIO_CHAN_MAX) {		warning("more than %i audio channels: %i, truncating to %i\n",		      AUDIO_CHAN_MAX, s->audio_num, AUDIO_CHAN_MAX);		s->audio_num = AUDIO_CHAN_MAX;	}        for (i=1; i<s->audio_num; i++)                tmp += sprintf(tmp, ", 0x%04x (%.4s)", s->audio_pid[i], s->audio_lang[i]);        debug("0x%04x 0x%04x: %s -- %s, pmt_pid 0x%04x, vpid 0x%04x, apid %s\n",	    s->transport_stream_id,	    s->service_id,	    s->provider_name, s->service_name,	    s->pmt_pid, s->video_pid, msg_buf);}static void parse_nit (const unsigned char *buf, int section_length, int network_id){	int descriptors_loop_len = ((buf[0] & 0x0f) << 8) | buf[1];	if (section_length < descriptors_loop_len + 4)	{		warning("section too short: network_id == 0x%04x, section_length == %i, "		     "descriptors_loop_len == %i\n",		     network_id, section_length, descriptors_loop_len);		return;	}	parse_descriptors (NIT, buf + 2, descriptors_loop_len, NULL);	section_length -= descriptors_loop_len + 4;	buf += descriptors_loop_len + 4;	while (section_length > 6) {		int transport_stream_id = (buf[0] << 8) | buf[1];		struct transponder *t, tn;		descriptors_loop_len = ((buf[4] & 0x0f) << 8) | buf[5];		if (section_length < descriptors_loop_len + 4)		{			warning("section too short: transport_stream_id == 0x%04x, "			     "section_length == %i, descriptors_loop_len == %i\n",			     transport_stream_id, section_length,			     descriptors_loop_len);			break;		}		debug("transport_stream_id 0x%04x\n", transport_stream_id);		memset(&tn, 0, sizeof(tn));		tn.type = -1;		tn.network_id = network_id;		tn.original_network_id = (buf[2] << 8) | buf[3];	/* onid patch by Hartmut Birr */		tn.transport_stream_id = transport_stream_id;		parse_descriptors (NIT, buf + 6, descriptors_loop_len, &tn);		if (tn.type == fe_info.type) {			/* only add if develivery_descriptor matches FE type */			t = find_transponder(tn.param.frequency);			if ((!t) && (add_frequencies)) {				info("found new transponder (%d)\n",tn.param.frequency/1000);				t = alloc_transponder(tn.param.frequency);				}			if (t) {				info("copying transponder info (%d)\n", tn.param.frequency/1000);				copy_transponder(t, &tn);				}		}		section_length -= descriptors_loop_len + 6;		buf += descriptors_loop_len + 6;	};}static void parse_sdt (const unsigned char *buf, int section_length,		int transport_stream_id){	buf += 3;	       /*  skip original network id + reserved field */	while (section_length > 4) {		int service_id = (buf[0] << 8) | buf[1];		int descriptors_loop_len = ((buf[3] & 0x0f) << 8) | buf[4];		struct service *s;		if (section_length < descriptors_loop_len || !descriptors_loop_len)		{			warning("section too short: service_id == 0x%02x, section_length == %i, "			     "descriptors_loop_len == %i\n",			     service_id, section_length,			     descriptors_loop_len);			break;		}		s = find_service(current_tp, service_id);		if (!s)			/* maybe PAT has not yet been parsed... */			s = alloc_service(current_tp, service_id);		s->running = (buf[3] >> 5) & 0x7;		s->scrambled = (buf[3] >> 4) & 1;		parse_descriptors (SDT, buf + 5, descriptors_loop_len, s);		section_length -= descriptors_loop_len + 5;		buf += descriptors_loop_len + 5;	};}static int get_bit (uint8_t *bitfield, int bit){	return (bitfield[bit/8] >> (bit % 8)) & 1;}static void set_bit (uint8_t *bitfield, int bit){	bitfield[bit/8] |= 1 << (bit % 8);}/** *   returns 0 when more sections are expected *	   1 when all sections are read on this pid *	   -1 on invalid table id */static int parse_section (struct section_buf *s){	const unsigned char *buf = s->buf;	int table_id;	int section_syntax_indicator;	int section_length;	int table_id_ext;	int section_version_number;	int current_next_indicator;	int section_number;	int last_section_number;	int pcr_pid;	int program_info_length;	int i;	table_id = buf[0];	if (s->table_id != table_id)		return -1;	section_syntax_indicator = buf[1] & 0x80;	section_length = (((buf[1] & 0x0f) << 8) | buf[2]) - 11;	table_id_ext = (buf[3] << 8) | buf[4];				// p.program_number	section_version_number = (buf[5] >> 1) & 0x1f;			// p.version_number = getBits (b, 0, 42, 5); -> 40 + 1 -> 5 bit weit? -> version_number = buf[5] & 0x3e;	current_next_indicator = buf[5] & 0x01;	section_number = buf[6];	last_section_number = buf[7];	pcr_pid = ((buf[8] & 0x1f) << 8) | buf[9];	program_info_length = ((buf[10] & 0x0f) << 8) | buf[11];	if (s->segmented && s->table_id_ext != -1 && s->table_id_ext != table_id_ext) {		/* find or allocate actual section_buf matching table_id_ext */		while (s->next_seg) {			s = s->next_seg;			if (s->table_id_ext == table_id_ext)				break;		}		if (s->table_id_ext != table_id_ext) {			assert(s->next_seg == NULL);			s->next_seg = calloc(1, sizeof(struct section_buf));			s->next_seg->segmented = s->segmented;			s->next_seg->run_once = s->run_once;			s->next_seg->timeout = s->timeout;			s = s->next_seg;			s->table_id = table_id;			s->table_id_ext = table_id_ext;			s->section_version_number = section_version_number;		}	}	if (s->section_version_number != section_version_number ||			s->table_id_ext != table_id_ext) {		struct section_buf *next_seg = s->next_seg;		if (s->section_version_number != -1 && s->table_id_ext != -1)			debug("section version_number or table_id_ext changed "				"%d -> %d / %04x -> %04x\n",				s->section_version_number, section_version_number,				s->table_id_ext, table_id_ext);		s->table_id_ext = table_id_ext;		s->section_version_number = section_version_number;		s->sectionfilter_done = 0;		memset (s->section_done, 0, sizeof(s->section_done));		s->next_seg = next_seg;	}	buf += 8;	if (!get_bit(s->section_done, section_number)) {		set_bit (s->section_done, section_number);		debug("pid 0x%02x tid 0x%02x table_id_ext 0x%04x, "		    "%i/%i (version %i)\n",		    s->pid, table_id, table_id_ext, section_number,		    last_section_number, section_version_number);		switch (table_id) {		case 0x00:			verbose("PAT\n");			parse_pat (buf, section_length, table_id_ext);			break;		case 0x02:			verbose("PMT 0x%04x for service 0x%04x\n", s->pid, table_id_ext);			parse_pmt (buf, section_length, table_id_ext);			break;		case 0x41:			verbose("////////////////////////////////////////////// NIT other\n");		case 0x40:			verbose("NIT (%s TS)\n", table_id == 0x40 ? "actual":"other");			parse_nit (buf, section_length, table_id_ext);			break;		case 0x42:		case 0x46:			verbose("SDT (%s TS)\n", table_id == 0x42 ? "actual":"other");			parse_sdt (buf, section_length, table_id_ext);			break;		default:			;		};		for (i = 0; i <= last_section_number; i++)			if (get_bit (s->section_done, i) == 0)				break;		if (i > last_section_number)			s->sectionfilter_done = 1;	}	if (s->segmented) {		/* always wait for timeout; this is because we don't now how		 * many segments there are		 */		return 0;	}	else if (s->sectionfilter_done)		return 1;	return 0;}static int read_sections (struct section_buf *s){	int section_length, count;	if (s->sectionfilter_done && !s->segmented)		return 1;	/* the section filter API guarantess that we get one full section	 * per read(), provided that the buffer is large enough (it is)	 */	if (((count = read (s->fd, s->buf, sizeof(s->buf))) < 0) && errno == EOVERFLOW)		count = read (s->fd, s->buf, sizeof(s->buf));	if (count < 0) {		errorn("read_sections: read error");		return -1;	}	if (count < 4)		return -1;	section_length = ((s->buf[1] & 0x0f) << 8) | s->buf[2];	if (count != section_length + 3)		return -1;	if (parse_section(s) == 1)		return 1;	return 0;}static LIST_HEAD(running_filters);static LIST_HEAD(waiting_filters);static int n_running;// see http://www.linuxtv.org/pipermail/linux-dvb/2005-October/005577.html:// #define MAX_RUNNING 32#define MAX_RUNNING 27static struct pollfd poll_fds[MAX_RUNNING];static struct section_buf* poll_section_bufs[MAX_RUNNING];static void setup_filter (struct section_buf* s, const char *dmx_devname,			  int pid, int tid, int run_once, int segmented, int timeout){	memset (s, 0, sizeof(struct section_buf));	s->fd = -1;	s->dmx_devname = dmx_devname;	s->pid = pid;

⌨️ 快捷键说明

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