Exemple #1
0
bool parse::take_pmt(dvbpsi_pmt_t* p_pmt, bool decoded)
{
	dprintf("(%s): v%d, service_id %d, pcr_pid %d",
		(decoded) ? "post" : "pre",
		p_pmt->i_version, p_pmt->i_program_number, p_pmt->i_pcr_pid);

	if (!decoded) return true;

	const map_decoded_pmt* decoded_pmt = decoders[ts_id].get_decoded_pmt();

	map_decoded_pmt::const_iterator iter_pmt = decoded_pmt->find(p_pmt->i_program_number);
	if (iter_pmt != decoded_pmt->end())
		process_pmt(&iter_pmt->second);

	rcvd_pmt[p_pmt->i_program_number] = true;

	return true;
}
static void *dvbthread_func(void* arg)
{
	int pat_fd = -1;
	int pmt_fd = -1;
	int tdt_fd = -1;
	struct pollfd pollfds[3];

	struct gnutv_dvb_params *params = (struct gnutv_dvb_params *) arg;

	tune_state = 0;

	// create PAT filter
	if ((pat_fd = create_section_filter(params->adapter_id, params->demux_id,
	     TRANSPORT_PAT_PID, stag_mpeg_program_association)) < 0) {
		fprintf(stderr, "Failed to create PAT section filter\n");
		exit(1);
	}
	pollfds[0].fd = pat_fd;
	pollfds[0].events = POLLIN|POLLPRI|POLLERR;

	// create TDT filter
	if ((tdt_fd = create_section_filter(params->adapter_id, params->demux_id, TRANSPORT_TDT_PID, stag_dvb_time_date)) < 0) {
		fprintf(stderr, "Failed to create TDT section filter\n");
		exit(1);
	}
	pollfds[1].fd = tdt_fd;
	pollfds[1].events = POLLIN|POLLPRI|POLLERR;

	// zero PMT filter
	pollfds[2].fd = 0;
	pollfds[2].events = 0;

	// the DVB loop
	while(!dvbthread_shutdown) {
		// tune frontend + monitor lock status
		if (tune_state == 0) {
			// get the type of frontend
			struct dvbfe_info result;
			char *types;
			memset(&result, 0, sizeof(result));
			dvbfe_get_info(params->fe, 0, &result, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0);
			switch(result.type) {
			case DVBFE_TYPE_DVBS:
				types = "DVB-S";
				break;
			case DVBFE_TYPE_DVBC:
				types = "DVB-C";
				break;
			case DVBFE_TYPE_DVBT:
				types = "DVB-T";
				break;
			case DVBFE_TYPE_ATSC:
				types = "ATSC";
				break;
			default:
				types = "Unknown";
			}
			fprintf(stderr, "Using frontend \"%s\", type %s\n", result.name, types);

			// do we have a valid SEC configuration?
			struct dvbsec_config *sec = NULL;
			if (params->valid_sec)
				sec = &params->sec;

			// tune!
			if (dvbsec_set(params->fe,
			    		  sec,
					  params->channel.polarization,
					  (params->channel.diseqc_switch & 0x01) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
					  (params->channel.diseqc_switch & 0x02) ? DISEQC_SWITCH_B : DISEQC_SWITCH_A,
					  &params->channel.fe_params,
					  0)) {
				fprintf(stderr, "Failed to set frontend\n");
				exit(1);
			}

			tune_state++;
		} else if (tune_state == 1) {
			struct dvbfe_info result;
			memset(&result, 0, sizeof(result));
			dvbfe_get_info(params->fe,
				       FE_STATUS_PARAMS,
				       &result,
				       DVBFE_INFO_QUERYTYPE_IMMEDIATE,
				       0);

			fprintf(stderr, "status %c%c%c%c%c | signal %04x | snr %04x | ber %08x | unc %08x | %s\r",
				result.signal ? 'S' : ' ',
				result.carrier ? 'C' : ' ',
				result.viterbi ? 'V' : ' ',
				result.sync ? 'Y' : ' ',
				result.lock ? 'L' : ' ',
				result.signal_strength,
				result.snr,
				result.ber,
				result.ucblocks,
				result.lock ? "FE_HAS_LOCK" : "");
			fflush(stderr);

			if (result.lock) {
				tune_state++;
				fprintf(stderr, "\n");
				fflush(stderr);
			} else {
				usleep(500000);
			}
		}

		// is there SI data?
		int count = poll(pollfds, 3, 100);
		if (count < 0) {
			if (errno != EINTR)
				fprintf(stderr, "Poll error: %m\n");
			break;
		}
		if (count == 0) {
			continue;
		}

		// PAT
		if (pollfds[0].revents & (POLLIN|POLLPRI)) {
			process_pat(pat_fd, params, &pmt_fd, &pollfds[2]);
		}

		// TDT
		if (pollfds[1].revents & (POLLIN|POLLPRI)) {
			process_tdt(tdt_fd);
		}

		//  PMT
		if (pollfds[2].revents & (POLLIN|POLLPRI)) {
			process_pmt(pmt_fd, params);
		}
	}

	// close demuxers
	if (pat_fd != -1)
		close(pat_fd);
	if (pmt_fd != -1)
		close(pmt_fd);
	if (tdt_fd != -1)
		close(tdt_fd);

	return 0;
}