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

📄 mpeg2dataparser.cpp

📁 * This file is part of DigitalWatch, a free DTV watching and recording * program for the VisionPlu
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				s->audio_num++;
			}
			else
				verbose.showf("more than %i audio channels, truncating\n", AUDIO_CHAN_MAX);
			break;
		case 0x06:
			if (find_descriptor(0x56, buf, ES_info_len, NULL, NULL)) {
				verbose.showf("  TELETEXT  : PID 0x%04x\n", elementary_pid);
				s->teletext_pid = elementary_pid;
				break;
			}
			else if (find_descriptor(0x59, buf, 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. */
				verbose.showf("  SUBTITLING: PID 0x%04x\n", elementary_pid);
				s->subtitling_pid = elementary_pid;
				break;
			}
			else if (find_descriptor(0x6a, buf, ES_info_len, NULL, NULL)) {
				verbose.showf("  AC3       : PID 0x%04x\n", elementary_pid);
				s->ac3_pid = elementary_pid;
				parse_descriptorsPMT(buf, ES_info_len, s);
				break;
			}
			/* fall through */
		default:
			verbose.showf("  OTHER     : PID 0x%04x TYPE 0x%02x\n", elementary_pid, streamType);
		};

		buf += ES_info_len;
		section_length -= ES_info_len;
	};


    tmp = msg_buf;
    tmp += sprintf(tmp, "0x%04x (%.4s)", s->audio_pid[0], s->audio_lang[0]);

	if (s->audio_num > AUDIO_CHAN_MAX) {
		verbose.showf("more than %i audio channels: %i, truncating to %i\n",
							AUDIO_CHAN_MAX, s->audio_num, AUDIO_CHAN_MAX);
		s->audio_num = AUDIO_CHAN_MAX;
	}

    for (i=1; i<s->audio_num; i++)
            tmp += sprintf(tmp, ", 0x%04x (%.4s)", s->audio_pid[i], s->audio_lang[i]);

    verbose.showf  ("0x%04x 0x%04x: %s -- %s, pmt_pid 0x%04x, vpid 0x%04x, apid %s\n",
				s->transport_stream_id,
				s->service_id,
				s->provider_name, s->service_name,
				s->pmt_pid, s->video_pid, msg_buf);
}


void Mpeg2DataParser::parse_nit (const unsigned char *buf, int section_length, int network_id)
{
	int descriptors_loop_len = ((buf[0] & 0x0f) << 8) | buf[1];

	if (section_length < descriptors_loop_len + 4)
	{
		verbose.showf("section too short: network_id == 0x%04x, section_length == %i, "
							"descriptors_loop_len == %i\n",
							network_id, section_length, descriptors_loop_len);
		return;
	}

	parse_descriptorsNIT (buf + 2, descriptors_loop_len, current_tp);

	section_length -= descriptors_loop_len + 4;
	buf += descriptors_loop_len + 4;

	while (section_length > 6) {
		int transport_stream_id = (buf[0] << 8) | buf[1];
		struct transponder *t;

		t = find_transponder(transport_stream_id);
		if (!t)
			t = alloc_transponder(transport_stream_id);

		t->network_id = network_id;
		t->original_network_id = (buf[2] << 8) | buf[3];

		descriptors_loop_len = ((buf[4] & 0x0f) << 8) | buf[5];

		if (section_length < descriptors_loop_len + 4)
		{
			verbose.showf("section too short: transport_stream_id == 0x%04x, "
								"section_length == %i, descriptors_loop_len == %i\n",
								t->transport_stream_id, section_length,
								descriptors_loop_len);
			break;
		}

		verbose.showf("  transport_stream_id 0x%04x\n", t->transport_stream_id);


		parse_descriptorsNIT (buf + 6, descriptors_loop_len, t);

/*		if (tn.type == fe_info.type) {
			// only add if develivery_descriptor matches FE type
			t = find_transponder(tn.param.frequency);
			if (!t)
				t = alloc_transponder(tn.param.frequency);
			copy_transponder(t, &tn);
		}*/

		section_length -= descriptors_loop_len + 6;
		buf += descriptors_loop_len + 6;
	};
}


