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

📄 mpeg2dataparser.cpp

📁 * This file is part of DigitalWatch, a free DTV watching and recording * program for the VisionPlu
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		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 + -