1 /*****************************************************************************
2 * psi.c: PSI management
3 * Manages structures containing PSI information, and affiliated decoders.
4 * TODO: Fonctions d'init des structures
5 *****************************************************************************
6 * Copyright (C) 1999, 2000 VideoLAN
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
29 #include <sys/types.h> /* on BSD, uio.h needs types.h */
30 #include <sys/uio.h> /* "input.h" */
31 #include <stdlib.h> /* free(), realloc() */
32 #include <string.h> /* bzero() */
33 #include <netinet/in.h> /* ntohs() */
43 #include "input_ctrl.h"
44 #include "input_psi.h"
49 * Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
51 boolean_t b_crc_initialised = 0;
52 u32 i_crc_32_table[256];
55 * Global configuration variable, need by AUTO_SPAWN to determine
56 * the option (audio and video) passed to the VideoLAN client.
59 //XXX?? extern program_data_t *p_main;
63 * Locale type definitions
65 #define PSI_VIDEO_STREAM_DESCRIPTOR 0x02
66 #define PSI_AUDIO_STREAM_DESCRIPTOR 0x03
67 #define PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR 0x07
68 #define PSI_VIDEO_WINDOW_DESCRIPTOR 0x08
71 #define PSI_SERVICE_DESCRIPTOR 0x48
74 /* That info must be stored in the version field since it contains
76 #define PSI_UNINITIALISED 0xFF
81 static int input_AddPsiPID( input_thread_t *p_input, int i_pid );
82 static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
83 static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
84 static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
85 static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
86 static void DecodePgrmDescriptor( byte_t* p_descr, pgrm_descriptor_t* p_pgrm );
87 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
89 static stream_descriptor_t* AddStreamDescr( input_thread_t* p_input,
91 static void DestroyStreamDescr( input_thread_t* p_input, u16 i_stream_id );
92 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
94 static void DestroyPgrmDescr( input_thread_t* p_input,
95 stream_descriptor_t* p_stream, u16 i_pgrm_id );
96 static es_descriptor_t* AddESDescr( input_thread_t* p_input,
97 pgrm_descriptor_t* p_pgrm, u16 i_es_pid );
98 static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
101 static void BuildCrc32Table();
102 static int CheckCRC32( u8* p_pms, int i_size);
103 static boolean_t Is_known( byte_t* a_known_section, u8 i_section );
104 static void Set_known( byte_t* a_known_section, u8 i_section );
105 static void Unset_known( byte_t* a_known_section, u8 i_section );
107 /*****************************************************************************
108 * input_PsiInit: Initialize PSI decoder
109 *****************************************************************************
110 * Init the structures in which the PSI decoder will put the informations it
111 * got from PSI tables and request for the reception of the PAT.
112 *****************************************************************************/
113 int input_PsiInit( input_thread_t *p_input )
117 /* Precalculate the 32-bit CRC table if not already done ?
118 FIXME: Put a lock or do that at pgrm init ?? */
119 if( !b_crc_initialised )
122 b_crc_initialised = 1;
125 /* Init the structure that describes the stream we are receiving */
126 AddStreamDescr( p_input, PSI_UNINITIALISED );
128 /* Request for reception of the program association table */
129 input_AddPsiPID( p_input, 0 );
131 #ifdef DVB_EXTENSIONS
132 /* Request for reception of the service description table */
133 input_AddPsiPID( p_input, 17 );
139 /*****************************************************************************
140 * input_PsiClean: Clean PSI structures before dying
141 *****************************************************************************/
142 int input_PsiEnd( input_thread_t *p_input )
146 /* Stop to receive all the PSI tables associated with that program */
147 /* FIXME: Not really useful ??*/
149 /* Clean also descriptors for programs associated with that stream */
150 /* FIXME: -> Not really useful and maybe buggy ??*/
152 /* Destroy the stream description */
153 DestroyStreamDescr( p_input, p_input->p_stream->i_stream_id );
158 /*****************************************************************************
159 * input_PsiRead: Read the table of programs
160 *****************************************************************************
161 * Ugly debugging function at that time ? XXX??
162 *****************************************************************************/
163 void input_PsiRead( input_thread_t *p_input /* XXX?? */ )
167 pgrm_descriptor_t* p_pgrm;
171 /* Lock the tables, since this method can be called from any thread */
174 /* Check if the table is complete or not */
175 if( !p_input->p_stream->b_is_PMT_complete )
177 intf_IntfMsg( "Warning: PMT not yet complete\n" );
181 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
183 p_pgrm = p_input->p_stream->ap_programs[i_index];
184 intf_DbgMsg("Printing info for program %d\n", p_pgrm->i_number );
185 intf_IntfMsg("Printing info for program %d\n", p_pgrm->i_number );
187 for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ )
189 intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
190 p_pgrm->ap_es[i_index2]->i_id,
191 p_pgrm->ap_es[i_index2]->i_type,
192 p_pgrm->ap_es[i_index2]->b_pcr,
193 p_pgrm->ap_es[i_index2]->b_psi);
195 intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
196 p_pgrm->ap_es[i_index2]->i_id,
197 p_pgrm->ap_es[i_index2]->i_type,
198 p_pgrm->ap_es[i_index2]->b_pcr,
199 p_pgrm->ap_es[i_index2]->b_psi);
203 /* Unock the tables */
207 /*****************************************************************************
208 * input_PsiDecode: Decode a PSI section
209 *****************************************************************************
210 * This funtion is essentially a wrapper that will perform basic checks on
211 * the section and then call the right function according to its type.
212 *****************************************************************************/
213 void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
216 ASSERT(p_psi_section);
218 /* Hexa dump of the beginning of the section (for real men) */
219 //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] );
221 /* Check the CRC validity if any CRC is carried */
223 if( p_psi_section->buffer[1] & 0x80 )
225 if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
227 intf_DbgMsg("iSize: %d, CRC: %d\n", p_psi_section->i_length,
228 U32_AT(&p_psi_section->buffer[p_psi_section->i_length-4]));
229 intf_DbgMsg( "Invalid CRC for PSI\n" );
235 /* If the section is not immediatly applicable, trash it (DVB drafts disallow
236 transmission of such sections, so we didn't implement it) */
237 if( !p_psi_section->buffer[5] & 0x01 )
239 intf_DbgMsg( "PSI not yet applicable: trash it\n" );
243 /* Handle the packet according to it's type given it the table_id */
244 switch ( p_psi_section->buffer[0] )
247 //intf_DbgMsg("Program association section received\n");
248 DecodePgrmAssocSection(p_psi_section->buffer, p_input);
251 //intf_DbgMsg("Conditional access section received\n");
254 //intf_DbgMsg("Program map section received\n");
255 DecodePgrmMapSection(p_psi_section->buffer, p_input);
258 //intf_DbgMsg("Service description section received\n");
259 DecodeSrvDescrSection(p_psi_section->buffer, p_input);
262 //intf_DbgMsg("Private PSI data received (type %x), ignoring it\n",
263 // p_psi_section->buffer[0]);
267 /*****************************************************************************
268 * DecodeAssocSection: Decode a PAS
269 *****************************************************************************
270 * No check is made to known if the table is currently applicable or not, so
271 * that unapplicable sections must be filtered before calling this function
272 * The Program Association Table can be segmented to occupy multiple sections
273 * so that we have to know which sections we have already received (IsKnown() /
275 *****************************************************************************/
276 static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
278 u8 i_stream_id; /* Id of the stream described in that section */
279 u8 i_version; /* Version of the table carried in the section */
281 u16 i_pgrm_id; /* Id of the current described pgrm */
282 u16 i_pgrm_map_pid; /* PID of the associated program map table */
283 int i_pgrm_number; /* Number of programs described in the section */
285 boolean_t b_is_invalid = 0;
287 u8 i_current_section;
296 #define p_descr (p_input->p_stream)
298 /* Read stream id and version number immediately, to be sure they will be
299 initialised in all cases we will need it */
300 i_stream_id = U16_AT(&p_pas[3]);
301 i_version = (p_pas[5] >> 1) & 0x1F;
302 //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
304 /* Test if the stream has not changed by looking at the stream_id */
305 if( p_descr->i_stream_id != i_stream_id )
307 /* This can either mean that the PSI decoder has just started or that
308 the stream has changed */
309 if( p_descr->i_PAT_version== PSI_UNINITIALISED )
310 intf_DbgMsg("Building Program Association table\n");
312 intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
314 /* Whatever it is, ask the PSI decoder to rebuild the table */
319 /* Stream has not changed, test if the PMT is up to date */
320 if( p_descr->i_PAT_version != i_version )
322 intf_DbgMsg("PAT has been updated, rebuilding it\n");
323 /* Ask the PSI decoder to rebuild the table */
328 /* Clear the table if needed */
331 intf_DbgMsg("Updating PAT table\n");
333 /* Any program in the stream may have disapeared, or a new one
334 can have been added. The good way to handle such a case would be
335 to build a temporary table and to make a diff */
337 /* Stop the reception of all programs and PSI informations
338 associated with this stream, excepted the PAT on PID 0 and the SDT
340 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES &&
341 p_input->pp_selected_es[i_es_index]; i_es_index++ )
343 if( p_input->pp_selected_es[i_es_index]->b_psi )
345 if( p_input->pp_selected_es[i_es_index]->i_id != 0
346 #ifdef DVB_EXTENSIONS
347 && p_input->pp_selected_es[i_es_index]->i_id != 17
350 input_DelPsiPID( p_input,
351 p_input->pp_selected_es[i_es_index]->i_id );
354 input_DelPgrmElem( p_input,
355 p_input->pp_selected_es[i_es_index]->i_id );
358 /* Recreate a new stream description. Since it is virgin, the decoder
359 will rebuild it entirely on is own */
360 DestroyStreamDescr(p_input, p_descr->i_stream_id);
361 AddStreamDescr(p_input, i_stream_id);
363 /* Record the new version for that table */
364 p_descr->i_PAT_version = i_version;
367 /* Build the table if not already complete or if it was cleared */
368 if( p_descr->b_is_PAT_complete )
372 intf_DbgMsg("Bug: table invalid but PAT said to be complete\n");
376 /* Check if we already heard about that section */
377 i_last_section = p_pas[7];
378 i_current_section = p_pas[6];
380 // intf_DbgMsg( "Section %d (last section %d)\n",
381 // i_current_section, i_last_section );
383 if( Is_known(p_descr->a_known_PAT_sections, i_current_section) )
386 // intf_DbgMsg("Section already received, skipping\n");
390 /* Compute the number of program_map PID carried in this section */
391 i_pgrm_number = ((U16_AT(&p_pas[1]) & 0xFFF) - 9) / 4;
392 intf_DbgMsg("Number of Pgrm in that section: %d\n", i_pgrm_number);
394 /* Start the reception of those program map PID */
395 for( i_pgrm_index = 0; i_pgrm_index < i_pgrm_number; i_pgrm_index++ )
397 i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
398 i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1fff;
399 intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id,
402 /* Check we are not already receiving that pid because it carries
403 info for another program */
404 for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
406 if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
408 intf_DbgMsg("Already receiving pid %d", i_pgrm_map_pid);
409 i_es_index = INPUT_MAX_ES+1;
413 /* Start to receive that PID if we're not already doing it */
414 if( i_es_index <= INPUT_MAX_ES )
415 input_AddPsiPID( p_input, i_pgrm_map_pid );
417 /* Append an entry to the pgrm_descriptor table to later store
418 the description of this program, unless program number is 0
419 (Network information table) */
422 intf_DbgMsg("Adding program %d to the PMT\n", i_pgrm_id);
423 AddPgrmDescr(p_descr, i_pgrm_id);
427 /* We now know the info carried in this section */
428 Set_known(p_descr->a_known_PAT_sections, i_current_section);
430 /* Check if the table is now complete */
431 p_descr->i_known_PAT_sections++;
432 if( p_descr->i_known_PAT_sections >= i_last_section)
433 p_descr->b_is_PAT_complete = 1;
440 /*****************************************************************************
441 * DecodePgrmMapSection: Decode a PMS
442 *****************************************************************************
443 * No check is made to known if the table is currently applicable or not, so
444 * that unapplicable sections must be filtered before calling this function
445 * The Program Map Table can be segmented to occupy multiple sections so that
446 * we have to know which sections we have already received (IsKnown() /
448 * Note that the processing of those sections is different from the one of the
449 * others since here a section refers to a single program, and a program cannot
450 * be segmented into multiple sections
451 *****************************************************************************/
452 static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
454 u16 i_pgrm_number; /* Id of the program described in that section */
455 u8 i_version; /* Version of the description for that program */
458 u16 i_section_length;
462 u8 i_current_section;
470 pgrm_descriptor_t* p_pgrm;
471 es_descriptor_t* p_es;
473 #define p_descr (p_input->p_stream)
475 /* Read the id of the program described in that section */
476 i_pgrm_number = U16_AT(&p_pms[3]);
477 // intf_DbgMsg( "PMT section received for program %d\n", i_pgrm_number );
479 /* Find where is stored the description of this program */
480 for( i_index = 0; i_index < p_descr->i_pgrm_number &&
481 i_pgrm_number != p_descr->ap_programs[i_index]->i_number; i_index++ );
483 if( i_index >= p_descr->i_pgrm_number )
485 /* If none entry exists, this simply means that the PAT is not complete,
486 so skip this section since it is the responsability of the PAT decoder
487 to add pgrm_descriptor slots to the table of known pgrms */
488 intf_DbgMsg( "Unknown pgrm %d: skipping its description\n", i_pgrm_number );
492 /* We now have the slot which is the program described: we can begin with
493 the decoding of its description */
494 p_pgrm = p_descr->ap_programs[i_index];
496 /* Which section of the description of that program did we receive ? */
497 i_last_section = p_pms[7];
498 i_current_section = p_pms[6];
499 // intf_DbgMsg("Section %d (last section %d)\n", i_current_section, i_last_section);
501 /* Is this an update of the description for this program ? */
502 i_version = (p_pms[5] >> 1) & 0x1F;
503 if( p_pgrm->i_version != i_version )
505 intf_DbgMsg("Updating PMT for program %d\n", i_pgrm_number);
507 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
509 /* Stop the reception of the ES if needed by calling the function
510 normally used by the interface to manage this */
511 if( input_IsElemRecv(p_input, p_pgrm->ap_es[i_index]->i_id) )
513 intf_DbgMsg( "PID %d is no more valid: stopping its reception\n",
514 p_pgrm->ap_es[i_index]->i_id );
515 input_DelPgrmElem( p_input, p_pgrm->ap_es[i_index]->i_id );
518 /* Remove the descriptor associated to the es of this programs */
519 intf_DbgMsg( "Invalidating PID %d\n", p_pgrm->ap_es[i_index]->i_id );
520 DestroyESDescr(p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id);
523 /* Update version number */
524 p_pgrm->i_version = i_version;
526 /* Ask the decoder to update the description of that program */
527 p_descr->i_known_PMT_sections--;
528 Unset_known( p_descr->a_known_PMT_sections, i_current_section );
532 /* Read the info for that pgrm is the one we have is not up to date or
533 if we don't have any */
534 if( p_pgrm->b_is_ok )
537 // intf_DbgMsg("Program description OK, nothing to do\n");
541 /* Check if we already heard about that section */
542 if( Is_known(p_descr->a_known_PMT_sections, i_current_section) )
545 // intf_DbgMsg("Section already received, skipping\n");
549 /* Read the corresponding PCR */
550 p_pgrm->i_pcr_pid = U16_AT(&p_pms[8]) & 0x1fff;
551 intf_DbgMsg("PCR at PID: %d\n", p_pgrm->i_pcr_pid);
553 /* Compute the length of the section minus the final CRC */
554 i_section_length = (U16_AT(&p_pms[1]) & 0xfff) + 3 - 4;
555 intf_DbgMsg("Section length (without CRC): %d\n", i_section_length);
557 /* Read additional info stored in the descriptors if any */
558 intf_DbgMsg("Description length for program %d: %d\n",
559 p_pgrm->i_number, (U16_AT(&p_pms[10]) & 0x0fff));
560 i_descr_end = (U16_AT(&p_pms[10]) & 0x0fff) + 12;
561 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
564 while( i_offset < i_descr_end )
566 DecodePgrmDescriptor(&p_pms[i_offset], p_pgrm);
567 i_offset += p_pms[i_offset+1] + 2;
570 /* Read all the ES descriptions */
571 while( i_offset < i_section_length )
573 /* Read type of that ES */
574 intf_DbgMsg("ES Type: %d\n", p_pms[i_offset]);
576 /* Read PID of that ES */
577 i_es_pid = U16_AT(&p_pms[i_offset+1]) & 0x1fff;
578 intf_DbgMsg("ES PID: %d\n", i_es_pid);
580 /* Add the ES to the program description and reserve a slot in the
581 table of ES to store its description */
582 p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
585 intf_ErrMsg("Warning: definition for pgrm %d won't be complete\n",
587 /* The best way to handle this is to stop decoding the info for
588 that section but do as if everything is ok. Thus we will
589 eventually have an uncomplete ES table marked as being
590 complete and some error msgs */
595 /* Store the description of that PID in the slot */
596 p_es->i_type = p_pms[i_offset];
598 if( i_es_pid == p_pgrm->i_pcr_pid )
603 /* Read additional info given by the descriptors */
605 intf_DbgMsg("description length for PID %d: %d\n", p_es->i_id,
606 (U16_AT(&p_pms[i_offset-2]) & 0x0fff));
607 i_descr_end = (U16_AT(&p_pms[i_offset-2]) & 0x0fff) + i_offset;
608 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
609 while( i_offset < i_descr_end )
611 DecodeESDescriptor(&p_pms[i_offset], p_es);
612 i_offset += p_pms[i_offset+1] + 2;
616 /* Jump to next ES description */
619 /* We now know the info carried in this section */
620 intf_DbgMsg("Description of program %d complete\n", p_pgrm->i_number);
622 Set_known(p_descr->a_known_PMT_sections, i_current_section);
624 /* Check if the PMT is now complete */
625 p_descr->i_known_PMT_sections++;
626 if( p_descr->i_known_PMT_sections >= i_last_section)
628 p_descr->b_is_PMT_complete = 1;
631 /* Spawn an audio and a video thread, if possible. */
632 for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
634 switch( p_input->p_es[i_es_loop].i_type )
638 if( p_main->b_video )
640 /* Spawn a video thread */
641 input_AddPgrmElem( p_input,
642 p_input->p_es[i_es_loop].i_id );
647 if ( p_main->b_audio )
649 /* Spawn an ac3 thread */
650 input_AddPgrmElem( p_input,
651 p_input->p_es[i_es_loop].i_id );
656 if ( p_main->b_video )
658 /* Spawn a spu decoder thread */
659 input_AddPgrmElem( p_input,
660 p_input->p_es[i_es_loop].i_id );
666 if( p_main->b_audio )
668 /* Spawn an audio thread */
669 input_AddPgrmElem( p_input,
670 p_input->p_es[i_es_loop].i_id );
686 /*****************************************************************************
687 * DecodeSrvDescrSection
688 *****************************************************************************
689 * FIXME: A finir et a refaire proprement ??
690 *****************************************************************************/
691 void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
699 boolean_t b_must_update = 0;
706 #define p_stream (p_input->p_stream)
708 /* Read stream id and version number immediately, to be sure they will be
709 initialised in all the cases in which we will need them */
710 i_stream_id = U16_AT(&p_sdt[3]);
711 i_version = (p_sdt[5] >> 1) & 0x1F;
712 intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version);
714 /* Take the descriptor into account only if it describes the streams we are
716 if( p_stream->i_stream_id != i_stream_id )
718 intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n",
723 /* Section applyies to our TS, test if the SDT is up to date */
724 if( p_stream->i_SDT_version != i_version )
726 intf_DbgMsg("SDT has been updated, NOT YET IMPLEMENTED\n");
728 /* Ask the PSI decoder to rebuild the table */
733 /* Rebuild the table if needed */
736 intf_DbgMsg("Updating SDT table\n");
738 i_length = p_sdt[1] & 0x0FFF;
741 while(i_offset < i_length)
744 /* Find the program to which the description applies */
745 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
747 if( p_stream->ap_programs[i_index]->i_number ==
748 U16_AT(&p_sdt[i_offset]) )
751 intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
756 /* Copy the info to the description of that program */
758 intf_DbgMsg("description length for SDT: %d\n",
759 (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF));
760 i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset;
761 intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
762 while( i_offset < i_descr_end )
764 DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]);
765 i_offset += p_sdt[i_offset+1] + 2;
772 /*****************************************************************************
774 *****************************************************************************
775 * Decode any descriptor applying to the definition of a program
776 *****************************************************************************/
777 static void DecodePgrmDescriptor( byte_t* p_descriptor,
778 pgrm_descriptor_t* p_pgrm )
780 u8 i_type; /* Type of the descriptor */
781 u8 i_length; /* Length of the descriptor */
782 #ifdef DVB_EXTENSIONS
783 int i_offset; /* Current position in the descriptor */
786 ASSERT(p_descriptor);
789 /* Read type and length of the descriptor */
790 i_type = p_descriptor[0];
791 i_length = p_descriptor[1];
793 /* Handle specific descriptor info */
796 #ifdef DVB_EXTENSIONS
797 case PSI_SERVICE_DESCRIPTOR:
799 /* Store service type */
800 p_pgrm->i_srv_type = p_descriptor[2];
802 /* Jump to the beginning of the service name */
803 i_offset = p_descriptor[3] + 5;
805 /* Check that the charset used is the normal one (latin) by testing the
806 first byte of the name */
807 if( p_descriptor[i_offset] >= 0x20 )
809 /* The charset is the one of our computer: just dup the string */
810 p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
811 memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset],
812 i_length - i_offset);
813 p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
817 /* Indicate that the name couldn't be printed */
818 p_pgrm->psz_srv_name = "Ununderstandable :)";
824 // intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);
825 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
829 /*****************************************************************************
831 *****************************************************************************
832 * Decode any descriptor applying to the definition of an ES
833 *****************************************************************************/
834 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
836 u8 i_type; /* Type of the descriptor */
837 u8 i_length; /* Length of the descriptor */
838 // int i_offset; /* Current position in the descriptor */
840 ASSERT(p_descriptor);
843 /* Read type and length of the descriptor */
844 i_type = p_descriptor[0];
845 i_length = p_descriptor[1];
849 case PSI_VIDEO_STREAM_DESCRIPTOR:
851 intf_DbgMsg("Video stream descriptor received\n");
854 case PSI_AUDIO_STREAM_DESCRIPTOR:
856 intf_DbgMsg("Audio stream descriptor received\n");
859 case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR:
861 intf_DbgMsg("Target background descriptor received\n");
864 case PSI_VIDEO_WINDOW_DESCRIPTOR:
866 intf_DbgMsg("Video window descriptor received\n");
870 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
871 // intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
875 /*****************************************************************************
876 * input_AddPsiPID: Start to receive the PSI info contained in a PID
877 *****************************************************************************
878 * Add a descriptor to the table of es descriptor for that es and mark the es
879 * as being to be received by the input (since all PSI must be received to
880 * build the description of the program)
881 *****************************************************************************/
882 static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
885 es_descriptor_t* p_psi_es;
888 /* Store the description of this stream in the input thread */
889 p_psi_es = AddESDescr(p_input, NULL, i_pid);
893 /* Precise this ES carries PSI */
896 /* Create the buffer needed by the PSI decoder */
897 p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) );
898 if( !p_psi_es->p_psi_section )
900 intf_ErrMsg( "Malloc error\n" );
905 /* Init the reception for that PID */
906 p_psi_es->p_psi_section->b_running_section = 0;
907 // p_psi_es->p_psi_section->b_discard_payload = 0;
909 /* Ask the input thread to demultiplex it: since the interface
910 can also access the table of selected es, lock the elementary
912 vlc_mutex_lock( &p_input->es_lock );
913 for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ )
915 if( !p_input->pp_selected_es[i_index] )
917 intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n",
919 p_input->pp_selected_es[i_index] = p_psi_es;
923 vlc_mutex_unlock( &p_input->es_lock );
925 if( i_index >= INPUT_MAX_SELECTED_ES )
927 intf_ErrMsg( "Stream carries to many PID for our decoder\n" );
936 /*****************************************************************************
937 * input_DelPsiPID: Stop to receive the PSI info contained in a PID
938 *****************************************************************************
939 * Remove the PID from the list of ES descriptors and from the list of ES that
940 * the input must receive.
941 * Known PID for PSI should always be received, so that their description
942 * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES
943 * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must
945 *****************************************************************************/
946 static int input_DelPsiPID( input_thread_t *p_input, int i_pid )
948 int i_es_index, i_last_sel;
950 intf_DbgMsg( "Deleting PSI PID %d\n", i_pid );
952 /* Stop to receive the ES. Since the interface can also access the table
953 of selected es, lock the elementary stream structure */
954 vlc_mutex_lock( &p_input->es_lock );
956 for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ )
958 if( p_input->pp_selected_es[i_es_index] &&
959 p_input->pp_selected_es[i_es_index]->i_id == i_pid )
961 /* Unmark the stream */
962 p_input->pp_selected_es[i_es_index] = NULL;
964 /* There must not be any gap in the pp_selected_es, so move the last
965 selected stream to this slot */
966 for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] &&
967 i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ );
968 p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel];
969 p_input->pp_selected_es[i_last_sel] = NULL;
974 vlc_mutex_unlock( &p_input->es_lock );
977 /* Check if the pp_selected_es table may be corrupted */
978 if( i_es_index >= INPUT_MAX_PROGRAM_ES )
980 intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid );
984 /* Remove the desription of that ES from the table of ES */
985 DestroyESDescr(p_input, NULL, i_pid);
990 /*****************************************************************************
991 * Precalculate the 32-bit CRC table
992 *****************************************************************************
993 * This table is a global variable shared by all decoders, so it has to be
994 * initialised only once
995 *****************************************************************************/
996 void BuildCrc32Table( )
999 for( i = 0 ; i < 256 ; i++ )
1002 for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
1003 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
1004 i_crc_32_table[i] = k;
1008 /*****************************************************************************
1009 * Test the validity of a checksum
1010 *****************************************************************************
1011 * The checksum must be stored at the end of the data, and the given size must
1012 * include the 32 bits of the CRC.
1013 * Return 0 if the checksum is OK, any other value if the data are corrupted
1014 *****************************************************************************/
1015 int CheckCRC32(byte_t* p_data, int i_data_size)
1018 u32 i_crc = 0xffffffff;
1022 for (i = 0; i < i_data_size; i++)
1023 i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]];
1028 /*****************************************************************************
1029 * Is_known: check if a given section has already been received
1030 *****************************************************************************
1031 * As a table cannot be segmented into more than 256 sections, we store a 256
1032 * bits long table, each bit set to one indicating that the corresponding
1033 * saction has been received
1034 *****************************************************************************/
1035 boolean_t Is_known( byte_t* a_known_section, u8 i_section )
1038 boolean_t b_is_known;
1040 /* Where to get the information ? */
1041 int i_bit_in_byte = i_section % 8;
1042 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1044 /* Build mask to read the Is_known flag */
1045 mask = 0x01 << i_bit_in_byte;
1048 b_is_known = a_known_section[i_byte_in_table] & mask;
1053 /*****************************************************************************
1054 * Set_known: mark a given section has having been received
1055 *****************************************************************************
1057 *****************************************************************************/
1058 static void Set_known( byte_t* a_known_section, u8 i_section )
1062 /* Where to get the information ? */
1063 int i_bit_in_byte = i_section % 8;
1064 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1066 /* Build mask to read the Is_known flag */
1067 mask = 0x01 << i_bit_in_byte;
1070 a_known_section[i_byte_in_table] |= mask;
1073 /*****************************************************************************
1074 * Unset_known: remove the 'received' mark for a given section
1075 *****************************************************************************
1077 *****************************************************************************/
1078 static void Unset_known( byte_t* a_known_section, u8 i_section )
1082 /* Where to get the information ? */
1083 int i_bit_in_byte = i_section % 8;
1084 int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1086 /* Build mask to read the Is_known flag */
1087 mask = 0x01 << i_bit_in_byte;
1090 /* Unset the flag */
1091 a_known_section[i_byte_in_table] &= mask;
1094 /*****************************************************************************
1095 * AddStreamDescr: add and init the stream descriptor of the given input
1096 *****************************************************************************
1098 *****************************************************************************/
1099 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
1104 intf_DbgMsg("Adding description for stream %d\n", i_stream_id);
1106 p_input->p_stream = malloc( sizeof(stream_descriptor_t) );
1108 p_input->p_stream->i_stream_id = i_stream_id;
1110 p_input->p_stream->i_PAT_version = PSI_UNINITIALISED;
1111 p_input->p_stream->i_known_PAT_sections = 0;
1112 bzero( p_input->p_stream->a_known_PAT_sections,
1113 sizeof(*p_input->p_stream->a_known_PAT_sections) );
1114 p_input->p_stream->b_is_PAT_complete = 0;
1116 p_input->p_stream->i_known_PMT_sections = 0;
1117 bzero( p_input->p_stream->a_known_PMT_sections,
1118 sizeof(*p_input->p_stream->a_known_PMT_sections) );
1119 p_input->p_stream->b_is_PMT_complete = 0;
1121 #ifdef DVB_EXTENSIONS
1122 p_input->p_stream->i_SDT_version = PSI_UNINITIALISED;
1123 p_input->p_stream->i_known_SDT_sections = 0;
1124 bzero( p_input->p_stream->a_known_SDT_sections,
1125 sizeof(*p_input->p_stream->a_known_SDT_sections) );
1126 p_input->p_stream->b_is_SDT_complete = 0;
1129 p_input->p_stream->i_pgrm_number = 0;
1130 p_input->p_stream->ap_programs = NULL;
1132 return p_input->p_stream;
1135 /*****************************************************************************
1136 * DestroyStreamDescr: destroy the stream desciptor of the given input
1137 *****************************************************************************
1139 *****************************************************************************/
1140 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1146 /* Free the structures that describes the programs of that stream */
1147 for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
1149 DestroyPgrmDescr( p_input, p_input->p_stream,
1150 p_input->p_stream->ap_programs[i_index]->i_number );
1153 /* Free the table of pgrm descriptors */
1154 free( p_input->p_stream->ap_programs );
1156 /* Free the structure that describes the stream itself */
1157 free( p_input->p_stream );
1159 /* Input thread has no more stream descriptor */
1160 p_input->p_stream = NULL;
1163 /*****************************************************************************
1164 * AddPgrmDescr: add and init a program descriptor
1165 *****************************************************************************
1166 * This program descriptor will be referenced in the given stream descriptor
1167 *****************************************************************************/
1168 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
1171 int i_pgrm_index = p_stream->i_pgrm_number; /* Where to add the pgrm */
1175 intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
1177 /* Add an entry to the list of program associated with the stream */
1178 p_stream->i_pgrm_number++;
1179 p_stream->ap_programs = realloc( p_stream->ap_programs,
1180 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
1182 /* Allocate the structure to store this description */
1183 p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t));
1185 /* Init this entry */
1186 p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id;
1187 p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED;
1188 p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0;
1190 p_stream->ap_programs[i_pgrm_index]->i_es_number = 0;
1191 p_stream->ap_programs[i_pgrm_index]->ap_es = NULL;
1193 /* descriptors ? XXX?? */
1195 return p_stream->ap_programs[i_pgrm_index];
1198 /*****************************************************************************
1199 * AddPgrmDescr: destroy a program descriptor
1200 *****************************************************************************
1201 * All ES descriptions referenced in the descriptor will be deleted.
1202 *****************************************************************************/
1203 static void DestroyPgrmDescr( input_thread_t * p_input,
1204 stream_descriptor_t * p_stream, u16 i_pgrm_id )
1206 int i_index, i_pgrm_index = -1;
1207 pgrm_descriptor_t* p_pgrm = NULL;
1211 intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id);
1213 /* Find where this program is described */
1214 for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
1216 if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id )
1218 i_pgrm_index = i_index;
1219 p_pgrm = p_stream->ap_programs[ i_pgrm_index ];
1224 /* Make sure that the pgrm exists */
1225 ASSERT(i_pgrm_index >= 0);
1228 /* Free the structures that describe the es that belongs to that program */
1229 for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
1231 DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id );
1234 /* Free the table of es descriptors */
1235 free( p_pgrm->ap_es );
1237 /* Free the description of this stream */
1240 /* Remove this program from the stream's list of programs */
1241 p_stream->i_pgrm_number--;
1242 p_stream->ap_programs[i_pgrm_index] =
1243 p_stream->ap_programs[p_stream->i_pgrm_number];
1244 p_stream->ap_programs = realloc( p_stream->ap_programs,
1245 p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );
1248 /*****************************************************************************
1250 *****************************************************************************
1251 * Reserve a slot in the table of ES descritors for the ES and add it to the
1252 * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand
1254 *****************************************************************************/
1255 static es_descriptor_t* AddESDescr(input_thread_t* p_input,
1256 pgrm_descriptor_t* p_pgrm, u16 i_es_pid)
1259 es_descriptor_t* p_es = NULL;
1263 intf_DbgMsg("Adding description for ES %d\n", i_es_pid);
1265 /* Find an empty slot to store the description of that es */
1266 for( i_index = 0; i_index < INPUT_MAX_ES &&
1267 p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ );
1269 if( i_index >= INPUT_MAX_ES )
1271 /* No slot is empty */
1272 intf_ErrMsg("Stream carries to many PID for our decoder\n");
1276 /* Reserve the slot for that ES */
1277 p_es = &p_input->p_es[i_index];
1278 p_es->i_id = i_es_pid;
1279 intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid);
1281 /* Init its values */
1282 p_es->i_type = 0; /* XXX?? */
1285 p_es->i_continuity_counter = 0xFF;
1287 p_es->p_pes_packet = NULL;
1288 // p_es->p_next_pes_packet = NULL;
1291 /* Add this ES to the program definition if one is given */
1294 p_pgrm->i_es_number++;
1295 p_pgrm->ap_es = realloc( p_pgrm->ap_es,
1296 p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
1297 p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
1298 intf_DbgMsg( "Added ES %d to definition of pgrm %d\n",
1299 i_es_pid, p_pgrm->i_number );
1302 intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n",
1309 /*****************************************************************************
1311 *****************************************************************************
1313 *****************************************************************************/
1314 static void DestroyESDescr(input_thread_t* p_input,
1315 pgrm_descriptor_t* p_pgrm, u16 i_pid)
1319 /* Look for the description of the ES */
1320 for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
1322 if( p_input->p_es[i_index].i_id == i_pid )
1324 /* The table of stream descriptors is static, so don't free memory
1325 but just mark the slot as unused */
1326 p_input->p_es[i_index].i_id = EMPTY_PID;
1331 /* Remove this ES from the description of the program if it is associated to
1335 for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
1337 if( p_input->p_es[i_index].i_id == i_pid )
1339 p_pgrm->i_es_number--;
1340 p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number];
1341 p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number);