1 #include <gpac/internal/dvb_mpe_dev.h>
2 #include <gpac/network.h>
3 #include <string.h>
4 
5 
6 #ifdef GPAC_ENABLE_MPE
7 
8 static void gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet *ip_packet);
9 
10 
empty_list(GF_List * list)11 static void empty_list(GF_List * list)
12 {
13 	while(gf_list_count(list)) {
14 		void *obj = gf_list_get(list,0);
15 		gf_list_rem(list,0);
16 		gf_free(obj);
17 		obj = NULL;
18 	}
19 
20 }
21 
on_dvb_mpe_section(GF_M2TS_Demuxer * ts,u32 evt_type,void * par)22 static void on_dvb_mpe_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
23 {
24 	GF_M2TS_SL_PCK *pck = (GF_M2TS_SL_PCK *)par;
25 	unsigned char *data;
26 	u32 u32_data_size;
27 	u32 u32_table_id;
28 
29 	if (evt_type == GF_M2TS_EVT_DVB_MPE) {
30 		data = pck->data;
31 		u32_data_size = pck->data_len;
32 		u32_table_id = data[0];
33 
34 		switch(u32_table_id) {
35 		case GF_M2TS_TABLE_ID_INT:
36 			gf_m2ts_process_int(ts, (GF_M2TS_SECTION_ES *)pck->stream, data, u32_data_size, u32_table_id);
37 			break;
38 
39 		case GF_M2TS_TABLE_ID_MPE_FEC:
40 		case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE:
41 			if ((ts->ip_platform != NULL) || ts->direct_mpe) {
42 				GF_M2TS_SECTION_MPE* mpe = (GF_M2TS_SECTION_MPE*)pck->stream;
43 				gf_m2ts_process_mpe(ts, mpe, data, u32_data_size, u32_table_id);
44 			}
45 			break;
46 		default:
47 			return;
48 		}
49 	}
50 }
51 
on_dvb_mpe_fec_frame(GF_M2TS_Demuxer * ts,MPE_FEC_FRAME * mff)52 static void on_dvb_mpe_fec_frame(GF_M2TS_Demuxer *ts, MPE_FEC_FRAME *mff)
53 {
54 	if (ts->ip_platform != NULL) {
55 		if(ts->dvb_h_demux == 0) {
56 			gf_m2ts_gather_ipdatagram_information(mff,ts);
57 		} else {
58 			gf_m2ts_process_ipdatagram(mff,ts);
59 		}
60 	}
61 }
62 
63 GF_EXPORT
gf_dvb_mpe_init(GF_M2TS_Demuxer * ts)64 void gf_dvb_mpe_init(GF_M2TS_Demuxer *ts)
65 {
66 	if (ts && !ts->on_mpe_event) ts->on_mpe_event = on_dvb_mpe_section;
67 }
68 
69 GF_EXPORT
gf_dvb_mpe_shutdown(GF_M2TS_Demuxer * ts)70 void gf_dvb_mpe_shutdown(GF_M2TS_Demuxer *ts)
71 {
72 	GF_M2TS_IP_PLATFORM * ip_platform;
73 	if (!ts)
74 		return;
75 	ip_platform = ts->ip_platform;
76 
77 	if (!ip_platform) return;
78 
79 	if (ip_platform->ip_streams) {
80 		while(gf_list_count(ip_platform->ip_streams)) {
81 			GF_M2TS_IP_Stream *ip_stream_buff = gf_list_get(ip_platform->ip_streams, 0);
82 
83 			while (gf_list_count(ip_stream_buff->targets)) {
84 				GF_M2TS_IP_Target *ip_targets = gf_list_get(ip_stream_buff->targets, 0);
85 				gf_free(ip_targets);
86 				gf_list_rem(ip_stream_buff->targets,0);
87 			}
88 			gf_free(ip_stream_buff);
89 			gf_list_rem(ip_platform->ip_streams,0);
90 
91 		}
92 		gf_list_del(ip_platform->ip_streams);
93 	}
94 	ip_platform->ip_streams = NULL;
95 	if (ip_platform->socket_struct) {
96 		while(gf_list_count(ip_platform->socket_struct)) {
97 			GF_SOCK_ENTRY *socket_struct = gf_list_get(ip_platform->socket_struct, 0);
98 			gf_free(socket_struct);
99 			gf_list_rem(ip_platform->socket_struct,0);
100 		}
101 		gf_list_del(ip_platform->socket_struct);
102 	}
103 	ip_platform->socket_struct = NULL;
104 	gf_free(ip_platform);
105 	ts->ip_platform = NULL;
106 }
107 
108 GF_EXPORT
gf_dvb_mpe_section_new()109 GF_M2TS_ES *gf_dvb_mpe_section_new()
110 {
111 	GF_M2TS_ES *es;
112 
113 	GF_M2TS_SECTION_MPE *ses;
114 	GF_SAFEALLOC(ses, GF_M2TS_SECTION_MPE);
115 	ses->mff = NULL;
116 	es = (GF_M2TS_ES *)ses;
117 	es->flags = GF_M2TS_ES_IS_SECTION | GF_M2TS_ES_IS_MPE;
118 	return es;
119 }
120 
121 GF_EXPORT
gf_dvb_mpe_section_del(GF_M2TS_ES * es)122 void gf_dvb_mpe_section_del(GF_M2TS_ES *es)
123 {
124 	GF_M2TS_SECTION_MPE *ses = (GF_M2TS_SECTION_MPE *)es;
125 
126 	/*TODO - cleanup MPE FEC frame state & co*/
127 	if (ses->mff) {
128 		if (ses->mff->mpe_holes)
129 			gf_list_del(ses->mff->mpe_holes);
130 		ses->mff->mpe_holes = NULL;
131 		gf_free(ses->mff);
132 		ses->mff=NULL;
133 	}
134 }
135 
136 
137 Bool gf_m2ts_crc32_check(u8 *data, u32 len);
138 
gf_m2ts_process_mpe(GF_M2TS_Demuxer * ts,GF_M2TS_SECTION_MPE * mpe,unsigned char * data,u32 data_size,u8 table_id)139 void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned char *data, u32 data_size, u8 table_id)
140 {
141 	GF_M2TS_IP_Stream *ip_stream_buff;
142 	GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform;
143 	u32 table_boundry_flag;
144 	u32 frame_boundry_flag;
145 	u32 offset;
146 	u32 i_streams,j;
147 	u32 section_number, last_section_number;
148 	s32 len_left = data_size;
149 	assert( ts );
150 
151 
152 	i_streams = 0;
153 
154 	if (!gf_m2ts_crc32_check(data, data_size - 4)) {
155 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("CRC error in the MPE/MPE-FEC data \n"));
156 	}
157 
158 	/*get number of rows of mpe_fec_frame from descriptor*/
159 	section_number = data[6];
160 	last_section_number = data[7];
161 
162 	if (ts->direct_mpe) {
163 		if (table_id != GF_M2TS_TABLE_ID_DSM_CC_PRIVATE) return;
164 		if (section_number != last_section_number) {
165 			GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("MPE IP datagram on several section not supported\n"));
166 			return;
167 		}
168 		/* send the IP data :
169 		   Remove the first 12 bytes of header (from table id to end of real time parameters
170 		   Remove also the last four 4 bytes of the section (CRC 32)
171 		*/
172 		gf_m2ts_mpe_send_datagram(ts, mpe->pid, data +12, data_size - (12+4));
173 		return;
174 	}
175 
176 
177 	/*get number of rows of mpe_fec_frame from descriptor*/
178 	/* Real-Time Parameters */
179 	//delta_t = (data[8]<<4)|(data[9]>>4);
180 	table_boundry_flag = (data[9] >> 3 )& 0x1;
181 	frame_boundry_flag = (data[9] >> 2 )& 0x1;
182 
183 	offset = ((data[9] & 0x3)<< 16) | (data[10] << 8)| data[11];
184 
185 	/* Using MFF structure attached to the MPE Stream */
186 	if(mpe->mff) {
187 		if(!mpe->mff->mpe_holes) {
188 			mpe->mff->mpe_holes = gf_list_new();
189 		}
190 	} else if(offset != 0) {
191 		/* If no MFF structure is attached to the MPE Stream, wait for a new IP Datagram before processing data */
192 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[IpdcEgine] buffer is not null, waiting for a new IP Datagram before processing data\n"));
193 		return;
194 	} else {
195 		GF_SAFEALLOC(mpe->mff,MPE_FEC_FRAME);
196 
197 		assert( ip_platform );
198 		assert(ip_platform->ip_streams);
199 		i_streams = gf_list_count(ip_platform->ip_streams);
200 		for(j=0; j<i_streams; j++) {
201 			ip_stream_buff=gf_list_get(ip_platform->ip_streams, j);
202 
203 			if(mpe->program->number == ip_stream_buff->location.service_id) {
204 				switch(ip_stream_buff->time_slice_fec.frame_size) {
205 				case 0:
206 					mpe->mff->rows =256;
207 					break;
208 				case 1:
209 					mpe->mff->rows =512;
210 					break;
211 				case 2:
212 					mpe->mff->rows =768;
213 					break;
214 				case 3:
215 					mpe->mff->rows =1024;
216 					break;
217 				default:
218 					break;
219 				}
220 				break;
221 			}
222 		}
223 		/*initialize the mpe fec frame */
224 		if (init_frame(mpe->mff, mpe->mff->rows)) {
225 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("MFF initialization successed \n"));
226 		} else {
227 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("MFF initialization failed \n"));
228 			return;
229 		}
230 	}
231 
232 	mpe->mff->PID = mpe->pid;
233 
234 	while (len_left>0) {
235 
236 		switch (table_id) {
237 		case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE: /* MPE */
238 			/* Sets the IP data in the Application Data Table
239 			   Remove the first 12 bytes of header (from table id to end of real time parameters
240 			   Remove also the last four 4 bytes of the section (CRC 32)*/
241 			setIpDatagram( mpe->mff, offset, data +12, data_size-(12+4));
242 			len_left = 0;
243 			break;
244 		case GF_M2TS_TABLE_ID_MPE_FEC:
245 			/*	RS data is set by column, one column at a time */
246 			//setColRS( mpe->mff, offset, data + 12, mpe->mff->rows);
247 			len_left = 0;
248 			//data += (mff->rows +12+4 );
249 			break;
250 		default:
251 			len_left = 0;
252 		}
253 
254 		if(table_boundry_flag == 1) { /* end of reception of ADT data or RS data */
255 			if(table_id == 0x3E) { /* end of ADT */
256 				mpe->mff->ADT_done =1;
257 				if(mpe->mff->current_offset_adt+1 !=  mpe->mff->capacity_total) {
258 					memset( mpe->mff->p_adt+mpe->mff->current_offset_adt,0, mpe->mff->capacity_total-( mpe->mff->current_offset_adt+1));
259 				}
260 			}
261 			/* end of RS should be catched below by frame_boundary_flag */
262 		}
263 
264 		if(frame_boundry_flag == 1) {
265 			if(table_id == 0x78) {
266 				if( mpe->mff->current_offset_rs+1 !=  mpe->mff->rows*64) {
267 					memset( mpe->mff->p_rs+ mpe->mff->current_offset_rs,0,( mpe->mff->rows*64)-( mpe->mff->current_offset_rs+1));
268 				}
269 			}
270 		}
271 
272 	}
273 
274 	if (frame_boundry_flag && table_boundry_flag && mpe->mff->ADT_done ==1 ) {
275 		//decode_fec(mpe->mff);
276 		on_dvb_mpe_fec_frame(ts, mpe->mff);
277 		resetMFF(mpe->mff);
278 		/*for each IP datagram reconstructed*/
279 	}
280 
281 }
282 
gf_m2ts_process_ipdatagram(MPE_FEC_FRAME * mff,GF_M2TS_Demuxer * ts)283 void gf_m2ts_process_ipdatagram(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts)
284 {
285 	GF_M2TS_IP_Packet *ip_packet;
286 	u8* ip_datagram;
287 	u32 i, i_holes;
288 	MPE_Error_Holes *mff_holes;
289 	u32 offset; /* offset to get through the datagram */
290 	u8 ip_address_bootstrap[4];
291 	Bool Boostrap_ip;
292 
293 	offset =0;
294 	ip_datagram = mff->p_adt;
295 
296 	GF_SAFEALLOC(ip_packet,GF_M2TS_IP_Packet);
297 
298 
299 	while(offset<mff->current_offset_adt)
300 	{
301 		/* Find the parts of the ADT which contain errors and skip them */
302 		if((mff->p_error_adt+offset)[0] == 0x01010101) {
303 			i_holes = gf_list_count(mff->mpe_holes);
304 			for(i=0; i<i_holes; i++) {
305 				mff_holes=gf_list_get(mff->mpe_holes, i);
306 				if(mff_holes->offset == offset) {
307 					offset += mff_holes->length;
308 					break;
309 				}
310 			}
311 		}
312 
313 		if(gf_m2ts_ipdatagram_reader(ip_datagram, ip_packet, offset)) {
314 
315 
316 			/* update the offset */
317 			//offset += ip_packet->u32_total_length;
318 			offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size;
319 
320 
321 			/* 224.0.23.14 IP Bosstrap */
322 			ip_address_bootstrap[0]=224;
323 			ip_address_bootstrap[1]=0;
324 			ip_address_bootstrap[2]=23;
325 			ip_address_bootstrap[3]=14;
326 			socket_simu(ip_packet,ts, 1);
327 
328 			/* compare the destination ip address and the ESG Bootstrap address */
329 			Boostrap_ip = gf_m2ts_compare_ip(ip_packet->u8_rx_adr,ip_address_bootstrap);
330 			if(Boostrap_ip) {
331 				GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("ESG Bootstrap found !\n"));
332 			}
333 		} else {
334 			offset += (ip_packet->u32_total_length);
335 		}
336 
337 		if(ip_packet->data) {
338 			gf_free(ip_packet->data);
339 		}
340 		ip_packet->data = NULL;
341 
342 	}
343 
344 	//gf_memory_print();
345 	//gf_memory_size();
346 
347 	empty_list(mff->mpe_holes);
348 	gf_list_del(mff->mpe_holes);
349 	mff->mpe_holes = NULL;
350 	gf_m2ts_Delete_IpPacket(ip_packet);
351 }
352 
353 
gf_m2ts_mpe_send_datagram(GF_M2TS_Demuxer * ts,u32 mpe_pid,unsigned char * data,u32 data_size)354 void gf_m2ts_mpe_send_datagram(GF_M2TS_Demuxer *ts, u32 mpe_pid, unsigned char *data, u32 data_size)
355 {
356 	GF_M2TS_IP_Packet ip_pck;
357 	u8 *udp_data;
358 	u32 hdr_len;
359 
360 	ip_pck.u32_version = data[0] >>4;
361 	ip_pck.u32_hdr_length =data[0] & 0xF;
362 	ip_pck.u32_total_length = data[2]<<8 | data[3];
363 	ip_pck.u32_id_nb = data[4]<<8 | data[5];
364 	ip_pck.u32_flag = data[6] >>5;
365 	ip_pck.u32_frag_offset = (data[6] & 0x1F)<<8 | data[7];
366 	ip_pck.u32_TTL = data[8];
367 	ip_pck.u32_protocol = data[9];
368 	ip_pck.u32_crc = data[10]<<8 | data[11];
369 	memcpy(ip_pck.u8_tx_adr,data+12,sizeof(ip_pck.u8_tx_adr));
370 	memcpy(ip_pck.u8_rx_adr,data+16,sizeof(ip_pck.u8_rx_adr));
371 
372 	hdr_len = ip_pck.u32_hdr_length;
373 	udp_data = data+(hdr_len*4);
374 
375 	ip_pck.u32_tx_udp_port = udp_data[0]<<8 | udp_data[1];
376 	if(!ip_pck.u32_tx_udp_port) {
377 		return;
378 	}
379 	ip_pck.u32_rx_udp_port = udp_data[2]<<8 | udp_data[3];
380 	if(!ip_pck.u32_rx_udp_port) {
381 		return;
382 	}
383 	ip_pck.u32_udp_data_size = udp_data[4]<<8 | udp_data[5];
384 	if(ip_pck.u32_udp_data_size == 0) {
385 		return;
386 	}
387 	ip_pck.u32_udp_chksm = udp_data[6]<<8 | udp_data[7];
388 
389 	/*excluding UDP header*/
390 	ip_pck.data = udp_data + 8;
391 
392 	socket_simu(&ip_pck, ts, 0);
393 
394 	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("MPE PID %d - send datagram %d bytes to %d.%d.%d.%d port:%d\n", mpe_pid, ip_pck.u32_udp_data_size-8, ip_pck.u8_rx_adr[0], ip_pck.u8_rx_adr[1], ip_pck.u8_rx_adr[2], ip_pck.u8_rx_adr[3], ip_pck.u32_rx_udp_port));
395 }
396 
397 
gf_m2ts_compare_ip(u8 rx_ip_address[4],u8 ip_address_bootstrap[4])398 Bool gf_m2ts_compare_ip(u8 rx_ip_address[4], u8 ip_address_bootstrap[4])
399 {
400 	u8 i;
401 	for (i=0; i<4; i++)
402 	{
403 		if (rx_ip_address[i] != ip_address_bootstrap[i])
404 			return 0;
405 	}
406 	return 1;
407 }
408 
409 
gf_m2ts_ipdatagram_reader(u8 * datagram,GF_M2TS_IP_Packet * ip_packet,u32 offset)410 u32 gf_m2ts_ipdatagram_reader(u8 *datagram,GF_M2TS_IP_Packet *ip_packet, u32 offset)
411 {
412 
413 	ip_packet->u32_version = ((datagram+offset)[0])>>4;
414 	ip_packet->u32_hdr_length =(((datagram+offset)[0])&0xF);
415 	ip_packet->u32_total_length = (datagram+offset)[2]<<8|(datagram+offset)[3];
416 	ip_packet->u32_id_nb = (datagram+offset)[4]<<8|datagram[5];
417 	ip_packet->u32_flag = ((datagram+offset)[6])>>5;
418 	ip_packet->u32_frag_offset = ((datagram+offset)[6]&0x1F)<<8|(datagram+offset)[7];
419 	ip_packet->u32_TTL = (datagram+offset)[8];
420 	ip_packet->u32_protocol = (datagram+offset)[9];
421 	ip_packet->u32_crc = (datagram+offset)[10]<<8|(datagram+offset)[11];
422 	memcpy(ip_packet->u8_tx_adr,(datagram+offset)+12,sizeof(ip_packet->u8_tx_adr));
423 	memcpy(ip_packet->u8_rx_adr,(datagram+offset)+16,sizeof(ip_packet->u8_rx_adr));
424 
425 	ip_packet->u32_tx_udp_port = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[0]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[1];
426 	if(!ip_packet->u32_tx_udp_port) {
427 		return 0;
428 	}
429 	ip_packet->u32_rx_udp_port = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[2]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[3];
430 	if(!ip_packet->u32_rx_udp_port) {
431 		return 0;
432 	}
433 	ip_packet->u32_udp_data_size = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[4]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[5];
434 	if(ip_packet->u32_udp_data_size == 0) {
435 		return 0;
436 	}
437 	ip_packet->u32_udp_chksm = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[6]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[7];
438 
439 
440 	ip_packet->data = gf_malloc((ip_packet->u32_udp_data_size-8)*sizeof(u8));
441 	memcpy(ip_packet->data,datagram+offset+(ip_packet->u32_hdr_length*4)+8,(ip_packet->u32_udp_data_size-8)*sizeof(u8));
442 	/*ip_packet->data = gf_malloc((ip_packet->u32_total_length-ip_packet->u32_hdr_length)*sizeof(char));
443 	memcpy(ip_packet->data,datagram+offset+20,(ip_packet->u32_total_length-ip_packet->u32_hdr_length)*sizeof(char));*/
444 
445 	GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("TX addr: %d.%d.%d.%d RX addr : %d.%d.%d.%d port:%d(0x%x) \n",ip_packet->u8_tx_adr[0],ip_packet->u8_tx_adr[1],ip_packet->u8_tx_adr[2],ip_packet->u8_tx_adr[3],ip_packet->u8_rx_adr[0],ip_packet->u8_rx_adr[1],ip_packet->u8_rx_adr[2],ip_packet->u8_rx_adr[3],ip_packet->u32_rx_udp_port,ip_packet->u32_rx_udp_port));
446 
447 	return 1;
448 
449 }
450 
gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet * ip_packet)451 static void gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet *ip_packet)
452 {
453 	ip_packet->u32_version = 0;
454 	ip_packet->u32_hdr_length =0;
455 	ip_packet->u32_total_length = 0;
456 	ip_packet->u32_id_nb = 0;
457 	ip_packet->u32_flag = 0;
458 	ip_packet->u32_frag_offset = 0;
459 	ip_packet->u32_TTL = 0;
460 	ip_packet->u32_protocol = 0;
461 	ip_packet->u32_crc = 0;
462 	ip_packet->u32_tx_udp_port = 0;
463 	ip_packet->u32_rx_udp_port = 0;
464 	ip_packet->u32_udp_data_size = 0;
465 	ip_packet->u32_udp_chksm = 0;
466 
467 	if(ip_packet->data) {
468 		gf_free(ip_packet->data);
469 	}
470 	gf_free(ip_packet);
471 }
472 
473 
474 
gf_m2ts_process_int(GF_M2TS_Demuxer * ts,GF_M2TS_SECTION_ES * ip_table,unsigned char * data,u32 data_size,u32 table_id)475 void gf_m2ts_process_int(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ip_table, unsigned char *data, u32 data_size, u32 table_id)
476 {
477 
478 	GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform ;
479 	assert( ts );
480 
481 	if ( ip_platform == NULL )
482 	{
483 		GF_SAFEALLOC(ip_platform,GF_M2TS_IP_PLATFORM );
484 		ip_platform->ip_streams= gf_list_new();
485 		section_DSMCC_INT (ip_platform, data, data_size);
486 		ts->ip_platform = ip_platform;
487 	}
488 }
489 
490 
491 /*the following code is copied from dvbsnoop project : http://dvbsnoop.sourceforge.net */
section_DSMCC_INT(GF_M2TS_IP_PLATFORM * ip_platform,u8 * data,u32 data_size)492 void section_DSMCC_INT(GF_M2TS_IP_PLATFORM* ip_platform,u8 *data, u32 data_size)
493 {
494 	/* EN 301 192 7.x */
495 
496 	s32  length,i;
497 
498 
499 	length = data_size ;
500 
501 	data += 12 ;
502 
503 	assert( ip_platform);
504 	i = dsmcc_pto_platform_descriptor_loop(ip_platform,data);
505 	data   += i;
506 	length -= i;
507 
508 	while (length > 4) {
509 		GF_M2TS_IP_Stream *ip_str;
510 		GF_SAFEALLOC(ip_str,GF_M2TS_IP_Stream );
511 
512 		i = dsmcc_pto_descriptor_loop(ip_str,data);
513 		data   += i;
514 		length -= i;
515 
516 		i = dsmcc_pto_descriptor_loop(ip_str,data);
517 		data   += i;
518 		length -= i;
519 		assert( ip_platform->ip_streams );
520 		gf_list_add(ip_platform->ip_streams, ip_str);
521 	}
522 
523 	return ;
524 }
525 
526 
527 /* Platform Descriptor */
528 
dsmcc_pto_platform_descriptor_loop(GF_M2TS_IP_PLATFORM * ip_platform,u8 * data)529 u32 dsmcc_pto_platform_descriptor_loop(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data)
530 {
531 	u32 loop_length;
532 	s32 length,i;
533 
534 
535 	loop_length = ((data[0]) & 0xF ) | data[1];
536 	length = loop_length;
537 	data += 2;
538 	while (length > 0) {
539 		assert( ip_platform);
540 		i   = platform_descriptorDSMCC_INT_UNT(ip_platform,data);
541 		data   += i;
542 		length -= i;
543 	}
544 
545 	return  (loop_length+2);
546 }
547 
548 
platform_descriptorDSMCC_INT_UNT(GF_M2TS_IP_PLATFORM * ip_platform,u8 * data)549 u32  platform_descriptorDSMCC_INT_UNT(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data)
550 
551 {
552 	u32 length;
553 	u32 id;
554 
555 
556 	id  =   data[0];
557 	length = data[1]+2;
558 
559 	switch (id) {
560 
561 
562 	case GF_M2TS_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR:
563 	{
564 		gf_ip_platform_descriptor(ip_platform, data);
565 	}
566 	break;
567 	case GF_M2TS_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR:
568 	{
569 		gf_ip_platform_provider_descriptor(ip_platform, data);
570 	}
571 	break;
572 
573 	default:
574 		break;
575 	}
576 	return length;   // (descriptor total length)
577 }
578 
gf_ip_platform_descriptor(GF_M2TS_IP_PLATFORM * ip_platform,u8 * data)579 void gf_ip_platform_descriptor(GF_M2TS_IP_PLATFORM* ip_platform,u8 * data)
580 {
581 	u32 length;
582 	length = data[1];
583 	assert( ip_platform );
584 	/* allocation ofr the name of the platform */
585 	ip_platform->name = gf_malloc(sizeof(char)*(length-3+1));
586 	memcpy(ip_platform->name, data+5, length-3);
587 	ip_platform->name[length-3] = 0;
588 	return ;
589 }
590 
gf_ip_platform_provider_descriptor(GF_M2TS_IP_PLATFORM * ip_platform,u8 * data)591 void gf_ip_platform_provider_descriptor(GF_M2TS_IP_PLATFORM* ip_platform, u8 * data)
592 {
593 	u32 length;
594 	length = data[1];
595 	/* allocation of the name of the platform */
596 	assert( ip_platform );
597 	ip_platform->provider_name = gf_malloc(sizeof(char)*(length-3+1));
598 	memcpy(ip_platform->provider_name, data+5, length-3);
599 	ip_platform->provider_name[length-3] = 0;
600 	return ;
601 }
602 
603 
604 
605 /* IP Stream Descriptors */
dsmcc_pto_descriptor_loop(GF_M2TS_IP_Stream * ip_str,u8 * data)606 u32 dsmcc_pto_descriptor_loop ( GF_M2TS_IP_Stream *ip_str,u8 *data)
607 {
608 	u32 loop_length;
609 	s32 length,i;
610 
611 	loop_length = ((data[0]) & 0xF ) | data[1];
612 
613 	length = loop_length;
614 	data += 2;
615 	while (length > 0) {
616 		i   = descriptorDSMCC_INT_UNT(ip_str,data);
617 		data   += i;
618 		length -= i;
619 	}
620 
621 	return  (loop_length+2);
622 }
623 
624 
descriptorDSMCC_INT_UNT(GF_M2TS_IP_Stream * ip_str,u8 * data)625 u32  descriptorDSMCC_INT_UNT(GF_M2TS_IP_Stream *ip_str,u8 *data)
626 
627 {
628 	u32 length;
629 	u32 id;
630 
631 	id  = data[0];
632 	length = data[1] +2;
633 
634 	switch (id) {
635 
636 
637 	case GF_M2TS_DVB_TARGET_IP_SLASH_DESCRIPTOR:
638 	{
639 
640 		gf_m2ts_target_ip(ip_str,data);
641 	}
642 	break;
643 
644 	case GF_M2TS_DVB_TIME_SLICE_FEC_DESCRIPTOR:
645 	{
646 		descriptorTime_slice_fec_identifier(ip_str,data);
647 	}
648 	break;
649 	case GF_M2TS_DVB_STREAM_LOCATION_DESCRIPTOR:
650 	{
651 		descriptorLocation(ip_str , data);
652 	}
653 	break;
654 	default:
655 		break;
656 	}
657 
658 
659 	return length;   // (descriptor total length)
660 }
661 
descriptorTime_slice_fec_identifier(GF_M2TS_IP_Stream * ip_str,u8 * data)662 void descriptorTime_slice_fec_identifier( GF_M2TS_IP_Stream *ip_str,u8 * data)
663 {
664 
665 	ip_str->time_slice_fec.time_slicing = (data[2] >> 7) & 0x1;
666 	ip_str->time_slice_fec.mpe_fec = (data[2] >> 5 ) & 0x3 ;
667 	ip_str->time_slice_fec.frame_size = data[2] & 0x7 ;
668 	ip_str->time_slice_fec.max_burst_duration = data[3];
669 	ip_str->time_slice_fec.max_average_rate = (data[4]  >> 4) & 0xf ;
670 	ip_str->time_slice_fec.time_slice_fec_id = data[4] & 0xf;
671 	ip_str->time_slice_fec.id_selector = gf_malloc( data[1] - 3 ) ;
672 	memcpy(ip_str->time_slice_fec.id_selector, data + 4, data[1]-3 );
673 	return ;
674 }
675 
descriptorLocation(GF_M2TS_IP_Stream * ip_str,u8 * data)676 void descriptorLocation(GF_M2TS_IP_Stream *ip_str , u8 * data)
677 {
678 	ip_str->location.network_id = (data[2]<<8)|data[3];
679 	ip_str->location.original_network_id =  (data[4]<<8)|data[5];
680 	ip_str->location.transport_stream_id = (data[6]<<8)|data[7];
681 	ip_str->location.service_id = (data[8]<<8)|data[9];
682 	ip_str->location.component_tag = data[10];
683 	return;
684 }
685 
gf_m2ts_target_ip(GF_M2TS_IP_Stream * ip_str,u8 * data)686 void gf_m2ts_target_ip(GF_M2TS_IP_Stream* ip_str, u8 * data)
687 {
688 	u32 i;
689 	u8 length;
690 	ip_str->targets = gf_list_new();
691 	length = data[1];
692 	for(i=0; i<length; i= i+5)
693 	{
694 		GF_M2TS_IP_Target* ip_data;
695 		GF_SAFEALLOC(ip_data,GF_M2TS_IP_Target);
696 		//ip_data=gf_malloc(sizeof(GF_M2TS_IP_Target));
697 		ip_data->type = 0;
698 		ip_data->address_mask = 0;
699 		memcpy(ip_data->address, data+2+i, 4);
700 		ip_data->slash_mask=data[2+i+4];
701 
702 		gf_list_add(ip_str->targets,ip_data);
703 	}
704 
705 	return;
706 }
707 
708 
709 /*generate RS code and fullfill the RS table of MPE_FEC_FRAME*/
encode_fec(MPE_FEC_FRAME * mff)710 void encode_fec(MPE_FEC_FRAME * mff)
711 {
712 #if 0
713 	u8 adt_rs_en_buffer [ MPE_ADT_COLS + MPE_RS_COLS ];
714 	u32 rows = mff->rows;
715 	u32 i = 0;
716 	u32 cols = 0;
717 
718 	cols = mff->col_adt;
719 	for ( i = 0; i < rows; i ++ ) {
720 		/* read a row from ADT into buffer */
721 		getRowFromADT(mff, i, adt_rs_en_buffer);
722 		/* ************** */
723 		/* Encode data into codeword, adding NPAR parity bytes */
724 		encode_data(adt_rs_en_buffer, cols, adt_rs_en_buffer);
725 		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("Encoded data is   : \"%s\"\n", adt_rs_en_buffer));
726 		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("data with error is: \"%s\"\n", adt_rs_en_buffer));
727 		/*set a row of RS into RS table*/
728 		setRowRS ( mff, i , (unsigned char *)(adt_rs_en_buffer + cols) );
729 	}
730 #endif
731 }
732 
733 /*decode the MPE_FEC_FRAME*/
decode_fec(MPE_FEC_FRAME * mff)734 void decode_fec(MPE_FEC_FRAME * mff)
735 {
736 	u32 i,ML,offset;
737 	size_t size;
738 	u8 *data;
739 	u8 linebuffer[255];
740 
741 	size = (mff->rows*191)*sizeof(char);
742 	data = gf_malloc(size);
743 	memset(data,0, size);
744 
745 	initialize_ecc ();
746 	ML = 255;
747 	memset(linebuffer, 0, 255);
748 	offset = 0;
749 
750 	for ( i = 0; i < mff->rows; i ++ )	{
751 		u8 tmp[255];
752 
753 		getRowFromADT(mff, i, linebuffer);
754 		getRowFromRS(mff, i, linebuffer + mff->col_adt);
755 
756 		encode_data(linebuffer, 191, tmp);
757 
758 		decode_data(linebuffer, ML);
759 		if (check_syndrome () != 0) {
760 			u32 nerasures = 0;
761 			u32 *erasures = NULL;
762 
763 			/* TODO: set the erasures and errors based on the MFF */
764 			if(correct_errors_erasures (linebuffer, ML, nerasures,  erasures) == 0)
765 			{
766 				GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("Correction Error line %d \n", i));
767 			}
768 
769 			/* TODO: replace the current line in MFF */
770 		}
771 
772 		memcpy(data+offset, linebuffer, 191);
773 		offset += 191;
774 	}
775 	memcpy(mff->p_adt, data, size);
776 }
777 
778 
gf_m2ts_gather_ipdatagram_information(MPE_FEC_FRAME * mff,GF_M2TS_Demuxer * ts)779 void gf_m2ts_gather_ipdatagram_information(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts)
780 {
781 	GF_M2TS_IP_Packet *ip_packet;
782 	u8* ip_datagram;
783 	u32 i, i_holes,i_streams,k,j,l;
784 	MPE_Error_Holes *mff_holes;
785 	u32 offset; /* offset to get through the datagram */
786 	//GF_TSImport *tsimp = (GF_TSImport *) ts->user;
787 	//GF_MediaImporter *import= (GF_MediaImporter *)tsimp->import;
788 	GF_M2TS_IP_Stream *ip_stream_buff;
789 	GF_M2TS_IP_Target *ip_targets;
790 	GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform;
791 
792 	assert( ts );
793 	offset =0;
794 	ip_datagram = mff->p_adt;
795 	GF_SAFEALLOC(ip_packet,GF_M2TS_IP_Packet);
796 	GF_SAFEALLOC(mff_holes,MPE_Error_Holes);
797 	assert( ip_platform );
798 	while(offset<mff->current_offset_adt)
799 	{
800 		/* Find the parts of the ADT which contain errors and skip them */
801 		if((mff->p_error_adt+offset)[0] == 0x01010101)
802 		{
803 			i_holes = gf_list_count(mff->mpe_holes);
804 			for(i=0; i<i_holes; i++)
805 			{
806 				mff_holes=gf_list_get(mff->mpe_holes, i);
807 				if(mff_holes->offset == offset)
808 				{
809 					offset += mff_holes->length;
810 					break;
811 				}
812 			}
813 
814 		}
815 
816 		if(gf_m2ts_ipdatagram_reader(ip_datagram, ip_packet, offset)) {
817 
818 
819 			/* update the offset */
820 			//offset += ip_packet->u32_total_length;
821 			offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size;
822 
823 			if(ip_platform->all_info_gathered != 1)
824 			{
825 				assert( ip_platform->ip_streams );
826 				i_streams = gf_list_count(ip_platform->ip_streams);
827 				for(k=0; k<i_streams; k++)
828 				{
829 					ip_stream_buff=gf_list_get(ip_platform->ip_streams, k);
830 
831 					if(ip_stream_buff == NULL || ip_stream_buff->stream_info_gathered ==1)
832 					{
833 						break;
834 					}
835 					else
836 					{
837 						u32 i_targets = gf_list_count(ip_stream_buff->targets);
838 						for(j=0; j<i_targets; j++)
839 						{
840 							ip_targets = gf_list_get(ip_stream_buff->targets, j);
841 
842 							if(gf_m2ts_compare_ip(ip_packet->u8_rx_adr,ip_targets->address))
843 							{
844 								for(l=0; l<9; l++)
845 								{
846 									if(ip_targets->rx_port[l] == ip_packet->u32_rx_udp_port) goto next;
847 									if(ip_targets->rx_port[l] ==0) break;
848 								}
849 
850 								ip_targets->rx_port[l] = ip_packet->u32_rx_udp_port;
851 								ip_stream_buff->PID = mff->PID;
852 								goto next;
853 
854 
855 							}
856 
857 						}
858 					}
859 				}
860 			}
861 		} else {
862 
863 			offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size;
864 		}
865 next :
866 		;
867 
868 	}
869 	empty_list(mff->mpe_holes);
870 	gf_list_del(mff->mpe_holes);
871 	mff->mpe_holes = NULL;
872 	gf_m2ts_Delete_IpPacket(ip_packet);
873 
874 }
875 
876 GF_EXPORT
gf_m2ts_print_mpe_info(GF_M2TS_Demuxer * ts)877 void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts)
878 {
879 	u32 i_streams,i,j,l;
880 	GF_M2TS_IP_Target *ip_targets;
881 	u8 *ip_address;
882 	GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform;
883 	assert( ts );
884 	if (!ts->ip_platform) return;
885 
886 	/* provider and ip platform name */
887 	GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" IP Platform : %s provided by %s \n",ip_platform->name,ip_platform->provider_name));
888 
889 	assert(ip_platform->ip_streams);
890 	i_streams = gf_list_count(ip_platform->ip_streams);
891 	for(i=0; i<i_streams; i++) {
892 		GF_M2TS_IP_Stream *ip_stream_buff = gf_list_get(ip_platform->ip_streams, i);
893 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("PID:%d - Target IP adress: \n", ip_stream_buff->PID));
894 		/*Print the target IP address  */
895 		u32 i_targets = gf_list_count(ip_stream_buff->targets);
896 		for(j=0; j<i_targets; j++)
897 		{
898 			ip_targets = gf_list_get(ip_stream_buff->targets, j);
899 
900 			l=0;
901 
902 			ip_address = ip_targets->address;
903 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("%d.%d.%d.%d/%d ",ip_address[0],ip_address[1],ip_address[2],ip_address[3],ip_targets->slash_mask));
904 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" RX port :"));
905 			while(ip_targets->rx_port[l] != 0)
906 			{
907 				GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" %d ",ip_targets->rx_port[l]));
908 				l++;
909 			}
910 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("\n"));
911 		}
912 
913 		/*Print the time slice fec descriptor */
914 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Time Slice Fec Descriptor : \n"));
915 
916 		if(ip_stream_buff->time_slice_fec.time_slicing==0)
917 		{
918 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" No Time Slicing \n"));
919 		} else
920 		{
921 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Time Slicing\n"));
922 		}
923 
924 		if(ip_stream_buff->time_slice_fec.mpe_fec==0)
925 		{
926 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" No MPE FEC used \n"));
927 		} else
928 		{
929 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" MPE FEC used \n"));
930 		}
931 
932 		switch(ip_stream_buff->time_slice_fec.frame_size)
933 		{
934 		case 0:
935 		{
936 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Frame size : 256 rows \n"));
937 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Max Burst Duration 512 kbits\n"));
938 		}
939 		break;
940 		case 1:
941 		{
942 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Frame size : 512 rows \n"));
943 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Max Burst Duration 1024 kbits\n"));
944 		}
945 		break;
946 		case 2:
947 		{
948 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Frame size : 768 rows \n"));
949 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Max Burst Duration 1536 kbits\n"));
950 		}
951 		break;
952 		case 3:
953 		{
954 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Frame size : 1024 rows \n"));
955 			GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Max Burst Duration 2048 kbits\n"));
956 		}
957 		break;
958 		default:
959 			break;
960 		}
961 
962 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, (" Time Slice Fec ID : %x\n",ip_stream_buff->time_slice_fec.time_slice_fec_id));
963 
964 		/* Locayion descriptor */
965 
966 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Location Descriptor \n"));
967 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Network ID:%d \n",ip_stream_buff->location.network_id));
968 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Original Network ID:%d \n",ip_stream_buff->location.original_network_id));
969 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Transport Stream ID:%d \n",ip_stream_buff->location.transport_stream_id));
970 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Service ID:%d \n",ip_stream_buff->location.service_id));
971 		GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("Component Tag:%d \n",ip_stream_buff->location.component_tag));
972 	}
973 }
974 
975 
socket_simu(GF_M2TS_IP_Packet * ip_packet,GF_M2TS_Demuxer * ts,Bool yield)976 void socket_simu(GF_M2TS_IP_Packet *ip_packet, GF_M2TS_Demuxer *ts, Bool yield)
977 {
978 	u32 ipv4_addr;
979 	GF_Err e;
980 	u8 nb_socket_struct, i;
981 	GF_SOCK_ENTRY *Sock_Struct = NULL;
982 	assert( ts );
983 	if(!ts->ip_platform) {
984 		GF_SAFEALLOC(ts->ip_platform,GF_M2TS_IP_PLATFORM );
985 	}
986 	if(ts->ip_platform->socket_struct == NULL) ts->ip_platform->socket_struct= gf_list_new();
987 
988 	ipv4_addr = GF_4CC(ip_packet->u8_rx_adr[0], ip_packet->u8_rx_adr[1], ip_packet->u8_rx_adr[2], ip_packet->u8_rx_adr[3]);
989 	nb_socket_struct = gf_list_count(ts->ip_platform->socket_struct);
990 	for(i=0; i<nb_socket_struct; i++) {
991 		Sock_Struct = gf_list_get(ts->ip_platform->socket_struct,i);
992 		if ((Sock_Struct->ipv4_addr==ipv4_addr)&& (Sock_Struct->port == (u16) ip_packet->u32_rx_udp_port)) {
993 			if (Sock_Struct->bind_failure) return;
994 			break;
995 		}
996 		Sock_Struct = NULL;
997 	}
998 	if (Sock_Struct == NULL) {
999 		char name[100];
1000 		GF_SAFEALLOC(Sock_Struct, GF_SOCK_ENTRY);
1001 
1002 		Sock_Struct->ipv4_addr = ipv4_addr;
1003 		Sock_Struct->port = ip_packet->u32_rx_udp_port;
1004 		Sock_Struct->sock = gf_sk_new(GF_SOCK_TYPE_UDP);
1005 		if (Sock_Struct->sock == NULL) {
1006 			gf_free(Sock_Struct);
1007 			return;
1008 		}
1009 
1010 		sprintf(name, "%d.%d.%d.%d", ip_packet->u8_rx_adr[0],ip_packet->u8_rx_adr[1], ip_packet->u8_rx_adr[2],ip_packet->u8_rx_adr[3]);
1011 
1012 		if (gf_sk_is_multicast_address(name) ) {
1013 			e = gf_sk_setup_multicast(Sock_Struct->sock, name, ip_packet->u32_rx_udp_port, 1/*TTL - FIXME this should be in a cfg file*/, 0, NULL/*FIXME this should be in a cfg file*/);
1014 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("Setting up multicast socket for MPE on %s:%d\n", name, ip_packet->u32_rx_udp_port ));
1015 		} else {
1016 			/*
1017 				binding of the socket to send data to port 4600 on the local machine
1018 				the first address / port parameters are NULL or 0 because there are not needed for sending UDP datagrams
1019 				the second address is "localhost" and the port is the destination port on localhost
1020 			*/
1021 			e = gf_sk_bind(Sock_Struct->sock, "127.0.0.1", ip_packet->u32_rx_udp_port,/*name*/"127.0.0.1", ip_packet->u32_rx_udp_port, 0);
1022 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("Setting up socket for MPE on 127.0.0.1:%d\n", ip_packet->u32_rx_udp_port ));
1023 		}
1024 
1025 		if (e != GF_OK) {
1026 			GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Server Bind Error: %s\n", gf_error_to_string(e)));
1027 			Sock_Struct->bind_failure = 1;
1028 		}
1029 		gf_list_add(ts->ip_platform->socket_struct, Sock_Struct);
1030 	}
1031 
1032 	// ********************************************************
1033 	// Envoi des donn�es
1034 	// ********************************************************
1035 
1036 	e = gf_sk_send(Sock_Struct->sock, ip_packet->data, ip_packet->u32_udp_data_size - 8);
1037 	if (e != GF_OK) {
1038 		GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Error sending to \n"));
1039 	}
1040 	if (yield) gf_sleep(10);
1041 
1042 }
1043 
1044 /*void gf_sock_shutdown()
1045 {
1046 	gf_sk_del(sock);
1047 }*/
1048 
1049 /* allocate the necessary memory space*/
init_frame(MPE_FEC_FRAME * mff,u32 rows)1050 Bool init_frame(MPE_FEC_FRAME * mff, u32 rows)
1051 {
1052 	assert (mff != NULL);
1053 	if (rows != 256 && rows != 512 && rows != 768 && rows != 1024) return 0;
1054 	mff->rows = rows ;
1055 	mff->col_adt = MPE_ADT_COLS;
1056 	mff->col_rs = MPE_RS_COLS;
1057 	mff->p_adt = (u8 *)gf_calloc(MPE_ADT_COLS*rows,sizeof(u8));
1058 	mff->p_rs = (u8 *)gf_calloc(MPE_RS_COLS*rows,sizeof(u8));
1059 
1060 
1061 	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("MPE_RS_COLS*rows :%d \n",MPE_RS_COLS*rows));
1062 
1063 	mff->capacity_total = mff->col_adt*rows;
1064 	mff->p_error_adt = (u32 *)gf_calloc(mff->col_adt*rows,sizeof(u32));
1065 	mff->p_error_rs = (u32 *)gf_calloc(mff->col_rs*rows,sizeof(u32));
1066 	mff->current_offset_adt = 0;
1067 	mff->current_offset_rs = 0;
1068 	mff->ADT_done = 0;
1069 	mff->PID = 0;
1070 	mff->mpe_holes = gf_list_new();
1071 	mff->initialized = 1;
1072 	return 1;
1073 }
1074 
resetMFF(MPE_FEC_FRAME * mff)1075 void resetMFF(MPE_FEC_FRAME * mff)
1076 {
1077 	mff->current_offset_adt = 0;
1078 	mff->current_offset_rs = 0;
1079 	memset(mff->p_error_adt, 0, mff->col_adt * mff->rows*sizeof(u32));
1080 	memset(mff->p_error_rs, 0, mff->col_rs * mff->rows*sizeof(u32));
1081 	memset(mff->p_adt, 0, MPE_ADT_COLS* mff->rows*sizeof(u8));
1082 	memset(mff->p_rs, 0, MPE_RS_COLS* mff->rows*sizeof(u8));
1083 	mff->ADT_done = 0;
1084 	mff->PID = 0;
1085 	if(mff->mpe_holes) {
1086 		empty_list(mff->mpe_holes);
1087 		//gf_list_del(mff->mpe_holes);
1088 	}
1089 
1090 }
1091 
1092 /* return a row of appplicatio data table*/
getRowFromADT(MPE_FEC_FRAME * mff,u32 index,u8 * adt_row)1093 void getRowFromADT(MPE_FEC_FRAME * mff, u32 index, u8* adt_row)
1094 {
1095 	u32 i = 0 ;
1096 	u32 base = 0;
1097 	//assert ( sizeof ( adt_row ) >= MPE_ADT_COLS );
1098 	for ( i = 0; i < mff->col_adt ; i ++ ) {
1099 		adt_row [ i ] = mff -> p_adt [ index + base ];
1100 		base += mff-> rows ;
1101 	}
1102 }
1103 
1104 /*return a row of RS table*/
getRowFromRS(MPE_FEC_FRAME * mff,u32 index,u8 * rs_row)1105 void getRowFromRS (MPE_FEC_FRAME * mff, u32 index, u8* rs_row)
1106 {
1107 	u32 i = 0 ;
1108 	u32 base = 0;
1109 	assert (rs_row != NULL );
1110 	//assert (sizeof ( rs_row ) >= MPE_ADT_COLS );
1111 	for ( i = 0; i < mff->col_rs ; i ++ ) {
1112 		rs_row [ i ] = mff -> p_rs [ index + base ];
1113 		base += mff -> rows ;
1114 	}
1115 }
1116 
setRowRS(MPE_FEC_FRAME * mff,u32 index,u8 * p_rs)1117 void setRowRS(MPE_FEC_FRAME *mff, u32 index, u8 *p_rs)
1118 {
1119 	u32 i = 0;
1120 	u32 base = 0;
1121 	assert ( p_rs != NULL );
1122 	//assert ( sizeof (p_rs ) >= MPE_RS_COLS ) ;
1123 	for ( i = 0; i < mff -> col_rs; i ++ ) {
1124 		mff -> p_rs [ base + index ] = p_rs [ i];
1125 		base += mff -> rows;
1126 	}
1127 
1128 }
addPadding(MPE_FEC_FRAME * mff,u32 offset)1129 void addPadding(MPE_FEC_FRAME *mff , u32 offset)
1130 {
1131 	u32 i = 0;
1132 	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("add paddings from %d to the end %d\n", offset, mff->capacity_total ));
1133 	for ( i = offset ; i <mff->capacity_total; i ++ )
1134 		mff -> p_adt [i] = 0xff ;
1135 }
1136 #ifdef GPAC_UNUSED_FUNC
print_bytes2(u8 * data,u32 length)1137 static void print_bytes2(u8 * data, u32 length ) /*print_bytes2 */
1138 {
1139 	u32 i = 0;
1140 	u32 row_num = 0;
1141 	u32 k = 0;
1142 	for ( i = 0; i < length ; i ++ ) {
1143 		if (k == 0) {
1144 			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("%x0  : ", row_num));
1145 			k = 0;
1146 		}
1147 		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("%#x ", data[i]));
1148 		k++;
1149 		if (k == 16) {
1150 			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("\n"));
1151 			k = 0;
1152 			row_num ++;
1153 		}
1154 	}
1155 }
1156 #endif /*GPAC_UNUSED_FUNC*/
1157 
1158 /*add a ip datagram into mpe fec frame, and indicate error positions*/
setIpDatagram(MPE_FEC_FRAME * mff,u32 offset,u8 * dgram,u32 length)1159 void setIpDatagram(MPE_FEC_FRAME * mff, u32 offset, u8* dgram, u32 length )
1160 {
1161 	MPE_Error_Holes *mpe_error_holes;
1162 
1163 	GF_SAFEALLOC(mpe_error_holes,MPE_Error_Holes);
1164 
1165 
1166 	if (offset >= mff->capacity_total) {
1167 		GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Offset %d bigger than capacity %d \n", offset, mff->capacity_total ));
1168 	}
1169 	if (offset+length >= mff->capacity_total) {
1170 		GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Offset+length %d+%d bigger than capacity %d \n", offset, length, mff->capacity_total ));
1171 	}
1172 	if (mff->current_offset_adt != offset) {
1173 		if (mff->current_offset_adt > offset) {
1174 			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("We missed an offset reset (%d to %d)\n", mff->current_offset_adt, offset));
1175 			mff->current_offset_adt = offset;
1176 		} else {
1177 			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("there is an error hole in the ADT from %d to %d \n", mff->current_offset_adt, offset));
1178 		}
1179 		setErrorIndicator( mff->p_error_adt , mff->current_offset_adt , (offset - mff->current_offset_adt)*sizeof(u32)  ) ;
1180 		mpe_error_holes->offset = mff->current_offset_adt;
1181 		mpe_error_holes->length = offset - mff->current_offset_adt;
1182 		gf_list_add(mff->mpe_holes,mpe_error_holes);
1183 		mff->current_offset_adt = offset  ; // update the offset
1184 	}
1185 
1186 	memcpy(mff->p_adt+mff->current_offset_adt,dgram, length);
1187 	mff->current_offset_adt = offset+length  ; // update the offset
1188 
1189 }
1190 /*set RS data into mpe fec frame*/
setColRS(MPE_FEC_FRAME * mff,u32 offset,u8 * pds,u32 length)1191 void setColRS( MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length )
1192 {
1193 	if ( mff->current_offset_rs != offset)	{
1194 		GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("there is an error hole in the RS from %d to %d \n", mff->current_offset_rs, offset ));
1195 		setErrorIndicator( mff->p_error_rs , mff->current_offset_rs , (offset - mff->current_offset_rs)*sizeof(u32));
1196 		mff->current_offset_rs = offset;
1197 	}
1198 	assert(mff->rows == length);
1199 	memcpy(mff->p_rs + mff->current_offset_rs , pds, length*sizeof(u8) );
1200 	mff->current_offset_rs = offset + length ;
1201 
1202 }
1203 
getColRS(MPE_FEC_FRAME * mff,u32 offset,u8 * pds,u32 length)1204 void getColRS(MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length)
1205 {
1206 	memcpy(pds,mff->p_rs + offset, length);
1207 }
1208 
getErrorPositions(MPE_FEC_FRAME * mff,u32 row,u32 * errPositions)1209 void getErrorPositions(MPE_FEC_FRAME *mff, u32 row, u32 * errPositions)
1210 {
1211 	u32 i = 0 ;
1212 	u32 base = row;
1213 	/*get error from adt*/
1214 	for ( i = 0; i < mff->col_adt ; i ++ ) {
1215 		errPositions [i] = mff->p_error_adt[base ];
1216 		base += mff->rows;
1217 	}
1218 	base = row;
1219 	for ( i = mff->col_adt ; i < mff->col_adt + mff-> col_rs ; i ++ ) {
1220 		errPositions [i] = mff->p_error_rs [ base ];
1221 		base += mff->rows ;
1222 	}
1223 }
1224 
getErrasurePositions(MPE_FEC_FRAME * mff,u32 row,u32 * errasures)1225 u32  getErrasurePositions( MPE_FEC_FRAME *mff , u32 row, u32 *errasures)
1226 {
1227 	u32 i = 0;
1228 	u32 base = row;
1229 	u32 nb = 0;
1230 	u32 k =0;
1231 	for ( i = 0  ; i <  mff-> col_rs ; i ++ ) {
1232 		if ( mff->p_error_rs[base] ==  1 ) {
1233 			errasures [k++] = mff->p_error_rs [ base ];
1234 			nb ++;
1235 		}
1236 		base += mff->rows ;
1237 	}
1238 	GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, (" the erasure locations is:\n"));
1239 	for ( i = 0; i < nb ; i ++ )
1240 		GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("%d ", errasures[i]));
1241 	return nb;
1242 }
1243 
setErrorIndicator(u32 * data,u32 offset,u32 length)1244 void setErrorIndicator(u32 * data , u32 offset, u32 length)
1245 {
1246 	memset(data+offset, 1, length);
1247 }
1248 
1249 #endif //GPAC_ENABLE_MPE
1250