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