コード例 #1
0
ファイル: nit.cpp プロジェクト: UkCvs/commando
int parse_nit(const t_satellite_position satellite_position, const unsigned char DiSEqC)
{
	CDemux dmx;

	unsigned char buffer[NIT_SIZE];

	/* position in buffer */
	unsigned short pos;
	unsigned short pos2;

	/* network_information_section elements */
	unsigned short section_length;
	unsigned short network_descriptors_length;
	unsigned short transport_descriptors_length;
	unsigned short transport_stream_loop_length;
	t_transport_stream_id transport_stream_id;
	t_original_network_id original_network_id;
//	unsigned short network_id;

	transponder_id_t transponder_id;

	unsigned char filter[DMX_FILTER_SIZE];
	unsigned char mask[DMX_FILTER_SIZE];

	memset(filter, 0x00, DMX_FILTER_SIZE);
	memset(mask, 0x00, DMX_FILTER_SIZE);

	filter[0] = 0x40;
	filter[4] = 0x00;
	mask[0] = 0xFF;
	mask[4] = 0xFF;

	do {
		if ((dmx.sectionFilter(0x10, filter, mask) < 0) || (dmx.read(buffer, NIT_SIZE) < 0))
			return -1;

		section_length = ((buffer[1] & 0x0F) << 8) + buffer[2];
//		network_id = ((buffer[3] << 8)| buffer [4]);
		network_descriptors_length = ((buffer[8] & 0x0F) << 8) | buffer[9];

		for (pos = 10; pos < network_descriptors_length + 10; pos += buffer[pos + 1] + 2)
		{
			switch (buffer[pos])
			{
/*			case 0x0F:
				Private_data_indicator_descriptor(buffer + pos);
				break;
*/
			case 0x40:
				network_name_descriptor(buffer + pos);
				break;

			case 0x4A:
				linkage_descriptor(buffer + pos);
				break;

			case 0x5B:
				multilingual_network_name_descriptor(buffer + pos);
				break;

/*			case 0x5F:
				private_data_specifier_descriptor(buffer + pos);
				break;
*/
			case 0x80: /* unknown, Eutelsat 13.0E */
				break;

			case 0x90: /* unknown, Eutelsat 13.0E */
				break;

			default:
				DBG("first_descriptor_tag: %02x", buffer[pos]);
				break;
			}
		}

		transport_stream_loop_length = ((buffer[pos] & 0x0F) << 8) | buffer[pos + 1];

		if (!transport_stream_loop_length)
			continue;

		for (pos += 2; pos < section_length - 3; pos += transport_descriptors_length + 6)
		{
			transport_stream_id = (buffer[pos] << 8) | buffer[pos + 1];
			original_network_id = (buffer[pos + 2] << 8) | buffer[pos + 3];
			transport_descriptors_length = ((buffer[pos + 4] & 0x0F) << 8) | buffer[pos + 5];

			// frequency will be inserted in satellite/cable_delivery_system_descriptor()
			transponder_id = CREATE_TRANSPONDER_ID_FROM_FREQUENCY_SATELLITEPOSITION_ORIGINALNETWORK_TRANSPORTSTREAM_ID(0, satellite_position,original_network_id,transport_stream_id);

			if (transponders.find(transponder_id) == transponders.end())
			{
				for (pos2 = pos + 6; pos2 < pos + transport_descriptors_length + 6; pos2 += buffer[pos2 + 1] + 2)
				{
					switch (buffer[pos2])
					{
					case 0x41:
						service_list_descriptor(buffer + pos2, transport_stream_id, original_network_id);
						break;

					case 0x42:
						stuffing_descriptor(buffer + pos2);
						break;

					case 0x43:
						if (satellite_delivery_system_descriptor(buffer + pos2, transponder_id, DiSEqC) < 0)
							return -2;
						break;

					case 0x44:
						if (cable_delivery_system_descriptor(buffer + pos2, transponder_id) < 0)
							return -2;
						break;

					case 0x5A:
						if (terrestrial_delivery_system_descriptor(buffer + pos2) < 0)
							return -2;
						break;

					case 0x5F:
						private_data_specifier_descriptor(buffer + pos2);
						break;

					case 0x62:
						frequency_list_descriptor(buffer + pos2);
						break;

					case 0x82: /* unknown, Eutelsat 13.0E */
						break;

					default:
						DBG("second_descriptor_tag: %02x", buffer[pos2]);
						break;
					}
				}
			}
		}
	} while (filter[4]++ != buffer[7]);

	return 0;
}
コード例 #2
0
int parse_nit(t_satellite_position satellitePosition, freq_id_t freq)
{
    int ret = 0;
    int secdone[255];
    int sectotal = -1;

    for(int i = 0; i < 255; i++)
        secdone[i] = 0;

    cDemux * dmx = new cDemux();;
    dmx->Open(DMX_PSI_CHANNEL);

    unsigned char buffer[NIT_SIZE];

    /* position in buffer */
    unsigned short pos;
    unsigned short pos2;

    /* network_information_section elements */
    unsigned short section_length;
    unsigned short network_descriptors_length;
    unsigned short transport_descriptors_length;
    unsigned short transport_stream_loop_length;
    t_transport_stream_id transport_stream_id;
    t_original_network_id original_network_id;
    unsigned short network_id;

    unsigned char filter[DMX_FILTER_SIZE];
    unsigned char mask[DMX_FILTER_SIZE];

    memset(filter, 0x00, DMX_FILTER_SIZE);
    memset(mask, 0x00, DMX_FILTER_SIZE);

    filter[0] = 0x40;
    //filter[4] = 0x00;
    mask[0] = 0xFF;
    //mask[4] = 0xFF;
    //unsigned char sec = 0x00;

    if (dmx->sectionFilter(0x10, filter, mask, 5) < 0) {
        delete dmx;
        return -1;
    }
    do {
        if (dmx->Read(buffer, NIT_SIZE) < 0) {
            delete dmx;
            return -1;
        }
        if(buffer[0] != 0x40)
            printf("[NIT] ******************************************* Bogus section received: 0x%x\n", buffer[0]);
        section_length = ((buffer[1] & 0x0F) << 8) + buffer[2];
        network_id = ((buffer[3] << 8)| buffer [4]);
        network_descriptors_length = ((buffer[8] & 0x0F) << 8) | buffer[9];
        unsigned char secnum = buffer[6];
        printf("[NIT] section %X last %X network_id 0x%x -> %s\n", secnum, buffer[7], network_id, secdone[secnum] ? "skip" : "use");
        if(secdone[secnum]) // mark sec XX done
            continue;
        secdone[secnum] = 1;
        sectotal++;
        for (pos = 10; pos < network_descriptors_length + 10; pos += buffer[pos + 1] + 2)
        {
            switch (buffer[pos])
            {
            /*			case 0x0F:
            			Private_data_indicator_descriptor(buffer + pos);
            			break;
            			*/
            case 0x40:
                network_name_descriptor(buffer + pos);
                break;

            case 0x4A:
                linkage_descriptor(buffer + pos);
                break;

            case 0x5B:
                multilingual_network_name_descriptor(buffer + pos);
                break;

            /*			case 0x5F:
            			private_data_specifier_descriptor(buffer + pos);
            			break;
            			*/
            case 0x80: /* unknown, Eutelsat 13.0E */
                break;

            case 0x90: /* unknown, Eutelsat 13.0E */
                break;

            default:
                DBG("first_descriptor_tag: %02x\n", buffer[pos]);
                break;
            }
        }

        transport_stream_loop_length = ((buffer[pos] & 0x0F) << 8) | buffer[pos + 1];

        if (!transport_stream_loop_length)
            continue;

        for (pos += 2; pos < section_length - 3; pos += transport_descriptors_length + 6)
        {
            transport_stream_id = (buffer[pos] << 8) | buffer[pos + 1];
            original_network_id = (buffer[pos + 2] << 8) | buffer[pos + 3];
            transport_descriptors_length = ((buffer[pos + 4] & 0x0F) << 8) | buffer[pos + 5];

            //if (transponders.find((transport_stream_id << 16) | original_network_id) == transponders.end())
            //if (scantransponders.find(CREATE_TRANSPONDER_ID_FROM_SATELLITEPOSITION_ORIGINALNETWORK_TRANSPORTSTREAM_ID(freq, satellitePosition, original_network_id, transport_stream_id)) == scantransponders.end())
            {
                for (pos2 = pos + 6; pos2 < pos + transport_descriptors_length + 6; pos2 += buffer[pos2 + 1] + 2)
                {
                    switch (buffer[pos2])
                    {
                    case 0x41:
                        service_list_descriptor(buffer + pos2, transport_stream_id, original_network_id, satellitePosition, freq);
                        break;

                    case 0x42:
                        stuffing_descriptor(buffer + pos2);
                        break;

                    case 0x43:
                        if (satellite_delivery_system_descriptor(buffer + pos2, transport_stream_id, original_network_id, satellitePosition, freq) < 0)
                        {
                            ret = -2;
                            goto _return;
                        }
                        break;

                    case 0x44:
                        if (cable_delivery_system_descriptor(buffer + pos2, transport_stream_id, original_network_id, satellitePosition, freq) < 0)
                        {
                            ret = -2;
                            goto _return;
                        }
                        break;

                    case 0x5A:
                        if (terrestrial_delivery_system_descriptor(buffer + pos2) < 0)
                        {
                            ret = -2;
                            goto _return;
                        }
                        break;

                    case 0x5F:
                        private_data_specifier_descriptor(buffer + pos2);
                        break;

                    case 0x62:
                        frequency_list_descriptor(buffer + pos2);
                        break;

                    case 0x82: /* unknown, Eutelsat 13.0E */
                        break;

                    default:
                        DBG("second_descriptor_tag: %02x\n", buffer[pos2]);
                        break;
                    }
                }
            }
        }
    } while(sectotal < buffer[7]);
    //} while (filter[4]++ != buffer[7]);
_return:
    dmx->Stop();
    delete dmx;
    return ret;
}
コード例 #3
0
ファイル: pmt.cpp プロジェクト: mohousch/neutrinohd2
unsigned short parse_ES_info(const unsigned char * const buffer, CZapitChannel * const channel, CCaPmt * const caPmt)
{
	unsigned short ES_info_length;
	unsigned short pos;
	unsigned char descriptor_tag;
	unsigned char descriptor_length;
	unsigned char i;

	bool isAC3 = false;
	bool isDTS = false;
	bool isAAC = false;
	bool isDTSHD = false;
	bool isEAC3 = false;
	bool isAACPLUS = false;
	bool isLPCM = false;
	
	bool descramble = false;
	std::string description = "";
	unsigned char componentTag = 0xFF;

	/* elementary stream info for ca pmt */
	CEsInfo * esInfo = new CEsInfo();

	esInfo->stream_type = buffer[0];
	esInfo->reserved1 = buffer[1] >> 5;
	esInfo->elementary_PID = ((buffer[1] & 0x1F) << 8) | buffer[2];
	esInfo->reserved2 = buffer[3] >> 4;

	ES_info_length = ((buffer[3] & 0x0F) << 8) | buffer[4];

	for (pos = 5; pos < ES_info_length + 5; pos += descriptor_length + 2) 
	{
		descriptor_tag = buffer[pos];
		descriptor_length = buffer[pos + 1];
		unsigned char fieldCount = descriptor_length / 5;

		switch (descriptor_tag) 
		{
			case VIDEO_STREAM_DESCRIPTOR:
				video_stream_descriptor(buffer + pos);
				break;

			case AUDIO_STREAM_DESCRIPTOR:
				audio_stream_descriptor(buffer + pos);
				break;

			case REGISTRATION_DESCRIPTOR:
				if (descriptor_length >= 3)
					if (!strncmp((const char*)&buffer[pos + 2], "DTS", 3))
						isDTS = true;
				break;

			case CA_DESCRIPTOR:
				esInfo->addCaDescriptor(buffer + pos);
				break;

			case ISO_639_LANGUAGE_DESCRIPTOR:
				for (i = 0; i < 3; i++)
					description += buffer[pos + i + 2];
				break;

			case MAXIMUM_BITRATE_DESCRIPTOR:
				Maximum_bitrate_descriptor(buffer + pos);
				break;

			case PRIVATE_DATA_INDICATOR_DESCRIPTOR:
				Private_data_indicator_descriptor(buffer + pos);
				break;

			case STD_DESCRIPTOR:
				STD_descriptor(buffer + pos);
				break;
				
			case 0x1C:
				isAACPLUS = true;
				break;
				
			case 0x2B:
				isAAC = true;
				break;
				
			case CAROUSEL_IDENTIFIER_DESCRIPTOR:
				break;

			case VBI_DATA_DESCRIPTOR:
				VBI_data_descriptor(buffer + pos);
				break;

			case STREAM_IDENTIFIER_DESCRIPTOR:
				componentTag = buffer[pos + 2];
				break;

			case TELETEXT_DESCRIPTOR:
				for (unsigned char fIdx = 0; fIdx < fieldCount; fIdx++) 
				{
					char tmpLang[4];
					memcpy(tmpLang, &buffer[pos + 5*fIdx + 2], 3);
					tmpLang[3] = '\0';
					unsigned char teletext_type = buffer[pos + 5*fIdx + 5]>> 3;
					unsigned char teletext_magazine_number = buffer[pos + 5*fIdx + 5] & 7;
					unsigned char teletext_page_number = buffer[pos + 5*fIdx + 6];
					if (teletext_type == 0x02)
					{
						channel->addTTXSubtitle(esInfo->elementary_PID, tmpLang, teletext_magazine_number, teletext_page_number);
					} 
					else 
					{
						if (teletext_type == 0x05)
						{
							channel->addTTXSubtitle(esInfo->elementary_PID, tmpLang, teletext_magazine_number, teletext_page_number, true);
						}
					}
				}

				channel->setTeletextPid(esInfo->elementary_PID);
				descramble = true;//FIXME ORF HD scramble txt ?
				break;

			case SUBTITLING_DESCRIPTOR:
				if (esInfo->stream_type == 0x06) 
				{
					unsigned char fieldCount1 = descriptor_length/8;
					for (unsigned char fIdx = 0; fIdx < fieldCount1; fIdx++)
					{
						char tmpLang[4];
						memcpy(tmpLang, &buffer[pos + 8*fIdx + 2], 3);
						tmpLang[3] = '\0';
						unsigned char subtitling_type = buffer[pos + 8*fIdx + 5];
						unsigned short composition_page_id = *((unsigned short*)(&buffer[pos + 8*fIdx + 6]));
						unsigned short ancillary_page_id = *((unsigned short*)(&buffer[pos + 8*fIdx + 8]));
							
						/*dvbsub */
						channel->addDVBSubtitle(esInfo->elementary_PID, tmpLang, subtitling_type, composition_page_id, ancillary_page_id);
					}
					descramble = true;//FIXME MGM / 10E scrambling subtitles ?
				}

				subtitling_descriptor(buffer + pos);
				break;

			case PRIVATE_DATA_SPECIFIER_DESCRIPTOR:
				private_data_specifier_descriptor(buffer + pos);
				break;

			case DATA_BROADCAST_ID_DESCRIPTOR:
				data_broadcast_id_descriptor(buffer + pos);
				break;

			case AC3_DESCRIPTOR:
				isAC3 = true;
				break;

			case APPLICATION_SIGNALLING_DESCRIPTOR:
				channel->setaitPid(esInfo->elementary_PID);
				dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: channel->setaitPid(0x%x)\n", esInfo->elementary_PID);			
				break;
				
			case ENHANCED_AC3_DESCRIPTOR:
				isEAC3 = true;
				break;

			case DTS_DESCRIPTOR:
				isDTS = true;
				break;

			case AAC_DESCRIPTOR:
				isAACPLUS = true;
				break;

			case 0xC5:
				for (i = 0; i < 24; i++)
					description += buffer[pos + i + 3];
				break;

			default:
				dprintf(DEBUG_INFO, "[pmt]parse_ES_info: descriptor_tag: 0x%02x\n", descriptor_tag);
				break;
		}
	}

	switch (esInfo->stream_type) 
	{
		case 0x01:	// MPEG 1 video
		case 0x02:	// MPEG 2 video
		case 0x1b: 	// AVC Video Stream (MPEG4 H264)
		case 0x10:	// MPEG 4 Part 2
		case 0x24:	// H265 HEVC
		case 0x27:	// H265 HEVC
		case 0x42: 	// CAVS
			channel->setVideoPid(esInfo->elementary_PID);
			descramble = true;

			if(esInfo->stream_type == 0x1b || esInfo->stream_type == 0x10)
				channel->videoType = CHANNEL_VIDEO_MPEG4;
			else if(esInfo->stream_type == 0x24 || esInfo->stream_type == 0x27)
				channel->videoType = CHANNEL_VIDEO_HEVC;
			else if(esInfo->stream_type == 0x42)
				channel->videoType = CHANNEL_VIDEO_CAVS;

			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: vpid 0x%x stream 0x%02x type 0x%02x\n", esInfo->elementary_PID, esInfo->stream_type, channel->videoType);
			break;

		case 0x03:
		case 0x04: /* audio es_pids */
			if (description == "")
				description = esInfo->elementary_PID;
			
			if(scan_runs) 
			{
				if(channel->getPreAudioPid() == 0)
					channel->setAudioPid(esInfo->elementary_PID);
			} 
			else
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::MPEG, description, componentTag);
			
			descramble = true;
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;

		case 0x05:// private section
			{
				int tmp = 0;	
				// Houdini: shameless stolen from enigma dvbservices.cpp
				for (pos = 5; pos < ES_info_length + 5; pos += descriptor_length + 2) 
				{
					descriptor_tag = buffer[pos];
					descriptor_length = buffer[pos + 1];

					switch (descriptor_tag) 
					{
						case 0x5F: //DESCR_PRIV_DATA_SPEC:
							if ( ((buffer[pos + 2]<<24) | (buffer[pos + 3]<<16) | (buffer[pos + 4]<<8) | (buffer[pos + 5])) == 190 )
								tmp |= 1;
							break;
							
						case 0x90:
							{
								if ( descriptor_length == 4 && !buffer[pos + 2] && !buffer[pos + 3] && buffer[pos + 4] == 0xFF && buffer[pos + 5] == 0xFF )
									tmp |= 2;
							}
							//break;??	
						case APPLICATION_SIGNALLING_DESCRIPTOR:
							channel->setaitPid(esInfo->elementary_PID);
							dprintf(DEBUG_NORMAL, "[pmt]0x05:parse_ES_info: channel->setaitPid(0x%x)\n", esInfo->elementary_PID);
							break;
							
						default:
							break;
					}
				}
				
				if ( tmp == 3 ) 
				{
					channel->setPrivatePid(esInfo->elementary_PID);
					dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: channel->setPrivatePid(0x%x)\n", esInfo->elementary_PID);
				}
				descramble = true;
				break;
			}
			
		case 0x81: 	// AC3
		case 0xA1: 	// bluray secondary AC3
			esInfo->stream_type = 0x6;
			if (description == "")
				description = esInfo->elementary_PID;
			description += " (AC3)";
			isAC3 = true;
			descramble = true;
			
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::AC3, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;
			
		case 0x06:
			if ( (isAC3) || (isDTS) || (isAAC) || (isAACPLUS) || (isEAC3)) 
			{
				if (description == "") 
				{
					description = esInfo->elementary_PID;
					if (isAC3)
						description += " (AC3)";
					else if (isDTS)
						description += " (DTS)";
					else if (isAAC)
	                                        description += " (AAC)";
					else if (isAACPLUS)
	                                        description += " (AACPLUS)";
					else if (isEAC3)
	                                        description += " (EAC3)";
				}
				
				if(!scan_runs)
				{
					CZapitAudioChannel::ZapitAudioChannelType Type;
					if (isAC3)
						Type = CZapitAudioChannel::AC3;
					else if (isDTS)
						Type = CZapitAudioChannel::DTS;
					else if (isAAC)
						Type = CZapitAudioChannel::AAC;
					else if (isAACPLUS)
						Type = CZapitAudioChannel::AACPLUS;
					else if (isEAC3)
						Type = CZapitAudioChannel::EAC3;
					else
						Type = CZapitAudioChannel::UNKNOWN;
					
					channel->addAudioChannel(esInfo->elementary_PID, Type, description, componentTag);
				}
				descramble = true;
				
				dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			}
			break;
			
		case 0x0F: 	// AAC 
			if (description == "")
				description = esInfo->elementary_PID;
			
			description += " (AAC)";
			isAAC = true;
			descramble = true;
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::AAC, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;
	        case 0x11:	 // AACPLUS
			if (description == "")
				description = esInfo->elementary_PID;
			
			description += " (AACPLUS)";
			isAACPLUS = true;
			descramble = true;
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::AACPLUS, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;
			
		case 0x80: // user private ... but bluray LPCM
		case 0xA0: // bluray secondary LPCM
			if (description == "")
				description = esInfo->elementary_PID;
			
			description += " (LPCM)";
			isLPCM = true;
			descramble = true;
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::LPCM, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;
			
		case 0x82: // bluray DTS (dvb user private...)
		case 0xA2: // bluray secondary DTS
			if (description == "")
				description = esInfo->elementary_PID;
			
			description += " (DTS)";
			isDTS = true;
			descramble = true;
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::DTS, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;
		
		case 0x85: // bluray DTS-HD HRA(dvb user private...)
		case 0x86: // bluray DTS-HD MA(dvb user private...)
		case 0xA6: // bluray secondary DTS-HD
			if (description == "")
				description = esInfo->elementary_PID;
			
			description += " (DTSHD)";
			isDTSHD = true;
			descramble = true;
			if(!scan_runs)
				channel->addAudioChannel(esInfo->elementary_PID, CZapitAudioChannel::DTSHD, description, componentTag);
			
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: apid 0x%x %s\n", esInfo->elementary_PID, description.c_str());
			break;

		default:
			dprintf(DEBUG_NORMAL, "[pmt]parse_ES_info: stream_type: 0x%02x\n", esInfo->stream_type);
			break;
	}

	if (descramble)
		caPmt->es_info.insert(caPmt->es_info.end(), esInfo);
	else
		delete esInfo;

	return ES_info_length;
}