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