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