1 /*****************************************************************************
2 * psi.c: PSI management
4 *****************************************************************************
5 * Manages structures containing PSI information, and affiliated decoders.
6 * TO DO: Fonctions d'init des structures
7 *****************************************************************************/
9 /*****************************************************************************
11 *****************************************************************************/
13 #include <stdlib.h> /* free(), realloc() */
14 #include <string.h> /* bzero() */
15 #include <netinet/in.h> /* ntohs() */
20 #include "vlc_thread.h"
25 #include "input_ctrl.h"
26 #include "input_psi.h"
31 * Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
33 boolean_t b_crc_initialised = 0;
34 u32 i_crc_32_table[256];
37 * Global configuration variable, need by AUTO_SPAWN to determine
38 * the option (audio and video) passed to the VideoLAN client.
41 //XXX?? extern program_data_t *p_main;
45 * Locale type definitions
47 #define PSI_VIDEO_STREAM_DESCRIPTOR 0x02
48 #define PSI_AUDIO_STREAM_DESCRIPTOR 0x03
49 #define PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR 0x07
50 #define PSI_VIDEO_WINDOW_DESCRIPTOR 0x08
53 #define PSI_SERVICE_DESCRIPTOR 0x48
56 /* That info must be stored in the version field since it contains
58 #define PSI_UNINITIALISED 0xFF
63 static int input_AddPsiPID( input_thread_t *p_input, int i_pid );
64 static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
65 static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
66 static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
67 static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
68 static void DecodePgrmDescriptor( byte_t* p_descr, pgrm_descriptor_t* p_pgrm );
69 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
71 static stream_descriptor_t* AddStreamDescr( input_thread_t* p_input,
73 static void DestroyStreamDescr( input_thread_t* p_input, u16 i_stream_id );
74 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
76 static void DestroyPgrmDescr( input_thread_t* p_input,
77 stream_descriptor_t* p_stream, u16 i_pgrm_id );
78 static es_descriptor_t* AddESDescr( input_thread_t* p_input,
79 pgrm_descriptor_t* p_pgrm, u16 i_es_pid );
80 static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
83 static void BuildCrc32Table();
84 static int CheckCRC32( u8* p_pms, int i_size);
85 static boolean_t Is_known( byte_t* a_known_section, u8 i_section );
86 static void Set_known( byte_t* a_known_section, u8 i_section );
87 static void Unset_known( byte_t* a_known_section, u8 i_section );
89 /*****************************************************************************
90 * input_PsiInit: Initialize PSI decoder
91 *****************************************************************************
92 * Init the structures in which the PSI decoder will put the informations it
93 * got from PSI tables and request for the reception of the PAT.
94 *****************************************************************************/
95 int input_PsiInit( input_thread_t *p_input )
99 /* Precalculate the 32-bit CRC table if not already done ?
100 FIXME: Put a lock or do that at pgrm init ?? */
101 if( !b_crc_initialised )
104 b_crc_initialised = 1;
107 /* Init the structure that describes the stream we are receiving */
108 AddStreamDescr( p_input, PSI_UNINITIALISED );
110 /* Request for reception of the program association table */
111 input_AddPsiPID( p_input, 0 );
113 #ifdef DVB_EXTENSIONS
114 /* Request for reception of the service description table */
115 input_AddPsiPID( p_input, 17 );
121 /*****************************************************************************
122 * input_PsiClean: Clean PSI structures before dying
123 *****************************************************************************/
124 int input_PsiEnd( input_thread_t *p_input )
128 /* Stop to receive all the PSI tables associated with that program */
129 /* FIXME: Not really useful ??*/
131 /* Clean also descriptors for programs associated with that stream */
132 /* FIXME: -> Not really useful and maybe buggy ??*/
134 /* Destroy the stream description */
135 DestroyStreamDescr( p_input, p_input->p_stream->i_stream_id );
140 /*****************************************************************************
141 * input_PsiRead: Read the table of programs
142 *****************************************************************************
143 * Ugly debugging function at that time ? XXX??
144 *****************************************************************************/
145 void input_PsiRead( input_thread_t *p_input /* XXX?? */ )
149 pgrm_descriptor_t* p_pgrm;
153 /* Lock the tables, since this method can be called from any thread */
156 /* Check if the table is complete or not */
157 if( !p_input->p_stream->b_is_PMT_complete )
159 intf_IntfMsg( "Warning: PMT not yet complete\n" );
163 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
165 p_pgrm = p_input->p_stream->ap_programs[i_index];
166 intf_DbgMsg("Printing info for program %d\n", p_pgrm->i_number );
167 intf_IntfMsg("Printing info for program %d\n", p_pgrm->i_number );
169 for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ )
171 intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
172 p_pgrm->ap_es[i_index2]->i_id,
173 p_pgrm->ap_es[i_index2]->i_type,
174 p_pgrm->ap_es[i_index2]->b_pcr,
175 p_pgrm->ap_es[i_index2]->b_psi);
177 intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
178 p_pgrm->ap_es[i_index2]->i_id,
179 p_pgrm->ap_es[i_index2]->i_type,
180 p_pgrm->ap_es[i_index2]->b_pcr,
181 p_pgrm->ap_es[i_index2]->b_psi);
185 /* Unock the tables */
189 /*****************************************************************************
190 * input_PsiDecode: Decode a PSI section
191 *****************************************************************************
192 * This funtion is essentially a wrapper that will perform basic checks on
193 * the section and then call the right function according to its type.
194 *****************************************************************************/
195 void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
198 ASSERT(p_psi_section);
200 /* Hexa dump of the beginning of the section (for real men) */
201 //intf_DbgMsg( "Section: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", (u8)p_psi_section->buffer[0], (u8)p_psi_section->buffer[1], (u8)p_psi_section->buffer[2], (u8)p_psi_section->buffer[3], (u8)p_psi_section->buffer[4], (u8)p_psi_section->buffer[5], (u8)p_psi_section->buffer[6], (u8)p_psi_section->buffer[7], (u8)p_psi_section->buffer[8], (u8)p_psi_section->buffer[9], (u8)p_psi_section->buffer[10], (u8)p_psi_section->buffer[11], (u8)p_psi_section->buffer[12], (u8)p_psi_section->buffer[13], (u8)p_psi_section->buffer[14], (u8)p_psi_section->buffer[15], (u8)p_psi_section->buffer[16], (u8)p_psi_section->buffer[17], (u8)p_psi_section->buffer[18], (u8)p_psi_section->buffer[19] );
203 /* Check the CRC validity if any CRC is carried */
205 if( p_psi_section->buffer[1] & 0x80 )
207 if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
209 intf_DbgMsg("iSize: %d, CRC: %d\n", p_psi_section->i_length,
210 U32_AT(&p_psi_section->buffer[p_psi_section->i_length-4]));
211 intf_DbgMsg( "Invalid CRC for PSI\n" );
217 /* If the section is not immediatly applicable, trash it (DVB drafts disallow
218 transmission of such sections, so we didn't implement it) */
219 if( !p_psi_section->buffer[5] & 0x01 )
221 intf_DbgMsg( "PSI not yet applicable: trash it\n" );
225 /* Handle the packet according to it's type given it the table_id */
226 switch ( p_psi_section->buffer[0] )
229 //intf_DbgMsg("Program association section received\n");
230 DecodePgrmAssocSection(p_psi_section->buffer, p_input);
233 //intf_DbgMsg("Conditional access section received\n");
236 //intf_DbgMsg("Program map section received\n");
237 DecodePgrmMapSection(p_psi_section->buffer, p_input);
240 //intf_DbgMsg("Service description section received\n");
241 DecodeSrvDescrSection(p_psi_section->buffer, p_input);
244 //intf_DbgMsg("Private PSI data received (type %x), ignoring it\n",
245 // p_psi_section->buffer[0]);
249 /*****************************************************************************
250 * DecodeAssocSection: Decode a PAS
251 *****************************************************************************
252 * No check is made to known if the table is currently applicable or not, so
253 * that unapplicable sections must be filtered before calling this function
254 * The Program Association Table can be segmented to occupy multiple sections
255 * so that we have to know which sections we have already received (IsKnown() /
257 *****************************************************************************/
258 static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
260 u8 i_stream_id; /* Id of the stream described in that section */
261 u8 i_version; /* Version of the table carried in the section */
263 u16 i_pgrm_id; /* Id of the current described pgrm */
264 u16 i_pgrm_map_pid; /* PID of the associated program map table */
265 int i_pgrm_number; /* Number of programs described in the section */
267 boolean_t b_is_invalid = 0;
269 u8 i_current_section;
278 #define p_descr (p_input->p_stream)
280 /* Read stream id and version number immediately, to be sure they will be
281 initialised in all cases we will need it */
282 i_stream_id = U16_AT(&p_pas[3]);
283 i_version = (p_pas[5] >> 1) & 0x1F;
284 //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
286 /* Test if the stream has not changed by looking at the stream_id */
287 if( p_descr->i_stream_id != i_stream_id )
289 /* This can either mean that the PSI decoder has just started or that
290 the stream has changed */
291 if( p_descr->i_PAT_version== PSI_UNINITIALISED )
292 intf_DbgMsg("Building Program Association table\n");
294 intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
296 /* Whatever it is, ask the PSI decoder to rebuild the table */
301 /* Stream has not changed, test if the PMT is up to date */
302 if( p_descr->i_PAT_version != i_version )
304 intf_DbgMsg("PAT has been updated, rebuilding it\n");
305 /* Ask the PSI decoder to rebuild the table */
310 /* Clear the table if needed */
313 intf_DbgMsg("Updating PAT table\n");
315 /* Any program in the stream may have disapeared, or a new one
316 can have been added. The good way to handle such a case would be
317 to build a temporary table and to make a diff */
319 /* Stop the reception of all programs and PSI informations
320 associated with this stream, excepted the PAT on PID 0 and the SDT
322 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES &&
323 p_input->pp_selected_es[i_es_index]; i_es_index++ )
325 if( p_input->pp_selected_es[i_es_index]->b_psi )
327 if( p_input->pp_selected_es[i_es_index]->i_id != 0
328 #ifdef DVB_EXTENSIONS
329 && p_input->pp_selected_es[i_es_index]->i_id != 17
332 input_DelPsiPID( p_input,
333 p_input->pp_selected_es[i_es_index]->i_id );
336 input_DelPgrmElem( p_input,
337 p_input->pp_selected_es[i_es_index]->i_id );
340 /* Recreate a new stream description. Since it is virgin, the decoder
341 will rebuild it entirely on is own */
342 DestroyStreamDescr(p_input, p_descr->i_stream_id);
343 AddStreamDescr(p_input, i_stream_id);
345 /* Record the new version for that table */
346 p_descr->i_PAT_version = i_version;
349 /* Build the table if not already complete or if it was cleared */
350 if( p_descr->b_is_PAT_complete )
354 intf_DbgMsg("Bug: table invalid but PAT said to be complete\n");
358 /* Check if we already heard about that section */
359 i_last_section = p_pas[7];
360 i_current_section = p_pas[6];
362 // intf_DbgMsg( "Section %d (last section %d)\n",
363 // i_current_section, i_last_section );
365 if( Is_known(p_descr->a_known_PAT_sections, i_current_section) )
368 // intf_DbgMsg("Section already received, skipping\n");
372 /* Compute the number of program_map PID carried in this section */
373 i_pgrm_number = ((U16_AT(&p_pas[1]) & 0xFFF) - 9) / 4;
374 intf_DbgMsg("Number of Pgrm in that section: %d\n", i_pgrm_number);
376 /* Start the reception of those program map PID */
377 for( i_pgrm_index = 0; i_pgrm_index < i_pgrm_number; i_pgrm_index++ )
379 i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
380 i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1fff;
381 intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id,
384 /* Check we are not already receiving that pid because it carries
385 info for another program */
386 for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
388 if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
390 intf_DbgMsg("Already receiving pid %d", i_pgrm_map_pid);
391 i_es_index = INPUT_MAX_ES+1;
395 /* Start to receive that PID if we're not already doing it */
396 if( i_es_index <= INPUT_MAX_ES )
397 input_AddPsiPID( p_input, i_pgrm_map_pid );
399 /* Append an entry to the pgrm_descriptor table to later store
400 the description of this program, unless program number is 0
401 (Network information table) */
404 intf_DbgMsg("Adding program %d to the PMT\n", i_pgrm_id);
405 AddPgrmDescr(p_descr, i_pgrm_id);
409 /* We now know the info carried in this section */
410 Set_known(p_descr->a_known_PAT_sections, i_current_section);
412 /* Check if the table is now complete */
413 p_descr->i_known_PAT_sections++;
414 if( p_descr->i_known_PAT_sections >= i_last_section)
415 p_descr->b_is_PAT_complete = 1;
422 /*****************************************************************************
423 * DecodePgrmMapSection: Decode a PMS
424 *****************************************************************************
425 * No check is made to known if the table is currently applicable or not, so
426 * that unapplicable sections must be filtered before calling this function
427 * The Program Map Table can be segmented to occupy multiple sections so that
428 * we have to know which sections we have already received (IsKnown() /
430 * Note that the processing of those sections is different from the one of the
431 * others since here a section refers to a single program, and a program cannot
432 * be segmented into multiple sections
433 *****************************************************************************/
434 static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
436 u16 i_pgrm_number; /* Id of the program described in that section */
437 u8 i_version; /* Version of the description for that program */
440 u16 i_section_length;
444 u8 i_current_section;
452 pgrm_descriptor_t* p_pgrm;
453 es_descriptor_t* p_es;
455 #define p_descr (p_input->p_stream)
457 /* Read the id of the program described in that section */
458 i_pgrm_number = U16_AT(&p_pms[3]);
459 // intf_DbgMsg( "PMT section received for program %d\n", i_pgrm_number );
461 /* Find where is stored the description of this program */
462 for( i_index = 0; i_index < p_descr->i_pgrm_number &&
463 i_pgrm_number != p_descr->ap_programs[i_index]->i_number; i_index++ );
465 if( i_index >= p_descr->i_pgrm_number )
467 /* If none entry exists, this simply means that the PAT is not complete,
468 so skip this section since it is the responsability of the PAT decoder
469 to add pgrm_descriptor slots to the table of known pgrms */
470 intf_DbgMsg( "Unknown pgrm %d: skipping its description\n", i_pgrm_number );
474 /* We now have the slot which is the program described: we can begin with
475 the decoding of its description */
476 p_pgrm = p_descr->ap_programs[i_index];
478 /* Which section of the description of that program did we receive ? */
479 i_last_section = p_pms[7];
480 i_current_section = p_pms[6];
481 // intf_DbgMsg("Section %d (last section %d)\n", i_current_section, i_last_section);
483 /* Is this an update of the description for this program ? */
484 i_version = (p_pms[5] >> 1) & 0x1F;
485 if( p_pgrm->i_version != i_version )
487 intf_DbgMsg("Updating PMT for program %d\n", i_pgrm_number);
489 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
491 /* Stop the reception of the ES if needed by calling the function
492 normally used by the interface to manage this */
493 if( input_IsElemRecv(p_input, p_pgrm->ap_es[i_index]->i_id) )
495 intf_DbgMsg( "PID %d is no more valid: stopping its reception\n",
496 p_pgrm->ap_es[i_index]->i_id );
497 input_DelPgrmElem( p_input, p_pgrm->ap_es[i_index]->i_id );
500 /* Remove the descriptor associated to the es of this programs */
501 intf_DbgMsg( "Invalidating PID %d\n", p_pgrm->ap_es[i_index]->i_id );
502 DestroyESDescr(p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id);
505 /* Update version number */
506 p_pgrm->i_version = i_version;
508 /* Ask the decoder to update the description of that program */
509 p_descr->i_known_PMT_sections--;
510 Unset_known( p_descr->a_known_PMT_sections, i_current_section );
514 /* Read the info for that pgrm is the one we have is not up to date or
515 if we don't have any */
516 if( p_pgrm->b_is_ok )
519 // intf_DbgMsg("Program description OK, nothing to do\n");
523 /* Check if we already heard about that section */
524 if( Is_known(p_descr->a_known_PMT_sections, i_current_section) )
527 // intf_DbgMsg("Section already received, skipping\n");
531 /* Read the corresponding PCR */
532 p_pgrm->i_pcr_pid = U16_AT(&p_pms[8]) & 0x1fff;
533 intf_DbgMsg("PCR at PID: %d\n", p_pgrm->i_pcr_pid);
535 /* Compute the length of the section minus the final CRC */
536 i_section_length = (U16_AT(&p_pms[1]) & 0xfff) + 3 - 4;
537 intf_DbgMsg("Section length (without CRC): %d\n", i_section_length);
539 /* Read additional info stored in the descriptors if any */
540 intf_DbgMsg("Description length for program %d: %d\n",
541 p_pgrm->i_number, (U16_AT(&p_pms[10]) & 0x0fff));
542 i_descr_end = (U16_AT(&p_pms[10]) & 0x0fff) + 12;
543 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
546 while( i_offset < i_descr_end )
548 DecodePgrmDescriptor(&p_pms[i_offset], p_pgrm);
549 i_offset += p_pms[i_offset+1] + 2;
552 /* Read all the ES descriptions */
553 while( i_offset < i_section_length )
555 /* Read type of that ES */
556 intf_DbgMsg("ES Type: %d\n", p_pms[i_offset]);
558 /* Read PID of that ES */
559 i_es_pid = U16_AT(&p_pms[i_offset+1]) & 0x1fff;
560 intf_DbgMsg("ES PID: %d\n", i_es_pid);
562 /* Add the ES to the program description and reserve a slot in the
563 table of ES to store its description */
564 p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
567 intf_ErrMsg("Warning: definition for pgrm %d won't be complete\n",
569 /* The best way to handle this is to stop decoding the info for
570 that section but do as if everything is ok. Thus we will
571 eventually have an uncomplete ES table marked as being
572 complete and some error msgs */
577 /* Store the description of that PID in the slot */
578 p_es->i_type = p_pms[i_offset];
580 if( i_es_pid == p_pgrm->i_pcr_pid )
585 /* Read additional info given by the descriptors */
587 intf_DbgMsg("description length for PID %d: %d\n", p_es->i_id,
588 (U16_AT(&p_pms[i_offset-2]) & 0x0fff));
589 i_descr_end = (U16_AT(&p_pms[i_offset-2]) & 0x0fff) + i_offset;
590 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
591 while( i_offset < i_descr_end )
593 DecodeESDescriptor(&p_pms[i_offset], p_es);
594 i_offset += p_pms[i_offset+1] + 2;
598 /* Jump to next ES description */
601 /* We now know the info carried in this section */
602 intf_DbgMsg("Description of program %d complete\n", p_pgrm->i_number);
604 Set_known(p_descr->a_known_PMT_sections, i_current_section);
606 /* Check if the PMT is now complete */
607 p_descr->i_known_PMT_sections++;
608 if( p_descr->i_known_PMT_sections >= i_last_section)
610 p_descr->b_is_PMT_complete = 1;
613 /* Spawn an audio and a video thread, if possible. */
614 for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
616 switch( p_input->p_es[i_es_loop].i_type )
620 if( p_main->b_video )
622 /* Spawn a video thread */
623 input_AddPgrmElem( p_input,
624 p_input->p_es[i_es_loop].i_id );
629 if ( p_main->b_audio )
631 /* Spawn an ac3 thread */
632 input_AddPgrmElem( p_input,
633 p_input->p_es[i_es_loop].i_id );
638 if ( p_main->b_video )
640 /* Spawn a spu decoder thread */
641 input_AddPgrmElem( p_input,
642 p_input->p_es[i_es_loop].i_id );
648 if( p_main->b_audio )
650 /* Spawn an audio thread */
651 input_AddPgrmElem( p_input,
652 p_input->p_es[i_es_loop].i_id );
668 /*****************************************************************************
669 * DecodeSrvDescrSection
670 *****************************************************************************
671 * FIXME: A finir et a refaire proprement ??
672 *****************************************************************************/
673 void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
681 boolean_t b_must_update = 0;
688 #define p_stream (p_input->p_stream)
690 /* Read stream id and version number immediately, to be sure they will be
691 initialised in all the cases in which we will need them */
692 i_stream_id = U16_AT(&p_sdt[3]);
693 i_version = (p_sdt[5] >> 1) & 0x1F;
694 intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version);
696 /* Take the descriptor into account only if it describes the streams we are
698 if( p_stream->i_stream_id != i_stream_id )
700 intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n",
705 /* Section applyies to our TS, test if the SDT is up to date */
706 if( p_stream->i_SDT_version != i_version )
708 intf_DbgMsg("SDT has been updated, NOT YET IMPLEMENTED\n");
710 /* Ask the PSI decoder to rebuild the table */
715 /* Rebuild the table if needed */
718 intf_DbgMsg("Updating SDT table\n");
720 i_length = p_sdt[1] & 0x0FFF;
723 while(i_offset < i_length)
726 /* Find the program to which the description applies */
727 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
729 if( p_stream->ap_programs[i_index]->i_number ==
730 U16_AT(&p_sdt[i_offset]) )
733 intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
738 /* Copy the info to the description of that program */
740 intf_DbgMsg("description length for SDT: %d\n",
741 (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF));
742 i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset;
743 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
744 while( i_offset < i_descr_end )
746 DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]);
747 i_offset += p_sdt[i_offset+1] + 2;
754 /*****************************************************************************
756 *****************************************************************************
757 * Decode any descriptor applying to the definition of a program
758 *****************************************************************************/
759 static void DecodePgrmDescriptor( byte_t* p_descriptor,
760 pgrm_descriptor_t* p_pgrm )
762 u8 i_type; /* Type of the descriptor */
763 u8 i_length; /* Length of the descriptor */
764 #ifdef DVB_EXTENSIONS
765 int i_offset; /* Current position in the descriptor */
768 ASSERT(p_descriptor);
771 /* Read type and length of the descriptor */
772 i_type = p_descriptor[0];
773 i_length = p_descriptor[1];
775 /* Handle specific descriptor info */
778 #ifdef DVB_EXTENSIONS
779 case PSI_SERVICE_DESCRIPTOR:
781 /* Store service type */
782 p_pgrm->i_srv_type = p_descriptor[2];
784 /* Jump to the beginning of the service name */
785 i_offset = p_descriptor[3] + 5;
787 /* Check that the charset used is the normal one (latin) by testing the
788 first byte of the name */
789 if( p_descriptor[i_offset] >= 0x20 )
791 /* The charset is the one of our computer: just dup the string */
792 p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
793 memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset],
794 i_length - i_offset);
795 p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
799 /* Indicate that the name couldn't be printed */
800 p_pgrm->psz_srv_name = "Ununderstandable :)";
806 // intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);
807 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
811 /*****************************************************************************
813 *****************************************************************************
814 * Decode any descriptor applying to the definition of an ES
815 *****************************************************************************/
816 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
818 u8 i_type; /* Type of the descriptor */
819 u8 i_length; /* Length of the descriptor */
820 // int i_offset; /* Current position in the descriptor */
822 ASSERT(p_descriptor);
825 /* Read type and length of the descriptor */
826 i_type = p_descriptor[0];
827 i_length = p_descriptor[1];
831 case PSI_VIDEO_STREAM_DESCRIPTOR:
833 intf_DbgMsg("Video stream descriptor received\n");
836 case PSI_AUDIO_STREAM_DESCRIPTOR:
838 intf_DbgMsg("Audio stream descriptor received\n");
841 case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR:
843 intf_DbgMsg("Target background descriptor received\n");
846 case PSI_VIDEO_WINDOW_DESCRIPTOR:
848 intf_DbgMsg("Video window descriptor received\n");
852 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
853 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
857 /*****************************************************************************
858 * input_AddPsiPID: Start to receive the PSI info contained in a PID
859 *****************************************************************************
860 * Add a descriptor to the table of es descriptor for that es and mark the es
861 * as being to be received by the input (since all PSI must be received to
862 * build the description of the program)
863 *****************************************************************************/
864 static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
867 es_descriptor_t* p_psi_es;
870 /* Store the description of this stream in the input thread */
871 p_psi_es = AddESDescr(p_input, NULL, i_pid);
875 /* Precise this ES carries PSI */
878 /* Create the buffer needed by the PSI decoder */
879 p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) );
880 if( !p_psi_es->p_psi_section )
882 intf_ErrMsg( "Malloc error\n" );
887 /* Init the reception for that PID */
888 p_psi_es->p_psi_section->b_running_section = 0;
889 // p_psi_es->p_psi_section->b_discard_payload = 0;
891 /* Ask the input thread to demultiplex it: since the interface
892 can also access the table of selected es, lock the elementary
894 vlc_mutex_lock( &p_input->es_lock );
895 for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ )
897 if( !p_input->pp_selected_es[i_index] )
899 intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n",
901 p_input->pp_selected_es[i_index] = p_psi_es;
905 vlc_mutex_unlock( &p_input->es_lock );
907 if( i_index >= INPUT_MAX_SELECTED_ES )
909 intf_ErrMsg( "Stream carries to many PID for our decoder\n" );
918 /*****************************************************************************
919 * input_DelPsiPID: Stop to receive the PSI info contained in a PID
920 *****************************************************************************
921 * Remove the PID from the list of ES descriptors and from the list of ES that
922 * the input must receive.
923 * Known PID for PSI should always be received, so that their description
924 * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES
925 * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must
927 *****************************************************************************/
928 static int input_DelPsiPID( input_thread_t *p_input, int i_pid )
930 int i_es_index, i_last_sel;
932 intf_DbgMsg( "Deleting PSI PID %d\n", i_pid );
934 /* Stop to receive the ES. Since the interface can also access the table
935 of selected es, lock the elementary stream structure */
936 vlc_mutex_lock( &p_input->es_lock );
938 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ )
940 if( p_input->pp_selected_es[i_es_index] &&
941 p_input->pp_selected_es[i_es_index]->i_id == i_pid )
943 /* Unmark the stream */
944 p_input->pp_selected_es[i_es_index] = NULL;
946 /* There must not be any gap in the pp_selected_es, so move the last
947 selected stream to this slot */
948 for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] &&
949 i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ );
950 p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel];
951 p_input->pp_selected_es[i_last_sel] = NULL;
956 vlc_mutex_unlock( &p_input->es_lock );
959 /* Check if the pp_selected_es table may be corrupted */
960 if( i_es_index >= INPUT_MAX_PROGRAM_ES )
962 intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid );
966 /* Remove the desription of that ES from the table of ES */
967 DestroyESDescr(p_input, NULL, i_pid);
972 /*****************************************************************************
973 * Precalculate the 32-bit CRC table
974 *****************************************************************************
975 * This table is a global variable shared by all decoders, so it has to be
976 * initialised only once
977 *****************************************************************************/
978 void BuildCrc32Table( )
981 for( i = 0 ; i < 256 ; i++ )
984 for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
985 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
986 i_crc_32_table[i] = k;
990 /*****************************************************************************
991 * Test the validity of a checksum
992 *****************************************************************************
993 * The checksum must be stored at the end of the data, and the given size must
994 * include the 32 bits of the CRC.
995 * Return 0 if the checksum is OK, any other value if the data are corrupted
996 *****************************************************************************/
997 int CheckCRC32(byte_t* p_data, int i_data_size)
1000 u32 i_crc = 0xffffffff;
1004 for (i = 0; i < i_data_size; i++)
1005 i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]];
1010 /*****************************************************************************
1011 * Is_known: check if a given section has already been received
1012 *****************************************************************************
1013 * As a table cannot be segmented into more than 256 sections, we store a 256
1014 * bits long table, each bit set to one indicating that the corresponding
1015 * saction has been received
1016 *****************************************************************************/
1017 boolean_t Is_known( byte_t* a_known_section, u8 i_section )
1020 boolean_t b_is_known;
1022 /* Where to get the information ? */
1023 int i_bit_in_byte = i_section % 8;
1024 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1026 /* Build mask to read the Is_known flag */
1027 mask = 0x01 << i_bit_in_byte;
1030 b_is_known = a_known_section[i_byte_in_table] & mask;
1035 /*****************************************************************************
1036 * Set_known: mark a given section has having been received
1037 *****************************************************************************
1039 *****************************************************************************/
1040 static void Set_known( byte_t* a_known_section, u8 i_section )
1044 /* Where to get the information ? */
1045 int i_bit_in_byte = i_section % 8;
1046 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1048 /* Build mask to read the Is_known flag */
1049 mask = 0x01 << i_bit_in_byte;
1052 a_known_section[i_byte_in_table] |= mask;
1055 /*****************************************************************************
1056 * Unset_known: remove the 'received' mark for a given section
1057 *****************************************************************************
1059 *****************************************************************************/
1060 static void Unset_known( byte_t* a_known_section, u8 i_section )
1064 /* Where to get the information ? */
1065 int i_bit_in_byte = i_section % 8;
1066 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1068 /* Build mask to read the Is_known flag */
1069 mask = 0x01 << i_bit_in_byte;
1072 /* Unset the flag */
1073 a_known_section[i_byte_in_table] &= mask;
1076 /*****************************************************************************
1077 * AddStreamDescr: add and init the stream descriptor of the given input
1078 *****************************************************************************
1080 *****************************************************************************/
1081 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
1086 intf_DbgMsg("Adding description for stream %d\n", i_stream_id);
1088 p_input->p_stream = malloc( sizeof(stream_descriptor_t) );
1090 p_input->p_stream->i_stream_id = i_stream_id;
1092 p_input->p_stream->i_PAT_version = PSI_UNINITIALISED;
1093 p_input->p_stream->i_known_PAT_sections = 0;
1094 bzero( p_input->p_stream->a_known_PAT_sections,
1095 sizeof(*p_input->p_stream->a_known_PAT_sections) );
1096 p_input->p_stream->b_is_PAT_complete = 0;
1098 p_input->p_stream->i_known_PMT_sections = 0;
1099 bzero( p_input->p_stream->a_known_PMT_sections,
1100 sizeof(*p_input->p_stream->a_known_PMT_sections) );
1101 p_input->p_stream->b_is_PMT_complete = 0;
1103 #ifdef DVB_EXTENSIONS
1104 p_input->p_stream->i_SDT_version = PSI_UNINITIALISED;
1105 p_input->p_stream->i_known_SDT_sections = 0;
1106 bzero( p_input->p_stream->a_known_SDT_sections,
1107 sizeof(*p_input->p_stream->a_known_SDT_sections) );
1108 p_input->p_stream->b_is_SDT_complete = 0;
1111 p_input->p_stream->i_pgrm_number = 0;
1112 p_input->p_stream->ap_programs = NULL;
1114 return p_input->p_stream;
1117 /*****************************************************************************
1118 * DestroyStreamDescr: destroy the stream desciptor of the given input
1119 *****************************************************************************
1121 *****************************************************************************/
1122 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1128 /* Free the structures that describes the programs of that stream */
1129 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
1131 DestroyPgrmDescr( p_input, p_input->p_stream,
1132 p_input->p_stream->ap_programs[i_index]->i_number );
1135 /* Free the table of pgrm descriptors */
1136 free( p_input->p_stream->ap_programs );
1138 /* Free the structure that describes the stream itself */
1139 free( p_input->p_stream );
1141 /* Input thread has no more stream descriptor */
1142 p_input->p_stream = NULL;
1145 /*****************************************************************************
1146 * AddPgrmDescr: add and init a program descriptor
1147 *****************************************************************************
1148 * This program descriptor will be referenced in the given stream descriptor
1149 *****************************************************************************/
1150 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
1153 int i_pgrm_index = p_stream->i_pgrm_number; /* Where to add the pgrm */
1157 intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
1159 /* Add an entry to the list of program associated with the stream */
1160 p_stream->i_pgrm_number++;
1161 p_stream->ap_programs = realloc( p_stream->ap_programs,
1162 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
1164 /* Allocate the structure to store this description */
1165 p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t));
1167 /* Init this entry */
1168 p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id;
1169 p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED;
1170 p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0;
1172 p_stream->ap_programs[i_pgrm_index]->i_es_number = 0;
1173 p_stream->ap_programs[i_pgrm_index]->ap_es = NULL;
1175 /* descriptors ? XXX?? */
1177 return p_stream->ap_programs[i_pgrm_index];
1180 /*****************************************************************************
1181 * AddPgrmDescr: destroy a program descriptor
1182 *****************************************************************************
1183 * All ES descriptions referenced in the descriptor will be deleted.
1184 *****************************************************************************/
1185 static void DestroyPgrmDescr( input_thread_t * p_input,
1186 stream_descriptor_t * p_stream, u16 i_pgrm_id )
1188 int i_index, i_pgrm_index = -1;
1189 pgrm_descriptor_t* p_pgrm = NULL;
1193 intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id);
1195 /* Find where this program is described */
1196 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
1198 if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id )
1200 i_pgrm_index = i_index;
1201 p_pgrm = p_stream->ap_programs[ i_pgrm_index ];
1206 /* Make sure that the pgrm exists */
1207 ASSERT(i_pgrm_index >= 0);
1210 /* Free the structures that describe the es that belongs to that program */
1211 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
1213 DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id );
1216 /* Free the table of es descriptors */
1217 free( p_pgrm->ap_es );
1219 /* Free the description of this stream */
1222 /* Remove this program from the stream's list of programs */
1223 p_stream->i_pgrm_number--;
1224 p_stream->ap_programs[i_pgrm_index] =
1225 p_stream->ap_programs[p_stream->i_pgrm_number];
1226 p_stream->ap_programs = realloc( p_stream->ap_programs,
1227 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );
1230 /*****************************************************************************
1232 *****************************************************************************
1233 * Reserve a slot in the table of ES descritors for the ES and add it to the
1234 * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand
1236 *****************************************************************************/
1237 static es_descriptor_t* AddESDescr(input_thread_t* p_input,
1238 pgrm_descriptor_t* p_pgrm, u16 i_es_pid)
1241 es_descriptor_t* p_es = NULL;
1245 intf_DbgMsg("Adding description for ES %d\n", i_es_pid);
1247 /* Find an empty slot to store the description of that es */
1248 for( i_index = 0; i_index < INPUT_MAX_ES &&
1249 p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ );
1251 if( i_index >= INPUT_MAX_ES )
1253 /* No slot is empty */
1254 intf_ErrMsg("Stream carries to many PID for our decoder\n");
1258 /* Reserve the slot for that ES */
1259 p_es = &p_input->p_es[i_index];
1260 p_es->i_id = i_es_pid;
1261 intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid);
1263 /* Init its values */
1264 p_es->i_type = 0; /* XXX?? */
1267 p_es->i_continuity_counter = 0xFF;
1269 p_es->p_pes_packet = NULL;
1270 // p_es->p_next_pes_packet = NULL;
1273 /* Add this ES to the program definition if one is given */
1276 p_pgrm->i_es_number++;
1277 p_pgrm->ap_es = realloc( p_pgrm->ap_es,
1278 p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
1279 p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
1280 intf_DbgMsg( "Added ES %d to definition of pgrm %d\n",
1281 i_es_pid, p_pgrm->i_number );
1284 intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n",
1291 /*****************************************************************************
1293 *****************************************************************************
1295 *****************************************************************************/
1296 static void DestroyESDescr(input_thread_t* p_input,
1297 pgrm_descriptor_t* p_pgrm, u16 i_pid)
1301 /* Look for the description of the ES */
1302 for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
1304 if( p_input->p_es[i_index].i_id == i_pid )
1306 /* The table of stream descriptors is static, so don't free memory
1307 but just mark the slot as unused */
1308 p_input->p_es[i_index].i_id = EMPTY_PID;
1313 /* Remove this ES from the description of the program if it is associated to
1317 for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
1319 if( p_input->p_es[i_index].i_id == i_pid )
1321 p_pgrm->i_es_number--;
1322 p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number];
1323 p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number);