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 *****************************************************************************/
19 #include <netinet/in.h>
20 #include <sys/soundcard.h>
25 #include "vlc_thread.h"
30 #include "input_ctrl.h"
31 #include "input_psi.h"
32 #include "input_vlan.h"
34 #include "audio_output.h"
36 #include "video_output.h"
37 #include "interface.h"
42 * Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
44 boolean_t b_crc_initialised = 0;
45 u32 i_crc_32_table[256];
48 * Global configuration variable, need by AUTO_SPAWN to determine
49 * the option (audio and video) passed to the VideoLAN client.
52 //XXX?? extern program_data_t *p_main;
56 * Locale type definitions
58 #define PSI_VIDEO_STREAM_DESCRIPTOR 0x02
59 #define PSI_AUDIO_STREAM_DESCRIPTOR 0x03
60 #define PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR 0x07
61 #define PSI_VIDEO_WINDOW_DESCRIPTOR 0x08
64 #define PSI_SERVICE_DESCRIPTOR 0x48
67 /* That info must be stored in the version field since it contains
69 #define PSI_UNINITIALISED 0xFF
74 static int input_AddPsiPID( input_thread_t *p_input, int i_pid );
75 static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
76 static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
77 static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
78 static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
79 static void DecodePgrmDescriptor( byte_t* p_descr, pgrm_descriptor_t* p_pgrm );
80 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
82 static stream_descriptor_t* AddStreamDescr( input_thread_t* p_input,
84 static void DestroyStreamDescr( input_thread_t* p_input, u16 i_stream_id );
85 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
87 static void DestroyPgrmDescr( input_thread_t* p_input,
88 stream_descriptor_t* p_stream, u16 i_pgrm_id );
89 static es_descriptor_t* AddESDescr( input_thread_t* p_input,
90 pgrm_descriptor_t* p_pgrm, u16 i_es_pid );
91 static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
94 static void BuildCrc32Table();
95 static int CheckCRC32( u8* p_pms, int i_size);
96 static boolean_t Is_known( byte_t* a_known_section, u8 i_section );
97 static void Set_known( byte_t* a_known_section, u8 i_section );
98 static void Unset_known( byte_t* a_known_section, u8 i_section );
100 /*****************************************************************************
101 * input_PsiInit: Initialize PSI decoder
102 *****************************************************************************
103 * Init the structures in which the PSI decoder will put the informations it
104 * got from PSI tables and request for the reception of the PAT.
105 *****************************************************************************/
106 int input_PsiInit( input_thread_t *p_input )
110 /* Precalculate the 32-bit CRC table if not already done ?
111 FIXME: Put a lock or do that at pgrm init ?? */
112 if( !b_crc_initialised )
115 b_crc_initialised = 1;
118 /* Init the structure that describes the stream we are receiving */
119 AddStreamDescr( p_input, PSI_UNINITIALISED );
121 /* Request for reception of the program association table */
122 input_AddPsiPID( p_input, 0 );
124 #ifdef DVB_EXTENSIONS
125 /* Request for reception of the service description table */
126 input_AddPsiPID( p_input, 17 );
132 /*****************************************************************************
133 * input_PsiClean: Clean PSI structures before dying
134 *****************************************************************************/
135 int input_PsiEnd( input_thread_t *p_input )
139 /* Stop to receive all the PSI tables associated with that program */
140 /* FIXME: Not really useful ??*/
142 /* Clean also descriptors for programs associated with that stream */
143 /* FIXME: -> Not really useful and maybe buggy ??*/
145 /* Destroy the stream description */
146 DestroyStreamDescr( p_input, p_input->p_stream->i_stream_id );
151 /*****************************************************************************
152 * input_PsiRead: Read the table of programs
153 *****************************************************************************
154 * Ugly debugging function at that time ? XXX??
155 *****************************************************************************/
156 void input_PsiRead( input_thread_t *p_input /* XXX?? */ )
160 pgrm_descriptor_t* p_pgrm;
164 /* Lock the tables, since this method can be called from any thread */
167 /* Check if the table is complete or not */
168 if( !p_input->p_stream->b_is_PMT_complete )
170 intf_IntfMsg( "Warning: PMT not yet complete\n" );
174 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
176 p_pgrm = p_input->p_stream->ap_programs[i_index];
177 intf_DbgMsg("Printing info for program %d\n", p_pgrm->i_number );
178 intf_IntfMsg("Printing info for program %d\n", p_pgrm->i_number );
180 for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ )
182 intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
183 p_pgrm->ap_es[i_index2]->i_id,
184 p_pgrm->ap_es[i_index2]->i_type,
185 p_pgrm->ap_es[i_index2]->b_pcr,
186 p_pgrm->ap_es[i_index2]->b_psi);
188 intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
189 p_pgrm->ap_es[i_index2]->i_id,
190 p_pgrm->ap_es[i_index2]->i_type,
191 p_pgrm->ap_es[i_index2]->b_pcr,
192 p_pgrm->ap_es[i_index2]->b_psi);
196 /* Unock the tables */
200 /*****************************************************************************
201 * input_PsiDecode: Decode a PSI section
202 *****************************************************************************
203 * This funtion is essentially a wrapper that will perform basic checks on
204 * the section and then call the right function according to its type.
205 *****************************************************************************/
206 void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
209 ASSERT(p_psi_section);
211 /* Hexa dump of the beginning of the section (for real men) */
212 //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] );
214 /* Check the CRC validity if any CRC is carried */
216 if( p_psi_section->buffer[1] & 0x80 )
218 if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
220 intf_DbgMsg("iSize: %d, CRC: %d\n", p_psi_section->i_length,
221 U32_AT(&p_psi_section->buffer[p_psi_section->i_length-4]));
222 intf_DbgMsg( "Invalid CRC for PSI\n" );
228 /* If the section is not immediatly applicable, trash it (DVB drafts disallow
229 transmission of such sections, so we didn't implement it) */
230 if( !p_psi_section->buffer[5] & 0x01 )
232 intf_DbgMsg( "PSI not yet applicable: trash it\n" );
236 /* Handle the packet according to it's type given it the table_id */
237 switch ( p_psi_section->buffer[0] )
240 //intf_DbgMsg("Program association section received\n");
241 DecodePgrmAssocSection(p_psi_section->buffer, p_input);
244 //intf_DbgMsg("Conditional access section received\n");
247 //intf_DbgMsg("Program map section received\n");
248 DecodePgrmMapSection(p_psi_section->buffer, p_input);
251 //intf_DbgMsg("Service description section received\n");
252 DecodeSrvDescrSection(p_psi_section->buffer, p_input);
255 //intf_DbgMsg("Private PSI data received (type %x), ignoring it\n",
256 // p_psi_section->buffer[0]);
260 /*****************************************************************************
261 * DecodeAssocSection: Decode a PAS
262 *****************************************************************************
263 * No check is made to known if the table is currently applicable or not, so
264 * that unapplicable sections must be filtered before calling this function
265 * The Program Association Table can be segmented to occupy multiple sections
266 * so that we have to know which sections we have already received (IsKnown() /
268 *****************************************************************************/
269 static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
271 u8 i_stream_id; /* Id of the stream described in that section */
272 u8 i_version; /* Version of the table carried in the section */
274 u16 i_pgrm_id; /* Id of the current described pgrm */
275 u16 i_pgrm_map_pid; /* PID of the associated program map table */
276 int i_pgrm_number; /* Number of programs described in the section */
278 boolean_t b_is_invalid = 0;
280 u8 i_current_section;
289 #define p_descr (p_input->p_stream)
291 /* Read stream id and version number immediately, to be sure they will be
292 initialised in all cases we will need it */
293 i_stream_id = U16_AT(&p_pas[3]);
294 i_version = (p_pas[5] >> 1) & 0x1F;
295 //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
297 /* Test if the stream has not changed by looking at the stream_id */
298 if( p_descr->i_stream_id != i_stream_id )
300 /* This can either mean that the PSI decoder has just started or that
301 the stream has changed */
302 if( p_descr->i_PAT_version== PSI_UNINITIALISED )
303 intf_DbgMsg("Building Program Association table\n");
305 intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
307 /* Whatever it is, ask the PSI decoder to rebuild the table */
312 /* Stream has not changed, test if the PMT is up to date */
313 if( p_descr->i_PAT_version != i_version )
315 intf_DbgMsg("PAT has been updated, rebuilding it\n");
316 /* Ask the PSI decoder to rebuild the table */
321 /* Clear the table if needed */
324 intf_DbgMsg("Updating PAT table\n");
326 /* Any program in the stream may have disapeared, or a new one
327 can have been added. The good way to handle such a case would be
328 to build a temporary table and to make a diff */
330 /* Stop the reception of all programs and PSI informations
331 associated with this stream, excepted the PAT on PID 0 and the SDT
333 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES &&
334 p_input->pp_selected_es[i_es_index]; i_es_index++ )
336 if( p_input->pp_selected_es[i_es_index]->b_psi )
338 if( p_input->pp_selected_es[i_es_index]->i_id != 0
339 #ifdef DVB_EXTENSIONS
340 && p_input->pp_selected_es[i_es_index]->i_id != 17
343 input_DelPsiPID( p_input,
344 p_input->pp_selected_es[i_es_index]->i_id );
347 input_DelPgrmElem( p_input,
348 p_input->pp_selected_es[i_es_index]->i_id );
351 /* Recreate a new stream description. Since it is virgin, the decoder
352 will rebuild it entirely on is own */
353 DestroyStreamDescr(p_input, p_descr->i_stream_id);
354 AddStreamDescr(p_input, i_stream_id);
356 /* Record the new version for that table */
357 p_descr->i_PAT_version = i_version;
360 /* Build the table if not already complete or if it was cleared */
361 if( p_descr->b_is_PAT_complete )
365 intf_DbgMsg("Bug: table invalid but PAT said to be complete\n");
369 /* Check if we already heard about that section */
370 i_last_section = p_pas[7];
371 i_current_section = p_pas[6];
373 // intf_DbgMsg( "Section %d (last section %d)\n",
374 // i_current_section, i_last_section );
376 if( Is_known(p_descr->a_known_PAT_sections, i_current_section) )
379 // intf_DbgMsg("Section already received, skipping\n");
383 /* Compute the number of program_map PID carried in this section */
384 i_pgrm_number = ((U16_AT(&p_pas[1]) & 0xFFF) - 9) / 4;
385 intf_DbgMsg("Number of Pgrm in that section: %d\n", i_pgrm_number);
387 /* Start the reception of those program map PID */
388 for( i_pgrm_index = 0; i_pgrm_index < i_pgrm_number; i_pgrm_index++ )
390 i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
391 i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1fff;
392 intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id,
395 /* Check we are not already receiving that pid because it carries
396 info for another program */
397 for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
399 if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
401 intf_DbgMsg("Already receiving pid %d", i_pgrm_map_pid);
402 i_es_index = INPUT_MAX_ES+1;
406 /* Start to receive that PID if we're not already doing it */
407 if( i_es_index <= INPUT_MAX_ES )
408 input_AddPsiPID( p_input, i_pgrm_map_pid );
410 /* Append an entry to the pgrm_descriptor table to later store
411 the description of this program, unless program number is 0
412 (Network information table) */
415 intf_DbgMsg("Adding program %d to the PMT\n", i_pgrm_id);
416 AddPgrmDescr(p_descr, i_pgrm_id);
420 /* We now know the info carried in this section */
421 Set_known(p_descr->a_known_PAT_sections, i_current_section);
423 /* Check if the table is now complete */
424 p_descr->i_known_PAT_sections++;
425 if( p_descr->i_known_PAT_sections >= i_last_section)
426 p_descr->b_is_PAT_complete = 1;
433 /*****************************************************************************
434 * DecodePgrmMapSection: Decode a PMS
435 *****************************************************************************
436 * No check is made to known if the table is currently applicable or not, so
437 * that unapplicable sections must be filtered before calling this function
438 * The Program Map Table can be segmented to occupy multiple sections so that
439 * we have to know which sections we have already received (IsKnown() /
441 * Note that the processing of those sections is different from the one of the
442 * others since here a section refers to a single program, and a program cannot
443 * be segmented into multiple sections
444 *****************************************************************************/
445 static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
447 u16 i_pgrm_number; /* Id of the program described in that section */
448 u8 i_version; /* Version of the description for that program */
451 u16 i_section_length;
455 u8 i_current_section;
463 pgrm_descriptor_t* p_pgrm;
464 es_descriptor_t* p_es;
466 #define p_descr (p_input->p_stream)
468 /* Read the id of the program described in that section */
469 i_pgrm_number = U16_AT(&p_pms[3]);
470 // intf_DbgMsg( "PMT section received for program %d\n", i_pgrm_number );
472 /* Find where is stored the description of this program */
473 for( i_index = 0; i_index < p_descr->i_pgrm_number &&
474 i_pgrm_number != p_descr->ap_programs[i_index]->i_number; i_index++ );
476 if( i_index >= p_descr->i_pgrm_number )
478 /* If none entry exists, this simply means that the PAT is not complete,
479 so skip this section since it is the responsability of the PAT decoder
480 to add pgrm_descriptor slots to the table of known pgrms */
481 intf_DbgMsg( "Unknown pgrm %d: skipping its description\n", i_pgrm_number );
485 /* We now have the slot which is the program described: we can begin with
486 the decoding of its description */
487 p_pgrm = p_descr->ap_programs[i_index];
489 /* Which section of the description of that program did we receive ? */
490 i_last_section = p_pms[7];
491 i_current_section = p_pms[6];
492 // intf_DbgMsg("Section %d (last section %d)\n", i_current_section, i_last_section);
494 /* Is this an update of the description for this program ? */
495 i_version = (p_pms[5] >> 1) & 0x1F;
496 if( p_pgrm->i_version != i_version )
498 intf_DbgMsg("Updating PMT for program %d\n", i_pgrm_number);
500 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
502 /* Stop the reception of the ES if needed by calling the function
503 normally used by the interface to manage this */
504 if( input_IsElemRecv(p_input, p_pgrm->ap_es[i_index]->i_id) )
506 intf_DbgMsg( "PID %d is no more valid: stopping its reception\n",
507 p_pgrm->ap_es[i_index]->i_id );
508 input_DelPgrmElem( p_input, p_pgrm->ap_es[i_index]->i_id );
511 /* Remove the descriptor associated to the es of this programs */
512 intf_DbgMsg( "Invalidating PID %d\n", p_pgrm->ap_es[i_index]->i_id );
513 DestroyESDescr(p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id);
516 /* Update version number */
517 p_pgrm->i_version = i_version;
519 /* Ask the decoder to update the description of that program */
520 p_descr->i_known_PMT_sections--;
521 Unset_known( p_descr->a_known_PMT_sections, i_current_section );
525 /* Read the info for that pgrm is the one we have is not up to date or
526 if we don't have any */
527 if( p_pgrm->b_is_ok )
530 // intf_DbgMsg("Program description OK, nothing to do\n");
534 /* Check if we already heard about that section */
535 if( Is_known(p_descr->a_known_PMT_sections, i_current_section) )
538 // intf_DbgMsg("Section already received, skipping\n");
542 /* Read the corresponding PCR */
543 p_pgrm->i_pcr_pid = U16_AT(&p_pms[8]) & 0x1fff;
544 intf_DbgMsg("PCR at PID: %d\n", p_pgrm->i_pcr_pid);
546 /* Compute the length of the section minus the final CRC */
547 i_section_length = (U16_AT(&p_pms[1]) & 0xfff) + 3 - 4;
548 intf_DbgMsg("Section length (without CRC): %d\n", i_section_length);
550 /* Read additional info stored in the descriptors if any */
551 intf_DbgMsg("Description length for program %d: %d\n",
552 p_pgrm->i_number, (U16_AT(&p_pms[10]) & 0x0fff));
553 i_descr_end = (U16_AT(&p_pms[10]) & 0x0fff) + 12;
554 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
557 while( i_offset < i_descr_end )
559 DecodePgrmDescriptor(&p_pms[i_offset], p_pgrm);
560 i_offset += p_pms[i_offset+1] + 2;
563 /* Read all the ES descriptions */
564 while( i_offset < i_section_length )
566 /* Read type of that ES */
567 intf_DbgMsg("ES Type: %d\n", p_pms[i_offset]);
569 /* Read PID of that ES */
570 i_es_pid = U16_AT(&p_pms[i_offset+1]) & 0x1fff;
571 intf_DbgMsg("ES PID: %d\n", i_es_pid);
573 /* Add the ES to the program description and reserve a slot in the
574 table of ES to store its description */
575 p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
578 intf_ErrMsg("Warning: definition for pgrm %d won't be complete\n",
580 /* The best way to handle this is to stop decoding the info for
581 that section but do as if everything is ok. Thus we will
582 eventually have an uncomplete ES table marked as being
583 complete and some error msgs */
588 /* Store the description of that PID in the slot */
589 p_es->i_type = p_pms[i_offset];
591 if( i_es_pid == p_pgrm->i_pcr_pid )
596 /* Read additional info given by the descriptors */
598 intf_DbgMsg("description length for PID %d: %d\n", p_es->i_id,
599 (U16_AT(&p_pms[i_offset-2]) & 0x0fff));
600 i_descr_end = (U16_AT(&p_pms[i_offset-2]) & 0x0fff) + i_offset;
601 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
602 while( i_offset < i_descr_end )
604 DecodeESDescriptor(&p_pms[i_offset], p_es);
605 i_offset += p_pms[i_offset+1] + 2;
609 /* Jump to next ES description */
612 /* We now know the info carried in this section */
613 intf_DbgMsg("Description of program %d complete\n", p_pgrm->i_number);
615 Set_known(p_descr->a_known_PMT_sections, i_current_section);
617 /* Check if the PMT is now complete */
618 p_descr->i_known_PMT_sections++;
619 if( p_descr->i_known_PMT_sections >= i_last_section)
621 p_descr->b_is_PMT_complete = 1;
624 /* Spawn an audio and a video thread, if possible. */
625 for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
627 switch( p_input->p_es[i_es_loop].i_type )
631 if( p_main->b_video )
633 /* Spawn a video thread */
634 input_AddPgrmElem( p_input,
635 p_input->p_es[i_es_loop].i_id );
640 if ( p_main->b_audio )
642 /* Spawn an ac3 thread */
643 input_AddPgrmElem( p_input,
644 p_input->p_es[i_es_loop].i_id );
649 if ( p_main->b_video )
651 /* Spawn a spu decoder thread */
652 input_AddPgrmElem( p_input,
653 p_input->p_es[i_es_loop].i_id );
659 if( p_main->b_audio )
661 /* Spawn an audio thread */
662 input_AddPgrmElem( p_input,
663 p_input->p_es[i_es_loop].i_id );
679 /*****************************************************************************
680 * DecodeSrvDescrSection
681 *****************************************************************************
682 * FIXME: A finir et a refaire proprement ??
683 *****************************************************************************/
684 void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
692 boolean_t b_must_update = 0;
699 #define p_stream (p_input->p_stream)
701 /* Read stream id and version number immediately, to be sure they will be
702 initialised in all the cases in which we will need them */
703 i_stream_id = U16_AT(&p_sdt[3]);
704 i_version = (p_sdt[5] >> 1) & 0x1F;
705 intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version);
707 /* Take the descriptor into account only if it describes the streams we are
709 if( p_stream->i_stream_id != i_stream_id )
711 intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n",
716 /* Section applyies to our TS, test if the SDT is up to date */
717 if( p_stream->i_SDT_version != i_version )
719 intf_DbgMsg("SDT has been updated, NOT YET IMPLEMENTED\n");
721 /* Ask the PSI decoder to rebuild the table */
726 /* Rebuild the table if needed */
729 intf_DbgMsg("Updating SDT table\n");
731 i_length = p_sdt[1] & 0x0FFF;
734 while(i_offset < i_length)
737 /* Find the program to which the description applies */
738 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
740 if( p_stream->ap_programs[i_index]->i_number ==
741 U16_AT(&p_sdt[i_offset]) )
744 intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
749 /* Copy the info to the description of that program */
751 intf_DbgMsg("description length for SDT: %d\n",
752 (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF));
753 i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset;
754 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
755 while( i_offset < i_descr_end )
757 DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]);
758 i_offset += p_sdt[i_offset+1] + 2;
765 /*****************************************************************************
767 *****************************************************************************
768 * Decode any descriptor applying to the definition of a program
769 *****************************************************************************/
770 static void DecodePgrmDescriptor( byte_t* p_descriptor,
771 pgrm_descriptor_t* p_pgrm )
773 u8 i_type; /* Type of the descriptor */
774 u8 i_length; /* Length of the descriptor */
775 #ifdef DVB_EXTENSIONS
776 int i_offset; /* Current position in the descriptor */
779 ASSERT(p_descriptor);
782 /* Read type and length of the descriptor */
783 i_type = p_descriptor[0];
784 i_length = p_descriptor[1];
786 /* Handle specific descriptor info */
789 #ifdef DVB_EXTENSIONS
790 case PSI_SERVICE_DESCRIPTOR:
792 /* Store service type */
793 p_pgrm->i_srv_type = p_descriptor[2];
795 /* Jump to the beginning of the service name */
796 i_offset = p_descriptor[3] + 5;
798 /* Check that the charset used is the normal one (latin) by testing the
799 first byte of the name */
800 if( p_descriptor[i_offset] >= 0x20 )
802 /* The charset is the one of our computer: just dup the string */
803 p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
804 memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset],
805 i_length - i_offset);
806 p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
810 /* Indicate that the name couldn't be printed */
811 p_pgrm->psz_srv_name = "Ununderstandable :)";
817 // intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);
818 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
822 /*****************************************************************************
824 *****************************************************************************
825 * Decode any descriptor applying to the definition of an ES
826 *****************************************************************************/
827 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
829 u8 i_type; /* Type of the descriptor */
830 u8 i_length; /* Length of the descriptor */
831 // int i_offset; /* Current position in the descriptor */
833 ASSERT(p_descriptor);
836 /* Read type and length of the descriptor */
837 i_type = p_descriptor[0];
838 i_length = p_descriptor[1];
842 case PSI_VIDEO_STREAM_DESCRIPTOR:
844 intf_DbgMsg("Video stream descriptor received\n");
847 case PSI_AUDIO_STREAM_DESCRIPTOR:
849 intf_DbgMsg("Audio stream descriptor received\n");
852 case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR:
854 intf_DbgMsg("Target background descriptor received\n");
857 case PSI_VIDEO_WINDOW_DESCRIPTOR:
859 intf_DbgMsg("Video window descriptor received\n");
863 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
864 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
868 /*****************************************************************************
869 * input_AddPsiPID: Start to receive the PSI info contained in a PID
870 *****************************************************************************
871 * Add a descriptor to the table of es descriptor for that es and mark the es
872 * as being to be received by the input (since all PSI must be received to
873 * build the description of the program)
874 *****************************************************************************/
875 static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
878 es_descriptor_t* p_psi_es;
881 /* Store the description of this stream in the input thread */
882 p_psi_es = AddESDescr(p_input, NULL, i_pid);
886 /* Precise this ES carries PSI */
889 /* Create the buffer needed by the PSI decoder */
890 p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) );
891 if( !p_psi_es->p_psi_section )
893 intf_ErrMsg( "Malloc error\n" );
898 /* Init the reception for that PID */
899 p_psi_es->p_psi_section->b_running_section = 0;
900 // p_psi_es->p_psi_section->b_discard_payload = 0;
902 /* Ask the input thread to demultiplex it: since the interface
903 can also access the table of selected es, lock the elementary
905 vlc_mutex_lock( &p_input->es_lock );
906 for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ )
908 if( !p_input->pp_selected_es[i_index] )
910 intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n",
912 p_input->pp_selected_es[i_index] = p_psi_es;
916 vlc_mutex_unlock( &p_input->es_lock );
918 if( i_index >= INPUT_MAX_SELECTED_ES )
920 intf_ErrMsg( "Stream carries to many PID for our decoder\n" );
929 /*****************************************************************************
930 * input_DelPsiPID: Stop to receive the PSI info contained in a PID
931 *****************************************************************************
932 * Remove the PID from the list of ES descriptors and from the list of ES that
933 * the input must receive.
934 * Known PID for PSI should always be received, so that their description
935 * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES
936 * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must
938 *****************************************************************************/
939 static int input_DelPsiPID( input_thread_t *p_input, int i_pid )
941 int i_es_index, i_last_sel;
943 intf_DbgMsg( "Deleting PSI PID %d\n", i_pid );
945 /* Stop to receive the ES. Since the interface can also access the table
946 of selected es, lock the elementary stream structure */
947 vlc_mutex_lock( &p_input->es_lock );
949 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ )
951 if( p_input->pp_selected_es[i_es_index] &&
952 p_input->pp_selected_es[i_es_index]->i_id == i_pid )
954 /* Unmark the stream */
955 p_input->pp_selected_es[i_es_index] = NULL;
957 /* There must not be any gap in the pp_selected_es, so move the last
958 selected stream to this slot */
959 for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] &&
960 i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ );
961 p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel];
962 p_input->pp_selected_es[i_last_sel] = NULL;
967 vlc_mutex_unlock( &p_input->es_lock );
970 /* Check if the pp_selected_es table may be corrupted */
971 if( i_es_index >= INPUT_MAX_PROGRAM_ES )
973 intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid );
977 /* Remove the desription of that ES from the table of ES */
978 DestroyESDescr(p_input, NULL, i_pid);
983 /*****************************************************************************
984 * Precalculate the 32-bit CRC table
985 *****************************************************************************
986 * This table is a global variable shared by all decoders, so it has to be
987 * initialised only once
988 *****************************************************************************/
989 void BuildCrc32Table( )
992 for( i = 0 ; i < 256 ; i++ )
995 for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
996 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
997 i_crc_32_table[i] = k;
1001 /*****************************************************************************
1002 * Test the validity of a checksum
1003 *****************************************************************************
1004 * The checksum must be stored at the end of the data, and the given size must
1005 * include the 32 bits of the CRC.
1006 * Return 0 if the checksum is OK, any other value if the data are corrupted
1007 *****************************************************************************/
1008 int CheckCRC32(byte_t* p_data, int i_data_size)
1011 u32 i_crc = 0xffffffff;
1015 for (i = 0; i < i_data_size; i++)
1016 i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]];
1021 /*****************************************************************************
1022 * Is_known: check if a given section has already been received
1023 *****************************************************************************
1024 * As a table cannot be segmented into more than 256 sections, we store a 256
1025 * bits long table, each bit set to one indicating that the corresponding
1026 * saction has been received
1027 *****************************************************************************/
1028 boolean_t Is_known( byte_t* a_known_section, u8 i_section )
1031 boolean_t b_is_known;
1033 /* Where to get the information ? */
1034 int i_bit_in_byte = i_section % 8;
1035 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1037 /* Build mask to read the Is_known flag */
1038 mask = 0x01 << i_bit_in_byte;
1041 b_is_known = a_known_section[i_byte_in_table] & mask;
1046 /*****************************************************************************
1047 * Set_known: mark a given section has having been received
1048 *****************************************************************************
1050 *****************************************************************************/
1051 static void Set_known( byte_t* a_known_section, u8 i_section )
1055 /* Where to get the information ? */
1056 int i_bit_in_byte = i_section % 8;
1057 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1059 /* Build mask to read the Is_known flag */
1060 mask = 0x01 << i_bit_in_byte;
1063 a_known_section[i_byte_in_table] |= mask;
1066 /*****************************************************************************
1067 * Unset_known: remove the 'received' mark for a given section
1068 *****************************************************************************
1070 *****************************************************************************/
1071 static void Unset_known( byte_t* a_known_section, u8 i_section )
1075 /* Where to get the information ? */
1076 int i_bit_in_byte = i_section % 8;
1077 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1079 /* Build mask to read the Is_known flag */
1080 mask = 0x01 << i_bit_in_byte;
1083 /* Unset the flag */
1084 a_known_section[i_byte_in_table] &= mask;
1087 /*****************************************************************************
1088 * AddStreamDescr: add and init the stream descriptor of the given input
1089 *****************************************************************************
1091 *****************************************************************************/
1092 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
1097 intf_DbgMsg("Adding description for stream %d\n", i_stream_id);
1099 p_input->p_stream = malloc( sizeof(stream_descriptor_t) );
1101 p_input->p_stream->i_stream_id = i_stream_id;
1103 p_input->p_stream->i_PAT_version = PSI_UNINITIALISED;
1104 p_input->p_stream->i_known_PAT_sections = 0;
1105 bzero( p_input->p_stream->a_known_PAT_sections,
1106 sizeof(*p_input->p_stream->a_known_PAT_sections) );
1107 p_input->p_stream->b_is_PAT_complete = 0;
1109 p_input->p_stream->i_known_PMT_sections = 0;
1110 bzero( p_input->p_stream->a_known_PMT_sections,
1111 sizeof(*p_input->p_stream->a_known_PMT_sections) );
1112 p_input->p_stream->b_is_PMT_complete = 0;
1114 #ifdef DVB_EXTENSIONS
1115 p_input->p_stream->i_SDT_version = PSI_UNINITIALISED;
1116 p_input->p_stream->i_known_SDT_sections = 0;
1117 bzero( p_input->p_stream->a_known_SDT_sections,
1118 sizeof(*p_input->p_stream->a_known_SDT_sections) );
1119 p_input->p_stream->b_is_SDT_complete = 0;
1122 p_input->p_stream->i_pgrm_number = 0;
1123 p_input->p_stream->ap_programs = NULL;
1125 return p_input->p_stream;
1128 /*****************************************************************************
1129 * DestroyStreamDescr: destroy the stream desciptor of the given input
1130 *****************************************************************************
1132 *****************************************************************************/
1133 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1139 /* Free the structures that describes the programs of that stream */
1140 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
1142 DestroyPgrmDescr( p_input, p_input->p_stream,
1143 p_input->p_stream->ap_programs[i_index]->i_number );
1146 /* Free the table of pgrm descriptors */
1147 free( p_input->p_stream->ap_programs );
1149 /* Free the structure that describes the stream itself */
1150 free( p_input->p_stream );
1152 /* Input thread has no more stream descriptor */
1153 p_input->p_stream = NULL;
1156 /*****************************************************************************
1157 * AddPgrmDescr: add and init a program descriptor
1158 *****************************************************************************
1159 * This program descriptor will be referenced in the given stream descriptor
1160 *****************************************************************************/
1161 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
1164 int i_pgrm_index = p_stream->i_pgrm_number; /* Where to add the pgrm */
1168 intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
1170 /* Add an entry to the list of program associated with the stream */
1171 p_stream->i_pgrm_number++;
1172 p_stream->ap_programs = realloc( p_stream->ap_programs,
1173 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
1175 /* Allocate the structure to store this description */
1176 p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t));
1178 /* Init this entry */
1179 p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id;
1180 p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED;
1181 p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0;
1183 p_stream->ap_programs[i_pgrm_index]->i_es_number = 0;
1184 p_stream->ap_programs[i_pgrm_index]->ap_es = NULL;
1186 /* descriptors ? XXX?? */
1188 return p_stream->ap_programs[i_pgrm_index];
1191 /*****************************************************************************
1192 * AddPgrmDescr: destroy a program descriptor
1193 *****************************************************************************
1194 * All ES descriptions referenced in the descriptor will be deleted.
1195 *****************************************************************************/
1196 static void DestroyPgrmDescr( input_thread_t * p_input,
1197 stream_descriptor_t * p_stream, u16 i_pgrm_id )
1199 int i_index, i_pgrm_index = -1;
1200 pgrm_descriptor_t* p_pgrm = NULL;
1204 intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id);
1206 /* Find where this program is described */
1207 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
1209 if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id )
1211 i_pgrm_index = i_index;
1212 p_pgrm = p_stream->ap_programs[ i_pgrm_index ];
1217 /* Make sure that the pgrm exists */
1218 ASSERT(i_pgrm_index >= 0);
1221 /* Free the structures that describe the es that belongs to that program */
1222 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
1224 DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id );
1227 /* Free the table of es descriptors */
1228 free( p_pgrm->ap_es );
1230 /* Free the description of this stream */
1233 /* Remove this program from the stream's list of programs */
1234 p_stream->i_pgrm_number--;
1235 p_stream->ap_programs[i_pgrm_index] =
1236 p_stream->ap_programs[p_stream->i_pgrm_number];
1237 p_stream->ap_programs = realloc( p_stream->ap_programs,
1238 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );
1241 /*****************************************************************************
1243 *****************************************************************************
1244 * Reserve a slot in the table of ES descritors for the ES and add it to the
1245 * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand
1247 *****************************************************************************/
1248 static es_descriptor_t* AddESDescr(input_thread_t* p_input,
1249 pgrm_descriptor_t* p_pgrm, u16 i_es_pid)
1252 es_descriptor_t* p_es = NULL;
1256 intf_DbgMsg("Adding description for ES %d\n", i_es_pid);
1258 /* Find an empty slot to store the description of that es */
1259 for( i_index = 0; i_index < INPUT_MAX_ES &&
1260 p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ );
1262 if( i_index >= INPUT_MAX_ES )
1264 /* No slot is empty */
1265 intf_ErrMsg("Stream carries to many PID for our decoder\n");
1269 /* Reserve the slot for that ES */
1270 p_es = &p_input->p_es[i_index];
1271 p_es->i_id = i_es_pid;
1272 intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid);
1274 /* Init its values */
1275 p_es->i_type = 0; /* XXX?? */
1278 p_es->i_continuity_counter = 0xFF;
1280 p_es->p_pes_packet = NULL;
1281 // p_es->p_next_pes_packet = NULL;
1284 /* Add this ES to the program definition if one is given */
1287 p_pgrm->i_es_number++;
1288 p_pgrm->ap_es = realloc( p_pgrm->ap_es,
1289 p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
1290 p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
1291 intf_DbgMsg( "Added ES %d to definition of pgrm %d\n",
1292 i_es_pid, p_pgrm->i_number );
1295 intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n",
1302 /*****************************************************************************
1304 *****************************************************************************
1306 *****************************************************************************/
1307 static void DestroyESDescr(input_thread_t* p_input,
1308 pgrm_descriptor_t* p_pgrm, u16 i_pid)
1312 /* Look for the description of the ES */
1313 for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
1315 if( p_input->p_es[i_index].i_id == i_pid )
1317 /* The table of stream descriptors is static, so don't free memory
1318 but just mark the slot as unused */
1319 p_input->p_es[i_index].i_id = EMPTY_PID;
1324 /* Remove this ES from the description of the program if it is associated to
1328 for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
1330 if( p_input->p_es[i_index].i_id == i_pid )
1332 p_pgrm->i_es_number--;
1333 p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number];
1334 p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number);