]> git.sesse.net Git - vlc/blob - src/input/input.c
Cosmetics.
[vlc] / src / input / input.c
1 /*****************************************************************************
2  * input.c: input thread
3  *****************************************************************************
4  * Copyright (C) 1998-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
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.
14  *
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
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33
34 #include <limits.h>
35 #include <assert.h>
36 #include <errno.h>
37
38 #include "input_internal.h"
39 #include "event.h"
40 #include "es_out.h"
41 #include "es_out_timeshift.h"
42 #include "access.h"
43 #include "demux.h"
44 #include "stream.h"
45 #include "item.h"
46 #include "resource.h"
47
48 #include <vlc_sout.h>
49 #include "../stream_output/stream_output.h"
50
51 #include <vlc_dialog.h>
52 #include <vlc_url.h>
53 #include <vlc_charset.h>
54 #include <vlc_strings.h>
55
56 #ifdef HAVE_SYS_STAT_H
57 #   include <sys/stat.h>
58 #endif
59
60 /*****************************************************************************
61  * Local prototypes
62  *****************************************************************************/
63 static void Destructor( input_thread_t * p_input );
64
65 static  void *Run            ( vlc_object_t *p_this );
66
67 static input_thread_t * Create  ( vlc_object_t *, input_item_t *,
68                                   const char *, bool, input_resource_t * );
69 static  int             Init    ( input_thread_t *p_input );
70 static void             End     ( input_thread_t *p_input );
71 static void             MainLoop( input_thread_t *p_input, bool b_interactive );
72
73 static void ObjectKillChildrens( input_thread_t *, vlc_object_t * );
74
75 static inline int ControlPop( input_thread_t *, int *, vlc_value_t *, mtime_t i_deadline, bool b_postpone_seek );
76 static void       ControlRelease( int i_type, vlc_value_t val );
77 static bool       ControlIsSeekRequest( int i_type );
78 static bool       Control( input_thread_t *, int, vlc_value_t );
79
80 static int  UpdateTitleSeekpointFromAccess( input_thread_t * );
81 static void UpdateGenericFromAccess( input_thread_t * );
82
83 static int  UpdateTitleSeekpointFromDemux( input_thread_t * );
84 static void UpdateGenericFromDemux( input_thread_t * );
85
86 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *);
87
88 static input_source_t *InputSourceNew( input_thread_t *);
89 static int  InputSourceInit( input_thread_t *, input_source_t *,
90                              const char *, const char *psz_forced_demux );
91 static void InputSourceClean( input_source_t * );
92 static void InputSourceMeta( input_thread_t *, input_source_t *, vlc_meta_t * );
93
94 /* TODO */
95 //static void InputGetAttachments( input_thread_t *, input_source_t * );
96 static void SlaveDemux( input_thread_t *p_input, bool *pb_demux_polled );
97 static void SlaveSeek( input_thread_t *p_input );
98
99 static void InputMetaUser( input_thread_t *p_input, vlc_meta_t *p_meta );
100 static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta );
101 static void InputGetExtraFiles( input_thread_t *p_input,
102                                 int *pi_list, char ***pppsz_list,
103                                 const char *psz_access, const char *psz_path );
104
105 static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment,
106                               int i_new, input_attachment_t **pp_new );
107
108 static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced );
109
110 static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */
111
112 /* Do not let a pts_delay from access/demux go beyong 60s */
113 #define INPUT_PTS_DELAY_MAX INT64_C(60000000)
114
115 /**
116  * Create a new input_thread_t.
117  *
118  * You need to call input_Start on it when you are done
119  * adding callback on the variables/events you want to monitor.
120  *
121  * \param p_parent a vlc_object
122  * \param p_item an input item
123  * \param psz_log an optional prefix for this input logs
124  * \param p_resource an optional input ressource
125  * \return a pointer to the spawned input thread
126  */
127
128 input_thread_t *__input_Create( vlc_object_t *p_parent,
129                                 input_item_t *p_item,
130                                 const char *psz_log, input_resource_t *p_resource )
131 {
132
133     return Create( p_parent, p_item, psz_log, false, p_resource );
134 }
135
136 /**
137  * Create a new input_thread_t and start it.
138  *
139  * Provided for convenience.
140  *
141  * \see input_Create
142  */
143 input_thread_t *__input_CreateAndStart( vlc_object_t *p_parent,
144                                         input_item_t *p_item, const char *psz_log )
145 {
146     input_thread_t *p_input = __input_Create( p_parent, p_item, psz_log, NULL );
147
148     if( input_Start( p_input ) )
149     {
150         vlc_object_release( p_input );
151         return NULL;
152     }
153     return p_input;
154 }
155
156 /**
157  * Initialize an input thread and run it until it stops by itself.
158  *
159  * \param p_parent a vlc_object
160  * \param p_item an input item
161  * \return an error code, VLC_SUCCESS on success
162  */
163 int __input_Read( vlc_object_t *p_parent, input_item_t *p_item )
164 {
165     input_thread_t *p_input = Create( p_parent, p_item, NULL, false, NULL );
166     if( !p_input )
167         return VLC_EGENERIC;
168
169     if( !Init( p_input ) )
170     {
171         MainLoop( p_input, false );
172         End( p_input );
173     }
174
175     vlc_object_release( p_input );
176     return VLC_SUCCESS;
177 }
178
179 /**
180  * Initialize an input and initialize it to preparse the item
181  * This function is blocking. It will only accept parsing regular files.
182  *
183  * \param p_parent a vlc_object_t
184  * \param p_item an input item
185  * \return VLC_SUCCESS or an error
186  */
187 int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
188 {
189     input_thread_t *p_input;
190
191     /* Allocate descriptor */
192     p_input = Create( p_parent, p_item, NULL, true, NULL );
193     if( !p_input )
194         return VLC_EGENERIC;
195
196     if( !Init( p_input ) )
197         End( p_input );
198
199     vlc_object_release( p_input );
200
201     return VLC_SUCCESS;
202 }
203
204 /**
205  * Start a input_thread_t created by input_Create.
206  *
207  * You must not start an already running input_thread_t.
208  *
209  * \param the input thread to start
210  */
211 int input_Start( input_thread_t *p_input )
212 {
213     /* Create thread and wait for its readiness. */
214     if( vlc_thread_create( p_input, "input", Run,
215                            VLC_THREAD_PRIORITY_INPUT ) )
216     {
217         input_ChangeState( p_input, ERROR_S );
218         msg_Err( p_input, "cannot create input thread" );
219         return VLC_EGENERIC;
220     }
221     return VLC_SUCCESS;
222 }
223
224 /**
225  * Request a running input thread to stop and die
226  *
227  * b_abort must be true when a user stop is requested and not because you have
228  * detected an error or an eof. It will be used to properly send the
229  * INPUT_EVENT_ABORT event.
230  *
231  * \param p_input the input thread to stop
232  * \param b_abort true if the input has been aborted by a user request
233  */
234 void input_Stop( input_thread_t *p_input, bool b_abort )
235 {
236     /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
237      * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
238      * unlock the control loop */
239     ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
240
241     vlc_mutex_lock( &p_input->p->lock_control );
242     p_input->p->b_abort |= b_abort;
243     vlc_mutex_unlock( &p_input->p->lock_control );
244
245     input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
246 }
247
248 input_resource_t *input_DetachResource( input_thread_t *p_input )
249 {
250     assert( p_input->b_dead );
251
252     input_resource_SetInput( p_input->p->p_resource, NULL );
253
254     input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
255     p_input->p->p_sout = NULL;
256
257     return p_resource;
258 }
259
260 /**
261  * Get the item from an input thread
262  * FIXME it does not increase ref count of the item.
263  * if it is used after p_input is destroyed nothing prevent it from
264  * being freed.
265  */
266 input_item_t *input_GetItem( input_thread_t *p_input )
267 {
268     assert( p_input && p_input->p );
269     return p_input->p->p_item;
270 }
271
272 /*****************************************************************************
273  * ObjectKillChildrens
274  *****************************************************************************/
275 static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
276 {
277     vlc_list_t *p_list;
278     int i;
279
280     /* FIXME ObjectKillChildrens seems a very bad idea in fact */
281     i = vlc_internals( p_obj )->i_object_type;
282     if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT ||
283         p_obj == VLC_OBJECT(p_input->p->p_sout) ||
284         i == VLC_OBJECT_DECODER )
285         return;
286
287     vlc_object_kill( p_obj );
288
289     p_list = vlc_list_children( p_obj );
290     for( i = 0; i < p_list->i_count; i++ )
291         ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
292     vlc_list_release( p_list );
293 }
294
295 /*****************************************************************************
296  * This function creates a new input, and returns a pointer
297  * to its description. On error, it returns NULL.
298  *
299  * XXX Do not forget to update vlc_input.h if you add new variables.
300  *****************************************************************************/
301 static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
302                                const char *psz_header, bool b_quick,
303                                input_resource_t *p_resource )
304 {
305     static const char input_name[] = "input";
306     input_thread_t *p_input = NULL;                 /* thread descriptor */
307     int i;
308
309     /* Allocate descriptor */
310     p_input = vlc_custom_create( p_parent, sizeof( *p_input ),
311                                  VLC_OBJECT_INPUT, input_name );
312     if( p_input == NULL )
313         return NULL;
314
315     vlc_object_attach( p_input, p_parent );
316
317     /* Construct a nice name for the input timer */
318     char psz_timer_name[255];
319     char * psz_name = input_item_GetName( p_item );
320     snprintf( psz_timer_name, sizeof(psz_timer_name),
321               "input launching for '%s'", psz_name );
322
323     msg_Dbg( p_input, "Creating an input for '%s'", psz_name);
324
325     free( psz_name );
326
327     /* Start a timer to mesure how long it takes
328      * to launch an input */
329     stats_TimerStart( p_input, psz_timer_name,
330         STATS_TIMER_INPUT_LAUNCHING );
331
332     p_input->p = calloc( 1, sizeof( input_thread_private_t ) );
333     if( !p_input->p )
334         return NULL;
335
336     p_input->b_preparsing = b_quick;
337     p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
338
339     /* Init Common fields */
340     p_input->b_eof = false;
341     p_input->p->b_can_pace_control = true;
342     p_input->p->i_start = 0;
343     p_input->p->i_time  = 0;
344     p_input->p->i_stop  = 0;
345     p_input->p->i_run   = 0;
346     p_input->p->i_title = 0;
347     p_input->p->title = NULL;
348     p_input->p->i_title_offset = p_input->p->i_seekpoint_offset = 0;
349     p_input->p->i_state = INIT_S;
350     p_input->p->i_rate = INPUT_RATE_DEFAULT
351                          / var_CreateGetFloat( p_input, "rate" );
352     /* Currently, the input rate variable is an integer. So we need to destroy
353      * the float variable inherited from the configuration. */
354     var_Destroy( p_input, "rate" );
355     p_input->p->b_recording = false;
356     memset( &p_input->p->bookmark, 0, sizeof(p_input->p->bookmark) );
357     TAB_INIT( p_input->p->i_bookmark, p_input->p->pp_bookmark );
358     TAB_INIT( p_input->p->i_attachment, p_input->p->attachment );
359     p_input->p->p_sout   = NULL;
360     p_input->p->b_out_pace_control = false;
361
362     vlc_gc_incref( p_item ); /* Released in Destructor() */
363     p_input->p->p_item = p_item;
364
365     /* Init Input fields */
366     p_input->p->input.p_access = NULL;
367     p_input->p->input.p_stream = NULL;
368     p_input->p->input.p_demux  = NULL;
369     p_input->p->input.b_title_demux = false;
370     p_input->p->input.i_title  = 0;
371     p_input->p->input.title    = NULL;
372     p_input->p->input.i_title_offset = p_input->p->input.i_seekpoint_offset = 0;
373     p_input->p->input.b_can_pace_control = true;
374     p_input->p->input.b_can_rate_control = true;
375     p_input->p->input.b_rescale_ts = true;
376     p_input->p->input.b_eof = false;
377
378     vlc_mutex_lock( &p_item->lock );
379
380     if( !p_item->p_stats )
381         p_item->p_stats = stats_NewInputStats( p_input );
382     vlc_mutex_unlock( &p_item->lock );
383
384     /* No slave */
385     p_input->p->i_slave = 0;
386     p_input->p->slave   = NULL;
387
388     /* */
389     if( p_resource )
390         p_input->p->p_resource = p_resource;
391     else
392         p_input->p->p_resource = input_resource_New();
393     input_resource_SetInput( p_input->p->p_resource, p_input );
394
395     /* Init control buffer */
396     vlc_mutex_init( &p_input->p->lock_control );
397     vlc_cond_init( &p_input->p->wait_control );
398     p_input->p->i_control = 0;
399     p_input->p->b_abort = false;
400
401     /* Parse input options */
402     vlc_mutex_lock( &p_item->lock );
403     assert( (int)p_item->optflagc == p_item->i_options );
404     for( i = 0; i < p_item->i_options; i++ )
405         var_OptionParse( VLC_OBJECT(p_input), p_item->ppsz_options[i],
406                          !!(p_item->optflagv[i] & VLC_INPUT_OPTION_TRUSTED) );
407     vlc_mutex_unlock( &p_item->lock );
408
409     /* Create Object Variables for private use only */
410     input_ConfigVarInit( p_input );
411
412     /* Create Objects variables for public Get and Set */
413     input_ControlVarInit( p_input );
414
415     /* */
416     if( !p_input->b_preparsing )
417     {
418         char *psz_bookmarks = var_GetNonEmptyString( p_input, "bookmarks" );
419         if( psz_bookmarks )
420         {
421             /* FIXME: have a common cfg parsing routine used by sout and others */
422             char *psz_parser, *psz_start, *psz_end;
423             psz_parser = psz_bookmarks;
424             while( (psz_start = strchr( psz_parser, '{' ) ) )
425             {
426                  seekpoint_t *p_seekpoint;
427                  char backup;
428                  psz_start++;
429                  psz_end = strchr( psz_start, '}' );
430                  if( !psz_end ) break;
431                  psz_parser = psz_end + 1;
432                  backup = *psz_parser;
433                  *psz_parser = 0;
434                  *psz_end = ',';
435
436                  p_seekpoint = vlc_seekpoint_New();
437                  while( (psz_end = strchr( psz_start, ',' ) ) )
438                  {
439                      *psz_end = 0;
440                      if( !strncmp( psz_start, "name=", 5 ) )
441                      {
442                          p_seekpoint->psz_name = strdup(psz_start + 5);
443                      }
444                      else if( !strncmp( psz_start, "bytes=", 6 ) )
445                      {
446                          p_seekpoint->i_byte_offset = atoll(psz_start + 6);
447                      }
448                      else if( !strncmp( psz_start, "time=", 5 ) )
449                      {
450                          p_seekpoint->i_time_offset = atoll(psz_start + 5) *
451                                                         1000000;
452                      }
453                      psz_start = psz_end + 1;
454                 }
455                 msg_Dbg( p_input, "adding bookmark: %s, bytes=%"PRId64", time=%"PRId64,
456                                   p_seekpoint->psz_name, p_seekpoint->i_byte_offset,
457                                   p_seekpoint->i_time_offset );
458                 input_Control( p_input, INPUT_ADD_BOOKMARK, p_seekpoint );
459                 vlc_seekpoint_Delete( p_seekpoint );
460                 *psz_parser = backup;
461             }
462             free( psz_bookmarks );
463         }
464     }
465
466     /* Remove 'Now playing' info as it is probably outdated */
467     input_item_SetNowPlaying( p_item, NULL );
468     input_SendEventMeta( p_input );
469
470     /* */
471     if( p_input->b_preparsing )
472         p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT;
473
474     /* */
475     memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) );
476     vlc_mutex_init( &p_input->p->counters.counters_lock );
477
478     p_input->p->p_es_out_display = input_EsOutNew( p_input, p_input->p->i_rate );
479     p_input->p->p_es_out = NULL;
480
481     /* Set the destructor when we are sure we are initialized */
482     vlc_object_set_destructor( p_input, (vlc_destructor_t)Destructor );
483
484     return p_input;
485 }
486
487 /**
488  * Input destructor (called when the object's refcount reaches 0).
489  */
490 static void Destructor( input_thread_t * p_input )
491 {
492 #ifndef NDEBUG
493     char * psz_name = input_item_GetName( p_input->p->p_item );
494     msg_Dbg( p_input, "Destroying the input for '%s'", psz_name);
495     free( psz_name );
496 #endif
497
498     stats_TimerDump( p_input, STATS_TIMER_INPUT_LAUNCHING );
499     stats_TimerClean( p_input, STATS_TIMER_INPUT_LAUNCHING );
500
501     if( p_input->p->p_es_out_display )
502         es_out_Delete( p_input->p->p_es_out_display );
503
504     if( p_input->p->p_resource )
505         input_resource_Delete( p_input->p->p_resource );
506
507     vlc_gc_decref( p_input->p->p_item );
508
509     vlc_mutex_destroy( &p_input->p->counters.counters_lock );
510
511     for( int i = 0; i < p_input->p->i_control; i++ )
512     {
513         input_control_t *p_ctrl = &p_input->p->control[i];
514         ControlRelease( p_ctrl->i_type, p_ctrl->val );
515     }
516
517     vlc_cond_destroy( &p_input->p->wait_control );
518     vlc_mutex_destroy( &p_input->p->lock_control );
519     free( p_input->p );
520 }
521
522 /*****************************************************************************
523  * Run: main thread loop
524  * This is the "normal" thread that spawns the input processing chain,
525  * reads the stream, cleans up and waits
526  *****************************************************************************/
527 static void *Run( vlc_object_t *p_this )
528 {
529     input_thread_t *p_input = (input_thread_t *)p_this;
530     const int canc = vlc_savecancel();
531
532     if( Init( p_input ) )
533         goto exit;
534
535     MainLoop( p_input, true ); /* FIXME it can be wrong (like with VLM) */
536
537     /* Clean up */
538     End( p_input );
539
540 exit:
541     /* Tell we're dead */
542     vlc_mutex_lock( &p_input->p->lock_control );
543     const bool b_abort = p_input->p->b_abort;
544     vlc_mutex_unlock( &p_input->p->lock_control );
545
546     if( b_abort )
547         input_SendEventAbort( p_input );
548     input_SendEventDead( p_input );
549
550     vlc_restorecancel( canc );
551     return NULL;
552 }
553
554 /*****************************************************************************
555  * Main loop: Fill buffers from access, and demux
556  *****************************************************************************/
557
558 /**
559  * MainLoopDemux
560  * It asks the demuxer to demux some data
561  */
562 static void MainLoopDemux( input_thread_t *p_input, bool *pb_changed, bool *pb_demux_polled, mtime_t i_start_mdate )
563 {
564     int i_ret;
565
566     *pb_changed = false;
567     *pb_demux_polled = p_input->p->input.p_demux->pf_demux != NULL;
568
569     if( ( p_input->p->i_stop > 0 && p_input->p->i_time >= p_input->p->i_stop ) ||
570         ( p_input->p->i_run > 0 && i_start_mdate+p_input->p->i_run < mdate() ) )
571         i_ret = 0; /* EOF */
572     else
573         i_ret = demux_Demux( p_input->p->input.p_demux );
574
575     if( i_ret > 0 )
576     {
577         if( p_input->p->input.p_demux->info.i_update )
578         {
579             if( p_input->p->input.b_title_demux )
580             {
581                 i_ret = UpdateTitleSeekpointFromDemux( p_input );
582                 *pb_changed = true;
583             }
584             UpdateGenericFromDemux( p_input );
585         }
586         else if( p_input->p->input.p_access &&
587                  p_input->p->input.p_access->info.i_update )
588         {
589             if( !p_input->p->input.b_title_demux )
590             {
591                 i_ret = UpdateTitleSeekpointFromAccess( p_input );
592                 *pb_changed = true;
593             }
594             UpdateGenericFromAccess( p_input );
595         }
596     }
597
598     if( i_ret == 0 )    /* EOF */
599     {
600         msg_Dbg( p_input, "EOF reached" );
601         p_input->p->input.b_eof = true;
602     }
603     else if( i_ret < 0 )
604     {
605         input_ChangeState( p_input, ERROR_S );
606     }
607
608     if( i_ret > 0 && p_input->p->i_slave > 0 )
609     {
610         bool b_demux_polled;
611         SlaveDemux( p_input, &b_demux_polled );
612
613         *pb_demux_polled |= b_demux_polled;
614     }
615 }
616
617 static int MainLoopTryRepeat( input_thread_t *p_input, mtime_t *pi_start_mdate )
618 {
619     int i_repeat = var_GetInteger( p_input, "input-repeat" );
620     if( i_repeat == 0 )
621         return VLC_EGENERIC;
622
623     vlc_value_t val;
624
625     msg_Dbg( p_input, "repeating the same input (%d)", i_repeat );
626     if( i_repeat > 0 )
627     {
628         i_repeat--;
629         var_SetInteger( p_input, "input-repeat", i_repeat );
630     }
631
632     /* Seek to start title/seekpoint */
633     val.i_int = p_input->p->input.i_title_start -
634         p_input->p->input.i_title_offset;
635     if( val.i_int < 0 || val.i_int >= p_input->p->input.i_title )
636         val.i_int = 0;
637     input_ControlPush( p_input,
638                        INPUT_CONTROL_SET_TITLE, &val );
639
640     val.i_int = p_input->p->input.i_seekpoint_start -
641         p_input->p->input.i_seekpoint_offset;
642     if( val.i_int > 0 /* TODO: check upper boundary */ )
643         input_ControlPush( p_input,
644                            INPUT_CONTROL_SET_SEEKPOINT, &val );
645
646     /* Seek to start position */
647     if( p_input->p->i_start > 0 )
648     {
649         val.i_time = p_input->p->i_start;
650         input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &val );
651     }
652     else
653     {
654         val.f_float = 0.0;
655         input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION, &val );
656     }
657
658     /* */
659     *pi_start_mdate = mdate();
660     return VLC_SUCCESS;
661 }
662
663 /**
664  * MainLoopInterface
665  * It update the variables used by the interfaces
666  */
667 static void MainLoopInterface( input_thread_t *p_input )
668 {
669     double f_position = 0.0;
670     mtime_t i_time = 0;
671     mtime_t i_length = 0;
672
673     /* update input status variables */
674     if( demux_Control( p_input->p->input.p_demux,
675                        DEMUX_GET_POSITION, &f_position ) )
676         f_position = 0.0;
677
678     if( demux_Control( p_input->p->input.p_demux,
679                        DEMUX_GET_TIME, &i_time ) )
680         i_time = 0;
681     p_input->p->i_time = i_time;
682
683     if( demux_Control( p_input->p->input.p_demux,
684                        DEMUX_GET_LENGTH, &i_length ) )
685         i_length = 0;
686
687     es_out_SetTimes( p_input->p->p_es_out, f_position, i_time, i_length );
688
689     /* update current bookmark */
690     vlc_mutex_lock( &p_input->p->p_item->lock );
691     p_input->p->bookmark.i_time_offset = i_time;
692     if( p_input->p->input.p_stream )
693         p_input->p->bookmark.i_byte_offset = stream_Tell( p_input->p->input.p_stream );
694     vlc_mutex_unlock( &p_input->p->p_item->lock );
695 }
696
697 /**
698  * MainLoopStatistic
699  * It updates the globals statics
700  */
701 static void MainLoopStatistic( input_thread_t *p_input )
702 {
703     stats_ComputeInputStats( p_input, p_input->p->p_item->p_stats );
704     input_SendEventStatistics( p_input );
705 }
706
707 /**
708  * MainLoop
709  * The main input loop.
710  */
711 static void MainLoop( input_thread_t *p_input, bool b_interactive )
712 {
713     mtime_t i_start_mdate = mdate();
714     mtime_t i_intf_update = 0;
715     mtime_t i_statistic_update = 0;
716     mtime_t i_last_seek_mdate = 0;
717     bool b_pause_after_eof = b_interactive &&
718                              var_CreateGetBool( p_input, "play-and-pause" );
719
720     /* Start the timer */
721     stats_TimerStop( p_input, STATS_TIMER_INPUT_LAUNCHING );
722
723     while( vlc_object_alive( p_input ) && !p_input->b_error )
724     {
725         bool b_force_update;
726         vlc_value_t val;
727         mtime_t i_current;
728         mtime_t i_wakeup;
729         bool b_paused;
730         bool b_demux_polled;
731
732         /* Demux data */
733         b_force_update = false;
734         i_wakeup = 0;
735         /* FIXME if p_input->p->i_state == PAUSE_S the access/access_demux
736          * is paused -> this may cause problem with some of them
737          * The same problem can be seen when seeking while paused */
738         b_paused = p_input->p->i_state == PAUSE_S &&
739                    ( !es_out_GetBuffering( p_input->p->p_es_out ) || p_input->p->input.b_eof );
740
741         b_demux_polled = true;
742         if( !b_paused )
743         {
744             if( !p_input->p->input.b_eof )
745             {
746                 MainLoopDemux( p_input, &b_force_update, &b_demux_polled, i_start_mdate );
747
748                 i_wakeup = es_out_GetWakeup( p_input->p->p_es_out );
749             }
750             else if( !es_out_GetEmpty( p_input->p->p_es_out ) )
751             {
752                 msg_Dbg( p_input, "waiting decoder fifos to empty" );
753                 i_wakeup = mdate() + INPUT_IDLE_SLEEP;
754             }
755             /* Pause after eof only if the input is pausable.
756              * This way we won't trigger timeshifting for nothing */
757             else if( b_pause_after_eof && p_input->p->b_can_pause )
758             {
759                 msg_Dbg( p_input, "pausing at EOF (pause after each)");
760                 val.i_int = PAUSE_S;
761                 Control( p_input, INPUT_CONTROL_SET_STATE, val );
762
763                 b_pause_after_eof = false;
764                 b_paused = true;
765             }
766             else
767             {
768                 if( MainLoopTryRepeat( p_input, &i_start_mdate ) )
769                     break;
770                 b_pause_after_eof = var_GetBool( p_input, "play-and-pause" );
771             }
772         }
773
774         /* */
775         do {
776             mtime_t i_deadline = i_wakeup;
777             if( b_paused || !b_demux_polled )
778                 i_deadline = __MIN( i_intf_update, i_statistic_update );
779
780             /* Handle control */
781             for( ;; )
782             {
783                 mtime_t i_limit = i_deadline;
784
785                 /* We will postpone the execution of a seek until we have
786                  * finished the ES bufferisation (postpone is limited to
787                  * 125ms) */
788                 bool b_buffering = es_out_GetBuffering( p_input->p->p_es_out ) &&
789                                    !p_input->p->input.b_eof;
790                 if( b_buffering )
791                 {
792                     /* When postpone is in order, check the ES level every 20ms */
793                     mtime_t i_current = mdate();
794                     if( i_last_seek_mdate + INT64_C(125000) >= i_current )
795                         i_limit = __MIN( i_deadline, i_current + INT64_C(20000) );
796                 }
797
798                 int i_type;
799                 if( ControlPop( p_input, &i_type, &val, i_limit, b_buffering ) )
800                 {
801                     if( b_buffering && i_limit < i_deadline )
802                         continue;
803                     break;
804                 }
805
806                 msg_Dbg( p_input, "control type=%d", i_type );
807
808                 if( Control( p_input, i_type, val ) )
809                 {
810                     if( ControlIsSeekRequest( i_type ) )
811                         i_last_seek_mdate = mdate();
812                     b_force_update = true;
813                 }
814             }
815
816             /* Update interface and statistics */
817             i_current = mdate();
818             if( i_intf_update < i_current || b_force_update )
819             {
820                 MainLoopInterface( p_input );
821                 i_intf_update = i_current + INT64_C(250000);
822                 b_force_update = false;
823             }
824             if( i_statistic_update < i_current )
825             {
826                 MainLoopStatistic( p_input );
827                 i_statistic_update = i_current + INT64_C(1000000);
828             }
829
830             /* Update the wakeup time */
831             if( i_wakeup != 0 )
832                 i_wakeup = es_out_GetWakeup( p_input->p->p_es_out );
833         } while( i_current < i_wakeup );
834     }
835
836     if( !p_input->b_error )
837         input_ChangeState( p_input, END_S );
838 }
839
840 static void InitStatistics( input_thread_t * p_input )
841 {
842     if( p_input->b_preparsing ) return;
843
844     /* Prepare statistics */
845 #define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \
846  stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
847     if( libvlc_stats( p_input ) )
848     {
849         INIT_COUNTER( read_bytes, INTEGER, COUNTER );
850         INIT_COUNTER( read_packets, INTEGER, COUNTER );
851         INIT_COUNTER( demux_read, INTEGER, COUNTER );
852         INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
853         INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
854         INIT_COUNTER( demux_corrupted, INTEGER, COUNTER );
855         INIT_COUNTER( demux_discontinuity, INTEGER, COUNTER );
856         INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
857         INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
858         INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
859         INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
860         INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
861         INIT_COUNTER( decoded_video, INTEGER, COUNTER );
862         INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
863         p_input->p->counters.p_sout_send_bitrate = NULL;
864         p_input->p->counters.p_sout_sent_packets = NULL;
865         p_input->p->counters.p_sout_sent_bytes = NULL;
866         if( p_input->p->counters.p_demux_bitrate )
867             p_input->p->counters.p_demux_bitrate->update_interval = 1000000;
868         if( p_input->p->counters.p_input_bitrate )
869             p_input->p->counters.p_input_bitrate->update_interval = 1000000;
870     }
871 }
872
873 #ifdef ENABLE_SOUT
874 static int InitSout( input_thread_t * p_input )
875 {
876     if( p_input->b_preparsing )
877         return VLC_SUCCESS;
878
879     /* Find a usable sout and attach it to p_input */
880     char *psz = var_GetNonEmptyString( p_input, "sout" );
881     if( psz && strncasecmp( p_input->p->p_item->psz_uri, "vlc:", 4 ) )
882     {
883         p_input->p->p_sout  = input_resource_RequestSout( p_input->p->p_resource, NULL, psz );
884         if( !p_input->p->p_sout )
885         {
886             input_ChangeState( p_input, ERROR_S );
887             msg_Err( p_input, "cannot start stream output instance, " \
888                               "aborting" );
889             free( psz );
890             return VLC_EGENERIC;
891         }
892         if( libvlc_stats( p_input ) )
893         {
894             INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
895             INIT_COUNTER( sout_sent_bytes, INTEGER, COUNTER );
896             INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
897             if( p_input->p->counters.p_sout_send_bitrate )
898                  p_input->p->counters.p_sout_send_bitrate->update_interval =
899                          1000000;
900         }
901     }
902     else
903     {
904         input_resource_RequestSout( p_input->p->p_resource, NULL, NULL );
905     }
906     free( psz );
907
908     return VLC_SUCCESS;
909 }
910 #endif
911
912 static void InitTitle( input_thread_t * p_input )
913 {
914     input_source_t *p_master = &p_input->p->input;
915
916     if( p_input->b_preparsing )
917         return;
918
919     /* Create global title (from master) */
920     p_input->p->i_title = p_master->i_title;
921     p_input->p->title   = p_master->title;
922     p_input->p->i_title_offset = p_master->i_title_offset;
923     p_input->p->i_seekpoint_offset = p_master->i_seekpoint_offset;
924     if( p_input->p->i_title > 0 )
925     {
926         /* Setup variables */
927         input_ControlVarNavigation( p_input );
928         input_SendEventTitle( p_input, 0 );
929     }
930
931     /* Global flag */
932     p_input->p->b_can_pace_control    = p_master->b_can_pace_control;
933     p_input->p->b_can_pause        = p_master->b_can_pause;
934     p_input->p->b_can_rate_control = p_master->b_can_rate_control;
935 }
936
937 static void StartTitle( input_thread_t * p_input )
938 {
939     vlc_value_t val;
940
941     /* Start title/chapter */
942     val.i_int = p_input->p->input.i_title_start -
943                 p_input->p->input.i_title_offset;
944     if( val.i_int > 0 && val.i_int < p_input->p->input.i_title )
945         input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val );
946
947     val.i_int = p_input->p->input.i_seekpoint_start -
948                 p_input->p->input.i_seekpoint_offset;
949     if( val.i_int > 0 /* TODO: check upper boundary */ )
950         input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &val );
951
952     /* Start/stop/run time */
953     p_input->p->i_start = (int64_t)(1000000.0
954                                      * var_GetFloat( p_input, "start-time" ));
955     p_input->p->i_stop  = (int64_t)(1000000.0
956                                      * var_GetFloat( p_input, "stop-time" ));
957     p_input->p->i_run   = (int64_t)(1000000.0
958                                      * var_GetFloat( p_input, "run-time" ));
959     if( p_input->p->i_run < 0 )
960     {
961         msg_Warn( p_input, "invalid run-time ignored" );
962         p_input->p->i_run = 0;
963     }
964
965     if( p_input->p->i_start > 0 )
966     {
967         vlc_value_t s;
968
969         msg_Dbg( p_input, "starting at time: %ds",
970                  (int)( p_input->p->i_start / INT64_C(1000000) ) );
971
972         s.i_time = p_input->p->i_start;
973         input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &s );
974     }
975     if( p_input->p->i_stop > 0 && p_input->p->i_stop <= p_input->p->i_start )
976     {
977         msg_Warn( p_input, "invalid stop-time ignored" );
978         p_input->p->i_stop = 0;
979     }
980     p_input->p->b_fast_seek = var_GetBool( p_input, "input-fast-seek" );
981 }
982
983 static void LoadSubtitles( input_thread_t *p_input )
984 {
985     /* Load subtitles */
986     /* Get fps and set it if not already set */
987     const double f_fps = p_input->p->f_fps;
988     if( f_fps > 1.0 )
989     {
990         float f_requested_fps;
991
992         var_Create( p_input, "sub-original-fps", VLC_VAR_FLOAT );
993         var_SetFloat( p_input, "sub-original-fps", f_fps );
994
995         f_requested_fps = var_CreateGetFloat( p_input, "sub-fps" );
996         if( f_requested_fps != f_fps )
997         {
998             var_Create( p_input, "sub-fps", VLC_VAR_FLOAT|
999                                             VLC_VAR_DOINHERIT );
1000             var_SetFloat( p_input, "sub-fps", f_requested_fps );
1001         }
1002     }
1003
1004     const int i_delay = var_CreateGetInteger( p_input, "sub-delay" );
1005     if( i_delay != 0 )
1006         var_SetTime( p_input, "spu-delay", (mtime_t)i_delay * 100000 );
1007
1008     /* Look for and add subtitle files */
1009     bool b_forced = true;
1010
1011     char *psz_subtitle = var_GetNonEmptyString( p_input, "sub-file" );
1012     if( psz_subtitle != NULL )
1013     {
1014         msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
1015         SubtitleAdd( p_input, psz_subtitle, b_forced );
1016         b_forced = false;
1017     }
1018
1019     if( var_GetBool( p_input, "sub-autodetect-file" ) )
1020     {
1021         char *psz_autopath = var_GetNonEmptyString( p_input, "sub-autodetect-path" );
1022         char **ppsz_subs = subtitles_Detect( p_input, psz_autopath,
1023                                              p_input->p->p_item->psz_uri );
1024         free( psz_autopath );
1025
1026         for( int i = 0; ppsz_subs && ppsz_subs[i]; i++ )
1027         {
1028             if( !psz_subtitle || strcmp( psz_subtitle, ppsz_subs[i] ) )
1029             {
1030                 SubtitleAdd( p_input, ppsz_subs[i], b_forced );
1031                 b_forced = false;
1032             }
1033
1034             free( ppsz_subs[i] );
1035         }
1036         free( ppsz_subs );
1037     }
1038     free( psz_subtitle );
1039
1040     /* Load subtitles from attachments */
1041     int i_attachment = 0;
1042     input_attachment_t **pp_attachment = NULL;
1043
1044     vlc_mutex_lock( &p_input->p->p_item->lock );
1045     for( int i = 0; i < p_input->p->i_attachment; i++ )
1046     {
1047         const input_attachment_t *a = p_input->p->attachment[i];
1048         if( !strcmp( a->psz_mime, "application/x-srt" ) )
1049             TAB_APPEND( i_attachment, pp_attachment,
1050                         vlc_input_attachment_New( a->psz_name, NULL,
1051                                                   a->psz_description, NULL, 0 ) );
1052     }
1053     vlc_mutex_unlock( &p_input->p->p_item->lock );
1054
1055     if( i_attachment > 0 )
1056         var_Create( p_input, "sub-description", VLC_VAR_STRING );
1057     for( int i = 0; i < i_attachment; i++ )
1058     {
1059         input_attachment_t *a = pp_attachment[i];
1060         if( !a )
1061             continue;
1062         char *psz_mrl;
1063         if( a->psz_name[i] &&
1064             asprintf( &psz_mrl, "attachment://%s", a->psz_name ) >= 0 )
1065         {
1066             var_SetString( p_input, "sub-description", a->psz_description ? a->psz_description : "");
1067
1068             SubtitleAdd( p_input, psz_mrl, b_forced );
1069
1070             b_forced = false;
1071             free( psz_mrl );
1072         }
1073         vlc_input_attachment_Delete( a );
1074     }
1075     free( pp_attachment );
1076     if( i_attachment > 0 )
1077         var_Destroy( p_input, "sub-description" );
1078 }
1079
1080 static void LoadSlaves( input_thread_t *p_input )
1081 {
1082     char *psz = var_GetNonEmptyString( p_input, "input-slave" );
1083     if( !psz )
1084         return;
1085
1086     char *psz_org = psz;
1087     while( psz && *psz )
1088     {
1089         while( *psz == ' ' || *psz == '#' )
1090             psz++;
1091
1092         char *psz_delim = strchr( psz, '#' );
1093         if( psz_delim )
1094             *psz_delim++ = '\0';
1095
1096         if( *psz == 0 )
1097             break;
1098
1099         msg_Dbg( p_input, "adding slave input '%s'", psz );
1100
1101         input_source_t *p_slave = InputSourceNew( p_input );
1102         if( p_slave && !InputSourceInit( p_input, p_slave, psz, NULL ) )
1103             TAB_APPEND( p_input->p->i_slave, p_input->p->slave, p_slave );
1104         else
1105             free( p_slave );
1106
1107         psz = psz_delim;
1108     }
1109     free( psz_org );
1110 }
1111
1112 static void UpdatePtsDelay( input_thread_t *p_input )
1113 {
1114     input_thread_private_t *p_sys = p_input->p;
1115
1116     /* Get max pts delay from input source */
1117     mtime_t i_pts_delay = p_sys->input.i_pts_delay;
1118     for( int i = 0; i < p_sys->i_slave; i++ )
1119         i_pts_delay = __MAX( i_pts_delay, p_sys->slave[i]->i_pts_delay );
1120
1121     if( i_pts_delay < 0 )
1122         i_pts_delay = 0;
1123
1124     /* Take care of audio/spu delay */
1125     const mtime_t i_audio_delay = var_GetTime( p_input, "audio-delay" );
1126     const mtime_t i_spu_delay   = var_GetTime( p_input, "spu-delay" );
1127     const mtime_t i_extra_delay = __MIN( i_audio_delay, i_spu_delay );
1128     if( i_extra_delay < 0 )
1129         i_pts_delay -= i_extra_delay;
1130
1131     /* Update cr_average depending on the caching */
1132     const int i_cr_average = var_GetInteger( p_input, "cr-average" ) * i_pts_delay / DEFAULT_PTS_DELAY;
1133
1134     /* */
1135     es_out_SetJitter( p_input->p->p_es_out, i_pts_delay, i_cr_average );
1136 }
1137
1138 static void InitPrograms( input_thread_t * p_input )
1139 {
1140     int i_es_out_mode;
1141     vlc_value_t val;
1142
1143     /* Compute correct pts_delay */
1144     UpdatePtsDelay( p_input );
1145
1146     /* Set up es_out */
1147     i_es_out_mode = ES_OUT_MODE_AUTO;
1148     if( p_input->p->p_sout )
1149     {
1150         if( var_GetBool( p_input, "sout-all" ) )
1151         {
1152             i_es_out_mode = ES_OUT_MODE_ALL;
1153         }
1154         else
1155         {
1156             var_Get( p_input, "programs", &val );
1157             if( val.p_list && val.p_list->i_count )
1158             {
1159                 i_es_out_mode = ES_OUT_MODE_PARTIAL;
1160                 /* Note : we should remove the "program" callback. */
1161             }
1162             else
1163             {
1164                 var_FreeList( &val, NULL );
1165             }
1166         }
1167     }
1168     es_out_SetMode( p_input->p->p_es_out, i_es_out_mode );
1169
1170     /* Inform the demuxer about waited group (needed only for DVB) */
1171     if( i_es_out_mode == ES_OUT_MODE_ALL )
1172     {
1173         demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1, NULL );
1174     }
1175     else if( i_es_out_mode == ES_OUT_MODE_PARTIAL )
1176     {
1177         demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1,
1178                         val.p_list );
1179     }
1180     else
1181     {
1182         demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP,
1183                        (int) var_GetInteger( p_input, "program" ), NULL );
1184     }
1185 }
1186
1187 static int Init( input_thread_t * p_input )
1188 {
1189     vlc_meta_t *p_meta;
1190     int i;
1191
1192     for( i = 0; i < p_input->p->p_item->i_options; i++ )
1193     {
1194         if( !strncmp( p_input->p->p_item->ppsz_options[i], "meta-file", 9 ) )
1195         {
1196             msg_Dbg( p_input, "Input is a meta file: disabling unneeded options" );
1197             var_SetString( p_input, "sout", "" );
1198             var_SetBool( p_input, "sout-all", false );
1199             var_SetString( p_input, "input-slave", "" );
1200             var_SetInteger( p_input, "input-repeat", 0 );
1201             var_SetString( p_input, "sub-file", "" );
1202             var_SetBool( p_input, "sub-autodetect-file", false );
1203         }
1204     }
1205
1206     InitStatistics( p_input );
1207 #ifdef ENABLE_SOUT
1208     if( InitSout( p_input ) )
1209         goto error_stats;
1210 #endif
1211
1212     /* Create es out */
1213     p_input->p->p_es_out = input_EsOutTimeshiftNew( p_input, p_input->p->p_es_out_display, p_input->p->i_rate );
1214
1215     /* */
1216     input_ChangeState( p_input, OPENING_S );
1217     input_SendEventCache( p_input, 0.0 );
1218
1219     /* */
1220     if( InputSourceInit( p_input, &p_input->p->input,
1221                          p_input->p->p_item->psz_uri, NULL ) )
1222     {
1223         goto error;
1224     }
1225
1226     InitTitle( p_input );
1227
1228     /* Load master infos */
1229     /* Init length */
1230     mtime_t i_length;
1231     if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH,
1232                          &i_length ) )
1233         i_length = 0;
1234     if( i_length <= 0 )
1235         i_length = input_item_GetDuration( p_input->p->p_item );
1236     input_SendEventLength( p_input, i_length );
1237
1238     input_SendEventPosition( p_input, 0.0, 0 );
1239
1240     if( !p_input->b_preparsing )
1241     {
1242         StartTitle( p_input );
1243         LoadSubtitles( p_input );
1244         LoadSlaves( p_input );
1245         InitPrograms( p_input );
1246     }
1247
1248     if( !p_input->b_preparsing && p_input->p->p_sout )
1249     {
1250         p_input->p->b_out_pace_control = (p_input->p->p_sout->i_out_pace_nocontrol > 0);
1251
1252         if( p_input->p->b_can_pace_control && p_input->p->b_out_pace_control )
1253         {
1254             /* We don't want a high input priority here or we'll
1255              * end-up sucking up all the CPU time */
1256             vlc_thread_set_priority( p_input, VLC_THREAD_PRIORITY_LOW );
1257         }
1258
1259         msg_Dbg( p_input, "starting in %s mode",
1260                  p_input->p->b_out_pace_control ? "async" : "sync" );
1261     }
1262
1263     p_meta = vlc_meta_New();
1264     if( p_meta )
1265     {
1266         /* Get meta data from users */
1267         InputMetaUser( p_input, p_meta );
1268
1269         /* Get meta data from master input */
1270         InputSourceMeta( p_input, &p_input->p->input, p_meta );
1271
1272         /* And from slave */
1273         for( int i = 0; i < p_input->p->i_slave; i++ )
1274             InputSourceMeta( p_input, p_input->p->slave[i], p_meta );
1275
1276         /* */
1277         InputUpdateMeta( p_input, p_meta );
1278     }
1279
1280     msg_Dbg( p_input, "`%s' successfully opened",
1281              p_input->p->p_item->psz_uri );
1282
1283     /* initialization is complete */
1284     input_ChangeState( p_input, PLAYING_S );
1285
1286     return VLC_SUCCESS;
1287
1288 error:
1289     input_ChangeState( p_input, ERROR_S );
1290
1291     if( p_input->p->p_es_out )
1292         es_out_Delete( p_input->p->p_es_out );
1293     es_out_SetMode( p_input->p->p_es_out_display, ES_OUT_MODE_END );
1294     if( p_input->p->p_resource )
1295     {
1296         if( p_input->p->p_sout )
1297             input_resource_RequestSout( p_input->p->p_resource,
1298                                          p_input->p->p_sout, NULL );
1299         input_resource_SetInput( p_input->p->p_resource, NULL );
1300     }
1301
1302 #ifdef ENABLE_SOUT
1303 error_stats:
1304 #endif
1305     if( !p_input->b_preparsing && libvlc_stats( p_input ) )
1306     {
1307 #define EXIT_COUNTER( c ) do { if( p_input->p->counters.p_##c ) \
1308                                    stats_CounterClean( p_input->p->counters.p_##c );\
1309                                p_input->p->counters.p_##c = NULL; } while(0)
1310         EXIT_COUNTER( read_bytes );
1311         EXIT_COUNTER( read_packets );
1312         EXIT_COUNTER( demux_read );
1313         EXIT_COUNTER( input_bitrate );
1314         EXIT_COUNTER( demux_bitrate );
1315         EXIT_COUNTER( demux_corrupted );
1316         EXIT_COUNTER( demux_discontinuity );
1317         EXIT_COUNTER( played_abuffers );
1318         EXIT_COUNTER( lost_abuffers );
1319         EXIT_COUNTER( displayed_pictures );
1320         EXIT_COUNTER( lost_pictures );
1321         EXIT_COUNTER( decoded_audio );
1322         EXIT_COUNTER( decoded_video );
1323         EXIT_COUNTER( decoded_sub );
1324
1325         if( p_input->p->p_sout )
1326         {
1327             EXIT_COUNTER( sout_sent_packets );
1328             EXIT_COUNTER( sout_sent_bytes );
1329             EXIT_COUNTER( sout_send_bitrate );
1330         }
1331 #undef EXIT_COUNTER
1332     }
1333
1334     /* Mark them deleted */
1335     p_input->p->input.p_demux = NULL;
1336     p_input->p->input.p_stream = NULL;
1337     p_input->p->input.p_access = NULL;
1338     p_input->p->p_es_out = NULL;
1339     p_input->p->p_sout = NULL;
1340
1341     return VLC_EGENERIC;
1342 }
1343
1344 /*****************************************************************************
1345  * End: end the input thread
1346  *****************************************************************************/
1347 static void End( input_thread_t * p_input )
1348 {
1349     int i;
1350
1351     /* We are at the end */
1352     input_ChangeState( p_input, END_S );
1353
1354     /* Clean control variables */
1355     input_ControlVarStop( p_input );
1356
1357     /* Stop es out activity */
1358     es_out_SetMode( p_input->p->p_es_out, ES_OUT_MODE_NONE );
1359
1360     /* Clean up master */
1361     InputSourceClean( &p_input->p->input );
1362
1363     /* Delete slave */
1364     for( i = 0; i < p_input->p->i_slave; i++ )
1365     {
1366         InputSourceClean( p_input->p->slave[i] );
1367         free( p_input->p->slave[i] );
1368     }
1369     free( p_input->p->slave );
1370
1371     /* Unload all modules */
1372     if( p_input->p->p_es_out )
1373         es_out_Delete( p_input->p->p_es_out );
1374     es_out_SetMode( p_input->p->p_es_out_display, ES_OUT_MODE_END );
1375
1376     if( !p_input->b_preparsing )
1377     {
1378 #define CL_CO( c ) stats_CounterClean( p_input->p->counters.p_##c ); p_input->p->counters.p_##c = NULL;
1379         if( libvlc_stats( p_input ) )
1380         {
1381             /* make sure we are up to date */
1382             stats_ComputeInputStats( p_input, p_input->p->p_item->p_stats );
1383             CL_CO( read_bytes );
1384             CL_CO( read_packets );
1385             CL_CO( demux_read );
1386             CL_CO( input_bitrate );
1387             CL_CO( demux_bitrate );
1388             CL_CO( demux_corrupted );
1389             CL_CO( demux_discontinuity );
1390             CL_CO( played_abuffers );
1391             CL_CO( lost_abuffers );
1392             CL_CO( displayed_pictures );
1393             CL_CO( lost_pictures );
1394             CL_CO( decoded_audio) ;
1395             CL_CO( decoded_video );
1396             CL_CO( decoded_sub) ;
1397         }
1398
1399         /* Close optional stream output instance */
1400         if( p_input->p->p_sout )
1401         {
1402             CL_CO( sout_sent_packets );
1403             CL_CO( sout_sent_bytes );
1404             CL_CO( sout_send_bitrate );
1405         }
1406 #undef CL_CO
1407     }
1408
1409     vlc_mutex_lock( &p_input->p->p_item->lock );
1410     if( p_input->p->i_attachment > 0 )
1411     {
1412         for( i = 0; i < p_input->p->i_attachment; i++ )
1413             vlc_input_attachment_Delete( p_input->p->attachment[i] );
1414         TAB_CLEAN( p_input->p->i_attachment, p_input->p->attachment );
1415     }
1416     vlc_mutex_unlock( &p_input->p->p_item->lock );
1417
1418     /* */
1419     input_resource_RequestSout( p_input->p->p_resource,
1420                                  p_input->p->p_sout, NULL );
1421     input_resource_SetInput( p_input->p->p_resource, NULL );
1422 }
1423
1424 /*****************************************************************************
1425  * Control
1426  *****************************************************************************/
1427 void input_ControlPush( input_thread_t *p_input,
1428                         int i_type, vlc_value_t *p_val )
1429 {
1430     vlc_mutex_lock( &p_input->p->lock_control );
1431     if( i_type == INPUT_CONTROL_SET_DIE )
1432     {
1433         /* Special case, empty the control */
1434         for( int i = 0; i < p_input->p->i_control; i++ )
1435         {
1436             input_control_t *p_ctrl = &p_input->p->control[i];
1437             ControlRelease( p_ctrl->i_type, p_ctrl->val );
1438         }
1439         p_input->p->i_control = 0;
1440     }
1441
1442     if( p_input->p->i_control >= INPUT_CONTROL_FIFO_SIZE )
1443     {
1444         msg_Err( p_input, "input control fifo overflow, trashing type=%d",
1445                  i_type );
1446         if( p_val )
1447             ControlRelease( i_type, *p_val );
1448     }
1449     else
1450     {
1451         input_control_t c;
1452         c.i_type = i_type;
1453         if( p_val )
1454             c.val = *p_val;
1455         else
1456             memset( &c.val, 0, sizeof(c.val) );
1457
1458         p_input->p->control[p_input->p->i_control++] = c;
1459     }
1460     vlc_cond_signal( &p_input->p->wait_control );
1461     vlc_mutex_unlock( &p_input->p->lock_control );
1462 }
1463
1464 static int ControlGetReducedIndexLocked( input_thread_t *p_input )
1465 {
1466     const int i_lt = p_input->p->control[0].i_type;
1467     int i;
1468     for( i = 1; i < p_input->p->i_control; i++ )
1469     {
1470         const int i_ct = p_input->p->control[i].i_type;
1471
1472         if( i_lt == i_ct &&
1473             ( i_ct == INPUT_CONTROL_SET_STATE ||
1474               i_ct == INPUT_CONTROL_SET_RATE ||
1475               i_ct == INPUT_CONTROL_SET_POSITION ||
1476               i_ct == INPUT_CONTROL_SET_TIME ||
1477               i_ct == INPUT_CONTROL_SET_PROGRAM ||
1478               i_ct == INPUT_CONTROL_SET_TITLE ||
1479               i_ct == INPUT_CONTROL_SET_SEEKPOINT ||
1480               i_ct == INPUT_CONTROL_SET_BOOKMARK ) )
1481         {
1482             continue;
1483         }
1484         else
1485         {
1486             /* TODO but that's not that important
1487                 - merge SET_X with SET_X_CMD
1488                 - ignore SET_SEEKPOINT/SET_POSITION/SET_TIME before a SET_TITLE
1489                 - ignore SET_SEEKPOINT/SET_POSITION/SET_TIME before another among them
1490                 - ?
1491                 */
1492             break;
1493         }
1494     }
1495     return i - 1;
1496 }
1497
1498
1499 static inline int ControlPop( input_thread_t *p_input,
1500                               int *pi_type, vlc_value_t *p_val,
1501                               mtime_t i_deadline, bool b_postpone_seek )
1502 {
1503     input_thread_private_t *p_sys = p_input->p;
1504
1505     vlc_mutex_lock( &p_sys->lock_control );
1506     while( p_sys->i_control <= 0 ||
1507            ( b_postpone_seek && ControlIsSeekRequest( p_sys->control[0].i_type ) ) )
1508     {
1509         if( !vlc_object_alive( p_input ) || i_deadline < 0 )
1510         {
1511             vlc_mutex_unlock( &p_sys->lock_control );
1512             return VLC_EGENERIC;
1513         }
1514
1515         if( vlc_cond_timedwait( &p_sys->wait_control, &p_sys->lock_control,
1516                                 i_deadline ) )
1517         {
1518             vlc_mutex_unlock( &p_sys->lock_control );
1519             return VLC_EGENERIC;
1520         }
1521     }
1522
1523     /* */
1524     const int i_index = ControlGetReducedIndexLocked( p_input );
1525
1526     /* */
1527     *pi_type = p_sys->control[i_index].i_type;
1528     *p_val   = p_sys->control[i_index].val;
1529
1530     p_sys->i_control -= i_index + 1;
1531     if( p_sys->i_control > 0 )
1532         memmove( &p_sys->control[0], &p_sys->control[i_index+1],
1533                  sizeof(*p_sys->control) * p_sys->i_control );
1534     vlc_mutex_unlock( &p_sys->lock_control );
1535
1536     return VLC_SUCCESS;
1537 }
1538 static bool ControlIsSeekRequest( int i_type )
1539 {
1540     switch( i_type )
1541     {
1542     case INPUT_CONTROL_SET_POSITION:
1543     case INPUT_CONTROL_SET_TIME:
1544     case INPUT_CONTROL_SET_TITLE:
1545     case INPUT_CONTROL_SET_TITLE_NEXT:
1546     case INPUT_CONTROL_SET_TITLE_PREV:
1547     case INPUT_CONTROL_SET_SEEKPOINT:
1548     case INPUT_CONTROL_SET_SEEKPOINT_NEXT:
1549     case INPUT_CONTROL_SET_SEEKPOINT_PREV:
1550     case INPUT_CONTROL_SET_BOOKMARK:
1551         return true;
1552     default:
1553         return false;
1554     }
1555 }
1556
1557 static void ControlRelease( int i_type, vlc_value_t val )
1558 {
1559     switch( i_type )
1560     {
1561     case INPUT_CONTROL_ADD_SUBTITLE:
1562     case INPUT_CONTROL_ADD_SLAVE:
1563         free( val.psz_string );
1564         break;
1565
1566     default:
1567         break;
1568     }
1569 }
1570
1571 /* Pause input */
1572 static void ControlPause( input_thread_t *p_input, mtime_t i_control_date )
1573 {
1574     int i_ret = VLC_SUCCESS;
1575     int i_state = PAUSE_S;
1576
1577     if( p_input->p->b_can_pause )
1578     {
1579         if( p_input->p->input.p_access )
1580             i_ret = access_Control( p_input->p->input.p_access,
1581                                      ACCESS_SET_PAUSE_STATE, true );
1582         else
1583             i_ret = demux_Control( p_input->p->input.p_demux,
1584                                     DEMUX_SET_PAUSE_STATE, true );
1585
1586         if( i_ret )
1587         {
1588             msg_Warn( p_input, "cannot set pause state" );
1589             return;
1590         }
1591     }
1592
1593     /* */
1594     i_ret = es_out_SetPauseState( p_input->p->p_es_out,
1595                                   p_input->p->b_can_pause, true,
1596                                   i_control_date );
1597     if( i_ret )
1598     {
1599         msg_Warn( p_input, "cannot set pause state at es_out level" );
1600         return;
1601     }
1602
1603     /* Switch to new state */
1604     input_ChangeState( p_input, i_state );
1605 }
1606
1607 static void ControlUnpause( input_thread_t *p_input, mtime_t i_control_date )
1608 {
1609     int i_ret = VLC_SUCCESS;
1610
1611     if( p_input->p->b_can_pause )
1612     {
1613         if( p_input->p->input.p_access )
1614             i_ret = access_Control( p_input->p->input.p_access,
1615                                      ACCESS_SET_PAUSE_STATE, false );
1616         else
1617             i_ret = demux_Control( p_input->p->input.p_demux,
1618                                     DEMUX_SET_PAUSE_STATE, false );
1619         if( i_ret )
1620         {
1621             /* FIXME What to do ? */
1622             msg_Warn( p_input, "cannot unset pause -> EOF" );
1623             input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
1624         }
1625     }
1626
1627     /* Switch to play */
1628     input_ChangeState( p_input, PLAYING_S );
1629
1630     /* */
1631     if( !i_ret )
1632         es_out_SetPauseState( p_input->p->p_es_out, false, false, i_control_date );
1633 }
1634
1635 static bool Control( input_thread_t *p_input,
1636                      int i_type, vlc_value_t val )
1637 {
1638     const mtime_t i_control_date = mdate();
1639     /* FIXME b_force_update is abused, it should be carefully checked */
1640     bool b_force_update = false;
1641
1642     if( !p_input )
1643         return b_force_update;
1644
1645     switch( i_type )
1646     {
1647         case INPUT_CONTROL_SET_DIE:
1648             msg_Dbg( p_input, "control: stopping input" );
1649
1650             /* Mark all submodules to die */
1651             ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
1652             break;
1653
1654         case INPUT_CONTROL_SET_POSITION:
1655         {
1656             double f_pos;
1657
1658             if( p_input->p->b_recording )
1659             {
1660                 msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) ignored while recording" );
1661                 break;
1662             }
1663             f_pos = val.f_float;
1664             if( i_type != INPUT_CONTROL_SET_POSITION )
1665                 f_pos += var_GetFloat( p_input, "position" );
1666             if( f_pos < 0.0 )
1667                 f_pos = 0.0;
1668             else if( f_pos > 1.0 )
1669                 f_pos = 1.0;
1670             /* Reset the decoders states and clock sync (before calling the demuxer */
1671             es_out_SetTime( p_input->p->p_es_out, -1 );
1672             if( demux_Control( p_input->p->input.p_demux, DEMUX_SET_POSITION,
1673                                 f_pos, !p_input->p->b_fast_seek ) )
1674             {
1675                 msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) "
1676                          "%2.1f%% failed", f_pos * 100 );
1677             }
1678             else
1679             {
1680                 if( p_input->p->i_slave > 0 )
1681                     SlaveSeek( p_input );
1682                 p_input->p->input.b_eof = false;
1683
1684                 b_force_update = true;
1685             }
1686             break;
1687         }
1688
1689         case INPUT_CONTROL_SET_TIME:
1690         {
1691             int64_t i_time;
1692             int i_ret;
1693
1694             if( p_input->p->b_recording )
1695             {
1696                 msg_Err( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) ignored while recording" );
1697                 break;
1698             }
1699
1700             i_time = val.i_time;
1701             if( i_type != INPUT_CONTROL_SET_TIME )
1702                 i_time += var_GetTime( p_input, "time" );
1703
1704             if( i_time < 0 )
1705                 i_time = 0;
1706
1707             /* Reset the decoders states and clock sync (before calling the demuxer */
1708             es_out_SetTime( p_input->p->p_es_out, -1 );
1709
1710             i_ret = demux_Control( p_input->p->input.p_demux,
1711                                    DEMUX_SET_TIME, i_time,
1712                                    !p_input->p->b_fast_seek );
1713             if( i_ret )
1714             {
1715                 int64_t i_length;
1716
1717                 /* Emulate it with a SET_POS */
1718                 if( !demux_Control( p_input->p->input.p_demux,
1719                                     DEMUX_GET_LENGTH, &i_length ) && i_length > 0 )
1720                 {
1721                     double f_pos = (double)i_time / (double)i_length;
1722                     i_ret = demux_Control( p_input->p->input.p_demux,
1723                                             DEMUX_SET_POSITION, f_pos,
1724                                             !p_input->p->b_fast_seek );
1725                 }
1726             }
1727             if( i_ret )
1728             {
1729                 msg_Warn( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) %"PRId64
1730                          " failed or not possible", i_time );
1731             }
1732             else
1733             {
1734                 if( p_input->p->i_slave > 0 )
1735                     SlaveSeek( p_input );
1736                 p_input->p->input.b_eof = false;
1737
1738                 b_force_update = true;
1739             }
1740             break;
1741         }
1742
1743         case INPUT_CONTROL_SET_STATE:
1744             if( val.i_int != PLAYING_S && val.i_int != PAUSE_S )
1745                 msg_Err( p_input, "invalid state in INPUT_CONTROL_SET_STATE" );
1746             else if( p_input->p->i_state == PAUSE_S )
1747             {
1748                 ControlUnpause( p_input, i_control_date );
1749
1750                 b_force_update = true;
1751             }
1752             else if( val.i_int == PAUSE_S && p_input->p->i_state == PLAYING_S /* &&
1753                      p_input->p->b_can_pause */ )
1754             {
1755                 ControlPause( p_input, i_control_date );
1756
1757                 b_force_update = true;
1758             }
1759             else if( val.i_int == PAUSE_S && !p_input->p->b_can_pause && 0 )
1760             {
1761                 b_force_update = true;
1762
1763                 /* Correct "state" value */
1764                 input_ChangeState( p_input, p_input->p->i_state );
1765             }
1766             break;
1767
1768         case INPUT_CONTROL_SET_RATE:
1769         case INPUT_CONTROL_SET_RATE_SLOWER:
1770         case INPUT_CONTROL_SET_RATE_FASTER:
1771         {
1772             int i_rate;
1773             int i_rate_sign;
1774
1775             /* Get rate and direction */
1776             if( i_type == INPUT_CONTROL_SET_RATE )
1777             {
1778                 i_rate = abs( val.i_int );
1779                 i_rate_sign = val.i_int < 0 ? -1 : 1;
1780             }
1781             else
1782             {
1783                 static const int ppi_factor[][2] = {
1784                     {1,64}, {1,32}, {1,16}, {1,8}, {1,4}, {1,3}, {1,2}, {2,3},
1785                     {1,1},
1786                     {3,2}, {2,1}, {3,1}, {4,1}, {8,1}, {16,1}, {32,1}, {64,1},
1787                     {0,0}
1788                 };
1789                 int i_error;
1790                 int i_idx;
1791                 int i;
1792
1793                 i_rate_sign = p_input->p->i_rate < 0 ? -1 : 1;
1794
1795                 i_error = INT_MAX;
1796                 i_idx = -1;
1797                 for( i = 0; ppi_factor[i][0] != 0; i++ )
1798                 {
1799                     const int i_test_r = INPUT_RATE_DEFAULT * ppi_factor[i][0] / ppi_factor[i][1];
1800                     const int i_test_e = abs( abs( p_input->p->i_rate ) - i_test_r );
1801                     if( i_test_e < i_error )
1802                     {
1803                         i_idx = i;
1804                         i_error = i_test_e;
1805                     }
1806                 }
1807
1808                 assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 );
1809
1810                 if( i_type == INPUT_CONTROL_SET_RATE_SLOWER )
1811                 {
1812                     if( ppi_factor[i_idx+1][0] > 0 )
1813                         i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx+1][0] / ppi_factor[i_idx+1][1];
1814                     else
1815                         i_rate = INPUT_RATE_MAX+1;
1816                 }
1817                 else
1818                 {
1819                     assert( i_type == INPUT_CONTROL_SET_RATE_FASTER );
1820                     if( i_idx > 0 )
1821                         i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx-1][0] / ppi_factor[i_idx-1][1];
1822                     else
1823                         i_rate = INPUT_RATE_MIN-1;
1824                 }
1825             }
1826
1827             /* Check rate bound */
1828             if( i_rate < INPUT_RATE_MIN )
1829             {
1830                 msg_Dbg( p_input, "cannot set rate faster" );
1831                 i_rate = INPUT_RATE_MIN;
1832             }
1833             else if( i_rate > INPUT_RATE_MAX )
1834             {
1835                 msg_Dbg( p_input, "cannot set rate slower" );
1836                 i_rate = INPUT_RATE_MAX;
1837             }
1838
1839             /* Apply direction */
1840             if( i_rate_sign < 0 )
1841             {
1842                 if( p_input->p->input.b_rescale_ts )
1843                 {
1844                     msg_Dbg( p_input, "cannot set negative rate" );
1845                     i_rate = p_input->p->i_rate;
1846                     assert( i_rate > 0 );
1847                 }
1848                 else
1849                 {
1850                     i_rate *= i_rate_sign;
1851                 }
1852             }
1853
1854             if( i_rate != INPUT_RATE_DEFAULT &&
1855                 ( ( !p_input->p->b_can_rate_control && !p_input->p->input.b_rescale_ts ) ||
1856                   ( p_input->p->p_sout && !p_input->p->b_out_pace_control ) ) )
1857             {
1858                 msg_Dbg( p_input, "cannot change rate" );
1859                 i_rate = INPUT_RATE_DEFAULT;
1860             }
1861             if( i_rate != p_input->p->i_rate &&
1862                 !p_input->p->b_can_pace_control && p_input->p->b_can_rate_control )
1863             {
1864                 int i_ret;
1865                 if( p_input->p->input.p_access )
1866                 {
1867                     i_ret = VLC_EGENERIC;
1868                 }
1869                 else
1870                 {
1871                     if( !p_input->p->input.b_rescale_ts )
1872                         es_out_Control( p_input->p->p_es_out, ES_OUT_RESET_PCR );
1873
1874                     i_ret = demux_Control( p_input->p->input.p_demux,
1875                                             DEMUX_SET_RATE, &i_rate );
1876                 }
1877                 if( i_ret )
1878                 {
1879                     msg_Warn( p_input, "ACCESS/DEMUX_SET_RATE failed" );
1880                     i_rate = p_input->p->i_rate;
1881                 }
1882             }
1883
1884             /* */
1885             if( i_rate != p_input->p->i_rate )
1886             {
1887                 p_input->p->i_rate = i_rate;
1888                 input_SendEventRate( p_input, i_rate );
1889
1890                 if( p_input->p->input.b_rescale_ts )
1891                 {
1892                     const int i_rate_source = (p_input->p->b_can_pace_control || p_input->p->b_can_rate_control ) ? i_rate : INPUT_RATE_DEFAULT;
1893                     es_out_SetRate( p_input->p->p_es_out, i_rate_source, i_rate );
1894                 }
1895
1896                 b_force_update = true;
1897             }
1898             break;
1899         }
1900
1901         case INPUT_CONTROL_SET_PROGRAM:
1902             /* No need to force update, es_out does it if needed */
1903             es_out_Control( p_input->p->p_es_out,
1904                             ES_OUT_SET_GROUP, val.i_int );
1905
1906             demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, val.i_int,
1907                             NULL );
1908             break;
1909
1910         case INPUT_CONTROL_SET_ES:
1911             /* No need to force update, es_out does it if needed */
1912             es_out_Control( p_input->p->p_es_out_display, ES_OUT_SET_ES_BY_ID, val.i_int );
1913             break;
1914
1915         case INPUT_CONTROL_RESTART_ES:
1916             es_out_Control( p_input->p->p_es_out_display, ES_OUT_RESTART_ES_BY_ID, val.i_int );
1917             break;
1918
1919         case INPUT_CONTROL_SET_AUDIO_DELAY:
1920             if( !es_out_SetDelay( p_input->p->p_es_out_display, AUDIO_ES, val.i_time ) )
1921             {
1922                 input_SendEventAudioDelay( p_input, val.i_time );
1923                 UpdatePtsDelay( p_input );
1924             }
1925             break;
1926
1927         case INPUT_CONTROL_SET_SPU_DELAY:
1928             if( !es_out_SetDelay( p_input->p->p_es_out_display, SPU_ES, val.i_time ) )
1929             {
1930                 input_SendEventSubtitleDelay( p_input, val.i_time );
1931                 UpdatePtsDelay( p_input );
1932             }
1933             break;
1934
1935         case INPUT_CONTROL_SET_TITLE:
1936         case INPUT_CONTROL_SET_TITLE_NEXT:
1937         case INPUT_CONTROL_SET_TITLE_PREV:
1938             if( p_input->p->b_recording )
1939             {
1940                 msg_Err( p_input, "INPUT_CONTROL_SET_TITLE(*) ignored while recording" );
1941                 break;
1942             }
1943             if( p_input->p->input.b_title_demux &&
1944                 p_input->p->input.i_title > 0 )
1945             {
1946                 /* TODO */
1947                 /* FIXME handle demux title */
1948                 demux_t *p_demux = p_input->p->input.p_demux;
1949                 int i_title;
1950
1951                 if( i_type == INPUT_CONTROL_SET_TITLE_PREV )
1952                     i_title = p_demux->info.i_title - 1;
1953                 else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT )
1954                     i_title = p_demux->info.i_title + 1;
1955                 else
1956                     i_title = val.i_int;
1957
1958                 if( i_title >= 0 && i_title < p_input->p->input.i_title )
1959                 {
1960                     es_out_SetTime( p_input->p->p_es_out, -1 );
1961
1962                     demux_Control( p_demux, DEMUX_SET_TITLE, i_title );
1963                     input_SendEventTitle( p_input, i_title );
1964                 }
1965             }
1966             else if( p_input->p->input.i_title > 0 )
1967             {
1968                 access_t *p_access = p_input->p->input.p_access;
1969                 int i_title;
1970
1971                 if( i_type == INPUT_CONTROL_SET_TITLE_PREV )
1972                     i_title = p_access->info.i_title - 1;
1973                 else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT )
1974                     i_title = p_access->info.i_title + 1;
1975                 else
1976                     i_title = val.i_int;
1977
1978                 if( i_title >= 0 && i_title < p_input->p->input.i_title )
1979                 {
1980                     es_out_SetTime( p_input->p->p_es_out, -1 );
1981
1982                     stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
1983                                     ACCESS_SET_TITLE, i_title );
1984                     input_SendEventTitle( p_input, i_title );
1985                 }
1986             }
1987             break;
1988         case INPUT_CONTROL_SET_SEEKPOINT:
1989         case INPUT_CONTROL_SET_SEEKPOINT_NEXT:
1990         case INPUT_CONTROL_SET_SEEKPOINT_PREV:
1991             if( p_input->p->b_recording )
1992             {
1993                 msg_Err( p_input, "INPUT_CONTROL_SET_SEEKPOINT(*) ignored while recording" );
1994                 break;
1995             }
1996
1997             if( p_input->p->input.b_title_demux &&
1998                 p_input->p->input.i_title > 0 )
1999             {
2000                 demux_t *p_demux = p_input->p->input.p_demux;
2001                 int i_seekpoint;
2002                 int64_t i_input_time;
2003                 int64_t i_seekpoint_time;
2004
2005                 if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV )
2006                 {
2007                     i_seekpoint = p_demux->info.i_seekpoint;
2008                     i_seekpoint_time = p_input->p->input.title[p_demux->info.i_title]->seekpoint[i_seekpoint]->i_time_offset;
2009                     i_input_time = var_GetTime( p_input, "time" );
2010                     if( i_seekpoint_time >= 0 && i_input_time >= 0 )
2011                     {
2012                         if( i_input_time < i_seekpoint_time + 3000000 )
2013                             i_seekpoint--;
2014                     }
2015                     else
2016                         i_seekpoint--;
2017                 }
2018                 else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT )
2019                     i_seekpoint = p_demux->info.i_seekpoint + 1;
2020                 else
2021                     i_seekpoint = val.i_int;
2022
2023                 if( i_seekpoint >= 0 && i_seekpoint <
2024                     p_input->p->input.title[p_demux->info.i_title]->i_seekpoint )
2025                 {
2026
2027                     es_out_SetTime( p_input->p->p_es_out, -1 );
2028
2029                     demux_Control( p_demux, DEMUX_SET_SEEKPOINT, i_seekpoint );
2030                     input_SendEventSeekpoint( p_input, p_demux->info.i_title, i_seekpoint );
2031                 }
2032             }
2033             else if( p_input->p->input.i_title > 0 )
2034             {
2035                 access_t *p_access = p_input->p->input.p_access;
2036                 int i_seekpoint;
2037                 int64_t i_input_time;
2038                 int64_t i_seekpoint_time;
2039
2040                 if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV )
2041                 {
2042                     i_seekpoint = p_access->info.i_seekpoint;
2043                     i_seekpoint_time = p_input->p->input.title[p_access->info.i_title]->seekpoint[i_seekpoint]->i_time_offset;
2044                     i_input_time = var_GetTime( p_input, "time" );
2045                     if( i_seekpoint_time >= 0 && i_input_time >= 0 )
2046                     {
2047                         if( i_input_time < i_seekpoint_time + 3000000 )
2048                             i_seekpoint--;
2049                     }
2050                     else
2051                         i_seekpoint--;
2052                 }
2053                 else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT )
2054                     i_seekpoint = p_access->info.i_seekpoint + 1;
2055                 else
2056                     i_seekpoint = val.i_int;
2057
2058                 if( i_seekpoint >= 0 && i_seekpoint <
2059                     p_input->p->input.title[p_access->info.i_title]->i_seekpoint )
2060                 {
2061                     es_out_SetTime( p_input->p->p_es_out, -1 );
2062
2063                     stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
2064                                     ACCESS_SET_SEEKPOINT, i_seekpoint );
2065                     input_SendEventSeekpoint( p_input, p_access->info.i_title, i_seekpoint );
2066                 }
2067             }
2068             break;
2069
2070         case INPUT_CONTROL_ADD_SUBTITLE:
2071             if( val.psz_string )
2072                 SubtitleAdd( p_input, val.psz_string, true );
2073             break;
2074
2075         case INPUT_CONTROL_ADD_SLAVE:
2076             if( val.psz_string )
2077             {
2078                 input_source_t *slave = InputSourceNew( p_input );
2079
2080                 if( slave && !InputSourceInit( p_input, slave, val.psz_string, NULL ) )
2081                 {
2082                     vlc_meta_t *p_meta;
2083                     int64_t i_time;
2084
2085                     /* Add the slave */
2086                     msg_Dbg( p_input, "adding %s as slave on the fly",
2087                              val.psz_string );
2088
2089                     /* Set position */
2090                     if( demux_Control( p_input->p->input.p_demux,
2091                                         DEMUX_GET_TIME, &i_time ) )
2092                     {
2093                         msg_Err( p_input, "demux doesn't like DEMUX_GET_TIME" );
2094                         InputSourceClean( slave );
2095                         free( slave );
2096                         break;
2097                     }
2098                     if( demux_Control( slave->p_demux,
2099                                        DEMUX_SET_TIME, i_time, true ) )
2100                     {
2101                         msg_Err( p_input, "seek failed for new slave" );
2102                         InputSourceClean( slave );
2103                         free( slave );
2104                         break;
2105                     }
2106
2107                     /* Get meta (access and demux) */
2108                     p_meta = vlc_meta_New();
2109                     if( p_meta )
2110                     {
2111                         access_Control( slave->p_access, ACCESS_GET_META, p_meta );
2112                         demux_Control( slave->p_demux, DEMUX_GET_META, p_meta );
2113                         InputUpdateMeta( p_input, p_meta );
2114                     }
2115
2116                     TAB_APPEND( p_input->p->i_slave, p_input->p->slave, slave );
2117                 }
2118                 else
2119                 {
2120                     free( slave );
2121                     msg_Warn( p_input, "failed to add %s as slave",
2122                               val.psz_string );
2123                 }
2124             }
2125             break;
2126
2127         case INPUT_CONTROL_SET_RECORD_STATE:
2128             if( !!p_input->p->b_recording != !!val.b_bool )
2129             {
2130                 if( p_input->p->input.b_can_stream_record )
2131                 {
2132                     if( demux_Control( p_input->p->input.p_demux,
2133                                        DEMUX_SET_RECORD_STATE, val.b_bool ) )
2134                         val.b_bool = false;
2135                 }
2136                 else
2137                 {
2138                     if( es_out_SetRecordState( p_input->p->p_es_out_display, val.b_bool ) )
2139                         val.b_bool = false;
2140                 }
2141                 p_input->p->b_recording = val.b_bool;
2142
2143                 input_SendEventRecord( p_input, val.b_bool );
2144
2145                 b_force_update = true;
2146             }
2147             break;
2148
2149         case INPUT_CONTROL_SET_FRAME_NEXT:
2150             if( p_input->p->i_state == PAUSE_S )
2151             {
2152                 es_out_SetFrameNext( p_input->p->p_es_out );
2153             }
2154             else if( p_input->p->i_state == PLAYING_S )
2155             {
2156                 ControlPause( p_input, i_control_date );
2157             }
2158             else
2159             {
2160                 msg_Err( p_input, "invalid state for frame next" );
2161             }
2162             b_force_update = true;
2163             break;
2164
2165         case INPUT_CONTROL_SET_BOOKMARK:
2166         {
2167             seekpoint_t bookmark;
2168
2169             bookmark.i_time_offset = -1;
2170             bookmark.i_byte_offset = -1;
2171
2172             vlc_mutex_lock( &p_input->p->p_item->lock );
2173             if( val.i_int >= 0 && val.i_int < p_input->p->i_bookmark )
2174             {
2175                 const seekpoint_t *p_bookmark = p_input->p->pp_bookmark[val.i_int];
2176                 bookmark.i_time_offset = p_bookmark->i_time_offset;
2177                 bookmark.i_byte_offset = p_bookmark->i_byte_offset;
2178             }
2179             vlc_mutex_unlock( &p_input->p->p_item->lock );
2180
2181             if( bookmark.i_time_offset < 0 && bookmark.i_byte_offset < 0 )
2182             {
2183                 msg_Err( p_input, "invalid bookmark %d", val.i_int );
2184                 break;
2185             }
2186
2187             if( bookmark.i_time_offset >= 0 )
2188             {
2189                 val.i_time = bookmark.i_time_offset;
2190                 b_force_update = Control( p_input, INPUT_CONTROL_SET_TIME, val );
2191             }
2192             else if( bookmark.i_byte_offset >= 0 &&
2193                      p_input->p->input.p_stream )
2194             {
2195                 const uint64_t i_size = stream_Size( p_input->p->input.p_stream );
2196                 if( i_size > 0 && bookmark.i_byte_offset <= i_size )
2197                 {
2198                     val.f_float = (double)bookmark.i_byte_offset / i_size;
2199                     b_force_update = Control( p_input, INPUT_CONTROL_SET_POSITION, val );
2200                 }
2201             }
2202             break;
2203         }
2204
2205         default:
2206             msg_Err( p_input, "not yet implemented" );
2207             break;
2208     }
2209
2210     ControlRelease( i_type, val );
2211     return b_force_update;
2212 }
2213
2214 /*****************************************************************************
2215  * UpdateTitleSeekpoint
2216  *****************************************************************************/
2217 static int UpdateTitleSeekpoint( input_thread_t *p_input,
2218                                  int i_title, int i_seekpoint )
2219 {
2220     int i_title_end = p_input->p->input.i_title_end -
2221                         p_input->p->input.i_title_offset;
2222     int i_seekpoint_end = p_input->p->input.i_seekpoint_end -
2223                             p_input->p->input.i_seekpoint_offset;
2224
2225     if( i_title_end >= 0 && i_seekpoint_end >= 0 )
2226     {
2227         if( i_title > i_title_end ||
2228             ( i_title == i_title_end && i_seekpoint > i_seekpoint_end ) )
2229             return 0;
2230     }
2231     else if( i_seekpoint_end >= 0 )
2232     {
2233         if( i_seekpoint > i_seekpoint_end )
2234             return 0;
2235     }
2236     else if( i_title_end >= 0 )
2237     {
2238         if( i_title > i_title_end )
2239             return 0;
2240     }
2241     return 1;
2242 }
2243 /*****************************************************************************
2244  * Update*FromDemux:
2245  *****************************************************************************/
2246 static int UpdateTitleSeekpointFromDemux( input_thread_t *p_input )
2247 {
2248     demux_t *p_demux = p_input->p->input.p_demux;
2249
2250     /* TODO event-like */
2251     if( p_demux->info.i_update & INPUT_UPDATE_TITLE )
2252     {
2253         input_SendEventTitle( p_input, p_demux->info.i_title );
2254
2255         p_demux->info.i_update &= ~INPUT_UPDATE_TITLE;
2256     }
2257     if( p_demux->info.i_update & INPUT_UPDATE_SEEKPOINT )
2258     {
2259         input_SendEventSeekpoint( p_input,
2260                                   p_demux->info.i_title, p_demux->info.i_seekpoint );
2261
2262         p_demux->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
2263     }
2264
2265     /* Hmmm only works with master input */
2266     if( p_input->p->input.p_demux == p_demux )
2267         return UpdateTitleSeekpoint( p_input,
2268                                      p_demux->info.i_title,
2269                                      p_demux->info.i_seekpoint );
2270     return 1;
2271 }
2272
2273 static void UpdateGenericFromDemux( input_thread_t *p_input )
2274 {
2275     demux_t *p_demux = p_input->p->input.p_demux;
2276
2277     if( p_demux->info.i_update & INPUT_UPDATE_META )
2278     {
2279         vlc_meta_t *p_meta = vlc_meta_New();
2280         if( p_meta )
2281         {
2282             demux_Control( p_input->p->input.p_demux, DEMUX_GET_META, p_meta );
2283             InputUpdateMeta( p_input, p_meta );
2284         }
2285         p_demux->info.i_update &= ~INPUT_UPDATE_META;
2286     }
2287
2288     p_demux->info.i_update &= ~INPUT_UPDATE_SIZE;
2289 }
2290
2291
2292 /*****************************************************************************
2293  * Update*FromAccess:
2294  *****************************************************************************/
2295 static int UpdateTitleSeekpointFromAccess( input_thread_t *p_input )
2296 {
2297     access_t *p_access = p_input->p->input.p_access;
2298
2299     if( p_access->info.i_update & INPUT_UPDATE_TITLE )
2300     {
2301         input_SendEventTitle( p_input, p_access->info.i_title );
2302
2303         stream_Control( p_input->p->input.p_stream, STREAM_UPDATE_SIZE );
2304
2305         p_access->info.i_update &= ~INPUT_UPDATE_TITLE;
2306     }
2307     if( p_access->info.i_update & INPUT_UPDATE_SEEKPOINT )
2308     {
2309         input_SendEventSeekpoint( p_input,
2310                                   p_access->info.i_title, p_access->info.i_seekpoint );
2311
2312         p_access->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
2313     }
2314     /* Hmmm only works with master input */
2315     if( p_input->p->input.p_access == p_access )
2316         return UpdateTitleSeekpoint( p_input,
2317                                      p_access->info.i_title,
2318                                      p_access->info.i_seekpoint );
2319     return 1;
2320 }
2321 static void UpdateGenericFromAccess( input_thread_t *p_input )
2322 {
2323     access_t *p_access = p_input->p->input.p_access;
2324
2325     if( p_access->info.i_update & INPUT_UPDATE_META )
2326     {
2327         /* TODO maybe multi - access ? */
2328         vlc_meta_t *p_meta = vlc_meta_New();
2329         if( p_meta )
2330         {
2331             access_Control( p_input->p->input.p_access, ACCESS_GET_META, p_meta );
2332             InputUpdateMeta( p_input, p_meta );
2333         }
2334         p_access->info.i_update &= ~INPUT_UPDATE_META;
2335     }
2336     if( p_access->info.i_update & INPUT_UPDATE_SIGNAL )
2337     {
2338         double f_quality;
2339         double f_strength;
2340
2341         if( access_Control( p_access, ACCESS_GET_SIGNAL, &f_quality, &f_strength ) )
2342             f_quality = f_strength = -1;
2343
2344         input_SendEventSignal( p_input, f_quality, f_strength );
2345
2346         p_access->info.i_update &= ~INPUT_UPDATE_SIGNAL;
2347     }
2348
2349     p_access->info.i_update &= ~INPUT_UPDATE_SIZE;
2350 }
2351
2352 /*****************************************************************************
2353  * InputSourceNew:
2354  *****************************************************************************/
2355 static input_source_t *InputSourceNew( input_thread_t *p_input )
2356 {
2357     VLC_UNUSED(p_input);
2358
2359     return calloc( 1,  sizeof( input_source_t ) );
2360 }
2361
2362 /*****************************************************************************
2363  * InputSourceInit:
2364  *****************************************************************************/
2365 static int InputSourceInit( input_thread_t *p_input,
2366                             input_source_t *in, const char *psz_mrl,
2367                             const char *psz_forced_demux )
2368 {
2369     const char *psz_access;
2370     const char *psz_demux;
2371     char *psz_path;
2372     char *psz_var_demux = NULL;
2373     double f_fps;
2374
2375     assert( psz_mrl );
2376     char *psz_dup = strdup( psz_mrl );
2377
2378     if( psz_dup == NULL )
2379         goto error;
2380
2381     /* Split uri */
2382     input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup );
2383
2384     /* FIXME: file:// handling plugins do not support URIs properly...
2385      * So we pre-decode the URI to a path for them. Note that we do not do it
2386      * for non-standard VLC-specific schemes. */
2387     if( !strcmp( psz_access, "file" ) )
2388     {
2389         if( psz_path[0] != '/'
2390 #if (DIR_SEP_CHAR != '/')
2391             /* We accept invalid URIs too. */
2392             && psz_path[0] != DIR_SEP_CHAR
2393 #endif
2394           )
2395         {   /* host specified -> only localhost is supported */
2396             static const size_t i_localhost = sizeof("localhost")-1;
2397             if( strncmp( psz_path, "localhost/", i_localhost + 1) != 0 )
2398             {
2399                 msg_Err( p_input, "cannot open remote file `%s://%s'",
2400                          psz_access, psz_path );
2401                 msg_Info( p_input, "Did you mean `%s:///%s'?",
2402                           psz_access, psz_path );
2403                 goto error;
2404             }
2405             psz_path += i_localhost;
2406         }
2407         /* Remove HTML anchor if present (not supported). */
2408         char *p = strchr( psz_path, '#' );
2409         if( p )
2410             *p = '\0';
2411         /* Then URI-decode the path. */
2412         decode_URI( psz_path );
2413 #if defined( WIN32 ) && !defined( UNDER_CE )
2414         /* Strip leading slash in front of the drive letter */
2415         psz_path++;
2416 #endif
2417 #if (DIR_SEP_CHAR != '/')
2418         /* Turn slashes into anti-slashes */
2419         for( char *s = strchr( psz_path, '/' ); s; s = strchr( s + 1, '/' ) )
2420             *s = DIR_SEP_CHAR;
2421 #endif
2422     }
2423
2424     msg_Dbg( p_input, "`%s' gives access `%s' demux `%s' path `%s'",
2425              psz_mrl, psz_access, psz_demux, psz_path );
2426     if( !p_input->b_preparsing )
2427     {
2428         /* Hack to allow udp://@:port syntax */
2429         if( !psz_access ||
2430             (strncmp( psz_access, "udp", 3 ) &&
2431              strncmp( psz_access, "rtp", 3 )) )
2432         {
2433             /* Find optional titles and seekpoints */
2434             MRLSections( p_input, psz_path, &in->i_title_start, &in->i_title_end,
2435                      &in->i_seekpoint_start, &in->i_seekpoint_end );
2436         }
2437
2438         if( psz_forced_demux && *psz_forced_demux )
2439         {
2440             psz_demux = psz_forced_demux;
2441         }
2442         else if( *psz_demux == '\0' )
2443         {
2444             /* special hack for forcing a demuxer with --demux=module
2445              * (and do nothing with a list) */
2446             psz_var_demux = var_GetNonEmptyString( p_input, "demux" );
2447
2448             if( psz_var_demux != NULL &&
2449                 !strchr(psz_var_demux, ',' ) &&
2450                 !strchr(psz_var_demux, ':' ) )
2451             {
2452                 psz_demux = psz_var_demux;
2453
2454                 msg_Dbg( p_input, "enforced demux ` %s'", psz_demux );
2455             }
2456         }
2457
2458         /* Try access_demux first */
2459         in->p_demux = demux_New( p_input, p_input, psz_access, psz_demux, psz_path,
2460                                   NULL, p_input->p->p_es_out, false );
2461     }
2462     else
2463     {
2464         /* Preparsing is only for file:// */
2465         if( *psz_demux )
2466             goto error;
2467         if( !*psz_access ) /* path without scheme:// */
2468             psz_access = "file";
2469         if( strcmp( psz_access, "file" ) )
2470             goto error;
2471         msg_Dbg( p_input, "trying to pre-parse %s",  psz_path );
2472     }
2473
2474     if( in->p_demux )
2475     {
2476         /* Get infos from access_demux */
2477         int i_ret = demux_Control( in->p_demux,
2478                                    DEMUX_GET_PTS_DELAY, &in->i_pts_delay );
2479         assert( !i_ret );
2480         in->i_pts_delay = __MAX( 0, __MIN( in->i_pts_delay, INPUT_PTS_DELAY_MAX ) );
2481
2482
2483         in->b_title_demux = true;
2484         if( demux_Control( in->p_demux, DEMUX_GET_TITLE_INFO,
2485                             &in->title, &in->i_title,
2486                             &in->i_title_offset, &in->i_seekpoint_offset ) )
2487         {
2488             TAB_INIT( in->i_title, in->title );
2489         }
2490         if( demux_Control( in->p_demux, DEMUX_CAN_CONTROL_PACE,
2491                             &in->b_can_pace_control ) )
2492             in->b_can_pace_control = false;
2493
2494         assert( in->p_demux->pf_demux != NULL || !in->b_can_pace_control );
2495
2496         if( !in->b_can_pace_control )
2497         {
2498             if( demux_Control( in->p_demux, DEMUX_CAN_CONTROL_RATE,
2499                                 &in->b_can_rate_control, &in->b_rescale_ts ) )
2500             {
2501                 in->b_can_rate_control = false;
2502                 in->b_rescale_ts = true; /* not used */
2503             }
2504         }
2505         else
2506         {
2507             in->b_can_rate_control = true;
2508             in->b_rescale_ts = true;
2509         }
2510         if( demux_Control( in->p_demux, DEMUX_CAN_PAUSE,
2511                             &in->b_can_pause ) )
2512             in->b_can_pause = false;
2513         var_SetBool( p_input, "can-pause", in->b_can_pause || !in->b_can_pace_control ); /* XXX temporary because of es_out_timeshift*/
2514         var_SetBool( p_input, "can-rate", !in->b_can_pace_control || in->b_can_rate_control ); /* XXX temporary because of es_out_timeshift*/
2515         var_SetBool( p_input, "can-rewind", !in->b_rescale_ts && !in->b_can_pace_control && in->b_can_rate_control );
2516
2517         bool b_can_seek;
2518         if( demux_Control( in->p_demux, DEMUX_CAN_SEEK, &b_can_seek ) )
2519             b_can_seek = false;
2520         var_SetBool( p_input, "can-seek", b_can_seek );
2521     }
2522     else
2523     {
2524         /* Now try a real access */
2525         in->p_access = access_New( p_input, p_input, psz_access, psz_demux, psz_path );
2526         if( in->p_access == NULL )
2527         {
2528             if( vlc_object_alive( p_input ) )
2529             {
2530                 msg_Err( p_input, "open of `%s' failed: %s", psz_mrl,
2531                                                              msg_StackMsg() );
2532                 dialog_Fatal( p_input, _("Your input can't be opened"),
2533                               _("VLC is unable to open the MRL '%s'."
2534                                 " Check the log for details."), psz_mrl );
2535             }
2536             goto error;
2537         }
2538
2539         /* Get infos from access */
2540         if( !p_input->b_preparsing )
2541         {
2542             bool b_can_seek;
2543             access_Control( in->p_access,
2544                              ACCESS_GET_PTS_DELAY, &in->i_pts_delay );
2545             in->i_pts_delay = __MAX( 0, __MIN( in->i_pts_delay, INPUT_PTS_DELAY_MAX ) );
2546
2547             in->b_title_demux = false;
2548             if( access_Control( in->p_access, ACCESS_GET_TITLE_INFO,
2549                                  &in->title, &in->i_title,
2550                                 &in->i_title_offset, &in->i_seekpoint_offset ) )
2551
2552             {
2553                 TAB_INIT( in->i_title, in->title );
2554             }
2555             access_Control( in->p_access, ACCESS_CAN_CONTROL_PACE,
2556                              &in->b_can_pace_control );
2557             in->b_can_rate_control = in->b_can_pace_control;
2558             in->b_rescale_ts = true;
2559
2560             access_Control( in->p_access, ACCESS_CAN_PAUSE, &in->b_can_pause );
2561             var_SetBool( p_input, "can-pause", in->b_can_pause || !in->b_can_pace_control ); /* XXX temporary because of es_out_timeshift*/
2562             var_SetBool( p_input, "can-rate", !in->b_can_pace_control || in->b_can_rate_control ); /* XXX temporary because of es_out_timeshift*/
2563             var_SetBool( p_input, "can-rewind", !in->b_rescale_ts && !in->b_can_pace_control );
2564
2565             access_Control( in->p_access, ACCESS_CAN_SEEK, &b_can_seek );
2566             var_SetBool( p_input, "can-seek", b_can_seek );
2567         }
2568
2569         /* */
2570         int  i_input_list;
2571         char **ppsz_input_list;
2572
2573         TAB_INIT( i_input_list, ppsz_input_list );
2574
2575         /* On master stream only, use input-list */
2576         if( &p_input->p->input == in )
2577         {
2578             char *psz_list;
2579             char *psz_parser;
2580
2581             psz_list =
2582             psz_parser = var_CreateGetNonEmptyString( p_input, "input-list" );
2583
2584             while( psz_parser && *psz_parser )
2585             {
2586                 char *p = strchr( psz_parser, ',' );
2587                 if( p )
2588                     *p++ = '\0';
2589
2590                 if( *psz_parser )
2591                 {
2592                     char *psz_name = strdup( psz_parser );
2593                     if( psz_name )
2594                         TAB_APPEND( i_input_list, ppsz_input_list, psz_name );
2595                 }
2596
2597                 psz_parser = p;
2598             }
2599             free( psz_list );
2600         }
2601         /* Autodetect extra files if none specified */
2602         if( i_input_list <= 0 )
2603         {
2604             InputGetExtraFiles( p_input, &i_input_list, &ppsz_input_list,
2605                                 psz_access, psz_path );
2606         }
2607         if( i_input_list > 0 )
2608             TAB_APPEND( i_input_list, ppsz_input_list, NULL );
2609
2610         /* Create the stream_t */
2611         in->p_stream = stream_AccessNew( in->p_access, ppsz_input_list );
2612         if( ppsz_input_list )
2613         {
2614             for( int i = 0; ppsz_input_list[i] != NULL; i++ )
2615                 free( ppsz_input_list[i] );
2616             TAB_CLEAN( i_input_list, ppsz_input_list );
2617         }
2618
2619         if( in->p_stream == NULL )
2620         {
2621             msg_Warn( p_input, "cannot create a stream_t from access" );
2622             goto error;
2623         }
2624
2625         /* Add stream filters */
2626         char *psz_stream_filter = var_GetNonEmptyString( p_input,
2627                                                          "stream-filter" );
2628         in->p_stream = stream_FilterChainNew( in->p_stream,
2629                                               psz_stream_filter,
2630                                               var_GetBool( p_input, "input-record-native" ) );
2631         free( psz_stream_filter );
2632
2633         /* Open a demuxer */
2634         if( *psz_demux == '\0' && *in->p_access->psz_demux )
2635         {
2636             psz_demux = in->p_access->psz_demux;
2637         }
2638
2639         {
2640             /* Take access/stream redirections into account */
2641             char *psz_real_path;
2642             char *psz_buf = NULL;
2643             if( in->p_stream->psz_path )
2644             {
2645                 const char *psz_a, *psz_d;
2646                 psz_buf = strdup( in->p_stream->psz_path );
2647                 input_SplitMRL( &psz_a, &psz_d, &psz_real_path, psz_buf );
2648             }
2649             else
2650             {
2651                 psz_real_path = psz_path;
2652             }
2653             in->p_demux = demux_New( p_input, p_input, psz_access, psz_demux,
2654                                       psz_real_path,
2655                                       in->p_stream, p_input->p->p_es_out,
2656                                       p_input->b_preparsing );
2657             free( psz_buf );
2658         }
2659
2660         if( in->p_demux == NULL )
2661         {
2662             if( vlc_object_alive( p_input ) )
2663             {
2664                 msg_Err( p_input, "no suitable demux module for `%s/%s://%s'",
2665                          psz_access, psz_demux, psz_path );
2666                 dialog_Fatal( VLC_OBJECT( p_input ),
2667                               _("VLC can't recognize the input's format"),
2668                               _("The format of '%s' cannot be detected. "
2669                                 "Have a look at the log for details."), psz_mrl );
2670             }
2671             goto error;
2672         }
2673         assert( in->p_demux->pf_demux != NULL );
2674
2675         /* Get title from demux */
2676         if( !p_input->b_preparsing && in->i_title <= 0 )
2677         {
2678             if( demux_Control( in->p_demux, DEMUX_GET_TITLE_INFO,
2679                                 &in->title, &in->i_title,
2680                                 &in->i_title_offset, &in->i_seekpoint_offset ))
2681             {
2682                 TAB_INIT( in->i_title, in->title );
2683             }
2684             else
2685             {
2686                 in->b_title_demux = true;
2687             }
2688         }
2689     }
2690
2691     free( psz_var_demux );
2692     free( psz_dup );
2693
2694     /* Set record capabilities */
2695     if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_stream_record ) )
2696         in->b_can_stream_record = false;
2697 #ifdef ENABLE_SOUT
2698     if( !var_GetBool( p_input, "input-record-native" ) )
2699         in->b_can_stream_record = false;
2700     var_SetBool( p_input, "can-record", true );
2701 #else
2702     var_SetBool( p_input, "can-record", in->b_can_stream_record );
2703 #endif
2704
2705     /* get attachment
2706      * FIXME improve for b_preparsing: move it after GET_META and check psz_arturl */
2707     if( 1 || !p_input->b_preparsing )
2708     {
2709         int i_attachment;
2710         input_attachment_t **attachment;
2711         if( !demux_Control( in->p_demux, DEMUX_GET_ATTACHMENTS,
2712                              &attachment, &i_attachment ) )
2713         {
2714             vlc_mutex_lock( &p_input->p->p_item->lock );
2715             AppendAttachment( &p_input->p->i_attachment, &p_input->p->attachment,
2716                               i_attachment, attachment );
2717             vlc_mutex_unlock( &p_input->p->p_item->lock );
2718         }
2719     }
2720     if( !demux_Control( in->p_demux, DEMUX_GET_FPS, &f_fps ) && f_fps > 0.0 )
2721     {
2722         vlc_mutex_lock( &p_input->p->p_item->lock );
2723         p_input->p->f_fps = f_fps;
2724         vlc_mutex_unlock( &p_input->p->p_item->lock );
2725     }
2726
2727     if( var_GetInteger( p_input, "clock-synchro" ) != -1 )
2728         in->b_can_pace_control = !var_GetInteger( p_input, "clock-synchro" );
2729
2730     return VLC_SUCCESS;
2731
2732 error:
2733     if( in->p_demux )
2734         demux_Delete( in->p_demux );
2735
2736     if( in->p_stream )
2737         stream_Delete( in->p_stream );
2738
2739     if( in->p_access )
2740         access_Delete( in->p_access );
2741
2742     free( psz_var_demux );
2743     free( psz_dup );
2744
2745     return VLC_EGENERIC;
2746 }
2747
2748 /*****************************************************************************
2749  * InputSourceClean:
2750  *****************************************************************************/
2751 static void InputSourceClean( input_source_t *in )
2752 {
2753     int i;
2754
2755     if( in->p_demux )
2756         demux_Delete( in->p_demux );
2757
2758     if( in->p_stream )
2759         stream_Delete( in->p_stream );
2760
2761     if( in->p_access )
2762         access_Delete( in->p_access );
2763
2764     if( in->i_title > 0 )
2765     {
2766         for( i = 0; i < in->i_title; i++ )
2767             vlc_input_title_Delete( in->title[i] );
2768         TAB_CLEAN( in->i_title, in->title );
2769     }
2770 }
2771
2772 /*****************************************************************************
2773  * InputSourceMeta:
2774  *****************************************************************************/
2775 static void InputSourceMeta( input_thread_t *p_input,
2776                              input_source_t *p_source, vlc_meta_t *p_meta )
2777 {
2778     access_t *p_access = p_source->p_access;
2779     demux_t *p_demux = p_source->p_demux;
2780
2781     /* XXX Remember that checking against p_item->p_meta->i_status & ITEM_PREPARSED
2782      * is a bad idea */
2783
2784     bool has_meta;
2785
2786     /* Read access meta */
2787     has_meta = p_access && !access_Control( p_access, ACCESS_GET_META, p_meta );
2788
2789     /* Read demux meta */
2790     has_meta |= !demux_Control( p_demux, DEMUX_GET_META, p_meta );
2791
2792     bool has_unsupported;
2793     if( demux_Control( p_demux, DEMUX_HAS_UNSUPPORTED_META, &has_unsupported ) )
2794         has_unsupported = true;
2795
2796     /* If the demux report unsupported meta data, or if we don't have meta data
2797      * try an external "meta reader" */
2798     if( has_meta && !has_unsupported )
2799         return;
2800
2801     demux_meta_t *p_demux_meta =
2802         vlc_custom_create( p_demux, sizeof( *p_demux_meta ),
2803                            VLC_OBJECT_GENERIC, "demux meta" );
2804     if( !p_demux_meta )
2805         return;
2806     vlc_object_attach( p_demux_meta, p_demux );
2807     p_demux_meta->p_demux = p_demux;
2808     p_demux_meta->p_item = p_input->p->p_item;
2809
2810     module_t *p_id3 = module_need( p_demux_meta, "meta reader", NULL, false );
2811     if( p_id3 )
2812     {
2813         if( p_demux_meta->p_meta )
2814         {
2815             vlc_meta_Merge( p_meta, p_demux_meta->p_meta );
2816             vlc_meta_Delete( p_demux_meta->p_meta );
2817         }
2818
2819         if( p_demux_meta->i_attachments > 0 )
2820         {
2821             vlc_mutex_lock( &p_input->p->p_item->lock );
2822             AppendAttachment( &p_input->p->i_attachment, &p_input->p->attachment,
2823                               p_demux_meta->i_attachments, p_demux_meta->attachments );
2824             vlc_mutex_unlock( &p_input->p->p_item->lock );
2825         }
2826         module_unneed( p_demux, p_id3 );
2827     }
2828     vlc_object_release( p_demux_meta );
2829 }
2830
2831
2832 static void SlaveDemux( input_thread_t *p_input, bool *pb_demux_polled )
2833 {
2834     int64_t i_time;
2835     int i;
2836
2837     *pb_demux_polled = false;
2838     if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_TIME, &i_time ) )
2839     {
2840         msg_Err( p_input, "demux doesn't like DEMUX_GET_TIME" );
2841         return;
2842     }
2843
2844     for( i = 0; i < p_input->p->i_slave; i++ )
2845     {
2846         input_source_t *in = p_input->p->slave[i];
2847         int i_ret;
2848
2849         if( in->b_eof )
2850             continue;
2851
2852         const bool b_demux_polled = in->p_demux->pf_demux != NULL;
2853         if( !b_demux_polled )
2854             continue;
2855
2856         *pb_demux_polled = true;
2857
2858         /* Call demux_Demux until we have read enough data */
2859         if( demux_Control( in->p_demux, DEMUX_SET_NEXT_DEMUX_TIME, i_time ) )
2860         {
2861             for( ;; )
2862             {
2863                 int64_t i_stime;
2864                 if( demux_Control( in->p_demux, DEMUX_GET_TIME, &i_stime ) )
2865                 {
2866                     msg_Err( p_input, "slave[%d] doesn't like "
2867                              "DEMUX_GET_TIME -> EOF", i );
2868                     i_ret = 0;
2869                     break;
2870                 }
2871
2872                 if( i_stime >= i_time )
2873                 {
2874                     i_ret = 1;
2875                     break;
2876                 }
2877
2878                 if( ( i_ret = demux_Demux( in->p_demux ) ) <= 0 )
2879                     break;
2880             }
2881         }
2882         else
2883         {
2884             i_ret = demux_Demux( in->p_demux );
2885         }
2886
2887         if( i_ret <= 0 )
2888         {
2889             msg_Dbg( p_input, "slave %d EOF", i );
2890             in->b_eof = true;
2891         }
2892     }
2893 }
2894
2895 static void SlaveSeek( input_thread_t *p_input )
2896 {
2897     int64_t i_time;
2898     int i;
2899
2900     if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_TIME, &i_time ) )
2901     {
2902         msg_Err( p_input, "demux doesn't like DEMUX_GET_TIME" );
2903         return;
2904     }
2905
2906     for( i = 0; i < p_input->p->i_slave; i++ )
2907     {
2908         input_source_t *in = p_input->p->slave[i];
2909
2910         if( demux_Control( in->p_demux, DEMUX_SET_TIME, i_time, true ) )
2911         {
2912             if( !in->b_eof )
2913                 msg_Err( p_input, "seek failed for slave %d -> EOF", i );
2914             in->b_eof = true;
2915         }
2916         else
2917         {
2918             in->b_eof = false;
2919         }
2920     }
2921 }
2922
2923 /*****************************************************************************
2924  * InputMetaUser:
2925  *****************************************************************************/
2926 static void InputMetaUser( input_thread_t *p_input, vlc_meta_t *p_meta )
2927 {
2928     static const struct { int i_meta; const char *psz_name; } p_list[] = {
2929         { vlc_meta_Title,       "meta-title" },
2930         { vlc_meta_Artist,      "meta-artist" },
2931         { vlc_meta_Genre,       "meta-genre" },
2932         { vlc_meta_Copyright,   "meta-copyright" },
2933         { vlc_meta_Description, "meta-description" },
2934         { vlc_meta_Date,        "meta-date" },
2935         { vlc_meta_URL,         "meta-url" },
2936         { 0, NULL }
2937     };
2938
2939     /* Get meta information from user */
2940     for( int i = 0; p_list[i].psz_name; i++ )
2941     {
2942         char *psz_string = var_GetNonEmptyString( p_input, p_list[i].psz_name );
2943         if( !psz_string )
2944             continue;
2945
2946         EnsureUTF8( psz_string );
2947         vlc_meta_Set( p_meta, p_list[i].i_meta, psz_string );
2948         free( psz_string );
2949     }
2950 }
2951
2952 /*****************************************************************************
2953  * InputUpdateMeta: merge p_item meta data with p_meta taking care of
2954  * arturl and locking issue.
2955  *****************************************************************************/
2956 static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta )
2957 {
2958     es_out_ControlSetMeta( p_input->p->p_es_out, p_meta );
2959     vlc_meta_Delete( p_meta );
2960 }
2961
2962 static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment,
2963                               int i_new, input_attachment_t **pp_new )
2964 {
2965     int i_attachment = *pi_attachment;
2966     input_attachment_t **attachment = *ppp_attachment;
2967     int i;
2968
2969     attachment = xrealloc( attachment,
2970                     sizeof(input_attachment_t**) * ( i_attachment + i_new ) );
2971     for( i = 0; i < i_new; i++ )
2972         attachment[i_attachment++] = pp_new[i];
2973     free( pp_new );
2974
2975     /* */
2976     *pi_attachment = i_attachment;
2977     *ppp_attachment = attachment;
2978 }
2979 /*****************************************************************************
2980  * InputGetExtraFiles
2981  *  Autodetect extra input list
2982  *****************************************************************************/
2983 static void InputGetExtraFilesPattern( input_thread_t *p_input,
2984                                        int *pi_list, char ***pppsz_list,
2985                                        const char *psz_path,
2986                                        const char *psz_match,
2987                                        const char *psz_format,
2988                                        int i_start, int i_stop )
2989 {
2990     int i_list;
2991     char **ppsz_list;
2992
2993     TAB_INIT( i_list, ppsz_list );
2994
2995     char *psz_base = strdup( psz_path );
2996     if( !psz_base )
2997         goto exit;
2998
2999     /* Remove the extension */
3000     char *psz_end = &psz_base[strlen(psz_base)-strlen(psz_match)];
3001     assert( psz_end >= psz_base);
3002     *psz_end = '\0';
3003
3004     /* Try to list files */
3005     for( int i = i_start; i <= i_stop; i++ )
3006     {
3007         struct stat st;
3008         char *psz_file;
3009
3010         if( asprintf( &psz_file, psz_format, psz_base, i ) < 0 )
3011             break;
3012
3013         if( utf8_stat( psz_file, &st ) || !S_ISREG( st.st_mode ) || !st.st_size )
3014         {
3015             free( psz_file );
3016             break;
3017         }
3018
3019         msg_Dbg( p_input, "Detected extra file `%s'", psz_file );
3020         TAB_APPEND( i_list, ppsz_list, psz_file );
3021     }
3022     free( psz_base );
3023 exit:
3024     *pi_list = i_list;
3025     *pppsz_list = ppsz_list;
3026 }
3027
3028 static void InputGetExtraFiles( input_thread_t *p_input,
3029                                 int *pi_list, char ***pppsz_list,
3030                                 const char *psz_access, const char *psz_path )
3031 {
3032     static const struct
3033     {
3034         const char *psz_match;
3035         const char *psz_format;
3036         int i_start;
3037         int i_stop;
3038     } p_pattern[] = {
3039         /* XXX the order is important */
3040         { ".001",         "%s.%.3d",        2, 999 },
3041         { ".part1.rar",   "%s.part%.1d.rar",2, 9 },
3042         { ".part01.rar",  "%s.part%.2d.rar",2, 99, },
3043         { ".part001.rar", "%s.part%.3d.rar",2, 999 },
3044         { ".rar",         "%s.r%.2d",       0, 99 },
3045         { NULL, NULL, 0, 0 }
3046     };
3047
3048     TAB_INIT( *pi_list, *pppsz_list );
3049
3050     if( ( psz_access && *psz_access && strcmp( psz_access, "file" ) ) || !psz_path )
3051         return;
3052
3053     const size_t i_path = strlen(psz_path);
3054
3055     for( int i = 0; p_pattern[i].psz_match != NULL; i++ )
3056     {
3057         const size_t i_ext = strlen(p_pattern[i].psz_match );
3058
3059         if( i_path < i_ext )
3060             continue;
3061         if( !strcmp( &psz_path[i_path-i_ext], p_pattern[i].psz_match ) )
3062         {
3063             InputGetExtraFilesPattern( p_input, pi_list, pppsz_list,
3064                                        psz_path,
3065                                        p_pattern[i].psz_match, p_pattern[i].psz_format,
3066                                        p_pattern[i].i_start, p_pattern[i].i_stop );
3067             return;
3068         }
3069     }
3070 }
3071
3072 /* */
3073 static void input_ChangeState( input_thread_t *p_input, int i_state )
3074 {
3075     const bool b_changed = p_input->p->i_state != i_state;
3076
3077     p_input->p->i_state = i_state;
3078     if( i_state == ERROR_S )
3079         p_input->b_error = true;
3080     else if( i_state == END_S )
3081         p_input->b_eof = true;
3082
3083     if( b_changed )
3084     {
3085         input_item_SetErrorWhenReading( p_input->p->p_item, p_input->b_error );
3086         input_SendEventState( p_input, i_state );
3087     }
3088 }
3089
3090
3091 /*****************************************************************************
3092  * MRLSplit: parse the access, demux and url part of the
3093  *           Media Resource Locator.
3094  *****************************************************************************/
3095 void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, char **ppsz_path,
3096                      char *psz_dup )
3097 {
3098     char *psz_access = NULL;
3099     char *psz_demux  = NULL;
3100     char *psz_path;
3101
3102     /* Either there is an access/demux specification before ://
3103      * or we have a plain local file path. */
3104     psz_path = strstr( psz_dup, "://" );
3105     if( psz_path != NULL )
3106     {
3107         *psz_path = '\0';
3108         psz_path += 3; /* skips "://" */
3109
3110         /* Separate access from demux (<access>/<demux>://<path>) */
3111         psz_access = psz_dup;
3112         psz_demux = strchr( psz_access, '/' );
3113         if( psz_demux )
3114             *psz_demux++ = '\0';
3115
3116         /* We really don't want module name substitution here! */
3117         if( psz_access[0] == '$' )
3118             psz_access++;
3119         if( psz_demux && psz_demux[0] == '$' )
3120             psz_demux++;
3121     }
3122     else
3123     {
3124         psz_path = psz_dup;
3125     }
3126     *ppsz_access = psz_access ? psz_access : "";
3127     *ppsz_demux = psz_demux ? psz_demux : "";
3128     *ppsz_path = psz_path;
3129 }
3130
3131 static inline bool next(char ** src)
3132 {
3133     char *end;
3134     errno = 0;
3135     long result = strtol( *src, &end, 0 );
3136     if( errno != 0 || result >= LONG_MAX || result <= LONG_MIN ||
3137         end == *src )
3138     {
3139         return false;
3140     }
3141     *src = end;
3142     return true;
3143 }
3144
3145 /*****************************************************************************
3146  * MRLSections: parse title and seekpoint info from the Media Resource Locator.
3147  *
3148  * Syntax:
3149  * [url][@[title-start][:chapter-start][-[title-end][:chapter-end]]]
3150  *****************************************************************************/
3151 static void MRLSections( input_thread_t *p_input, char *psz_source,
3152                          int *pi_title_start, int *pi_title_end,
3153                          int *pi_chapter_start, int *pi_chapter_end )
3154 {
3155     char *psz, *psz_end, *psz_next, *psz_check;
3156
3157     *pi_title_start = *pi_title_end = -1;
3158     *pi_chapter_start = *pi_chapter_end = -1;
3159
3160     /* Start by parsing titles and chapters */
3161     if( !psz_source || !( psz = strrchr( psz_source, '@' ) ) ) return;
3162
3163
3164     /* Check we are really dealing with a title/chapter section */
3165     psz_check = psz + 1;
3166     if( !*psz_check ) return;
3167     if( isdigit(*psz_check) )
3168         if(!next(&psz_check)) return;
3169     if( *psz_check != ':' && *psz_check != '-' && *psz_check ) return;
3170     if( *psz_check == ':' && ++psz_check )
3171     {
3172         if( isdigit(*psz_check) )
3173             if(!next(&psz_check)) return;
3174     }
3175     if( *psz_check != '-' && *psz_check ) return;
3176     if( *psz_check == '-' && ++psz_check )
3177     {
3178         if( isdigit(*psz_check) )
3179             if(!next(&psz_check)) return;
3180     }
3181     if( *psz_check != ':' && *psz_check ) return;
3182     if( *psz_check == ':' && ++psz_check )
3183     {
3184         if( isdigit(*psz_check) )
3185             if(!next(&psz_check)) return;
3186     }
3187     if( *psz_check ) return;
3188
3189     /* Separate start and end */
3190     *psz++ = 0;
3191     if( ( psz_end = strchr( psz, '-' ) ) ) *psz_end++ = 0;
3192
3193     /* Look for the start title */
3194     *pi_title_start = strtol( psz, &psz_next, 0 );
3195     if( !*pi_title_start && psz == psz_next ) *pi_title_start = -1;
3196     *pi_title_end = *pi_title_start;
3197     psz = psz_next;
3198
3199     /* Look for the start chapter */
3200     if( *psz ) psz++;
3201     *pi_chapter_start = strtol( psz, &psz_next, 0 );
3202     if( !*pi_chapter_start && psz == psz_next ) *pi_chapter_start = -1;
3203     *pi_chapter_end = *pi_chapter_start;
3204
3205     if( psz_end )
3206     {
3207         /* Look for the end title */
3208         *pi_title_end = strtol( psz_end, &psz_next, 0 );
3209         if( !*pi_title_end && psz_end == psz_next ) *pi_title_end = -1;
3210         psz_end = psz_next;
3211
3212         /* Look for the end chapter */
3213         if( *psz_end ) psz_end++;
3214         *pi_chapter_end = strtol( psz_end, &psz_next, 0 );
3215         if( !*pi_chapter_end && psz_end == psz_next ) *pi_chapter_end = -1;
3216     }
3217
3218     msg_Dbg( p_input, "source=`%s' title=%d/%d seekpoint=%d/%d",
3219              psz_source, *pi_title_start, *pi_chapter_start,
3220              *pi_title_end, *pi_chapter_end );
3221 }
3222
3223 /*****************************************************************************
3224  * input_AddSubtitles: add a subtitles file and enable it
3225  *****************************************************************************/
3226 static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced )
3227 {
3228     input_source_t *sub;
3229     vlc_value_t count;
3230     vlc_value_t list;
3231     char *psz_path, *psz_extension;
3232
3233     /* if we are provided a subtitle.sub file,
3234      * see if we don't have a subtitle.idx and use it instead */
3235     psz_path = strdup( psz_subtitle );
3236     if( psz_path )
3237     {
3238         psz_extension = strrchr( psz_path, '.');
3239         if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 )
3240         {
3241             struct stat st;
3242
3243             strcpy( psz_extension, ".idx" );
3244
3245             if( !utf8_stat( psz_path, &st ) && S_ISREG( st.st_mode ) )
3246             {
3247                 msg_Dbg( p_input, "using %s subtitles file instead of %s",
3248                          psz_path, psz_subtitle );
3249                 strcpy( psz_subtitle, psz_path );
3250             }
3251         }
3252         free( psz_path );
3253     }
3254
3255     var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
3256
3257     sub = InputSourceNew( p_input );
3258     if( !sub || InputSourceInit( p_input, sub, psz_subtitle, "subtitle" ) )
3259     {
3260         free( sub );
3261         return;
3262     }
3263     TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub );
3264
3265     /* Select the ES */
3266     if( b_forced && !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list, NULL ) )
3267     {
3268         if( count.i_int == 0 )
3269             count.i_int++;
3270         /* if it was first one, there is disable too */
3271
3272         if( count.i_int < list.p_list->i_count )
3273         {
3274             const int i_id = list.p_list->p_values[count.i_int].i_int;
3275
3276             es_out_Control( p_input->p->p_es_out_display, ES_OUT_SET_ES_DEFAULT_BY_ID, i_id );
3277             es_out_Control( p_input->p->p_es_out_display, ES_OUT_SET_ES_BY_ID, i_id );
3278         }
3279         var_FreeList( &list, NULL );
3280     }
3281 }
3282
3283 /*****************************************************************************
3284  * Statistics
3285  *****************************************************************************/
3286 void input_UpdateStatistic( input_thread_t *p_input,
3287                             input_statistic_t i_type, int i_delta )
3288 {
3289     assert( p_input->p->i_state != INIT_S );
3290
3291     vlc_mutex_lock( &p_input->p->counters.counters_lock);
3292     switch( i_type )
3293     {
3294 #define I(c) stats_UpdateInteger( p_input, p_input->p->counters.c, i_delta, NULL )
3295     case INPUT_STATISTIC_DECODED_VIDEO:
3296         I(p_decoded_video);
3297         break;
3298     case INPUT_STATISTIC_DECODED_AUDIO:
3299         I(p_decoded_audio);
3300         break;
3301     case INPUT_STATISTIC_DECODED_SUBTITLE:
3302         I(p_decoded_sub);
3303         break;
3304     case INPUT_STATISTIC_SENT_PACKET:
3305         I(p_sout_sent_packets);
3306         break;
3307 #undef I
3308     case INPUT_STATISTIC_SENT_BYTE:
3309     {
3310         int i_bytes; /* That's pretty stupid to define it as an integer, it will overflow
3311                         really fast ... */
3312         if( !stats_UpdateInteger( p_input, p_input->p->counters.p_sout_sent_bytes, i_delta, &i_bytes ) )
3313             stats_UpdateFloat( p_input, p_input->p->counters.p_sout_send_bitrate, i_bytes, NULL );
3314         break;
3315     }
3316     default:
3317         msg_Err( p_input, "Invalid statistic type %d (internal error)", i_type );
3318         break;
3319     }
3320     vlc_mutex_unlock( &p_input->p->counters.counters_lock);
3321 }
3322
3323 /**/
3324 /* TODO FIXME nearly the same logic that snapshot code */
3325 char *input_CreateFilename( vlc_object_t *p_obj, const char *psz_path, const char *psz_prefix, const char *psz_extension )
3326 {
3327     char *psz_file;
3328     DIR *path;
3329
3330     path = utf8_opendir( psz_path );
3331     if( path )
3332     {
3333         closedir( path );
3334
3335         char *psz_tmp = str_format( p_obj, psz_prefix );
3336         if( !psz_tmp )
3337             return NULL;
3338
3339         char *psz_tmp2 = filename_sanitize( psz_tmp );
3340         free( psz_tmp );
3341
3342         if( !psz_tmp2 ||
3343             asprintf( &psz_file, "%s"DIR_SEP"%s%s%s",
3344                       psz_path, psz_tmp2,
3345                       psz_extension ? "." : "",
3346                       psz_extension ? psz_extension : "" ) < 0 )
3347             psz_file = NULL;
3348         free( psz_tmp2 );
3349         return psz_file;
3350     }
3351     else
3352     {
3353         psz_file = str_format( p_obj, psz_path );
3354         path_sanitize( psz_file );
3355         return psz_file;
3356     }
3357 }
3358