void Mpeg2DataParser::parse_sdt (const unsigned char *buf, int section_length, int transport_stream_id)
{
	buf += 3;	       /*  skip original network id + reserved field */

	struct transponder *tp;
	tp = find_transponder(transport_stream_id);	//i'm not expecting this to return anything, but just in case
	if (!tp)
		tp = alloc_transponder(transport_stream_id);

	while (section_length > 4)
	{
		int service_id = (buf[0] << 8) | buf[1];
		int remainingLength = ((buf[3] & 0x0f) << 8) | buf[4];
		struct service *s;

		if (section_length < remainingLength || !remainingLength)
		{
			verbose.showf("  section too short: service_id == 0x%02x, section_length == %i, "
								"remainingLength == %i\n",
								service_id, section_length,
								remainingLength);
			return;
		}

		s = find_service(tp, service_id);
		if (!s)
			/* maybe PAT has not yet been parsed... */
			s = alloc_service(tp, service_id);

		s->running = (enum running_mode)((buf[3] >> 5) & 0x7);
		s->scrambled = (buf[3] >> 4) & 1;
		s->transport_stream_id = transport_stream_id;

		parse_descriptorsSDT (buf + 5, remainingLength - 5, s);

		section_length -= remainingLength + 5;
		buf += remainingLength + 5;
	};
}

/**
 *   returns 0 when more sections are expected
 *	   1 when all sections are read on this pid
 *	   -1 on invalid table id
 */
int Mpeg2DataParser::parse_section (struct section_buf *s)
{
	const unsigned char *buf = s->buf;
	int table_id;
	int section_length;
	int table_id_ext;
	int section_version_number;
	int section_number;
	int last_section_number;
	int i;

	table_id = buf[0];

	SECTION *pSection = (SECTION*)buf;
	LONG_SECTION *pLong = (LONG_SECTION*)buf;
    MPEG_HEADER_BITS *pHeader = (MPEG_HEADER_BITS*)&pSection->Header.W;
    MPEG_HEADER_VERSION_BITS *pVersion = (MPEG_HEADER_VERSION_BITS*)&pLong->Version.B; 

	if (s->table_id != table_id)
		return -1;

	section_length = (((buf[2] & 0x0f) << 8) | buf[1]) + 3;	//the mpeg2 field doesn't include the first 3 bytes of data
	section_length -= 4; //let's ignore the CRC at he end

	table_id_ext = (buf[4] << 8) | buf[3];
	section_version_number = (buf[5] >> 1) & 0x1f;
	section_number = buf[6];
	last_section_number = buf[7];

	if (s->segmented && s->table_id_ext != -1 && s->table_id_ext != table_id_ext) {
		/* find or allocate actual section_buf matching table_id_ext */
		while (s->next_seg) {
			s = s->next_seg;
			if (s->table_id_ext == table_id_ext)
				break;
		}
		if (s->table_id_ext != table_id_ext) {
			//assert(s->next_seg == NULL);
			s->next_seg = (struct section_buf *)calloc(1, sizeof(struct section_buf));
			s->next_seg->segmented = s->segmented;
			s->next_seg->run_once = s->run_once;
			s->next_seg->timeout = s->timeout;
			s = s->next_seg;
			s->table_id = table_id;
			s->table_id_ext = table_id_ext;
			s->section_version_number = section_version_number;
		}
	}

	if (s->section_version_number != section_version_number ||
			s->table_id_ext != table_id_ext) {
		struct section_buf *next_seg = s->next_seg;

		if (s->section_version_number != -1 && s->table_id_ext != -1)
			verbose.showf("section version_number or table_id_ext changed "
								"%d -> %d / %04x -> %04x\n",
								s->section_version_number, section_version_number,
								s->table_id_ext, table_id_ext);
		s->table_id_ext = table_id_ext;
		s->section_version_number = section_version_number;
		s->sectionfilter_done = 0;
		memset (s->section_done, 0, sizeof(s->section_done));
		s->next_seg = next_seg;
	}

	buf += 8;
	section_length -= 8;

	if (!get_bit(s->section_done, section_number)) {
		set_bit (s->section_done, section_number);

		verbose.showf("pid 0x%02x tid 0x%02x table_id_ext 0x%04x, "
							"%i/%i (version %i)\n",
							s->pid, table_id, table_id_ext, section_number,
							last_section_number, section_version_number);

		switch (table_id)
		{
		case 0x00:
			verbose.showf("PAT\n");
			parse_pat (buf, section_length, table_id_ext);
			break;

		case 0x02:
			verbose.showf("PMT 0x%04x for service 0x%04x\n", s->pid, table_id_ext);
			parse_pmt (buf, section_length, table_id_ext);
			break;

		case 0x41:
			verbose.showf("////////////////////////////////////////////// NIT other\n");
		case 0x40:
			verbose.showf("NIT (%s TS)\n", table_id == 0x40 ? "actual":"other");
			parse_nit (buf, section_length, table_id_ext);
			break;

		case 0x42:
		case 0x46:
			verbose.showf("SDT (%s TS)\n", table_id == 0x42 ? "actual":"other");
			parse_sdt (buf, section_length, table_id_ext);
			break;

		default:
			;
		};

		for (i = 0; i <= last_section_number; i++)
			if (get_bit (s->section_done, i) == 0)
				break;

		if (i > last_section_number)
			s->sectionfilter_done = 1;
	}

	if (s->segmented) {
		/* always wait for timeout; this is because we don't now how
		 * many segments there are
		 */
		return 0;
	}
	else if (s->sectionfilter_done)
		return 1;

	return 0;
}

