Changeset 910f40f93c543d78c5c9f3da3f5a5706be98b453
- Timestamp:
- 02/21/01 05:38:59 (8 years ago)
- git-parent:
- Files:
-
- include/mpeg_system.h (modified) (7 diffs)
- plugins/mpeg/input_ts.c (modified) (4 diffs)
- plugins/mpeg/input_ts.h (modified) (2 diffs)
- src/input/mpeg_system.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
include/mpeg_system.h
r0935df9 r910f40f 4 4 ***************************************************************************** 5 5 * Copyright (C) 1999, 2000 VideoLAN 6 * $Id: mpeg_system.h,v 1. 1 2001/02/08 04:43:27 samExp $6 * $Id: mpeg_system.h,v 1.2 2001/02/21 04:38:59 henri Exp $ 7 7 * 8 8 * Authors: … … 29 29 #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */ 30 30 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 31 37 32 38 /***************************************************************************** … … 40 46 byte_t buffer[PSI_SECTION_SIZE]; 41 47 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; 44 59 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 47 66 } psi_section_t; 48 67 … … 54 73 boolean_t b_psi; /* Does the stream have to be handled by 55 74 * the PSI decoder ? */ 75 76 int i_psi_type; /* There are different types of PSI */ 77 56 78 psi_section_t * p_psi_section; /* PSI packets */ 57 79 … … 66 88 { 67 89 u16 i_pcr_pid; /* PCR ES, for TS streams */ 90 int i_pmt_version; 68 91 } pgrm_ts_data_t; 69 92 … … 73 96 typedef struct stream_ts_data_s 74 97 { 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 */ 97 99 } stream_ts_data_t; 98 100 … … 121 123 void input_DemuxPS( struct input_thread_s *, struct data_packet_s * ); 122 124 void input_DemuxTS( struct input_thread_s *, struct data_packet_s * ); 125 void input_DemuxPSI( input_thread_t *, data_packet_t *, es_descriptor_t *, 126 boolean_t, boolean_t ); plugins/mpeg/input_ts.c
r583c655 r910f40f 3 3 ***************************************************************************** 4 4 * Copyright (C) 1998, 1999, 2000 VideoLAN 5 * $Id: input_ts.c,v 1. 5 2001/02/20 07:49:13 samExp $5 * $Id: input_ts.c,v 1.6 2001/02/21 04:38:59 henri Exp $ 6 6 * 7 7 * Authors: … … 131 131 /* Initialize netlist and TS structures */ 132 132 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; 135 136 136 137 /* Initialise structure */ … … 160 161 input_InitStream( p_input, sizeof( stream_ts_data_t ) ); 161 162 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 184 178 } 185 179 … … 189 183 static void TSEnd( input_thread_t * p_input ) 190 184 { 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); 192 192 } 193 193 plugins/mpeg/input_ts.h
r79b4615 r910f40f 3 3 ***************************************************************************** 4 4 * 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 $ 6 6 * 7 7 * Authors: … … 23 23 24 24 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 29 27 30 28 /* Will be used whne NetworkOpen is ready */ 31 29 typedef struct thread_ts_data_s { 32 30 src/input/mpeg_system.c
r33f6628 r910f40f 3 3 ***************************************************************************** 4 4 * Copyright (C) 1998, 1999, 2000 VideoLAN 5 * $Id: mpeg_system.c,v 1.3 7 2001/02/19 19:08:59 massiotExp $5 * $Id: mpeg_system.c,v 1.38 2001/02/21 04:38:59 henri Exp $ 6 6 * 7 7 * Authors: Christophe Massiot <massiot@via.ecp.fr> … … 9 9 * Beno�Steiner <benny@via.ecp.fr> 10 10 * Samuel Hocevar <sam@via.ecp.fr> 11 * Henri Fallon <henri@via.ecp.fr> 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify … … 52 53 *****************************************************************************/ 53 54 55 static void input_DecodePAT( input_thread_t *, es_descriptor_t *); 56 static void input_DecodePMT( input_thread_t *, es_descriptor_t *); 54 57 55 58 /* … … 888 891 void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) 889 892 { 890 int i_pid, i_dummy; 893 u16 i_pid; 894 int i_dummy; 891 895 boolean_t b_adaptation; /* Adaptation field is present */ 892 896 boolean_t b_payload; /* Packet carries payload */ … … 894 898 boolean_t b_trash = 0; /* Is the packet unuseful ? */ 895 899 boolean_t b_lost = 0; /* Was there a packet loss ? */ 900 boolean_t b_psi = 0; /* Is this a PSI ? */ 896 901 es_descriptor_t * p_es = NULL; 897 902 es_ts_data_t * p_es_demux = NULL; … … 899 904 900 905 #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 905 907 /* Extract flags values from TS common header. */ 906 908 i_pid = U16_AT(&p[1]) & 0x1fff; … … 912 914 vlc_mutex_lock( &p_input->stream.stream_lock ); 913 915 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 929 927 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) ) 932 930 { 933 931 /* Not selected. Just read the adaptation field for a PCR. */ 934 932 b_trash = 1; 935 933 } 934 else if( p_es->p_decoder_fifo == NULL && !b_psi ) 935 b_trash =1; 936 936 937 vlc_mutex_unlock( &p_input->stream.control.control_lock ); 937 938 vlc_mutex_unlock( &p_input->stream.stream_lock ); 938 939 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 950 952 #ifdef STATS 951 953 p_es->c_packets++; … … 1083 1085 } /* continuity */ 1084 1086 } /* if selected or PCR */ 1085 1086 }1087 1087 1088 1088 /* Trash the packet if it has no payload or if it isn't selected */ 1089 1089 if( b_trash ) 1090 1090 { 1091 1092 1091 p_input->pf_delete_packet( p_input->p_method_data, p_data ); 1093 1092 #ifdef STATS … … 1097 1096 else 1098 1097 { 1099 if( p_es_demux->b_psi ) 1100 { 1101 //debug 1102 //printf("DemuxTS : Was a PSI\n"); 1098 if( b_psi ) 1099 { 1103 1100 /* The payload contains PSI tables */ 1104 #if 01105 /* FIXME ! write the PSI decoder :p */1106 1101 input_DemuxPSI( p_input, p_data, p_es, 1107 1102 b_unit_start, b_lost ); 1108 #endif 1103 1109 1104 } 1110 1105 else … … 1113 1108 input_GatherPES( p_input, p_data, p_es, b_unit_start, b_lost ); 1114 1109 } 1110 1115 1111 } 1116 1112 … … 1118 1114 1119 1115 } 1116 1117 /* 1118 * PSI demultiplexing and decoding 1119 */ 1120 1121 /***************************************************************************** 1122 * DemuxPSI : makes up complete PSI data 1123 *****************************************************************************/ 1124 void 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 *****************************************************************************/ 1254 static 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 *****************************************************************************/ 1342 static 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 }
