| | 217 | } |
|---|
| | 218 | |
|---|
| | 219 | /***************************************************************************** |
|---|
| | 220 | * Close: frees unused data |
|---|
| | 221 | *****************************************************************************/ |
|---|
| | 222 | static void Close( vlc_object_t *p_this ) |
|---|
| | 223 | { |
|---|
| | 224 | input_thread_t *p_input = (input_thread_t *)p_this; |
|---|
| | 225 | demux_sys_t *p_sys = p_input->p_demux_data ; |
|---|
| | 226 | |
|---|
| | 227 | /* Cleanup the bitstream parser */ |
|---|
| | 228 | ogg_sync_clear( &p_sys->oy ); |
|---|
| | 229 | |
|---|
| | 230 | Ogg_EndOfStream( p_input ); |
|---|
| | 231 | |
|---|
| | 232 | free( p_sys ); |
|---|
| | 233 | } |
|---|
| | 234 | |
|---|
| | 235 | /***************************************************************************** |
|---|
| | 236 | * Demux: reads and demuxes data packets |
|---|
| | 237 | ***************************************************************************** |
|---|
| | 238 | * Returns -1 in case of error, 0 in case of EOF, 1 otherwise |
|---|
| | 239 | *****************************************************************************/ |
|---|
| | 240 | static int Demux( input_thread_t * p_input ) |
|---|
| | 241 | { |
|---|
| | 242 | demux_sys_t *p_sys = p_input->p_demux_data; |
|---|
| | 243 | ogg_page oggpage; |
|---|
| | 244 | ogg_packet oggpacket; |
|---|
| | 245 | int i_stream; |
|---|
| | 246 | |
|---|
| | 247 | |
|---|
| | 248 | if( p_sys->i_eos == p_sys->i_streams ) |
|---|
| | 249 | { |
|---|
| | 250 | if( p_sys->i_eos ) |
|---|
| | 251 | { |
|---|
| | 252 | msg_Dbg( p_input, "end of a group of logical streams" ); |
|---|
| | 253 | Ogg_EndOfStream( p_input ); |
|---|
| | 254 | } |
|---|
| | 255 | |
|---|
| | 256 | if( Ogg_BeginningOfStream( p_input ) != VLC_SUCCESS ) return 0; |
|---|
| | 257 | p_sys->i_eos = 0; |
|---|
| | 258 | |
|---|
| | 259 | msg_Dbg( p_input, "beginning of a group of logical streams" ); |
|---|
| | 260 | es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); |
|---|
| | 261 | } |
|---|
| | 262 | |
|---|
| | 263 | /* |
|---|
| | 264 | * Demux an ogg page from the stream |
|---|
| | 265 | */ |
|---|
| | 266 | if( Ogg_ReadPage( p_input, &oggpage ) != VLC_SUCCESS ) |
|---|
| | 267 | { |
|---|
| | 268 | return 0; /* EOF */ |
|---|
| | 269 | } |
|---|
| | 270 | |
|---|
| | 271 | /* Test for End of Stream */ |
|---|
| | 272 | if( ogg_page_eos( &oggpage ) ) p_sys->i_eos++; |
|---|
| | 273 | |
|---|
| | 274 | |
|---|
| | 275 | for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) |
|---|
| | 276 | { |
|---|
| | 277 | logical_stream_t *p_stream = p_sys->pp_stream[i_stream]; |
|---|
| | 278 | |
|---|
| | 279 | if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 ) |
|---|
| | 280 | continue; |
|---|
| | 281 | |
|---|
| | 282 | while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 ) |
|---|
| | 283 | { |
|---|
| | 284 | /* Read info from any secondary header packets, if there are any */ |
|---|
| | 285 | if( p_stream->secondary_header_packets > 0 ) |
|---|
| | 286 | { |
|---|
| | 287 | if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) && |
|---|
| | 288 | oggpacket.bytes >= 7 && |
|---|
| | 289 | ! strncmp( &oggpacket.packet[1], "theora", 6 ) ) |
|---|
| | 290 | { |
|---|
| | 291 | Ogg_ReadTheoraHeader( p_stream, &oggpacket ); |
|---|
| | 292 | p_stream->secondary_header_packets = 0; |
|---|
| | 293 | } |
|---|
| | 294 | else if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) && |
|---|
| | 295 | oggpacket.bytes >= 7 && |
|---|
| | 296 | ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) ) |
|---|
| | 297 | { |
|---|
| | 298 | Ogg_ReadVorbisHeader( p_stream, &oggpacket ); |
|---|
| | 299 | p_stream->secondary_header_packets = 0; |
|---|
| | 300 | } |
|---|
| | 301 | else if ( p_stream->fmt.i_codec == VLC_FOURCC( 'c','m','m','l' ) ) |
|---|
| | 302 | { |
|---|
| | 303 | p_stream->secondary_header_packets = 0; |
|---|
| | 304 | } |
|---|
| | 305 | |
|---|
| | 306 | p_stream->secondary_header_packets--; |
|---|
| | 307 | } |
|---|
| | 308 | |
|---|
| | 309 | if( p_stream->b_reinit ) |
|---|
| | 310 | { |
|---|
| | 311 | /* If synchro is re-initialized we need to drop all the packets |
|---|
| | 312 | * until we find a new dated one. */ |
|---|
| | 313 | Ogg_UpdatePCR( p_stream, &oggpacket ); |
|---|
| | 314 | |
|---|
| | 315 | if( p_stream->i_pcr >= 0 ) |
|---|
| | 316 | { |
|---|
| | 317 | p_stream->b_reinit = 0; |
|---|
| | 318 | } |
|---|
| | 319 | else |
|---|
| | 320 | { |
|---|
| | 321 | p_stream->i_interpolated_pcr = -1; |
|---|
| | 322 | continue; |
|---|
| | 323 | } |
|---|
| | 324 | |
|---|
| | 325 | /* An Ogg/vorbis packet contains an end date granulepos */ |
|---|
| | 326 | if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) || |
|---|
| | 327 | p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) || |
|---|
| | 328 | p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) ) |
|---|
| | 329 | { |
|---|
| | 330 | if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 ) |
|---|
| | 331 | { |
|---|
| | 332 | Ogg_DecodePacket( p_input, p_stream, &oggpacket ); |
|---|
| | 333 | } |
|---|
| | 334 | else |
|---|
| | 335 | { |
|---|
| | 336 | es_out_Control( p_input->p_es_out, ES_OUT_SET_PCR, p_stream->i_pcr ); |
|---|
| | 337 | } |
|---|
| | 338 | continue; |
|---|
| | 339 | } |
|---|
| | 340 | } |
|---|
| | 341 | |
|---|
| | 342 | Ogg_DecodePacket( p_input, p_stream, &oggpacket ); |
|---|
| | 343 | } |
|---|
| | 344 | break; |
|---|
| | 345 | } |
|---|
| | 346 | |
|---|
| | 347 | i_stream = 0; p_sys->i_pcr = -1; |
|---|
| | 348 | for( ; i_stream < p_sys->i_streams; i_stream++ ) |
|---|
| | 349 | { |
|---|
| | 350 | logical_stream_t *p_stream = p_sys->pp_stream[i_stream]; |
|---|
| | 351 | |
|---|
| | 352 | if( p_stream->fmt.i_cat == SPU_ES ) |
|---|
| | 353 | continue; |
|---|
| | 354 | if( p_stream->i_interpolated_pcr < 0 ) |
|---|
| | 355 | continue; |
|---|
| | 356 | |
|---|
| | 357 | if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr ) |
|---|
| | 358 | p_sys->i_pcr = p_stream->i_interpolated_pcr; |
|---|
| | 359 | } |
|---|
| | 360 | |
|---|
| | 361 | if( p_sys->i_pcr >= 0 ) |
|---|
| | 362 | { |
|---|
| | 363 | es_out_Control( p_input->p_es_out, ES_OUT_SET_PCR, p_sys->i_pcr ); |
|---|
| | 364 | } |
|---|
| | 365 | |
|---|
| | 366 | |
|---|
| | 367 | return 1; |
|---|
| | 368 | } |
|---|
| | 369 | |
|---|
| | 370 | /***************************************************************************** |
|---|
| | 371 | * Control: |
|---|
| | 372 | *****************************************************************************/ |
|---|
| | 373 | static int Control( input_thread_t *p_input, int i_query, va_list args ) |
|---|
| | 374 | { |
|---|
| | 375 | demux_sys_t *p_sys = p_input->p_demux_data; |
|---|
| | 376 | int64_t *pi64; |
|---|
| | 377 | int i; |
|---|
| | 378 | |
|---|
| | 379 | switch( i_query ) |
|---|
| | 380 | { |
|---|
| | 381 | case DEMUX_GET_TIME: |
|---|
| | 382 | pi64 = (int64_t*)va_arg( args, int64_t * ); |
|---|
| | 383 | *pi64 = p_sys->i_pcr; |
|---|
| | 384 | return VLC_SUCCESS; |
|---|
| | 385 | |
|---|
| | 386 | case DEMUX_SET_TIME: |
|---|
| | 387 | return VLC_EGENERIC; |
|---|
| | 388 | |
|---|
| | 389 | case DEMUX_SET_POSITION: |
|---|
| | 390 | for( i = 0; i < p_sys->i_streams; i++ ) |
|---|
| | 391 | { |
|---|
| | 392 | logical_stream_t *p_stream = p_sys->pp_stream[i]; |
|---|
| | 393 | |
|---|
| | 394 | /* we'll trash all the data until we find the next pcr */ |
|---|
| | 395 | p_stream->b_reinit = 1; |
|---|
| | 396 | p_stream->i_pcr = -1; |
|---|
| | 397 | p_stream->i_interpolated_pcr = -1; |
|---|
| | 398 | ogg_stream_reset( &p_stream->os ); |
|---|
| | 399 | } |
|---|
| | 400 | ogg_sync_reset( &p_sys->oy ); |
|---|
| | 401 | |
|---|
| | 402 | default: |
|---|
| | 403 | return demux_vaControlDefault( p_input, i_query, args ); |
|---|
| | 404 | } |
|---|
| 974 | | /***************************************************************************** |
|---|
| 975 | | * Activate: initializes ogg demux structures |
|---|
| 976 | | *****************************************************************************/ |
|---|
| 977 | | static int Activate( vlc_object_t * p_this ) |
|---|
| 978 | | { |
|---|
| 979 | | input_thread_t *p_input = (input_thread_t *)p_this; |
|---|
| 980 | | demux_sys_t *p_ogg; |
|---|
| 981 | | int b_forced; |
|---|
| 982 | | |
|---|
| 983 | | p_input->p_demux_data = NULL; |
|---|
| 984 | | b_forced = ( ( *p_input->psz_demux )&& |
|---|
| 985 | | ( !strncmp( p_input->psz_demux, "ogg", 10 ) ) ) ? 1 : 0; |
|---|
| 986 | | |
|---|
| 987 | | /* Check if we are dealing with an ogg stream */ |
|---|
| 988 | | if( !b_forced && ( Ogg_Check( p_input ) != VLC_SUCCESS ) ) |
|---|
| 989 | | return -1; |
|---|
| 990 | | |
|---|
| 991 | | /* Allocate p_ogg */ |
|---|
| 992 | | if( !( p_ogg = malloc( sizeof( demux_sys_t ) ) ) ) |
|---|
| 993 | | { |
|---|
| 994 | | msg_Err( p_input, "out of memory" ); |
|---|
| 995 | | goto error; |
|---|
| 996 | | } |
|---|
| 997 | | memset( p_ogg, 0, sizeof( demux_sys_t ) ); |
|---|
| 998 | | p_input->p_demux_data = p_ogg; |
|---|
| 999 | | p_ogg->pp_stream = NULL; |
|---|
| 1000 | | |
|---|
| 1001 | | /* Initialize the Ogg physical bitstream parser */ |
|---|
| 1002 | | ogg_sync_init( &p_ogg->oy ); |
|---|
| 1003 | | |
|---|
| 1004 | | /* Set exported functions */ |
|---|
| 1005 | | p_input->pf_demux = Demux; |
|---|
| 1006 | | p_input->pf_demux_control = Control; |
|---|
| 1007 | | |
|---|
| 1008 | | /* Initialize access plug-in structures. */ |
|---|
| 1009 | | if( p_input->i_mtu == 0 ) |
|---|
| 1010 | | { |
|---|
| 1011 | | /* Improve speed. */ |
|---|
| 1012 | | p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE; |
|---|
| 1013 | | } |
|---|
| 1014 | | |
|---|
| 1015 | | /* Create one program */ |
|---|
| 1016 | | vlc_mutex_lock( &p_input->stream.stream_lock ); |
|---|
| 1017 | | if( input_InitStream( p_input, 0 ) == -1) |
|---|
| 1018 | | { |
|---|
| 1019 | | vlc_mutex_unlock( &p_input->stream.stream_lock ); |
|---|
| 1020 | | msg_Err( p_input, "cannot init stream" ); |
|---|
| 1021 | | goto error; |
|---|
| 1022 | | } |
|---|
| 1023 | | if( input_AddProgram( p_input, 0, 0) == NULL ) |
|---|
| 1024 | | { |
|---|
| 1025 | | vlc_mutex_unlock( &p_input->stream.stream_lock ); |
|---|
| 1026 | | msg_Err( p_input, "cannot add program" ); |
|---|
| 1027 | | goto error; |
|---|
| 1028 | | } |
|---|
| 1029 | | p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; |
|---|
| 1030 | | vlc_mutex_unlock( &p_input->stream.stream_lock ); |
|---|
| 1031 | | |
|---|
| 1032 | | /* Begnning of stream, tell the demux to look for elementary streams. */ |
|---|
| 1033 | | p_ogg->i_eos = 0; |
|---|
| 1034 | | |
|---|
| 1035 | | p_ogg->i_old_synchro_state = !SYNCHRO_REINIT; |
|---|
| 1036 | | |
|---|
| 1037 | | return 0; |
|---|
| 1038 | | |
|---|
| 1039 | | error: |
|---|
| 1040 | | Deactivate( (vlc_object_t *)p_input ); |
|---|
| 1041 | | return -1; |
|---|
| 1042 | | |
|---|
| 1043 | | } |
|---|
| 1044 | | |
|---|
| 1127 | | } |
|---|
| 1128 | | |
|---|
| 1129 | | /***************************************************************************** |
|---|
| 1130 | | * Deactivate: frees unused data |
|---|
| 1131 | | *****************************************************************************/ |
|---|
| 1132 | | static void Deactivate( vlc_object_t *p_this ) |
|---|
| 1133 | | { |
|---|
| 1134 | | input_thread_t *p_input = (input_thread_t *)p_this; |
|---|
| 1135 | | demux_sys_t *p_ogg = (demux_sys_t *)p_input->p_demux_data ; |
|---|
| 1136 | | |
|---|
| 1137 | | if( p_ogg ) |
|---|
| 1138 | | { |
|---|
| 1139 | | /* Cleanup the bitstream parser */ |
|---|
| 1140 | | ogg_sync_clear( &p_ogg->oy ); |
|---|
| 1141 | | |
|---|
| 1142 | | Ogg_EndOfStream( p_input, p_ogg ); |
|---|
| 1143 | | |
|---|
| 1144 | | free( p_ogg ); |
|---|
| 1145 | | } |
|---|
| 1146 | | } |
|---|
| 1147 | | |
|---|
| 1148 | | /***************************************************************************** |
|---|
| 1149 | | * Demux: reads and demuxes data packets |
|---|
| 1150 | | ***************************************************************************** |
|---|
| 1151 | | * Returns -1 in case of error, 0 in case of EOF, 1 otherwise |
|---|
| 1152 | | *****************************************************************************/ |
|---|
| 1153 | | static int Demux( input_thread_t * p_input ) |
|---|
| 1154 | | { |
|---|
| 1155 | | demux_sys_t *p_ogg = (demux_sys_t *)p_input->p_demux_data; |
|---|
| 1156 | | ogg_page oggpage; |
|---|
| 1157 | | ogg_packet oggpacket; |
|---|
| 1158 | | int i_stream; |
|---|
| 1159 | | |
|---|
| 1160 | | #define p_stream p_ogg->pp_stream[i_stream] |
|---|
| 1161 | | |
|---|
| 1162 | | if( p_ogg->i_eos == p_ogg->i_streams ) |
|---|
| 1163 | | { |
|---|
| 1164 | | if( p_ogg->i_eos ) |
|---|
| 1165 | | { |
|---|
| 1166 | | msg_Dbg( p_input, "end of a group of logical streams" ); |
|---|
| 1167 | | Ogg_EndOfStream( p_input, p_ogg ); |
|---|
| 1168 | | } |
|---|
| 1169 | | |
|---|
| 1170 | | if( Ogg_BeginningOfStream( p_input, p_ogg ) != VLC_SUCCESS ) return 0; |
|---|
| 1171 | | p_ogg->i_eos = 0; |
|---|
| 1172 | | |
|---|
| 1173 | | msg_Dbg( p_input, "beginning of a group of logical streams" ); |
|---|
| 1174 | | |
|---|
| 1175 | | p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_REINIT; |
|---|
| 1176 | | input_ClockManageRef( p_input, p_input->stream.p_selected_program, 0 ); |
|---|
| 1177 | | } |
|---|
| 1178 | | |
|---|
| 1179 | | if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) |
|---|
| 1180 | | { |
|---|
| 1181 | | msg_Warn( p_input, "synchro reinit" ); |
|---|
| 1182 | | |
|---|
| 1183 | | if( p_ogg->i_old_synchro_state != SYNCHRO_REINIT ) |
|---|
| 1184 | | for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ ) |
|---|
| 1185 | | { |
|---|
| 1186 | | /* we'll trash all the data until we find the next pcr */ |
|---|
| 1187 | | p_stream->b_reinit = 1; |
|---|
| 1188 | | p_stream->i_pcr = -1; |
|---|
| 1189 | | p_stream->i_interpolated_pcr = -1; |
|---|
| 1190 | | ogg_stream_reset( &p_stream->os ); |
|---|
| 1191 | | } |
|---|
| 1192 | | if( p_ogg->i_old_synchro_state != SYNCHRO_REINIT ) |
|---|
| 1193 | | ogg_sync_reset( &p_ogg->oy ); |
|---|
| 1194 | | } |
|---|
| 1195 | | |
|---|
| 1196 | | /* |
|---|
| 1197 | | * Demux an ogg page from the stream |
|---|
| 1198 | | */ |
|---|
| 1199 | | if( Ogg_ReadPage( p_input, p_ogg, &oggpage ) != VLC_SUCCESS ) |
|---|
| 1200 | | { |
|---|
| 1201 | | return 0; /* EOF */ |
|---|
| 1202 | | } |
|---|
| 1203 | | |
|---|
| 1204 | | /* Test for End of Stream */ |
|---|
| 1205 | | if( ogg_page_eos( &oggpage ) ) p_ogg->i_eos++; |
|---|
| 1206 | | |
|---|
| 1207 | | |
|---|
| 1208 | | for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ ) |
|---|
| 1209 | | { |
|---|
| 1210 | | if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 ) |
|---|
| 1211 | | continue; |
|---|
| 1212 | | |
|---|
| 1213 | | while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 ) |
|---|
| 1214 | | { |
|---|
| 1215 | | /* Read info from any secondary header packets, if there are any */ |
|---|
| 1216 | | if( p_stream->secondary_header_packets > 0 ) |
|---|
| 1217 | | { |
|---|
| 1218 | | if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) && |
|---|
| 1219 | | oggpacket.bytes >= 7 && |
|---|
| 1220 | | ! strncmp( &oggpacket.packet[1], "theora", 6 ) ) |
|---|
| 1221 | | { |
|---|
| 1222 | | Ogg_ReadTheoraHeader( p_stream, &oggpacket ); |
|---|
| 1223 | | p_stream->secondary_header_packets = 0; |
|---|
| 1224 | | } |
|---|
| 1225 | | else if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) && |
|---|
| 1226 | | oggpacket.bytes >= 7 && |
|---|
| 1227 | | ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) ) |
|---|
| 1228 | | { |
|---|
| 1229 | | Ogg_ReadVorbisHeader( p_stream, &oggpacket ); |
|---|
| 1230 | | p_stream->secondary_header_packets = 0; |
|---|
| 1231 | | } |
|---|
| 1232 | | else if ( p_stream->fmt.i_codec == VLC_FOURCC( 'c','m','m','l' ) ) |
|---|
| 1233 | | { |
|---|
| 1234 | | p_stream->secondary_header_packets = 0; |
|---|
| 1235 | | } |
|---|
| 1236 | | |
|---|
| 1237 | | p_stream->secondary_header_packets--; |
|---|
| 1238 | | } |
|---|
| 1239 | | |
|---|
| 1240 | | if( p_stream->b_reinit ) |
|---|
| 1241 | | { |
|---|
| 1242 | | /* If synchro is re-initialized we need to drop all the packets |
|---|
| 1243 | | * until we find a new dated one. */ |
|---|
| 1244 | | Ogg_UpdatePCR( p_stream, &oggpacket ); |
|---|
| 1245 | | |
|---|
| 1246 | | if( p_stream->i_pcr >= 0 ) |
|---|
| 1247 | | { |
|---|
| 1248 | | p_stream->b_reinit = 0; |
|---|
| 1249 | | } |
|---|
| 1250 | | else |
|---|
| 1251 | | { |
|---|
| 1252 | | p_stream->i_interpolated_pcr = -1; |
|---|
| 1253 | | continue; |
|---|
| 1254 | | } |
|---|
| 1255 | | |
|---|
| 1256 | | /* An Ogg/vorbis packet contains an end date granulepos */ |
|---|
| 1257 | | if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) || |
|---|
| 1258 | | p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) || |
|---|
| 1259 | | p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) ) |
|---|
| 1260 | | { |
|---|
| 1261 | | if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 ) |
|---|
| 1262 | | { |
|---|
| 1263 | | Ogg_DecodePacket( p_input, p_stream, &oggpacket ); |
|---|
| 1264 | | } |
|---|
| 1265 | | else |
|---|
| 1266 | | { |
|---|
| 1267 | | input_ClockManageRef( p_input, |
|---|
| 1268 | | p_input->stream.p_selected_program, |
|---|
| 1269 | | p_stream->i_pcr ); |
|---|
| 1270 | | } |
|---|
| 1271 | | continue; |
|---|
| 1272 | | } |
|---|
| 1273 | | } |
|---|
| 1274 | | |
|---|
| 1275 | | Ogg_DecodePacket( p_input, p_stream, &oggpacket ); |
|---|
| 1276 | | } |
|---|
| 1277 | | break; |
|---|
| 1278 | | } |
|---|
| 1279 | | |
|---|
| 1280 | | i_stream = 0; p_ogg->i_pcr = -1; |
|---|
| 1281 | | for( ; i_stream < p_ogg->i_streams; i_stream++ ) |
|---|
| 1282 | | { |
|---|
| 1283 | | if( p_stream->fmt.i_cat == SPU_ES ) |
|---|
| 1284 | | continue; |
|---|
| 1285 | | if( p_stream->i_interpolated_pcr < 0 ) |
|---|
| 1286 | | continue; |
|---|
| 1287 | | |
|---|
| 1288 | | if( p_ogg->i_pcr < 0 || p_stream->i_interpolated_pcr < p_ogg->i_pcr ) |
|---|
| 1289 | | p_ogg->i_pcr = p_stream->i_interpolated_pcr; |
|---|
| 1290 | | } |
|---|
| 1291 | | |
|---|
| 1292 | | if( p_ogg->i_pcr >= 0 ) |
|---|
| 1293 | | { |
|---|
| 1294 | | input_ClockManageRef( p_input, p_input->stream.p_selected_program, |
|---|
| 1295 | | p_ogg->i_pcr ); |
|---|
| 1296 | | } |
|---|
| 1297 | | |
|---|
| 1298 | | #undef p_stream |
|---|
| 1299 | | |
|---|
| 1300 | | p_ogg->i_old_synchro_state = |
|---|
| 1301 | | p_input->stream.p_selected_program->i_synchro_state; |
|---|
| 1302 | | |
|---|
| 1303 | | return 1; |
|---|
| 1304 | | } |
|---|
| 1305 | | |
|---|
| 1306 | | /***************************************************************************** |
|---|
| 1307 | | * Control: |
|---|
| 1308 | | *****************************************************************************/ |
|---|
| 1309 | | static int Control( input_thread_t *p_input, int i_query, va_list args ) |
|---|
| 1310 | | { |
|---|
| 1311 | | demux_sys_t *p_ogg = (demux_sys_t *)p_input->p_demux_data; |
|---|
| 1312 | | int64_t *pi64; |
|---|
| 1313 | | |
|---|
| 1314 | | switch( i_query ) |
|---|
| 1315 | | { |
|---|
| 1316 | | case DEMUX_GET_TIME: |
|---|
| 1317 | | pi64 = (int64_t*)va_arg( args, int64_t * ); |
|---|
| 1318 | | *pi64 = p_ogg->i_pcr * 100 / 9; |
|---|
| 1319 | | return VLC_SUCCESS; |
|---|
| 1320 | | |
|---|
| 1321 | | default: |
|---|
| 1322 | | return demux_vaControlDefault( p_input, i_query, args ); |
|---|
| 1323 | | } |
|---|