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