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