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 *******************************************************************************/
15 #include <sys/uio.h> /* iovec */
16 #include <stdlib.h> /* atoi(), malloc(), free() */
18 #include <netinet/in.h> /* ntohs */
19 #include <sys/soundcard.h>
21 #include <X11/extensions/XShm.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"
38 #include "interface.h"
43 * Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
45 boolean_t b_crc_initialised = 0;
46 u32 i_crc_32_table[256];
49 * Global configuration variable, need by AUTO_SPAWN to determine
50 * the option (audio and video) passed to the VideoLAN client.
53 extern program_data_t *p_program_data;
57 * Locale type definitions
59 #define PSI_VIDEO_STREAM_DESCRIPTOR 0x02
60 #define PSI_AUDIO_STREAM_DESCRIPTOR 0x03
61 #define PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR 0x07
62 #define PSI_VIDEO_WINDOW_DESCRIPTOR 0x08
65 #define PSI_SERVICE_DESCRIPTOR 0x48
68 /* That info must be stored in the version field since it contains
70 #define PSI_UNINITIALISED 0xFF
75 static int input_AddPsiPID( input_thread_t *p_input, int i_pid );
76 static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
77 static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
78 static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
79 static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
80 static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgrm );
81 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
83 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
85 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id);
86 static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream,
88 static void DestroyPgrmDescr(input_thread_t* p_input, 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 TO DO -> 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_PsiClean( input_thread_t *p_input )
139 /* Stop to receive all the PSI tables associated with that program */
140 /* TO DO ??? -> Not really usefull */
142 /* Clean also descriptors for programs associated with that stream */
143 /* TO DO ??? -> Not really usefull 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 ???????
155 ******************************************************************************/
156 void input_PsiRead( input_thread_t *p_input /* ??? */ )
160 pgrm_descriptor_t* p_pgrm;
164 /* Lock the tables, since this method can be called from any thread */
165 //pthread_mutex_lock()
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_Msg("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_Msg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n", p_pgrm->ap_es[i_index2]->i_id,
183 p_pgrm->ap_es[i_index2]->i_type, p_pgrm->ap_es[i_index2]->b_pcr,
184 p_pgrm->ap_es[i_index2]->b_psi);
186 intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n", p_pgrm->ap_es[i_index2]->i_id,
187 p_pgrm->ap_es[i_index2]->i_type, p_pgrm->ap_es[i_index2]->b_pcr,
188 p_pgrm->ap_es[i_index2]->b_psi);
192 /* Unock the tables */
193 //pthread_mutex_unlock()
196 /******************************************************************************
197 * input_PsiDecode: Decode a PSI section
198 ******************************************************************************
199 * This funtion is essentially a wrapper that will perform basic checks on
200 * the section and then call the right function according to its type.
201 ******************************************************************************/
202 void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
205 ASSERT(p_psi_section);
207 /* Hexa dump of the beginning of the section (for real men) */
208 //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] );
210 /* Check the CRC validity if any CRC is carried */
211 if( p_psi_section->buffer[1] & 0x80 )
213 if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
215 intf_DbgMsg("iSize: %d, CRC: %d\n", p_psi_section->i_length,
216 U32_AT(&p_psi_section->buffer[p_psi_section->i_length-4]));
217 intf_DbgMsg( "Invalid CRC for PSI\n" );
222 /* If the section is not immediatly applicable, trash it (DVB drafts disallow
223 transmission of such sections, so we didn't implement it) */
224 if( !p_psi_section->buffer[5] & 0x01 )
226 intf_DbgMsg( "PSI not yet applicable: trash it\n" );
230 /* Handle the packet according to it's type given it the table_id */
231 switch ( p_psi_section->buffer[0] )
234 //intf_DbgMsg("Program association section received\n");
235 DecodePgrmAssocSection(p_psi_section->buffer, p_input);
238 //intf_DbgMsg("Conditional access section received\n");
241 //intf_DbgMsg("Program map section received\n");
242 DecodePgrmMapSection(p_psi_section->buffer, p_input);
245 //intf_DbgMsg("Service description section received\n");
246 DecodeSrvDescrSection(p_psi_section->buffer, p_input);
249 //intf_DbgMsg("Private PSI data received (type %x), ignoring it\n",
250 // p_psi_section->buffer[0]);
254 /******************************************************************************
255 * DecodeAssocSection: Decode a PAS
256 ******************************************************************************
257 * No check is made to known if the table is currently applicable or not, so
258 * that unapplicable sections must be filtered before calling this function
259 * The Program Association Table can be segmented to occupy multiple sections
260 * so that we have to know which sections we have already received (IsKnown() /
262 ******************************************************************************/
263 static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
265 u8 i_stream_id; /* Id of the stream described in that section */
266 u8 i_version; /* Version of the table carried in the section */
268 u16 i_pgrm_id; /* Id of the current described pgrm */
269 u16 i_pgrm_map_pid; /* PID of the associated program map table */
270 int i_pgrm_number; /* Number of programs described in the section */
272 boolean_t b_is_invalid = 0;
274 u8 i_current_section;
283 #define p_descr (p_input->p_stream)
285 /* Read stream id and version number immediately, to be sure they will be
286 initialised in all cases we will need it */
287 i_stream_id = U16_AT(&p_pas[3]);
288 i_version = (p_pas[5] >> 1) & 0x1F;
289 //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
291 /* Test if the stream has not changed by looking at the stream_id */
292 if( p_descr->i_stream_id != i_stream_id )
294 /* This can either mean that the PSI decoder has just started or that
295 the stream has changed */
296 if( p_descr->i_PAT_version== PSI_UNINITIALISED )
297 intf_Msg("Building Program Association table\n");
299 intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
301 /* Whatever it is, ask the PSI decoder to rebuild the table */
306 /* Stream has not changed, test if the PMT is up to date */
307 if( p_descr->i_PAT_version != i_version )
309 intf_Msg("PAT has been updated, rebuilding it\n");
310 /* Ask the PSI decoder to rebuild the table */
315 /* Clear the table if needed */
318 intf_DbgMsg("Updating PAT table\n");
320 /* Any program in the stream may have disapeared, or a new one
321 can have been added. The good way to handle such a case would be
322 to build a temporary table and to make a diff */
324 /* Stop the reception of all programs and PSI informations
325 associated with this stream, excepted the PAT on PID 0 and the SDT
327 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES &&
328 p_input->pp_selected_es[i_es_index]; i_es_index++ )
330 if( p_input->pp_selected_es[i_es_index]->b_psi )
332 if( p_input->pp_selected_es[i_es_index]->i_id != 0
333 #ifdef DVB_EXTENSIONS
334 && p_input->pp_selected_es[i_es_index]->i_id != 17
337 input_DelPsiPID( p_input, p_input->pp_selected_es[i_es_index]->i_id );
340 input_DelPgrmElem( p_input, p_input->pp_selected_es[i_es_index]->i_id );
343 /* Recreate a new stream description. Since it is virgin, the decoder
344 will on is own rebuild it entirely */
345 DestroyStreamDescr(p_input, p_descr->i_stream_id);
346 AddStreamDescr(p_input, i_stream_id);
348 /* Record the new version for that table */
349 p_descr->i_PAT_version = i_version;
352 /* Build the table if not already complete or if it was cleared */
353 if( p_descr->b_is_PAT_complete )
356 //intf_DbgMsg("Table already complete\n");
360 /* Check if we already heard about that section */
361 i_last_section = p_pas[7];
362 i_current_section = p_pas[6];
364 // intf_DbgMsg( "Section %d (last section %d)\n",
365 // i_current_section, i_last_section );
367 if( Is_known(p_descr->a_known_PAT_sections, i_current_section) )
370 // intf_DbgMsg("Section already received, skipping\n");
374 /* Compute the number of program_map PID carried in this section */
375 i_pgrm_number = ((U16_AT(&p_pas[1]) & 0xFFF) - 9) / 4;
376 intf_DbgMsg("Number of Pgrm in that section: %d\n", i_pgrm_number);
378 /* Start the reception of those program map PID */
379 for( i_pgrm_index = 0; i_pgrm_index < i_pgrm_number; i_pgrm_index++ )
381 i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
382 i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1FFF;
383 intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id, i_pgrm_map_pid);
385 /* Check we are not already receiving that pid because it carries info
386 for another program */
387 for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
389 if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
391 intf_DbgMsg("Already receiving pid %d", i_pgrm_map_pid);
392 i_es_index = INPUT_MAX_ES+1;
396 /* Start to receive that PID if we're not already doing it */
397 if( i_es_index <= INPUT_MAX_ES )
398 input_AddPsiPID( p_input, i_pgrm_map_pid );
400 /* Append an entry to the pgrm_descriptor table to later store
401 the description of this program, unless program number is 0
402 (Network information table) */
405 intf_Msg("Adding program %d to the Program Map Table\n", i_pgrm_id);
406 AddPgrmDescr(p_descr, i_pgrm_id);
410 /* We now know the info carried in this section */
411 Set_known(p_descr->a_known_PAT_sections, i_current_section);
413 /* Check if the table is now complete */
414 p_descr->i_known_PAT_sections++;
415 if( p_descr->i_known_PAT_sections >= i_last_section)
416 p_descr->b_is_PAT_complete = 1;
423 /******************************************************************************
424 * DecodePgrmMapSection: Decode a PMS
425 ******************************************************************************
426 * No check is made to known if the table is currently applicable or not, so
427 * that unapplicable sections must be filtered before calling this function
428 * The Program Map Table can be segmented to occupy multiple sections so that
429 * we have to know which sections we have already received (IsKnown() /
431 * Note that the processing of those sections is different from the one of the
432 * others since here a section refers to a single program, and a program cannot
433 * be segmented into multiple sections
434 ******************************************************************************/
435 static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
437 u16 i_pgrm_number; /* Id of the program described in that section */
438 u8 i_version; /* Version of the description for that program */
441 u16 i_section_length;
445 u8 i_current_section;
453 pgrm_descriptor_t* p_pgrm;
454 es_descriptor_t* p_es;
456 #define p_descr (p_input->p_stream)
458 /* Read the id of the program described in that section */
459 i_pgrm_number = U16_AT(&p_pms[3]);
460 // intf_DbgMsg( "PMT section received for program %d\n", i_pgrm_number );
462 /* Find where is stored the description of this program */
463 for( i_index = 0; i_index < p_descr->i_pgrm_number &&
464 i_pgrm_number != p_descr->ap_programs[i_index]->i_number; i_index++ );
466 if( i_index >= p_descr->i_pgrm_number )
468 /* If none entry exists, this simply means that the PAT is not complete,
469 so skip this section since it is the responsability of the PAT decoder
470 to add pgrm_descriptor slots to the table of known pgrms */
471 intf_DbgMsg( "Pgrm %d is unknown: skipping its description\n", i_pgrm_number );
475 /* We now have the slot which is the program described: we can begin with
476 the decoding of its description */
477 p_pgrm = p_descr->ap_programs[i_index];
479 /* Which section of the description of that program did we receive ? */
480 i_last_section = p_pms[7];
481 i_current_section = p_pms[6];
482 // intf_DbgMsg("Section %d (last section %d)\n", i_current_section, i_last_section);
484 /* Is this an update of the description for this program ? */
485 i_version = (p_pms[5] >> 1) && 0x1F;
486 if( p_pgrm->i_version != i_version )
488 intf_Msg("Updating PMT for program %d\n", i_pgrm_number);
490 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
492 /* Stop the reception of the ES if needed by calling the function
493 normally used by the interface to manage this */
494 if( input_IsElemRecv(p_input, p_pgrm->ap_es[i_index]->i_id) )
496 intf_Msg( "PID %d is no more valid: stopping its reception\n",
497 p_pgrm->ap_es[i_index]->i_id );
498 input_DelPgrmElem( p_input, p_pgrm->ap_es[i_index]->i_id );
501 /* Remove the descriptor associated to the es of this programs */
502 intf_DbgMsg( "Invalidating PID %d\n", p_pgrm->ap_es[i_index]->i_id );
503 DestroyESDescr(p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id);
506 /* Update version number */
507 p_pgrm->i_version = i_version;
509 /* Ask the decoder to update the description of that program */
510 p_descr->i_known_PMT_sections--;
511 Unset_known( p_descr->a_known_PMT_sections, i_current_section );
515 /* Read the info for that pgrm is the one we have is not up to date or
516 if we don't have any */
517 if( p_pgrm->b_is_ok )
520 // intf_DbgMsg("Program description OK, nothing to do\n");
524 /* Check if we already heard about that section */
525 if( Is_known(p_descr->a_known_PMT_sections, i_current_section) )
528 // intf_DbgMsg("Section already received, skipping\n");
532 /* Read the corresponding PCR */
533 p_pgrm->i_pcr_pid = U16_AT(&p_pms[8]) & 0x1fff;
534 intf_DbgMsg("PCR at PID: %d\n", p_pgrm->i_pcr_pid);
536 /* Compute the length of the section minus the final CRC */
537 i_section_length = (U16_AT(&p_pms[1]) & 0xFFF) + 3 - 4;
538 intf_DbgMsg("Section length (CRC not included): %d\n", i_section_length);
540 /* Read additional info stored in the descriptors if any */
541 intf_DbgMsg("description length for program %d: %d\n", p_pgrm->i_number,
542 (U16_AT(&p_pms[10]) & 0x0FFF));
543 i_descr_end = (U16_AT(&p_pms[10]) & 0x0FFF) + 12;
544 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
547 while( i_offset < i_descr_end )
549 DecodePgrmDescriptor(&p_pms[i_offset], p_pgrm);
550 i_offset += p_pms[i_offset+1] + 2;
553 /* Read all the ES descriptions */
554 while( i_offset < i_section_length )
556 /* Read type of that ES */
557 intf_DbgMsg("ES Type: %d\n", p_pms[i_offset]);
559 /* Read PID of that ES */
560 i_es_pid = U16_AT(&p_pms[i_offset+1]) & 0x1FF;
561 intf_DbgMsg("ES PID: %d\n", i_es_pid);
563 /* Add the ES to the program description and reserve a slot in the
564 table of ES to store its description */
565 p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
568 intf_ErrMsg("Warning: definition of program %d will be uncomplete\n",
570 /* The best way to handle this is to stop decoding the info for that
571 section but do as if everything is ok. Thus we will eventually have
572 an uncomplete ES table marked as being 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_Msg("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_program_data->cfg.b_video )
622 /* Spawn a video thread */
623 input_AddPgrmElem( p_input, p_input->p_es[i_es_loop].i_id );
628 if( p_program_data->cfg.b_audio )
630 /* Spawn an audio thread */
631 input_AddPgrmElem( p_input, p_input->p_es[i_es_loop].i_id );
645 /******************************************************************************
646 * DecodeSrvDescrSection
647 ******************************************************************************
648 * A finir et a refaire proprement ????
649 ******************************************************************************/
650 void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
658 boolean_t b_must_update = 0;
665 #define p_stream (p_input->p_stream)
667 /* Read stream id and version number immediately, to be sure they will be
668 initialised in all the cases in which we will need them */
669 i_stream_id = U16_AT(&p_sdt[3]);
670 i_version = (p_sdt[5] >> 1) & 0x1F;
671 intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version);
673 /* Take the descriptor into account only if it describes the streams we are
675 if( p_stream->i_stream_id != i_stream_id )
677 intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n",
682 /* Section applyies to our TS, test if the SDT is up to date */
683 if( p_stream->i_SDT_version != i_version )
685 intf_Msg("SDT has been updated, NOT YET IMPLEMENTED\n");
687 /* Ask the PSI decoder to rebuild the table */
692 /* Rebuild the table if needed */
695 intf_DbgMsg("Updating SDT table\n");
697 i_length = p_sdt[1] & 0x0FFF;
700 while(i_offset < i_length)
703 /* Find the program to which the description applies */
704 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
706 if( p_stream->ap_programs[i_index]->i_number == U16_AT(&p_sdt[i_offset]) )
709 intf_Msg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
714 /* Copy the info to the description of that program */
716 intf_DbgMsg("description length for SDT: %d\n",
717 (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF));
718 i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset;
719 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
720 while( i_offset < i_descr_end )
722 DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]);
723 i_offset += p_sdt[i_offset+1] + 2;
730 /******************************************************************************
732 ******************************************************************************
733 * Decode any descriptor applying to the definition of a program
734 ******************************************************************************/
735 static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgrm )
737 u8 i_type; /* Type of the descriptor */
738 u8 i_length; /* Length of the descriptor */
739 #ifdef DVB_EXTENSIONS
740 int i_offset; /* Current position in the descriptor */
743 ASSERT(p_descriptor);
746 /* Read type and length of the descriptor */
747 i_type = p_descriptor[0];
748 i_length = p_descriptor[1];
750 /* Handle specific descriptor info */
753 #ifdef DVB_EXTENSIONS
754 case PSI_SERVICE_DESCRIPTOR:
756 /* Store service type */
757 p_pgrm->i_srv_type = p_descriptor[2];
759 /* Jump to the beginning of the service name */
760 i_offset = p_descriptor[3] + 5;
762 /* Check that the charset used is the normal one (latin) by testing the
763 first byte of the name */
764 if( p_descriptor[i_offset] >= 0x20 )
766 /* The charset is the one of our computer: just manually dup the string */
767 p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
768 memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset], i_length - i_offset);
769 p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
773 /* Indicate that the name couldn't be printed */
774 p_pgrm->psz_srv_name = "Ununderstandable :)";
780 // intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);
781 // intf_Msg("Unhandled ES descriptor received (type: %d)\n", i_type);
785 /******************************************************************************
787 ******************************************************************************
788 * Decode any descriptor applying to the definition of an ES
789 ******************************************************************************/
790 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
792 u8 i_type; /* Type of the descriptor */
793 u8 i_length; /* Length of the descriptor */
794 // int i_offset; /* Current position in the descriptor */
796 ASSERT(p_descriptor);
799 /* Read type and length of the descriptor */
800 i_type = p_descriptor[0];
801 i_length = p_descriptor[1];
805 case PSI_VIDEO_STREAM_DESCRIPTOR:
807 intf_DbgMsg("Video stream descriptor received\n");
810 case PSI_AUDIO_STREAM_DESCRIPTOR:
812 intf_DbgMsg("Audio stream descriptor received\n");
815 case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR:
817 intf_DbgMsg("Target background descriptor received\n");
820 case PSI_VIDEO_WINDOW_DESCRIPTOR:
822 intf_DbgMsg("Video window descriptor received\n");
826 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
827 // intf_Msg("Unhandled ES descriptor received (type: %d)\n", i_type);
831 /******************************************************************************
832 * input_AddPsiPID: Start to receive the PSI info contained in a PID
833 ******************************************************************************
834 * Add a descriptor to the table of es descriptor for that es and mark the es
835 * as being to be received by the input (since all PSI must be received to
836 * build the description of the program)
837 ******************************************************************************/
838 static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
841 es_descriptor_t* p_psi_es;
844 /* Store the description of this stream in the input thread */
845 p_psi_es = AddESDescr(p_input, NULL, i_pid);
849 /* Precise this ES carries PSI */
852 /* Create the buffer needed by the PSI decoder */
853 p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) );
854 if( !p_psi_es->p_psi_section )
856 intf_ErrMsg( "Malloc error\n" );
861 /* Init the reception for that PID */
862 p_psi_es->p_psi_section->b_running_section = 0;
863 // p_psi_es->p_psi_section->b_discard_payload = 0;
865 /* Ask the input thread to demultiplex it: since the interface
866 can also access the table of selected es, lock the elementary
868 pthread_mutex_lock( &p_input->es_lock );
869 for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ )
871 if( !p_input->pp_selected_es[i_index] )
873 intf_DbgMsg( "Free Selected ES slot found at offset %d: Will use it for PID %d\n",
875 p_input->pp_selected_es[i_index] = p_psi_es;
879 pthread_mutex_unlock( &p_input->es_lock );
881 if( i_index >= INPUT_MAX_SELECTED_ES )
883 intf_ErrMsg( "Stream carries to many PID for our decoder\n" );
892 /******************************************************************************
893 * input_DelPsiPID: Stop to receive the PSI info contained in a PID
894 ******************************************************************************
895 * Remove the PID from the list of ES descriptors and from the list of ES that
896 * the input must receive.
897 * Known PID for PSI should always be received, so that their description
898 * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES
899 * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must
901 ******************************************************************************/
902 static int input_DelPsiPID( input_thread_t *p_input, int i_pid )
904 int i_es_index, i_last_sel;
906 intf_DbgMsg( "Deleting PSI PID %d\n", i_pid );
908 /* Stop to receive the ES. Since the interface can also access the table
909 of selected es, lock the elementary stream structure */
910 pthread_mutex_lock( &p_input->es_lock );
912 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ )
914 if( p_input->pp_selected_es[i_es_index] &&
915 p_input->pp_selected_es[i_es_index]->i_id == i_pid )
917 /* Unmark the stream */
918 p_input->pp_selected_es[i_es_index] = NULL;
920 /* There must not be any gap in the pp_selected_es, so move the last
921 selected stream to this slot */
922 for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] &&
923 i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ );
924 p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel];
925 p_input->pp_selected_es[i_last_sel] = NULL;
930 pthread_mutex_unlock( &p_input->es_lock );
933 /* Check if the pp_selected_es table may be corrupted */
934 if( i_es_index >= INPUT_MAX_PROGRAM_ES )
936 intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid );
940 /* Remove the desription of that ES from the table of ES */
941 DestroyESDescr(p_input, NULL, i_pid);
946 /******************************************************************************
947 * Precalculate the 32-bit CRC table
948 ******************************************************************************
949 * This table is a global variable shared by all decoders, so it has to be
950 * initialised only once
951 ******************************************************************************/
952 void BuildCrc32Table( )
955 for( i = 0 ; i < 256 ; i++ )
958 for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
959 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
960 i_crc_32_table[i] = k;
964 /******************************************************************************
965 * Test the validity of a checksum
966 ******************************************************************************
967 * The checksum must be stored at the end of the data, and the given size must
968 * include the 32 bits of the CRC.
969 * Return 0 if the checksum is OK, any other value if the data are corrupted
970 ******************************************************************************/
971 int CheckCRC32(byte_t* p_data, int i_data_size)
974 u32 i_crc = 0xffffffff;
978 for (i = 0; i < i_data_size; i++)
979 i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]];
984 /******************************************************************************
985 * Is_known: check if a given section has already been received
986 ******************************************************************************
987 * As a table cannot be segmented into more than 256 sections, we store a 256
988 * bits long table, each bit set to one indicating that the corresponding
989 * saction has been received
990 ******************************************************************************/
991 boolean_t Is_known( byte_t* a_known_section, u8 i_section )
994 boolean_t b_is_known;
996 /* Where to get the information ? */
997 int i_bit_in_byte = i_section % 8;
998 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1000 /* Build mask to read the Is_known flag */
1001 mask = 0x01 << i_bit_in_byte;
1004 b_is_known = a_known_section[i_byte_in_table] & mask;
1009 /******************************************************************************
1010 * Set_known: mark a given section has having been received
1011 ******************************************************************************
1013 ******************************************************************************/
1014 static void Set_known( byte_t* a_known_section, u8 i_section )
1018 /* Where to get the information ? */
1019 int i_bit_in_byte = i_section % 8;
1020 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1022 /* Build mask to read the Is_known flag */
1023 mask = 0x01 << i_bit_in_byte;
1026 a_known_section[i_byte_in_table] |= mask;
1029 /******************************************************************************
1030 * Unset_known: remove the 'received' mark for a given section
1031 ******************************************************************************
1033 ******************************************************************************/
1034 static void Unset_known( byte_t* a_known_section, u8 i_section )
1038 /* Where to get the information ? */
1039 int i_bit_in_byte = i_section % 8;
1040 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1042 /* Build mask to read the Is_known flag */
1043 mask = 0x01 << i_bit_in_byte;
1046 /* Unset the flag */
1047 a_known_section[i_byte_in_table] &= mask;
1050 /******************************************************************************
1051 * AddStreamDescr: add and init the stream descriptor of the given input
1052 ******************************************************************************
1054 ******************************************************************************/
1055 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1059 intf_DbgMsg("Adding description for stream %d\n", i_stream_id);
1061 p_input->p_stream = malloc( sizeof(stream_descriptor_t) );
1063 p_input->p_stream->i_stream_id = i_stream_id;
1065 p_input->p_stream->i_PAT_version = PSI_UNINITIALISED;
1066 p_input->p_stream->i_known_PAT_sections = 0;
1067 bzero( p_input->p_stream->a_known_PAT_sections,
1068 sizeof(*p_input->p_stream->a_known_PAT_sections) );
1069 p_input->p_stream->b_is_PAT_complete = 0;
1071 p_input->p_stream->i_known_PMT_sections = 0;
1072 bzero( p_input->p_stream->a_known_PMT_sections,
1073 sizeof(*p_input->p_stream->a_known_PMT_sections) );
1074 p_input->p_stream->b_is_PMT_complete = 0;
1076 #ifdef DVB_EXTENSIONS
1077 p_input->p_stream->i_SDT_version = PSI_UNINITIALISED;
1078 p_input->p_stream->i_known_SDT_sections = 0;
1079 bzero( p_input->p_stream->a_known_SDT_sections,
1080 sizeof(*p_input->p_stream->a_known_SDT_sections) );
1081 p_input->p_stream->b_is_SDT_complete = 0;
1084 p_input->p_stream->i_pgrm_number = 0;
1085 p_input->p_stream->ap_programs = NULL;
1087 return p_input->p_stream;
1090 /******************************************************************************
1091 * DestroyStreamDescr: destroy the stream desciptor of the given input
1092 ******************************************************************************
1094 ******************************************************************************/
1095 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1101 /* Free the structures that describes the programs of that stream */
1102 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
1104 DestroyPgrmDescr( p_input, p_input->p_stream, p_input->p_stream->ap_programs[i_index]->i_number );
1107 /* Free the table of pgrm descriptors */
1108 free( p_input->p_stream->ap_programs );
1110 /* Free the structure that describes the stream itself */
1111 free( p_input->p_stream );
1113 /* Input thread has no more stream descriptor */
1114 p_input->p_stream = NULL;
1117 /******************************************************************************
1118 * AddPgrmDescr: add and init a program descriptor
1119 ******************************************************************************
1120 * This program descriptor will be referenced in the given stream descriptor
1121 ******************************************************************************/
1122 static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm_id)
1126 intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
1128 /* Add an entry to the list of program associated with the stream */
1129 p_stream->i_pgrm_number++;
1130 p_stream->ap_programs = realloc( p_stream->ap_programs,
1131 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
1133 /* Allocate the structure to store this description */
1134 p_stream->ap_programs[p_stream->i_pgrm_number-1] = malloc(sizeof(pgrm_descriptor_t));
1136 /* Init this entry */
1137 p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_number = i_pgrm_id;
1138 p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_version = PSI_UNINITIALISED;
1139 p_stream->ap_programs[p_stream->i_pgrm_number-1]->b_is_ok = 0;
1141 p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_es_number = 0;
1142 p_stream->ap_programs[p_stream->i_pgrm_number-1]->ap_es = NULL;
1144 /* descriptors ???? */
1146 return p_stream->ap_programs[p_stream->i_pgrm_number-1];
1149 /******************************************************************************
1150 * AddPgrmDescr: destroy a program descriptor
1151 ******************************************************************************
1152 * All ES descriptions referenced in the descriptor will be deleted.
1153 ******************************************************************************/
1154 static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_stream, u16 i_pgrm_id )
1156 int i_index, i_pgrm_index;
1157 pgrm_descriptor_t * p_pgrm;
1161 /* Find where this program is described */
1162 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
1164 if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id )
1166 i_pgrm_index = i_index;
1167 p_pgrm = p_stream->ap_programs[ i_pgrm_index ];
1172 /* Free the structures that describe the es that belongs to that program */
1173 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
1175 DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id );
1178 /* Free the table of es descriptors */
1179 free( p_pgrm->ap_es );
1181 /* Free the description of this stream */
1184 /* Remove this program from the stream's list of programs */
1185 p_stream->i_pgrm_number--;
1186 p_stream->ap_programs[ i_pgrm_index ] = p_stream->ap_programs[ p_stream->i_pgrm_number ];
1187 p_stream->ap_programs = realloc( p_stream->ap_programs, p_stream->i_pgrm_number * sizeof(pgrm_descriptor_t *) );
1190 /******************************************************************************
1192 ******************************************************************************
1193 * Reserve a slot in the table of ES descritors for the ES and add it to the
1194 * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand
1196 ******************************************************************************/
1197 static es_descriptor_t* AddESDescr(input_thread_t* p_input,
1198 pgrm_descriptor_t* p_pgrm, u16 i_es_pid)
1201 es_descriptor_t* p_es = NULL;
1205 intf_DbgMsg("Adding description for ES %d\n", i_es_pid);
1207 /* Find an empty slot to store the description of that es */
1208 for( i_index = 0; i_index < INPUT_MAX_ES &&
1209 p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ );
1211 if( i_index >= INPUT_MAX_ES )
1213 /* No slot is empty */
1214 intf_ErrMsg("Stream carries to many PID for our decoder\n");
1218 /* Reserve the slot for that ES */
1219 p_es = &p_input->p_es[i_index];
1220 p_es->i_id = i_es_pid;
1221 intf_DbgMsg("Slot %d in p_es table reserved for ES %d\n", i_index, i_es_pid);
1223 /* Init its values */
1224 p_es->i_type = 0; /* ??? */
1228 p_es->p_pes_packet = NULL;
1229 // p_es->p_next_pes_packet = NULL;
1232 /* Add this ES to the program definition if one is given */
1235 p_pgrm->i_es_number++;
1236 p_pgrm->ap_es = realloc( p_pgrm->ap_es, p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
1237 p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
1238 intf_DbgMsg("Added ES %d to definition of pgrm %d\n", i_es_pid, p_pgrm->i_number);
1241 intf_DbgMsg("Added ES %d not added to the definition of any pgrm\n", i_es_pid);
1247 /******************************************************************************
1249 ******************************************************************************
1251 ******************************************************************************/
1252 static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u16 i_pid)
1258 /* Look for the description of the ES */
1259 for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
1261 if( p_input->p_es[i_index].i_id == i_pid )
1263 /* The table of stream descriptors is static, so don't free memory
1264 but just mark the slot as unused */
1265 p_input->p_es[i_index].i_id = EMPTY_PID;
1270 /* Remove this ES from the description of the program if it is associated to
1274 for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
1276 if( p_input->p_es[i_index].i_id == i_pid )
1278 p_pgrm->i_es_number--;
1279 p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number];
1280 p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number);