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 = ¶ms->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, ¶ms->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; }