📄 scan.c
字号:
t->param.u.qam.modulation = qam_tab[buf[8] & 0x0f]; t->param.inversion = caps_inversion; if (verbosity >= 5) { debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); dump_dvb_parameters (stderr, t); if (t->scan_done) dprintf(5, " (done)"); if (t->last_tuning_failed) dprintf(5, " (no signal)"); dprintf(5, "\n"); }}static void parse_terrestrial_delivery_system_descriptor (const unsigned char *buf, struct transponder *t){ static const fe_modulation_t m_tab [] = { QPSK, QAM_16, QAM_64, QAM_AUTO }; static const fe_code_rate_t ofec_tab [8] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8 }; struct dvb_ofdm_parameters *o; if (!t) { warning("terrestrial_delivery_system_descriptor outside transport stream definition (ignored)\n"); return; } o = &t->param.u.ofdm; t->type = FE_OFDM; t->param.frequency = (buf[2] << 24) | (buf[3] << 16); t->param.frequency |= (buf[4] << 8) | buf[5]; t->param.frequency *= 10; t->param.inversion = caps_inversion; o->bandwidth = BANDWIDTH_8_MHZ + ((buf[6] >> 5) & 0x3); o->constellation = m_tab[(buf[7] >> 6) & 0x3]; o->hierarchy_information = HIERARCHY_NONE + ((buf[7] >> 3) & 0x3); if ((buf[7] & 0x7) > 4) o->code_rate_HP = FEC_AUTO; else o->code_rate_HP = ofec_tab [buf[7] & 0x7]; if (((buf[8] >> 5) & 0x7) > 4) o->code_rate_LP = FEC_AUTO; else o->code_rate_LP = ofec_tab [(buf[8] >> 5) & 0x7]; o->guard_interval = GUARD_INTERVAL_1_32 + ((buf[8] >> 3) & 0x3); o->transmission_mode = (buf[8] & 0x2) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K; t->other_frequency_flag = (buf[8] & 0x01); if (verbosity >= 5) { debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); dump_dvb_parameters (stderr, t); if (t->scan_done) dprintf(5, " (done)"); if (t->last_tuning_failed) dprintf(5, " (no signal)"); dprintf(5, "\n"); }}static void parse_frequency_list_descriptor (const unsigned char *buf, struct transponder *t){ int n, i; typeof(*t->other_f) f; if (!t) { warning("frequency_list_descriptor outside transport stream definition (ignored)\n"); return; } if (t->other_f) return; n = (buf[1] - 1) / 4; if (n < 1 || (buf[2] & 0x03) != 3) return; t->other_f = calloc(n, sizeof(*t->other_f)); t->n_other_f = n; buf += 3; for (i = 0; i < n; i++) { f = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; t->other_f[i] = f * 10; buf += 4; }}static void parse_service_descriptor (const unsigned char *buf, struct service *s){ unsigned char len; unsigned char *src, *dest; s->type = buf[2]; buf += 3; len = *buf; buf++; if (s->provider_name) free (s->provider_name); s->provider_name = malloc (len + 1); memcpy (s->provider_name, buf, len); s->provider_name[len] = '\0'; /* remove control characters (FIXME: handle short/long name) */ /* FIXME: handle character set correctly (e.g. via iconv) * c.f. EN 300 468 annex A */ for (src = dest = s->provider_name; *src; src++) if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) *dest++ = *src; *dest = '\0'; if (!s->provider_name[0]) { /* zap zero length names */ free (s->provider_name); s->provider_name = 0; } if (s->service_name) free (s->service_name); buf += len; len = *buf; buf++; s->service_name = malloc (len + 1); memcpy (s->service_name, buf, len); s->service_name[len] = '\0'; /* remove control characters (FIXME: handle short/long name) */ /* FIXME: handle character set correctly (e.g. via iconv) * c.f. EN 300 468 annex A */ for (src = dest = s->service_name; *src; src++) if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) *dest++ = *src; *dest = '\0'; if (!s->service_name[0]) { /* zap zero length names */ free (s->service_name); s->service_name = 0; } info(" %s(%s)\n", s->service_name, s->provider_name);}static int find_descriptor(uint8_t tag, const unsigned char *buf, int descriptors_loop_len, const unsigned char **desc, int *desc_len){ while (descriptors_loop_len > 0) { unsigned char descriptor_tag = buf[0]; unsigned char descriptor_len = buf[1] + 2; if (!descriptor_len) { warning("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag); break; } if (tag == descriptor_tag) { if (desc) *desc = buf; if (desc_len) *desc_len = descriptor_len; return 1; } buf += descriptor_len; descriptors_loop_len -= descriptor_len; } return 0;}static void parse_descriptors(enum table_type t, const unsigned char *buf, int descriptors_loop_len, void *data){ while (descriptors_loop_len > 0) { unsigned char descriptor_tag = buf[0]; unsigned char descriptor_len = buf[1] + 2; if (!descriptor_len) { warning("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag); break; } switch (descriptor_tag) { case 0x00: break; /* 0x00 MHP application_descriptor */ case 0x01: break; /* 0x01 MHP application_name_desriptor */ case 0x02: break; /* 0x02 MHP transport_protocol_descriptor */ case 0x03: break; /* 0x03 dvb_j_application_descriptor() */ case 0x04: break; /* 0x04 dvb_j_application_location_descriptor */ case 0x09: /* 0x09 ca_descriptor, 20080106 */ if (t == PMT) parse_ca_descriptor (buf, data); break; case 0x0A: /* 0x0A iso_639_language_descriptor */ if (t == PMT) parse_iso639_language_descriptor (buf, data); break; case 0x0B: break; /* 0x0B application_icons_descriptor */ case 0x13: break; /* 0x13 carousel_identifier_descriptor, to do */ case 0x40: /* 0x40 network_name_descriptor */ if (t == NIT) parse_network_name_descriptor (buf, data); break; case 0x41: break; /* 0x41 service_list_descriptor */ case 0x42: break; /* 0x42 stuffing_descriptor */ case 0x43: break; /* 0x43 satellite_delivery_system_descriptor */ case 0x44: /* 0x44 cable_delivery_system_descriptor */ if (t == NIT) parse_cable_delivery_system_descriptor (buf, data); break; case 0x45: /* 0x45 vbi_data_descriptor */ case 0x46: /* 0x46 vbi_teletext_descriptor */ case 0x47: /* 0x47 bouquet_name_descriptor */ case 0x48: /* 0x48 service_descriptor */ if (t == SDT) parse_service_descriptor (buf, data); break; case 0x49: break; /* 0x49 country_availability_descriptor */ case 0x4A: break; /* 0x4A linkage_descriptor */ case 0x4B: break; /* 0x4B nvod_reference_descriptor */ case 0x4C: break; /* 0x4C time_shifted_service_descriptor */ case 0x4D: break; /* 0x4D short_event_descriptor */ case 0x4E: break; /* 0x4E extended_event_descriptor */ case 0x4F: break; /* 0x4F time_shifted_event_descriptor */ case 0x50: break; /* 0x50 component_descriptor */ case 0x51: break; /* 0x51 mosaic_descriptor */ case 0x52: break; /* 0x52 stream_identifier_descriptor */ case 0x53: /* 0x53 ca_identifier_descriptor */ if (t == SDT) parse_ca_identifier_descriptor (buf, data); break; case 0x54: break; /* 0x54 content_descriptor */ case 0x55: break; /* 0x55 parental_rating_descriptor */ case 0x56: break; /* 0x56 teletext_descriptor */ case 0x57: break; /* 0x57 telephone_descriptor */ case 0x58: break; /* 0x58 local_time_offset_descriptor */ case 0x59: break; /* 0x59 subtitling_descriptor */ case 0x5A: /* 0x5A terrestrial_delivery_system_descriptor */ if (t == NIT) parse_terrestrial_delivery_system_descriptor (buf, data); break; case 0x5B: break; /* 0x5B multilingual_network_name_descriptor */ case 0x5C: break; /* 0x5C multilingual_bouquet_name_descriptor */ case 0x5D: break; /* 0x5D multilingual_service_name_descriptor */ case 0x5E: break; /* 0x5E multilingual_component_descriptor */ case 0x5F: break; /* 0x5F private_data_specifier_descriptor */ case 0x60: break; /* 0x60 service_move_descriptor */ case 0x61: break; /* 0x61 short_smoothing_buffer_descriptor */ case 0x62: /* 0x62 frequency_list_descriptor */ if (t == NIT) parse_frequency_list_descriptor (buf, data); break; case 0x63: break; /* 0x63 partial_transport_stream_descriptor */ case 0x64: break; /* 0x64 data_broadcast_descriptor */ case 0x65: break; /* 0x65 scrambling_descriptor */ case 0x66: break; /* 0x66 data_broadcast_id_descriptor */ case 0x67: break; /* 0x67 transport_stream_descriptor */ case 0x68: break; /* 0x68 dsng_descriptor */ case 0x69: break; /* 0x69 pdc_descriptor */ case 0x6A: break; /* 0x6A ac3_descriptor */ case 0x6B: break; /* 0x6B ancillary_data_descriptor */ case 0x6C: break; /* 0x6C cell_list_descriptor */ case 0x6D: break; /* 0x6D cell_frequency_link_descriptor */ case 0x6E: break; /* 0x6E announcement_support_descriptor */ case 0x6F: break; /* 0x6F application_signalling_descriptor */ case 0x71: break; /* 0x71 service_identifier_descriptor (ETSI TS 102 812, MHP) */ case 0x72: break; /* 0x72 service_availbility_descriptor */ case 0x73: break; /* 0x73 default_authority_descriptor (ETSI TS 102 323) */ case 0x74: break; /* 0x74 related_content_descriptor (ETSI TS 102 323) */ case 0x75: break; /* 0x75 tva_id_descriptor (ETSI TS 102 323) */ case 0x76: break; /* 0x76 content_identifier_descriptor (ETSI TS 102 323) */ case 0x77: break; /* 0x77 time_slice_fec_identifier_descriptor (ETSI EN 301 192) */ case 0x78: break; /* 0x78 ecm_repetition_rate_descriptor (ETSI EN 301 192) */ case 0x79: break; /* 0x79 s2_satellite_delivery_system_descriptor */ case 0x7A: break; /* 0x7A enhanced_ac3_descriptor */ case 0x7B: break; /* 0x7B dts_descriptor */ case 0x7C: break; /* 0x7C aac_descriptor */ case 0x7F: break; /* 0x7F extension_descriptor */ case 0x83: /* 0x83 is in the privately defined range of descriptor tags, * so we parse this only if the user says so to avoid * problems when 0x83 is something entirely different... */ if (t == NIT && vdr_dump_channum) parse_terrestrial_uk_channel_number (buf, data); break; case 0xF2: break; // 0xF2 Private DVB Descriptor Premiere.de, Content Transmission Descriptor default: verbosedebug("skip descriptor 0x%02x\n", descriptor_tag); }; buf += descriptor_len; descriptors_loop_len -= descriptor_len; }}static void parse_pat(const unsigned char *buf, int section_length, int transport_stream_id){ while (section_length > 0) { struct service *s; int service_id = (buf[0] << 8) | buf[1]; if (service_id == 0) { verbosedebug ("skipping %02x %02x %02x %02x (service_id == 0)\n", buf[0],buf[1],buf[2],buf[3]); buf += 4; /* skip nit pid entry... */ section_length -= 4; continue; } /* SDT might have been parsed first... */ s = find_service(current_tp, service_id); if (!s) s = alloc_service(current_tp, service_id); s->pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3]; if (!s->priv && s->pmt_pid) { s->priv = malloc(sizeof(struct section_buf)); setup_filter(s->priv, demux_devname, s->pmt_pid, 0x02, 1, 0, 5); add_filter (s->priv); } buf += 4; section_length -= 4; };}static void parse_pmt (const unsigned char *buf, int section_length, int service_id){ int program_info_len; struct service *s; char msg_buf[14 * AUDIO_CHAN_MAX + 1]; char *tmp; int i; s = find_service (current_tp, service_id); if (!s) { error("PMT for service_id 0x%04x was not in PAT\n", service_id); return; } s->pcr_pid = ((buf[0] & 0x1f) << 8) | buf[1]; program_info_len = ((buf[2] & 0x0f) << 8) | buf[3]; // 20080106, search PMT program info for CA Ids buf +=4; section_length -= 4; while (program_info_len > 0) { int descriptor_length = ((int)buf[1]) + 2; parse_descriptors(PMT, buf, section_length, s); buf += descriptor_length; section_length -= descriptor_length; program_info_len -= descriptor_length; } while (section_length > 0) { int ES_info_len = ((buf[3] & 0x0f) << 8) | buf[4]; int elementary_pid = ((buf[1] & 0x1f) << 8) | buf[2]; switch (buf[0]) { // das ist stream type case 0x01:// STREAMTYPE ISO/IEC 11172 Video case 0x02:// STREAMTYPE ITU-T Rec. H.262 | ISO/IEC 13818-2 Video | ISO/IEC 11172-2 constr. parameter video stream moreverbose(" VIDEO : PID 0x%04x\n", elementary_pid); if (s->video_pid == 0) s->video_pid = elementary_pid; break; case 0x03:// STREAMTYPE_11172_AUDIO case 0x04:// STREAMTYPE_13818-3_AUDIO moreverbose(" AUDIO : PID 0x%04x\n", elementary_pid); 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 0x05:// STREAMTYPE_13818_PRIVATE (ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private sections) case 0x06:// STREAMTYPE_13818_PES_PRIVATE (ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data) /* ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data*/ if (find_descriptor(0x56, buf + 5, ES_info_len, NULL, NULL)) { moreverbose(" TELETEXT : PID 0x%04x\n", elementary_pid); s->teletext_pid = elementary_pid; break; } else if (find_descriptor(0x59, buf + 5, ES_info_len, NULL, NULL)) { /* Note: The subtitling descriptor can also signal * teletext subtitling, but then the teletext descriptor * will also be present; so we can be quite confident * that we catch DVB subtitling streams only here, w/o * parsing the descriptor. */ moreverbose(" SUBTITLING: PID 0x%04x\n", elementary_pid); s->subtitling_pid = elementary_pid; break; } else if (find_descriptor(0x6a, buf + 5, ES_info_len, NULL, NULL)) { moreverbose(" AC3 : PID 0x%04x\n", elementary_pid); s->ac3_pid = elementary_pid; break; } /* we shouldn't reach this one, usually it should be Teletext, Subtitling or AC3 .. */ moreverbose(" unknown private data: PID 0x%04x\n", elementary_pid); break; case 0x07://ISO/IEC 13512 MHEG /* MHEG-5, or ISO/IEC 13522-5, is part of a set of international standards relating to the presentation of multimedia information, standardized by the Multimedia and Hypermedia Experts Group (MHEG). It is most commonly used as a language to describe interactive television services. */ moreverbose(" MHEG : PID 0x%04x\n", elementary_pid); break; case 0x08://ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM CC moreverbose(" DSM CC : PID 0x%04x\n", elementary_pid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -