📄 mpeg2dataparser.cpp
字号:
break;
case 1:
verbose.showf(" HP - FEC_2_3");
break;
case 2:
verbose.showf(" HP - FEC_3_4");
break;
case 3:
verbose.showf(" HP - FEC_5_6");
break;
case 4:
verbose.showf(" HP - FEC_7_8");
break;
default:
verbose.showf(" HP - FEC_AUTO");
break;
}
//if (((buf[8] >> 5) & 0x7) > 4)
//DWORD coderateLP = (buf[8] >> 5) & 0x7;
switch ((buf[8] >> 5) & 0x7)
{
case 0:
verbose.showf(" LP - FEC_1_2");
break;
case 1:
verbose.showf(" LP - FEC_2_3");
break;
case 2:
verbose.showf(" LP - FEC_3_4");
break;
case 3:
verbose.showf(" LP - FEC_5_6");
break;
case 4:
verbose.showf(" LP - FEC_7_8");
break;
default:
verbose.showf(" LP - FEC_AUTO");
break;
}
//o->guard_interval = GUARD_INTERVAL_1_32 + ((buf[8] >> 3) & 0x3);
//o->transmission_mode = (buf[8] & 0x2) ?
// TRANSMISSION_MODE_8K :
// TRANSMISSION_MODE_2K;
switch (buf[8] & 0x2)
{
case 0:
verbose.showf(" Transmission mode 2K\n");
break;
default:
verbose.showf(" Transmission mode 8K\n");
break;
}
t->other_frequency_flag = (buf[8] & 0x01);
if (t->other_frequency_flag)
verbose.showf(" Other frequency flags set\n");
//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, " (tuning failed)");
// dprintf(5, "\n");
//}
}
void Mpeg2DataParser::parse_frequency_list_descriptor (const unsigned char *buf, struct transponder *t)
{
t->n_other_f = (buf[1] - 1) / 4;
if (t->n_other_f < 1 || (buf[2] & 0x03) != 3)
{
t->n_other_f = 0;
return;
}
if (t->other_f)
free(t->other_f);
t->other_f = (__int32*)malloc(sizeof(int)*t->n_other_f);
buf += 3;
for (int i = 0; i < t->n_other_f; i++)
{
t->other_f[i] = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
t->other_f[i] /= 100;
verbose.showf(" Alternate Frequency %i\n", t->other_f[i]);
buf += 4;
}
}
void Mpeg2DataParser::parse_terrestrial_uk_channel_number (const unsigned char *buf, struct transponder *t)
{
int i, n, channel_num, service_id;
//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);
verbose.showf(" Service ID 0x%x has channel number %d\n", service_id, channel_num);
//Might need to loop here for other transponders
s = find_service(t, service_id);
if (!s)
alloc_service(t, service_id);
if (s)
s->channel_num = channel_num;
buf += 4;
}
}
void Mpeg2DataParser::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 = (unsigned char *)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 = (unsigned char *)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;
}
verbose.showf( " 0x%04x 0x%04x: pmt_pid 0x%04x %s -- %s (%s%s)\n",
s->transport_stream_id,
s->service_id,
s->pmt_pid,
s->provider_name, s->service_name,
s->running == RM_NOT_RUNNING ? "not running" :
s->running == RM_STARTS_SOON ? "starts soon" :
s->running == RM_PAUSING ? "pausing" :
s->running == RM_RUNNING ? "running" : "???",
s->scrambled ? ", scrambled" : "");
}
int Mpeg2DataParser::find_descriptor(__int8 tag, const unsigned char *buf, int remaining_length, const unsigned char **desc, int *desc_len)
{
while (remaining_length > 0) {
unsigned char descriptor_tag = buf[0];
unsigned char descriptor_len = buf[1] + 2;
if (!descriptor_len) {
verbose.showf("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;
remaining_length -= descriptor_len;
}
return 0;
}
void Mpeg2DataParser::parse_descriptorsPMT(const unsigned char *buf, int remaining_length, struct service *s)
{
while (remaining_length > 0)
{
unsigned char descriptor_tag = buf[0];
unsigned char descriptor_len = buf[1] + 2;
if (!descriptor_len)
{
verbose.showf("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag);
break;
}
switch (descriptor_tag)
{
case 0x0a:
parse_iso639_language_descriptor (buf, s);
break;
default:
verbose.showf(" skip descriptor 0x%02x\n", descriptor_tag);
print_unknown_descriptor(buf, descriptor_len);
};
buf += descriptor_len;
remaining_length -= descriptor_len;
}
}
void Mpeg2DataParser::parse_descriptorsNIT(const unsigned char *buf, int remaining_length, struct transponder *tp)
{
while (remaining_length > 0)
{
unsigned char descriptor_tag = buf[0];
unsigned char descriptor_len = buf[1] + 2;
if (!descriptor_len)
{
verbose.showf("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag);
break;
}
switch (descriptor_tag)
{
case 0x40:
verbose.showf(" Found a network name descriptor\n");
parse_network_name_descriptor (buf, tp);
break;
case 0x43:
verbose.showf(" Found a satellite delivery system descriptor\n");
//parse_satellite_delivery_system_descriptor (buf, tp);
print_unknown_descriptor(buf, descriptor_len);
break;
case 0x44:
verbose.showf(" Found a cable delivery system descriptor\n");
//parse_cable_delivery_system_descriptor (buf, tp);
print_unknown_descriptor(buf, descriptor_len);
break;
case 0x5a:
verbose.showf(" Found a terrestrial delivery system descriptor\n");
parse_terrestrial_delivery_system_descriptor (buf, tp);
break;
case 0x62:
verbose.showf(" Found a frequency list descriptor\n");
parse_frequency_list_descriptor (buf, tp);
break;
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 (vdr_dump_channum)
verbose.showf(" Found a terrestrial uk channel number\n");
parse_terrestrial_uk_channel_number (buf, tp);
break;
default:
verbose.showf(" skip descriptor 0x%02x\n", descriptor_tag);
print_unknown_descriptor(buf, descriptor_len);
};
buf += descriptor_len;
remaining_length -= descriptor_len;
}
}
void Mpeg2DataParser::parse_descriptorsSDT(const unsigned char *buf, int remaining_length, struct service *s)
{
while (remaining_length > 0)
{
unsigned char descriptor_tag = buf[0];
unsigned char descriptor_len = buf[1] + 2;
if (!descriptor_len)
{
verbose.showf(" descriptor_tag == 0x%02x, len is 0\n", descriptor_tag);
break;
}
switch (descriptor_tag)
{
case 0x48:
parse_service_descriptor (buf, s);
break;
/* case 0x53:
parse_ca_identifier_descriptor (buf, data);
break;
*/
default:
verbose.showf(" skip descriptor 0x%02x\n", descriptor_tag);
print_unknown_descriptor(buf, descriptor_len);
};
buf += descriptor_len;
remaining_length -= descriptor_len;
}
}
void Mpeg2DataParser::parse_pat(const unsigned char *buf, int section_length, int transport_stream_id)
{
while (section_length >= 4)
{
struct service *s;
int service_id = (buf[0] << 8) | buf[1];
int pmtPID = ((buf[2] & 0x1f) << 8) | buf[3];
if (service_id != 0) /* skip nit pid entry... */
{
if (!current_tp)
{
current_tp = find_transponder(transport_stream_id); //i'm not expecting this to return anything, but just in case
if (!current_tp)
current_tp = alloc_transponder(transport_stream_id);
}
verbose.showf(" Found service id 0x%04x with PMT 0x%04x\n", service_id, pmtPID);
/* SDT might have been parsed first... */
s = find_service(current_tp, service_id);
if (!s)
s = alloc_service(current_tp, service_id);
else
verbose.showf("Existing service object found\n");
s->pmt_pid = pmtPID;
if (!s->pmt_pid)
{
verbose.showf("Skipping adding filter. pmt pid is 0x00\n");
}
else if (s->priv)
{
verbose.showf("Skipping adding filter.\n");
}
else
{
s->priv = (struct section_buf *)malloc(sizeof(struct section_buf));
SetupFilter(s->priv, s->pmt_pid, 0x02, 1, 0, 5);
AddFilter (s->priv);
s->priv = NULL;
}
}
else
{
verbose.showf("Skipping nit pid entry with service_id 0x00\n");
}
buf += 4;
section_length -= 4;
};
}
void Mpeg2DataParser::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) {
verbose.showf("PMT for serivce_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];
buf += program_info_len + 4;
section_length -= program_info_len + 4;
while (section_length >= 5) {
int ES_info_len = ((buf[3] & 0x0f) << 8) | buf[4];
int elementary_pid = ((buf[1] & 0x1f) << 8) | buf[2];
int streamType = buf[0];
buf += 5;
section_length -= 5;
switch (streamType) {
case 0x01:
case 0x02:
verbose.showf(" VIDEO : PID 0x%04x\n", elementary_pid);
if (s->video_pid == 0)
s->video_pid = elementary_pid;
break;
case 0x03:
case 0x04:
verbose.showf(" AUDIO : PID 0x%04x\n", elementary_pid);
if (s->audio_num < AUDIO_CHAN_MAX) {
s->audio_pid[s->audio_num] = elementary_pid;
parse_descriptorsPMT (buf, ES_info_len, s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -