Пример #1
0
/** @brief, tell if the eit have a newer version than the one recorded actually
 * In the EIT pid there is a field to say if the EIT was updated
 * This function check if it has changed (in order to rewrite the eit only once)
 * Note this function can give false positive since it doesn't check the CRC32
 *
 *@param rewrite_vars the parameters for eit rewriting
 *@param buf : the received buffer
 */
int eit_need_update(rewrite_parameters_t *rewrite_vars, unsigned char *buf, int raw)
{

	//Get the SID of the new EIT
	//loop over the stored EIT
	//if found and version > : need update
	//if not found need update


	eit_t       *eit;
	//if it's a raw TS packet we search for the beginning
	if(raw)
		eit=(eit_t*)(get_ts_begin(buf));
	else
		eit=(eit_t*)(buf);

	eit_packet_t *eit_packet;
	if(eit) //It's the beginning of a new packet
	{
		eit_packet=eit_find_by_tsid(rewrite_vars,HILO(eit->service_id));
		if(eit_packet==NULL)
		{
			log_message( log_module, MSG_DETAIL,"EIT sid %d not stored, need update.",
											HILO(eit->service_id));
			return 1;
		}
		//		if((eit->table_id==0x4E)||((eit->table_id&0xF0)==0x50))
		//if((eit->table_id&0xF0)==0x50)
		//	log_message( log_module, MSG_DETAIL,"EIT table id 0x%x schedule not supported yet.",eit->table_id);
		if(eit->table_id==0x4E)
			// 0x4E event_information_section - actual_transport_stream, present/following
			// 0x50 to 0x5F event_information_section - actual_transport_stream, schedule
			//TODO : deal with all these table id_ which could have different version number for the same service
		{
			/*current_next_indicator – A 1-bit indicator, which when set to '1' indicates that the table
        sent is currently applicable.*/
			if(eit->current_next_indicator == 0)
				return 0;

			if(eit->version_number!=eit_packet->version)
			{
				log_message( log_module, MSG_DETAIL,"EIT sid %d need update. stored version : %d, new: %d",
						HILO(eit->service_id),
						eit_packet->version,
						eit->version_number);
				return 1;
			}
			if(!eit_packet->sections_stored[eit->section_number] )
			{
				log_message( log_module, MSG_DETAIL,"EIT sid %d new section %d version : %d",
										HILO(eit->service_id),
										eit->section_number,
										eit_packet->version,
										eit->version_number);
				return 1;
			}
		}
	}
	return 0;
}
Пример #2
0
/** @brief This function is called when a new EIT packet for a channel is there and we asked for rewrite
 * This function copy the rewritten EIT to the buffer. And checks if the EIT was changed so the rewritten version have to be updated
 */
void eit_rewrite_new_channel_packet(unsigned char *ts_packet, rewrite_parameters_t *rewrite_vars, mumudvb_channel_t *channel,
		multicast_parameters_t *multicast_vars, unicast_parameters_t *unicast_vars, mumudvb_chan_and_pids_t *chan_and_pids,fds_t *fds)
{
	int i=0;
	//If payload unit start indicator , we will send all the present EIT for this service, otherwise nothing
	//We generate the TS packets on by one, and for each one, we check if we have to send
	//Otherwise we skip the packet


	//If payload unit start indicator, we will send all the present EIT for this service, otherwise nothing
	//just a matter to send an EIT per service only if an EIT is starting in the stream,
	//the better way would be an EIT starting and corresponding to this SID but, it's more difficult to get this information
	ts_header_t *ts_header=(ts_header_t *)ts_packet;
	if(!(ts_header->payload_unit_start_indicator))
		return;

	//If there is an EIT PID sorted for this channel
	eit_packet_t *eit_pkt;
	eit_pkt=eit_find_by_tsid(rewrite_vars,channel->service_id);
	if((eit_pkt==NULL)||(!eit_pkt->full_eit_ok))
		return;

	//search for the next section we can send
	//just in case we have a new version with less sections
	channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
	//the real search
	while((i<=eit_pkt->last_section_number)&&(!eit_pkt->sections_stored[channel->eit_section_to_send]))
	{
		channel->eit_section_to_send++;
		channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
		i++;
	}
	//if nothing found
	if(!eit_pkt->sections_stored[channel->eit_section_to_send])
		return; //bye

	//ok we send this!
	mumudvb_ts_packet_t *pkt_to_send;
	int data_left_to_send,sent;
	unsigned char send_buf[TS_PACKET_SIZE];
	ts_header=(ts_header_t *)send_buf;
	pkt_to_send=eit_pkt->full_eit_sections[channel->eit_section_to_send];
	data_left_to_send=pkt_to_send->full_buffer_len;
	sent=0;
	//log_message(log_module,MSG_FLOOD,"Sending EIT to channel %s (sid %d) section %d data_len %d",
	//		channel->name,
	//		channel->service_id,
	//		channel->eit_section_to_send,
	//		data_left_to_send);
	while(data_left_to_send>0)
	{
		int header_len;
		memset(send_buf,0,TS_PACKET_SIZE*sizeof(unsigned char));
		//we fill the TS header
		ts_header->sync_byte=0x47;
		if(sent==0)
		{
			ts_header->payload_unit_start_indicator=1;
			header_len=TS_HEADER_LEN; //includes the pointer field
		}
		else
			header_len=TS_HEADER_LEN-1; //the packet has started, we don't count the pointer field
		ts_header->pid_lo=18;							//specify the PID
		ts_header->adaptation_field_control=1;			//always one
		ts_header->continuity_counter=channel->eit_cc;	//continuity counter
		channel->eit_cc++;
		channel->eit_cc= channel->eit_cc % 16;
		//We send the data
		//plus one because of pointer field
		if(data_left_to_send>(TS_PACKET_SIZE-header_len))
		{
			memcpy(send_buf+header_len,pkt_to_send->data_full+sent,(TS_PACKET_SIZE-header_len)*sizeof(unsigned char));
			sent+=(TS_PACKET_SIZE-header_len);
			data_left_to_send-=(TS_PACKET_SIZE-header_len);
		}
		else
		{
			memcpy(send_buf+header_len,pkt_to_send->data_full+sent,data_left_to_send*sizeof(unsigned char));
			sent+=data_left_to_send;
			//Padding with OxFF
			memset(send_buf+header_len+data_left_to_send,
						0xFF,
						(TS_PACKET_SIZE-(header_len+data_left_to_send))*sizeof(unsigned char));
			data_left_to_send=0;
		}
		//NOW we really send the data over the network
		// we fill the channel buffer
		memcpy(channel->buf + channel->nb_bytes, send_buf, TS_PACKET_SIZE*sizeof(unsigned char));
		channel->nb_bytes += TS_PACKET_SIZE;
		//The buffer is full, we send it
		if ((!multicast_vars->rtp_header && ((channel->nb_bytes + TS_PACKET_SIZE) > MAX_UDP_SIZE))
				||(multicast_vars->rtp_header && ((channel->nb_bytes + RTP_HEADER_LEN + TS_PACKET_SIZE) > MAX_UDP_SIZE)))
		{
			uint64_t now_time;
			now_time=get_time();
			send_func(channel, &now_time, unicast_vars, multicast_vars, chan_and_pids, fds);
		}

	}

	//We update which section we want to send
	channel->eit_section_to_send++;
	channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
	//TODO increase table id if we reached the end

}
Пример #3
0
/** @brief This function is called when a new EIT packet for a channel is there and we asked for rewrite
 * This function copy the rewritten EIT to the buffer. And checks if the EIT was changed so the rewritten version have to be updated
 */
void eit_rewrite_new_channel_packet(unsigned char *ts_packet, rewrite_parameters_t *rewrite_vars, mumudvb_channel_t *channel,
		multi_p_t *multi_p, unicast_parameters_t *unicast_vars, void *scam_vars_v,fds_t *fds)
{
	int i=0;
	//If payload unit start indicator , we will send all the present EIT for this service, otherwise nothing
	//We generate the TS packets on by one, and for each one, we check if we have to send
	//Otherwise we skip the packet


	//If payload unit start indicator, we will send all the present EIT for this service, otherwise nothing
	//just a matter to send an EIT per service only if an EIT is starting in the stream,
	//the better way would be an EIT starting and corresponding to this SID but, it's more difficult to get this information
	ts_header_t *ts_header=(ts_header_t *)ts_packet;
	if(!(ts_header->payload_unit_start_indicator))
		return;

	//If there is an EIT PID sorted for this channel
	eit_packet_t *eit_pkt;
	uint8_t section_start;
	//we check we start with a valid section
	if((channel->eit_table_id_to_send!=0x4E)&&((channel->eit_table_id_to_send&0xF0)!=0x50))
		channel->eit_table_id_to_send=0x4E;

	//We search for the EIT packet to send, if not found we loop on the sections
	section_start=channel->eit_table_id_to_send;
	do
	{
		eit_pkt=eit_find_by_tsid(rewrite_vars,channel->service_id,channel->eit_table_id_to_send);
		//loop over the table id
		if((eit_pkt==NULL)||(!eit_pkt->full_eit_ok))
		{
			channel->eit_table_id_to_send=eit_next_table_id(channel->eit_table_id_to_send);
			eit_pkt=NULL;
		}
	}
	while((eit_pkt==NULL)&&(channel->eit_table_id_to_send!=section_start));

	//we go away if there is no EIT packet to send
	if(eit_pkt==NULL)
		return;
	//search for the next section we can send
	//just in case we have a new version with less sections
	channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
	//the real search
	while((i<=eit_pkt->last_section_number)&&(!eit_pkt->sections_stored[channel->eit_section_to_send]))
	{
		channel->eit_section_to_send++;
		channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
		i++;
	}
	//if nothing found
	if(!eit_pkt->sections_stored[channel->eit_section_to_send])
	{
		//bye (we should be here BTW) but we avoid to stay on invalid packet by going to next section
		channel->eit_table_id_to_send=eit_next_table_id(channel->eit_table_id_to_send);
		return;
	}

	//ok we send this!
	mumudvb_ts_packet_t *pkt_to_send;
	int data_left_to_send,sent;
	unsigned char send_buf[TS_PACKET_SIZE];
	ts_header=(ts_header_t *)send_buf;
	pkt_to_send=eit_pkt->full_eit_sections[channel->eit_section_to_send];
	data_left_to_send=pkt_to_send->len_full;
	sent=0;
	//log_message(log_module,MSG_FLOOD,"Sending EIT to channel %s (sid %d) section %d table_id 0x%02x data_len %d",
	//		channel->name,
	//		channel->service_id,
	//		channel->eit_section_to_send,
	//		channel->eit_table_id_to_send,
	//		data_left_to_send);
	while(data_left_to_send>0)
	{
		int header_len;
		memset(send_buf,0,TS_PACKET_SIZE*sizeof(unsigned char));
		//we fill the TS header
		ts_header->sync_byte=0x47;
		if(sent==0)
		{
			ts_header->payload_unit_start_indicator=1;
			header_len=TS_HEADER_LEN; //includes the pointer field
		}
		else
			header_len=TS_HEADER_LEN-1; //the packet has started, we don't count the pointer field
		ts_header->pid_lo=18;							//specify the PID
		ts_header->adaptation_field_control=1;			//always one
		ts_header->continuity_counter=channel->eit_cc;	//continuity counter
		channel->eit_cc++;
		channel->eit_cc= channel->eit_cc % 16;
		//We send the data
		//plus one because of pointer field
		if(data_left_to_send>=(TS_PACKET_SIZE-header_len))
		{
			memcpy(send_buf+header_len,pkt_to_send->data_full+sent,(TS_PACKET_SIZE-header_len)*sizeof(unsigned char));
			sent+=(TS_PACKET_SIZE-header_len);
			data_left_to_send-=(TS_PACKET_SIZE-header_len);
		}
		else
		{
			memcpy(send_buf+header_len,pkt_to_send->data_full+sent,data_left_to_send*sizeof(unsigned char));
			sent+=data_left_to_send;
			//Padding with OxFF
			memset(send_buf+header_len+data_left_to_send,
					0xFF,
					(TS_PACKET_SIZE-(header_len+data_left_to_send))*sizeof(unsigned char));
			data_left_to_send=0;
		}
		//NOW we fill the channel buffer for sending
		buffer_func(channel, send_buf, unicast_vars, multi_p, scam_vars_v, fds);
	}

	//We update which section we want to send
	channel->eit_section_to_send++;
	channel->eit_section_to_send=channel->eit_section_to_send % (eit_pkt->last_section_number+1);
	//if we reached the end, we go to the next table_id
	if(channel->eit_section_to_send==0)
		channel->eit_table_id_to_send=eit_next_table_id(channel->eit_table_id_to_send);


}