void Mpeg2DataParser::PrintByteArray(const BYTE *pData, long cbSize)
{
	char str[9];
	memset((char*)&str, 32, 8);
	str[8] = '\0';
	int iter = 0;
	for (iter = 0; iter < cbSize; iter++)
	{
		int pos = iter % 8;

		if (pos == 0)
			verbose.showf("\t");

		verbose.showf("0x%.2x ", pData[iter]);
		if ((pData[iter] >= 32) && (pData[iter] <= 126))
			str[pos] = pData[iter];

		if (pos == 7)
		{
			verbose.showf("  %S\n", (char*)&str);
			memset((char*)&str, 32, 8);
		}
	} 
	int missing = 8 - (((iter-1)%8)+1);
	if (missing != 0)
	{
		for (int i=0 ; i< missing ; i++ )
			verbose.showf("     ");
		verbose.showf("  %S\n", (char*)&str);
	}
}

void Mpeg2DataParser::PrintWordArray(const BYTE *pData, long cbSize)
{ 
	int iter = 0;
	while (iter < cbSize) 
	{
		if (iter % 16 == 0)
			verbose.showf("\t");

		if (iter%2 == 0)
			verbose.showf("0x");

		verbose.showf(_T("%.2x"), pData[iter]);

		if (iter%2 == 1)
			verbose.showf(" ");

		if (iter % 16 == 15)
			verbose.showf("\n");

		iter++;
	} 
	if (iter % 16 != 0)
		verbose.showf("\n");
}

void Mpeg2DataParser::PaddingForNumber(long number, long totalWidth)
{
	long len = 0;
	if (number != 0)
		len = log10((double)((number > 0) ? number : -1 * number));
	if (number < 0)
		len++;
	len++;

	while ( len < totalWidth )
	{
		output.showf(" ");
		len++;
	}
}

void Mpeg2DataParser::PrintDigitalWatchChannelsIni()
{
	struct service *s;

	output.showf("\nNetwork_%i(\"%s\", %i, %i, 1)\n", m_networkNumber, current_tp->network_name, current_tp->frequency, current_tp->bandwidth);

	int i;
	if (current_tp->n_other_f > 0)
		output.showf("#Alternate %s\n", ((current_tp->n_other_f > 1) ? "frequencies" : "frequency"));
	for ( i=0 ; i<current_tp->n_other_f ; i++ )
	{
		output.showf("#Network_%i(\"%s\", %i, %i, 1)\n", m_networkNumber, current_tp->network_name, current_tp->other_f[i], current_tp->bandwidth);
	}

	i=1;
	vector<service *>::iterator it;
	for ( it = current_tp->services.begin() ; it != current_tp->services.end() ; it++ )
	{
		s = *it;

		for (int audio = 0 ; audio <= s->audio_num ; audio++ )
		{
			if (((audio < s->audio_num) && (s->audio_pid[audio])) || (s->ac3_pid))
			{
				output.showf("  Program_");
				if (i < 10) output.showf(" ");
				output.showf("%i(\"%s", i, s->service_name);

				int len = strlen((char *)s->service_name);
				if ((audio > 0) && (audio == s->audio_num))
				{
					output.showf(" AC3");
					len += 4;
				}
				output.showf("\"");
				
				while ( len < 20 ) { output.showf(" "); len++; }
				output.showf(", ");

				PaddingForNumber(s->service_id, 4);
				output.showf("%i, ",	s->service_id);

				PaddingForNumber(s->video_pid, 4);
				output.showf("%i, ", s->video_pid);

				if (audio < s->audio_num)
				{
					PaddingForNumber(s->audio_pid[audio], 5);
					output.showf("%i, ", s->audio_pid[audio]);
				}
				else
				{
					PaddingForNumber(s->ac3_pid, 4);
					output.showf("A%i, ", s->ac3_pid);
				}
				
				PaddingForNumber(s->pmt_pid, 4);
				output.showf("%i)    #", s->pmt_pid);

				if (audio == 0)
				{
					if (s->channel_num)
						output.showf(" LCN=%i", s->channel_num);

					if (s->teletext_pid)
						output.showf(" Teletext=%i", s->teletext_pid);
				}

				output.showf("\n");

				i++;
			}
		}
	}
	output.showf("\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -