Changeset 910f40f93c543d78c5c9f3da3f5a5706be98b453

Show
Ignore:
Timestamp:
02/21/01 05:38:59 (8 years ago)
Author:
Henri Fallon <henri@videolan.org>
git-committer:
Henri Fallon <henri@videolan.org> 982730339 +0000
git-parent:

[9584da59d18a95604a43843009bad4e27c9d8226]

git-author:
Henri Fallon <henri@videolan.org> 982730339 +0000
Message:

TS Input :
- Added DemuxPSI, DecodePAT and DecodePMT. Never tested which streams

where PAT or PMT are splitted in more than one section.

- Some TS files still don't work (matrix.ts i.e : no sound ),

others do ... i'll have to investigate.

Todo :
- What if data get unaligned ?
- Write NetworkOpen?
- Try to find why I get no sound on matrix.ts
- Support Stream and program selection.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/mpeg_system.h

    r0935df9 r910f40f  
    44 ***************************************************************************** 
    55 * Copyright (C) 1999, 2000 VideoLAN 
    6  * $Id: mpeg_system.h,v 1.1 2001/02/08 04:43:27 sam Exp $ 
     6 * $Id: mpeg_system.h,v 1.2 2001/02/21 04:38:59 henri Exp $ 
    77 * 
    88 * Authors: 
     
    2929#define PSI_SECTION_SIZE    4096            /* Maximum size of a PSI section */ 
    3030 
     31#define PAT_UNINITIALIZED    (1 << 6) 
     32#define PMT_UNINITIALIZED    (1 << 6) 
     33 
     34#define PSI_IS_PAT          0x00 
     35#define PSI_IS_PMT          0x01 
     36#define UNKNOWN_PSI         0xff 
    3137 
    3238/***************************************************************************** 
     
    4046    byte_t                  buffer[PSI_SECTION_SIZE]; 
    4147 
    42     /* Is there a section being decoded ? */ 
    43     boolean_t               b_running_section; 
     48    u8                      i_section_number; 
     49    u8                      i_last_section_number; 
     50    u8                      i_version_number; 
     51    u16                     i_section_length; 
     52    u16                     i_read_in_section; 
     53     
     54    /* the PSI is complete */ 
     55    boolean_t               b_is_complete; 
     56     
     57    /* packet missed up ? */ 
     58    boolean_t               b_trash; 
    4459 
    45     u16                     i_length; 
    46     u16                     i_current_position; 
     60    /*about sections  */  
     61    boolean_t               b_section_complete; 
     62 
     63    /* where are we currently ? */ 
     64    byte_t                * p_current; 
     65 
    4766} psi_section_t; 
    4867 
     
    5473    boolean_t               b_psi;   /* Does the stream have to be handled by 
    5574                                      *                    the PSI decoder ? */ 
     75 
     76    int                     i_psi_type;  /* There are different types of PSI */ 
     77     
    5678    psi_section_t *         p_psi_section;                    /* PSI packets */ 
    5779 
     
    6688{ 
    6789    u16                     i_pcr_pid;             /* PCR ES, for TS streams */ 
     90    int                     i_pmt_version; 
    6891} pgrm_ts_data_t; 
    6992 
     
    7396typedef struct stream_ts_data_s 
    7497{ 
    75     /* Program Association Table status */ 
    76     u8                      i_PAT_version;                 /* version number */ 
    77     boolean_t               b_is_PAT_complete;      /* Is the PAT complete ? */ 
    78     u8                      i_known_PAT_sections; 
    79                                      /* Number of section we received so far */ 
    80     byte_t                  a_known_PAT_sections[32]; 
    81                                                 /* Already received sections */ 
    82  
    83     /* Program Map Table status */ 
    84     boolean_t               b_is_PMT_complete;      /* Is the PMT complete ? */ 
    85     u8                      i_known_PMT_sections; 
    86                                      /* Number of section we received so far */ 
    87     byte_t                  a_known_PMT_sections[32]; 
    88                                                 /* Already received sections */ 
    89  
    90     /* Service Description Table status */ 
    91     u8                      i_SDT_version;                 /* version number */ 
    92     boolean_t               b_is_SDT_complete;      /* Is the SDT complete ? */ 
    93     u8                      i_known_SDT_sections; 
    94                                      /* Number of section we received so far */ 
    95     byte_t                  a_known_SDT_sections[32]; 
    96                                                 /* Already received sections */ 
     98    int i_pat_version;          /* Current version of the PAT */ 
    9799} stream_ts_data_t; 
    98100 
     
    121123void input_DemuxPS( struct input_thread_s *, struct data_packet_s * ); 
    122124void input_DemuxTS( struct input_thread_s *, struct data_packet_s * ); 
     125void input_DemuxPSI( input_thread_t *, data_packet_t *, es_descriptor_t *,  
     126                     boolean_t, boolean_t ); 
  • plugins/mpeg/input_ts.c

    r583c655 r910f40f  
    33 ***************************************************************************** 
    44 * Copyright (C) 1998, 1999, 2000 VideoLAN 
    5  * $Id: input_ts.c,v 1.5 2001/02/20 07:49:13 sam Exp $ 
     5 * $Id: input_ts.c,v 1.6 2001/02/21 04:38:59 henri Exp $ 
    66 * 
    77 * Authors:  
     
    131131    /* Initialize netlist and TS structures */ 
    132132    thread_ts_data_t    * p_method; 
    133     pgrm_ts_data_t      * p_pgrm_demux; 
    134     es_descriptor_t     * kludge1; 
     133    es_descriptor_t     * p_pat_es; 
     134    es_ts_data_t        * p_demux_data; 
     135    stream_ts_data_t    * p_stream_data; 
    135136 
    136137    /* Initialise structure */ 
     
    160161    input_InitStream( p_input, sizeof( stream_ts_data_t ) ); 
    161162 
    162     /* FIXME : PSIDemux and PSIDecode */ 
    163     /* Add audio and video programs */ 
    164     /* p_input->stream.pp_programs[0] = */ 
    165     input_AddProgram( p_input, 0, sizeof( pgrm_ts_data_t ) ); 
    166     p_pgrm_demux =  
    167         (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data; 
    168     p_pgrm_demux->i_pcr_pid = 0x78; 
    169  
    170     kludge1 = input_AddES( p_input, p_input->stream.pp_programs[0],  
    171                            0x78, sizeof( es_ts_data_t ) ); 
    172  
    173     // kludge 
    174     kludge1->i_type = MPEG2_VIDEO_ES; 
    175  
    176     input_SelectES( p_input, kludge1 ); 
    177  
    178     vlc_mutex_lock( &(p_input->stream.stream_lock) ); 
    179     p_input->stream.pp_programs[0]->b_is_ok = 1; 
    180     vlc_mutex_unlock( &(p_input->stream.stream_lock) ); 
    181  
    182 //debug 
    183 intf_ErrMsg("End of TSINIT");     
     163    /* Init */ 
     164    p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data; 
     165    p_stream_data->i_pat_version = PAT_UNINITIALIZED ; 
     166 
     167    /* We'll have to catch the PAT in order to continue  
     168     * Then the input will catch the PMT and then the others ES 
     169     * The PAT es is indepedent of any program. */ 
     170    p_pat_es = input_AddES( p_input, NULL, 
     171                           0x00, sizeof( es_ts_data_t ) ); 
     172    p_demux_data=(es_ts_data_t *)p_pat_es->p_demux_data; 
     173    p_demux_data->b_psi = 1; 
     174    p_demux_data->i_psi_type = PSI_IS_PAT; 
     175    p_demux_data->p_psi_section = malloc(sizeof(psi_section_t)); 
     176    p_demux_data->p_psi_section->b_is_complete = 1; 
     177     
    184178} 
    185179 
     
    189183static void TSEnd( input_thread_t * p_input ) 
    190184{ 
    191  
     185    es_descriptor_t     * p_pat_es; 
     186     
     187    p_pat_es = input_FindES( p_input, 0x00 ); 
     188 
     189    if( p_pat_es != NULL ) 
     190        input_DelES( p_input, p_pat_es ); 
     191    free(p_input->p_plugin_data); 
    192192} 
    193193 
  • plugins/mpeg/input_ts.h

    r79b4615 r910f40f  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999, 2000 VideoLAN 
    5  * $Id: input_ts.h,v 1.1 2001/02/14 15:58:29 henri Exp $ 
     5 * $Id: input_ts.h,v 1.2 2001/02/21 04:38:59 henri Exp $ 
    66 * 
    77 * Authors: 
     
    2323 
    2424 
    25 // #define NB_DATA 16384  
    26 // #define NB_PES  8192 
    27 #define NB_DATA 17000 
    28 #define NB_PES  9000 
     25#define NB_DATA 16384  
     26#define NB_PES  8192 
    2927 
    30  
     28/* Will be used whne NetworkOpen is ready */ 
    3129typedef struct thread_ts_data_s {  
    3230     
  • src/input/mpeg_system.c

    r33f6628 r910f40f  
    33 ***************************************************************************** 
    44 * Copyright (C) 1998, 1999, 2000 VideoLAN 
    5  * $Id: mpeg_system.c,v 1.37 2001/02/19 19:08:59 massiot Exp $ 
     5 * $Id: mpeg_system.c,v 1.38 2001/02/21 04:38:59 henri Exp $ 
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     
    99 *          Beno�Steiner <benny@via.ecp.fr> 
    1010 *          Samuel Hocevar <sam@via.ecp.fr> 
     11 *          Henri Fallon <henri@via.ecp.fr> 
    1112 * 
    1213 * This program is free software; you can redistribute it and/or modify 
     
    5253 *****************************************************************************/ 
    5354 
     55static void input_DecodePAT( input_thread_t *, es_descriptor_t *); 
     56static void input_DecodePMT( input_thread_t *, es_descriptor_t *); 
    5457 
    5558/* 
     
    888891void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) 
    889892{ 
    890     int                 i_pid, i_dummy; 
     893    u16                 i_pid; 
     894    int                 i_dummy; 
    891895    boolean_t           b_adaptation;         /* Adaptation field is present */ 
    892896    boolean_t           b_payload;                 /* Packet carries payload */ 
     
    894898    boolean_t           b_trash = 0;             /* Is the packet unuseful ? */ 
    895899    boolean_t           b_lost = 0;             /* Was there a packet loss ? */ 
     900    boolean_t           b_psi = 0;                        /* Is this a PSI ? */ 
    896901    es_descriptor_t *   p_es = NULL; 
    897902    es_ts_data_t *      p_es_demux = NULL; 
     
    899904 
    900905    #define p (p_data->p_buffer) 
    901  
    902     //intf_DbgMsg("input debug: TS-demultiplexing packet %p, pid %d", 
    903     //            p_ts_packet, U16_AT(&p[1]) & 0x1fff); 
    904  
     906    
    905907    /* Extract flags values from TS common header. */ 
    906908    i_pid = U16_AT(&p[1]) & 0x1fff; 
     
    912914    vlc_mutex_lock( &p_input->stream.stream_lock ); 
    913915 
    914 // kludge     
    915 if ( i_pid == 0x78 ) 
    916 
    917     p_es = input_FindES( p_input, 0x78 ); 
    918     p_es->i_type = MPEG2_VIDEO_ES; 
    919     if( p_es->p_pes == NULL ) 
    920       intf_ErrMsg("Got p_es . p_es->p_pes == null ? %d",p_es->p_pes == NULL); 
    921 
    922 else 
    923 
    924     p_es = NULL; 
    925     b_trash = 1; 
    926 
    927  
    928      
     916         
     917    p_es= input_FindES( p_input, i_pid ); 
     918     
     919    if( (p_es != NULL) && (p_es->p_demux_data != NULL) ) 
     920    { 
     921        p_es_demux = (es_ts_data_t *)p_es->p_demux_data; 
     922         
     923        if( p_es_demux->b_psi ) 
     924            b_psi = 1; 
     925    } 
     926 
    929927    vlc_mutex_lock( &p_input->stream.control.control_lock ); 
    930     if( p_es == NULL || p_es->p_decoder_fifo == NULL 
    931         || (p_es->b_audio && p_input->stream.control.b_mute) ) 
     928 
     929    if( ( p_es == NULL ) || (p_es->b_audio && p_input->stream.control.b_mute) ) 
    932930    { 
    933931        /* Not selected. Just read the adaptation field for a PCR. */ 
    934932        b_trash = 1; 
    935933    } 
     934    else if( p_es->p_decoder_fifo == NULL  && !b_psi ) 
     935      b_trash =1;  
     936 
    936937    vlc_mutex_unlock( &p_input->stream.control.control_lock ); 
    937938    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
    938939 
    939 // kludge 
    940     if (p_es != NULL ) 
    941     { 
    942      
    943     p_es_demux = (es_ts_data_t *)p_es->p_demux_data; 
    944     p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;  
    945      
    946     p_pgrm_demux->i_pcr_pid = 0x78; 
    947  
    948     if( (p_es->p_decoder_fifo != NULL) || (p_pgrm_demux->i_pcr_pid == i_pid) ) 
    949     { 
     940 
     941    if( ( p_es != NULL ) &&  
     942        ((p_es->p_decoder_fifo != NULL) || b_psi  
     943                                   || (p_pgrm_demux->i_pcr_pid == i_pid) ) ) 
     944    { 
     945        p_es_demux = (es_ts_data_t *)p_es->p_demux_data; 
     946 
     947        if( ! p_es_demux->b_psi ) 
     948        { 
     949            p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;  
     950        } 
     951 
    950952#ifdef STATS 
    951953        p_es->c_packets++; 
     
    10831085        } /* continuity */ 
    10841086    } /* if selected or PCR */ 
    1085  
    1086     } 
    10871087     
    10881088    /* Trash the packet if it has no payload or if it isn't selected */ 
    10891089    if( b_trash ) 
    10901090    { 
    1091          
    10921091        p_input->pf_delete_packet( p_input->p_method_data, p_data ); 
    10931092#ifdef STATS 
     
    10971096    else 
    10981097    { 
    1099         if( p_es_demux->b_psi ) 
    1100         { 
    1101 //debug 
    1102 //printf("DemuxTS : Was a PSI\n"); 
     1098        if( b_psi ) 
     1099        { 
    11031100            /* The payload contains PSI tables */ 
    1104 #if 0 
    1105             /* FIXME ! write the PSI decoder :p */ 
    11061101            input_DemuxPSI( p_input, p_data, p_es, 
    11071102                            b_unit_start, b_lost ); 
    1108 #endif 
     1103 
    11091104        } 
    11101105        else 
     
    11131108            input_GatherPES( p_input, p_data, p_es, b_unit_start, b_lost );  
    11141109        } 
     1110 
    11151111    } 
    11161112 
     
    11181114 
    11191115} 
     1116 
     1117/* 
     1118 * PSI demultiplexing and decoding 
     1119 */ 
     1120 
     1121/***************************************************************************** 
     1122 * DemuxPSI : makes up complete PSI data 
     1123 *****************************************************************************/ 
     1124void input_DemuxPSI( input_thread_t * p_input, data_packet_t * p_data,  
     1125        es_descriptor_t * p_es, boolean_t b_unit_start, boolean_t b_lost ) 
     1126{ 
     1127    es_ts_data_t  * p_demux_data; 
     1128     
     1129    p_demux_data = (es_ts_data_t *)p_es->p_demux_data; 
     1130 
     1131#define p_psi (p_demux_data->p_psi_section) 
     1132#define p (p_data->p_payload_start) 
     1133 
     1134    if( b_unit_start ) 
     1135    { 
     1136        /* unit_start set to 1 -> presence of a pointer field 
     1137         * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */ 
     1138        if( (u8)p[0] != 0x00 ) 
     1139        { 
     1140        /*    intf_WarnMsg( 2, */ 
     1141            intf_ErrMsg( "Non zero pointer field found. Trying to continue" ); 
     1142            p+=(u8)p[0]; 
     1143        } 
     1144        else 
     1145            p++; 
     1146 
     1147        /* This is the begining of a new section */ 
     1148 
     1149        if( ((u8)(p[1]) & 0xc0) != 0x80 )  
     1150        { 
     1151            intf_ErrMsg( "Invalid PSI packet" ); 
     1152            p_psi->b_trash = 1; 
     1153        } 
     1154        else  
     1155        { 
     1156            p_psi->i_section_length = U16_AT(p+1) & 0x0fff; 
     1157            p_psi->b_section_complete = 0; 
     1158            p_psi->i_read_in_section = 0; 
     1159            p_psi->i_section_number = (u8)p[6]; 
     1160 
     1161            if( p_psi->b_is_complete || p_psi->i_section_number == 0 ) 
     1162            { 
     1163                /* This is a new PSI packet */ 
     1164                p_psi->b_is_complete = 0; 
     1165                p_psi->b_trash = 0; 
     1166                p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f; 
     1167                p_psi->i_last_section_number = (u8)p[7]; 
     1168 
     1169                /* We'll write at the begining of the buffer */ 
     1170                p_psi->p_current = p_psi->buffer; 
     1171            } 
     1172            else 
     1173            { 
     1174                if( p_psi->b_section_complete ) 
     1175                { 
     1176                    /* New Section of an already started PSI */ 
     1177                    p_psi->b_section_complete = 0; 
     1178                     
     1179                    if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) ) 
     1180                    { 
     1181                        intf_WarnMsg( 2,"PSI version differs inside same PAT" ); 
     1182                        p_psi->b_trash = 1; 
     1183                    } 
     1184                    if( p_psi->i_section_number + 1 != (u8)p[6] ) 
     1185                    { 
     1186                        intf_WarnMsg( 2,  
     1187                                "PSI Section discontinuity. Packet lost ?"); 
     1188                        p_psi->b_trash = 1; 
     1189                    } 
     1190                    else 
     1191                        p_psi->i_section_number++; 
     1192                } 
     1193                else 
     1194                { 
     1195                    intf_WarnMsg( 2, "Received unexpected new PSI section" ); 
     1196                    p_psi->b_trash = 1; 
     1197                } 
     1198            } 
     1199        } 
     1200    } /* b_unit_start */ 
     1201     
     1202    if( !p_psi->b_trash ) 
     1203    { 
     1204        /* read */ 
     1205        if( (p_data->p_payload_end - p) >= 
     1206            ( p_psi->i_section_length - p_psi->i_read_in_section ) ) 
     1207        { 
     1208            /* The end of the section is in this TS packet */ 
     1209            memcpy( p_psi->p_current, p,  
     1210            (p_psi->i_section_length - p_psi->i_read_in_section) ); 
     1211     
     1212            p_psi->b_section_complete = 1; 
     1213            p_psi->p_current +=  
     1214                (p_psi->i_section_length - p_psi->i_read_in_section); 
     1215                         
     1216            if( p_psi->i_section_number == p_psi->i_last_section_number ) 
     1217            { 
     1218                /* This was the last section of PSI */ 
     1219                p_psi->b_is_complete = 1; 
     1220            } 
     1221        } 
     1222        else 
     1223        { 
     1224            memcpy( p_psi->buffer, p, p_data->p_payload_end - p ); 
     1225            p_psi->i_read_in_section+= p_data->p_payload_end - p; 
     1226 
     1227            p_psi->p_current += p_data->p_payload_end - p; 
     1228        } 
     1229    } 
     1230 
     1231    if ( p_psi->b_is_complete ) 
     1232    { 
     1233        switch( p_demux_data->i_psi_type) 
     1234        { 
     1235            case PSI_IS_PAT: 
     1236                input_DecodePAT( p_input, p_es ); 
     1237                break; 
     1238            case PSI_IS_PMT: 
     1239                input_DecodePMT( p_input, p_es ); 
     1240                break; 
     1241            default: 
     1242                intf_ErrMsg("Received unknown PSI in demuxPSI"); 
     1243        } 
     1244    } 
     1245#undef p_psi     
     1246#undef p 
     1247     
     1248    return ; 
     1249} 
     1250 
     1251/***************************************************************************** 
     1252 * DecodePAT : Decodes Programm association table and deal with it 
     1253 *****************************************************************************/ 
     1254static void input_DecodePAT( input_thread_t * p_input, es_descriptor_t * p_es ) 
     1255{ 
     1256     
     1257    stream_ts_data_t  * p_stream_data; 
     1258    es_ts_data_t      * p_demux_data; 
     1259 
     1260    
     1261    p_demux_data = (es_ts_data_t *)p_es->p_demux_data; 
     1262    p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data; 
     1263     
     1264#define p_psi (p_demux_data->p_psi_section) 
     1265 
     1266    if( p_stream_data->i_pat_version != p_psi->i_version_number ) 
     1267    { 
     1268        /* PAT has changed. We are going to delete all programms and  
     1269         * create new ones. We chose not to only change what was needed 
     1270         * as a PAT change may mean the stream is radically changing and 
     1271         * this is a secure method to avoid krashed */ 
     1272        pgrm_descriptor_t * p_pgrm; 
     1273        es_descriptor_t   * p_current_es; 
     1274        es_ts_data_t      * p_es_demux; 
     1275        pgrm_ts_data_t    * p_pgrm_demux; 
     1276        byte_t            * p_current_data;            
     1277         
     1278        int                 i_section_length,i_program_id,i_pmt_pid; 
     1279        int                 i_loop, i_current_section; 
     1280         
     1281        p_current_data = p_psi->buffer; 
     1282 
     1283 
     1284        for( i_loop = 0; i_loop < p_input->stream.i_pgrm_number; i_loop++ ) 
     1285        { 
     1286            input_DelProgram( p_input, p_input->stream.pp_programs[i_loop] ); 
     1287        } 
     1288         
     1289        do 
     1290        { 
     1291            i_section_length = U16_AT(p_current_data+1) & 0x0fff; 
     1292            i_current_section = (u8)p_current_data[6]; 
     1293     
     1294            for( i_loop = 0; i_loop < (i_section_length-9)/4 ; i_loop++ ) 
     1295            { 
     1296                i_program_id = U16_AT(p_current_data + i_loop*4 + 8); 
     1297                i_pmt_pid = U16_AT( p_current_data + i_loop*4 + 10) & 0x1fff; 
     1298     
     1299                /* If program = 0, we're having info about NIT not PMT */ 
     1300                if( i_program_id ) 
     1301                { 
     1302                    /* Add this program */ 
     1303                    p_pgrm = input_AddProgram( p_input, i_program_id,  
     1304                                               sizeof( pgrm_ts_data_t ) ); 
     1305                    
     1306                    /* whatis the PID of the PMT of this program */ 
     1307                    p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data; 
     1308                    p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED; 
     1309     
     1310                    /* Add the PMT ES to this program */ 
     1311                    p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid, 
     1312                                        sizeof( es_ts_data_t) ); 
     1313                    p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data; 
     1314                    p_es_demux->b_psi = 1; 
     1315                    p_es_demux->i_psi_type = PSI_IS_PMT; 
     1316                     
     1317                    p_es_demux->p_psi_section =  
     1318                                            malloc( sizeof( psi_section_t ) ); 
     1319                    p_es_demux->p_psi_section->b_is_complete = 0; 
     1320                } 
     1321            } 
     1322             
     1323            p_current_data+=3+i_section_length; 
     1324             
     1325        } while( i_current_section < p_psi->i_last_section_number ); 
     1326         
     1327        /* Go to the beginning of the next section*/ 
     1328        p_stream_data->i_pat_version = p_psi->i_version_number; 
     1329 
     1330    } 
     1331#undef p_psi     
     1332 
     1333} 
     1334 
     1335/***************************************************************************** 
     1336 * DecodePMT : decode a given Program Stream Map 
     1337 * *************************************************************************** 
     1338 * When the PMT changes, it may mean a deep change in the stream, and it is 
     1339 * careful to deletes the ES and add them again. If the PMT doesn't change, 
     1340 * there no need to do anything. 
     1341 *****************************************************************************/ 
     1342static void input_DecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) 
     1343{ 
     1344 
     1345    pgrm_ts_data_t            * p_pgrm_data; 
     1346    es_ts_data_t              * p_demux_data; 
     1347 
     1348    p_demux_data = (es_ts_data_t *)p_es->p_demux_data; 
     1349    p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data; 
     1350     
     1351#define p_psi (p_demux_data->p_psi_section) 
     1352 
     1353    if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )  
     1354    { 
     1355        es_descriptor_t   * p_new_es;   
     1356        es_ts_data_t      * p_es_demux; 
     1357        byte_t            * p_current_data, * p_current_section; 
     1358        int                 i_section_length,i_current_section; 
     1359        int                 i_prog_info_length, i_loop; 
     1360        int                 i_es_info_length, i_pid, i_stream_type; 
     1361         
     1362        p_current_section = p_psi->buffer; 
     1363        p_current_data = p_psi->buffer; 
     1364         
     1365        p_pgrm_data->i_pcr_pid = U16_AT(p_current_section + 8) & 0x1fff; 
     1366 
     1367        /* Delete all ES in this program  except the PSI */ 
     1368        for( i_loop=0; i_loop < p_es->p_pgrm->i_es_number; i_loop++ ) 
     1369        { 
     1370            p_es_demux = (es_ts_data_t *) 
     1371                         p_es->p_pgrm->pp_es[i_loop]->p_demux_data; 
     1372            if ( ! p_es_demux->b_psi ) 
     1373            input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] ); 
     1374        } 
     1375 
     1376        /* Then add what we received in this PMT */ 
     1377        do 
     1378        { 
     1379             
     1380            i_section_length = U16_AT(p_current_data+1) & 0x0fff; 
     1381            i_current_section = (u8)p_current_data[6]; 
     1382            i_prog_info_length = U16_AT(p_current_data+10) & 0x0fff; 
     1383 
     1384            /* For the moment we ignore program descriptors */ 
     1385            p_current_data += 12+i_prog_info_length; 
     1386     
     1387            /* The end of the section, before the CRC is at  
     1388             * p_current_section + i_section_length -1 */ 
     1389            while( p_current_data < p_current_section + i_section_length -1 ) 
     1390            { 
     1391                i_stream_type = (int)p_current_data[0]; 
     1392                i_pid = U16_AT( p_current_data + 1 ) & 0x1fff; 
     1393                i_es_info_length = U16_AT( p_current_data + 3 ) & 0x0fff; 
     1394                 
     1395                /* Add this ES to the program */ 
     1396                p_new_es = input_AddES( p_input, p_es->p_pgrm,  
     1397                                        (u16)i_pid, sizeof( es_ts_data_t ) ); 
     1398                p_new_es->i_type = i_stream_type; 
     1399                 
     1400                /* We want to decode */ 
     1401                input_SelectES( p_input, p_new_es ); 
     1402 
     1403                p_current_data += 5 + i_es_info_length; 
     1404            } 
     1405 
     1406            /* Go to the beginning of the next section*/ 
     1407            p_current_data += 3+i_section_length; 
     1408            
     1409            p_current_section+=1; 
     1410             
     1411        } while( i_current_section < p_psi->i_last_section_number ); 
     1412 
     1413        p_pgrm_data->i_pmt_version = p_psi->i_version_number; 
     1414 
     1415    } 
     1416     
     1417#undef p_psi 
     1418}