root/src/input/input.c

Revision c35c18a622dad4f768370aacd1cbcd2b59c7204d, 98.1 kB (checked in by Laurent Aimar <fenrir@videolan.org>, 22 hours ago)

Do not set object b_eof/b_error after sending the event.

This fixes a few "deadlocks" with input waiting for playlist, while
playlist is waiting for input event.

  • Property mode set to 100644
Line 
1 /*****************************************************************************
2  * input.c: input thread
3  *****************************************************************************
4  * Copyright (C) 1998-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33
34 #include <ctype.h>
35 #include <limits.h>
36 #include <assert.h>
37
38 #include "input_internal.h"
39
40 #include <vlc_sout.h>
41 #include "../stream_output/stream_output.h"
42
43 #include <vlc_interface.h>
44 #include <vlc_url.h>
45 #include <vlc_charset.h>
46 #include <vlc_strings.h>
47
48 #ifdef HAVE_SYS_STAT_H
49 #   include <sys/stat.h>
50 #endif
51
52 /*****************************************************************************
53  * Local prototypes
54  *****************************************************************************/
55 static void Destructor( input_thread_t * p_input );
56
57 static  void* Run            ( vlc_object_t *p_this );
58 static  void* RunAndDestroy  ( vlc_object_t *p_this );
59
60 static input_thread_t * Create  ( vlc_object_t *, input_item_t *,
61                                   const char *, bool, sout_instance_t * );
62 static  int             Init    ( input_thread_t *p_input );
63 static void             WaitDie   ( input_thread_t *p_input );
64 static void             End     ( input_thread_t *p_input );
65 static void             MainLoop( input_thread_t *p_input );
66
67 static inline int ControlPopNoLock( input_thread_t *, int *, vlc_value_t * );
68 static void       ControlReduce( input_thread_t * );
69 static bool Control( input_thread_t *, int, vlc_value_t );
70
71 static int  UpdateFromAccess( input_thread_t * );
72 static int  UpdateFromDemux( input_thread_t * );
73
74 static void UpdateItemLength( input_thread_t *, int64_t i_length );
75
76 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *);
77
78 static input_source_t *InputSourceNew( input_thread_t *);
79 static int  InputSourceInit( input_thread_t *, input_source_t *,
80                              const char *, const char *psz_forced_demux );
81 static void InputSourceClean( input_source_t * );
82 /* TODO */
83 //static void InputGetAttachments( input_thread_t *, input_source_t * );
84 static void SlaveDemux( input_thread_t *p_input );
85 static void SlaveSeek( input_thread_t *p_input );
86
87 static void InputMetaUser( input_thread_t *p_input, vlc_meta_t *p_meta );
88 static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta );
89
90 static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux );
91 static void AccessMeta( input_thread_t * p_input, vlc_meta_t *p_meta );
92 static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment,
93                               int i_new, input_attachment_t **pp_new );
94
95 /*****************************************************************************
96  * This function creates a new input, and returns a pointer
97  * to its description. On error, it returns NULL.
98  *
99  * Variables for _public_ use:
100  * * Get and Set:
101  *  - state
102  *  - rate,rate-slower, rate-faster
103  *  - position, position-offset
104  *  - time, time-offset
105  *  - title,title-next,title-prev
106  *  - chapter,chapter-next, chapter-prev
107  *  - program, audio-es, video-es, spu-es
108  *  - audio-delay, spu-delay
109  *  - bookmark
110  * * Get only:
111  *  - length
112  *  - bookmarks
113  *  - seekable (if you can seek, it doesn't say if 'bar display' has be shown
114  *    or not, for that check position != 0.0)
115  *  - can-pause
116  *  - can-record (if a stream can be recorded while playing)
117  *  - teletext-es to get the index of spu track that is teletext --1 if no teletext)
118  * * For intf callback upon changes:
119  *  - intf-change
120  *  - intf-change-vout for when a vout is created or destroyed
121  *  - rate-change for when playback rate changes
122  * TODO explain when Callback is called
123  * TODO complete this list (?)
124  *****************************************************************************/
125 static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
126                                const char *psz_header, bool b_quick,
127                                sout_instance_t *p_sout )
128 {
129     static const char input_name[] = "input";
130     input_thread_t *p_input = NULL;                 /* thread descriptor */
131     vlc_value_t val;
132     int i;
133
134     /* Allocate descriptor */
135     p_input = vlc_custom_create( p_parent, sizeof( *p_input ),
136                                  VLC_OBJECT_INPUT, input_name );
137     if( p_input == NULL )
138         return NULL;
139
140     /* Construct a nice name for the input timer */
141     char psz_timer_name[255];
142     char * psz_name = input_item_GetName( p_item );
143     snprintf( psz_timer_name, sizeof(psz_timer_name),
144               "input launching for '%s'", psz_name );
145
146     msg_Dbg( p_input, "Creating an input for '%s'", psz_name);
147
148     free( psz_name );
149
150     /* Start a timer to mesure how long it takes
151      * to launch an input */
152     stats_TimerStart( p_input, psz_timer_name,
153         STATS_TIMER_INPUT_LAUNCHING );
154
155     MALLOC_NULL( p_input->p, input_thread_private_t );
156     memset( p_input->p, 0, sizeof( input_thread_private_t ) );
157
158     /* One "randomly" selected input thread is responsible for computing
159      * the global stats. Check if there is already someone doing this */
160     if( p_input->p_libvlc->p_stats && !b_quick )
161     {
162         libvlc_priv_t *p_private = libvlc_priv( p_input->p_libvlc );
163         vlc_mutex_lock( &p_input->p_libvlc->p_stats->lock );
164         if( p_private->p_stats_computer == NULL )
165             p_private->p_stats_computer = p_input;
166         vlc_mutex_unlock( &p_input->p_libvlc->p_stats->lock );
167     }
168
169     p_input->b_preparsing = b_quick;
170     p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
171
172     /* Init events */
173     vlc_event_manager_t * p_em = &p_input->p->event_manager;
174     vlc_event_manager_init_with_vlc_object( p_em, p_input );
175     vlc_event_manager_register_event_type( p_em, vlc_InputStateChanged );
176     vlc_event_manager_register_event_type( p_em, vlc_InputSelectedStreamChanged );
177
178     /* Init Common fields */
179     p_input->b_eof = false;
180     p_input->b_can_pace_control = true;
181     p_input->p->i_start = 0;
182     p_input->i_time  = 0;
183     p_input->p->i_stop  = 0;
184     p_input->p->i_run  = 0;
185     p_input->p->i_title = 0;
186     p_input->p->title   = NULL;
187     p_input->p->i_title_offset = p_input->p->i_seekpoint_offset = 0;
188     p_input->i_state = INIT_S;
189     p_input->p->i_rate  = INPUT_RATE_DEFAULT;
190     p_input->p->b_recording = false;
191     TAB_INIT( p_input->p->i_bookmark, p_input->p->bookmark );
192     TAB_INIT( p_input->p->i_attachment, p_input->p->attachment );
193     p_input->p->p_es_out = NULL;
194     p_input->p->p_sout  = NULL;
195     p_input->p->b_out_pace_control = false;
196     p_input->i_pts_delay = 0;
197
198     /* Init Input fields */
199     vlc_gc_incref( p_item ); /* Released in Destructor() */
200     p_input->p->input.p_item = p_item;
201     p_input->p->input.p_access = NULL;
202     p_input->p->input.p_stream = NULL;
203     p_input->p->input.p_demux  = NULL;
204     p_input->p->input.b_title_demux = false;
205     p_input->p->input.i_title  = 0;
206     p_input->p->input.title    = NULL;
207     p_input->p->input.i_title_offset = p_input->p->input.i_seekpoint_offset = 0;
208     p_input->p->input.b_can_pace_control = true;
209     p_input->p->input.b_can_rate_control = true;
210     p_input->p->input.b_rescale_ts = true;
211     p_input->p->input.b_eof = false;
212     p_input->p->input.i_cr_average = 0;
213
214     vlc_mutex_lock( &p_item->lock );
215
216     if( !p_item->p_stats )
217         p_item->p_stats = stats_NewInputStats( p_input );
218     vlc_mutex_unlock( &p_item->lock );
219
220     /* No slave */
221     p_input->p->i_slave = 0;
222     p_input->p->slave   = NULL;
223
224     /* Init control buffer */
225     vlc_mutex_init( &p_input->p->lock_control );
226     p_input->p->i_control = 0;
227
228     /* Parse input options */
229     vlc_mutex_lock( &p_item->lock );
230     assert( (int)p_item->optflagc == p_item->i_options );
231     for( i = 0; i < p_item->i_options; i++ )
232         var_OptionParse( VLC_OBJECT(p_input), p_item->ppsz_options[i],
233                          !!(p_item->optflagv[i] & VLC_INPUT_OPTION_TRUSTED) );
234     vlc_mutex_unlock( &p_item->lock );
235
236     /* Create Object Variables for private use only */
237     input_ConfigVarInit( p_input );
238
239     /* Create Objects variables for public Get and Set */
240     input_ControlVarInit( p_input );
241
242     /* */
243     p_input->p->pts_adjust.b_auto_adjust = var_GetBool( p_input, "auto-adjust-pts-delay" );
244     p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" );
245
246     if( !p_input->b_preparsing )
247     {
248         var_Get( p_input, "bookmarks", &val );
249         if( val.psz_string )
250         {
251             /* FIXME: have a common cfg parsing routine used by sout and others */
252             char *psz_parser, *psz_start, *psz_end;
253             psz_parser = val.psz_string;
254             while( (psz_start = strchr( psz_parser, '{' ) ) )
255             {
256                  seekpoint_t *p_seekpoint = vlc_seekpoint_New();
257                  char backup;
258                  psz_start++;
259                  psz_end = strchr( psz_start, '}' );
260                  if( !psz_end ) break;
261                  psz_parser = psz_end + 1;
262                  backup = *psz_parser;
263                  *psz_parser = 0;
264                  *psz_end = ',';
265                  while( (psz_end = strchr( psz_start, ',' ) ) )
266                  {
267                      *psz_end = 0;
268                      if( !strncmp( psz_start, "name=", 5 ) )
269                      {
270                          p_seekpoint->psz_name = strdup(psz_start + 5);
271                      }
272                      else if( !strncmp( psz_start, "bytes=", 6 ) )
273                      {
274                          p_seekpoint->i_byte_offset = atoll(psz_start + 6);
275                      }
276                      else if( !strncmp( psz_start, "time=", 5 ) )
277                      {
278                          p_seekpoint->i_time_offset = atoll(psz_start + 5) *
279                                                         1000000;
280                      }
281                      psz_start = psz_end + 1;
282                 }
283                 msg_Dbg( p_input, "adding bookmark: %s, bytes=%"PRId64", time=%"PRId64,
284                                   p_seekpoint->psz_name, p_seekpoint->i_byte_offset,
285                                   p_seekpoint->i_time_offset );
286                 input_Control( p_input, INPUT_ADD_BOOKMARK, p_seekpoint );
287                 vlc_seekpoint_Delete( p_seekpoint );
288                 *psz_parser = backup;
289             }
290             free( val.psz_string );
291         }
292     }
293
294     /* Remove 'Now playing' info as it is probably outdated */
295     input_item_SetNowPlaying( p_item, NULL );
296
297     /* */
298     if( p_input->b_preparsing )
299         p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT;
300
301     /* */
302     if( p_sout )
303         p_input->p->p_sout = p_sout;
304
305     memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) );
306     vlc_mutex_init( &p_input->p->counters.counters_lock );
307
308     /* Set the destructor when we are sure we are initialized */
309     vlc_object_set_destructor( p_input, (vlc_destructor_t)Destructor );
310
311     /* Attach only once we are ready */
312     vlc_object_attach( p_input, p_parent );
313
314     return p_input;
315 }
316
317 /**
318  * Input destructor (called when the object's refcount reaches 0).
319  */
320 static void Destructor( input_thread_t * p_input )
321 {
322 #ifndef NDEBUG
323     char * psz_name = input_item_GetName( p_input->p->input.p_item );
324     msg_Dbg( p_input, "Destroying the input for '%s'", psz_name);
325     free( psz_name );
326 #endif
327
328     vlc_event_manager_fini( &p_input->p->event_manager );
329
330     stats_TimerDump( p_input, STATS_TIMER_INPUT_LAUNCHING );
331     stats_TimerClean( p_input, STATS_TIMER_INPUT_LAUNCHING );
332 #ifdef ENABLE_SOUT
333     if( p_input->p->p_sout )
334         sout_DeleteInstance( p_input->p->p_sout );
335 #endif
336     vlc_gc_decref( p_input->p->input.p_item );
337
338     vlc_mutex_destroy( &p_input->p->counters.counters_lock );
339
340     vlc_mutex_destroy( &p_input->p->lock_control );
341     free( p_input->p );
342 }
343
344 /**
345  * Initialize an input thread and run it. You will need to monitor the
346  * thread to clean up after it is done
347  *
348  * \param p_parent a vlc_object
349  * \param p_item an input item
350  * \return a pointer to the spawned input thread
351  */
352 input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
353                                       input_item_t *p_item )
354 {
355     return __input_CreateThreadExtended( p_parent, p_item, NULL, NULL );
356 }
357
358 /* */
359 input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
360                                               input_item_t *p_item,
361                                               const char *psz_log, sout_instance_t *p_sout )
362 {
363     input_thread_t *p_input;
364
365     p_input = Create( p_parent, p_item, psz_log, false, p_sout );
366     if( !p_input )
367         return NULL;
368
369     /* Create thread and wait for its readiness. */
370     if( vlc_thread_create( p_input, "input", Run,
371                            VLC_THREAD_PRIORITY_INPUT, true ) )
372     {
373         input_ChangeState( p_input, ERROR_S );
374         msg_Err( p_input, "cannot create input thread" );
375         vlc_object_detach( p_input );
376         vlc_object_release( p_input );
377         return NULL;
378     }
379
380     return p_input;
381 }
382
383 /**
384  * Initialize an input thread and run it. This thread will clean after itself,
385  * you can forget about it. It can work either in blocking or non-blocking mode
386  *
387  * \param p_parent a vlc_object
388  * \param p_item an input item
389  * \param b_block should we block until read is finished ?
390  * \return the input object id if non blocking, an error code else
391  */
392 int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
393                    bool b_block )
394 {
395     input_thread_t *p_input;
396
397     p_input = Create( p_parent, p_item, NULL, false, NULL );
398     if( !p_input )
399         return VLC_EGENERIC;
400
401     if( b_block )
402     {
403         RunAndDestroy( VLC_OBJECT(p_input) );
404         return VLC_SUCCESS;
405     }
406     else
407     {
408         if( vlc_thread_create( p_input, "input", RunAndDestroy,
409                                VLC_THREAD_PRIORITY_INPUT, true ) )
410         {
411             input_ChangeState( p_input, ERROR_S );
412             msg_Err( p_input, "cannot create input thread" );
413             vlc_object_release( p_input );
414             return VLC_EGENERIC;
415         }
416     }
417     return p_input->i_object_id;
418 }
419
420 /**
421  * Initialize an input and initialize it to preparse the item
422  * This function is blocking. It will only accept to parse files
423  *
424  * \param p_parent a vlc_object_t
425  * \param p_item an input item
426  * \return VLC_SUCCESS or an error
427  */
428 int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
429 {
430     input_thread_t *p_input;
431
432     /* Allocate descriptor */
433     p_input = Create( p_parent, p_item, NULL, true, NULL );
434     if( !p_input )
435         return VLC_EGENERIC;
436
437     if( !Init( p_input ) )
438         End( p_input );
439
440     vlc_object_detach( p_input );
441     vlc_object_release( p_input );
442
443     return VLC_SUCCESS;
444 }
445
446 /**
447  * Request a running input thread to stop and die
448  *
449  * \param the input thread to stop
450  */
451 static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
452 {
453     vlc_list_t *p_list;
454     int i;
455
456     if( p_obj->i_object_type == VLC_OBJECT_VOUT ||
457         p_obj->i_object_type == VLC_OBJECT_AOUT ||
458         p_obj == VLC_OBJECT(p_input->p->p_sout) )
459         return;
460
461     vlc_object_kill( p_obj );
462
463     p_list = vlc_list_children( p_obj );
464     for( i = 0; i < p_list->i_count; i++ )
465         ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
466     vlc_list_release( p_list );
467 }
468 void input_StopThread( input_thread_t *p_input )
469 {
470     /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
471      * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
472      * unlock the control loop */
473     ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
474
475     input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
476 }
477
478 sout_instance_t * input_DetachSout( input_thread_t *p_input )
479 {
480     sout_instance_t *p_sout = p_input->p->p_sout;
481     vlc_object_detach( p_sout );
482     p_input->p->p_sout = NULL;
483     return p_sout;
484 }
485
486 /*****************************************************************************
487  * Run: main thread loop
488  * This is the "normal" thread that spawns the input processing chain,
489  * reads the stream, cleans up and waits
490  *****************************************************************************/
491 static void* Run( vlc_object_t *p_this )
492 {
493     input_thread_t *p_input = (input_thread_t *)p_this;
494     const int canc = vlc_savecancel();
495
496     /* Signal that the thread is launched */
497     vlc_thread_ready( p_input );
498
499     if( Init( p_input ) )
500     {
501         /* If we failed, wait before we are killed, and exit */
502         WaitDie( p_input );
503
504         /* Tell we're dead */
505         p_input->b_dead = true;
506
507         vlc_restorecancel( canc );
508         return NULL;
509     }
510
511     MainLoop( p_input );
512
513     if( !p_input->b_eof && !p_input->b_error && p_input->p->input.b_eof )
514     {
515         /* We have finish to demux data but not to play them */
516         while( !p_input->b_die )
517         {
518             if( input_EsOutDecodersEmpty( p_input->p->p_es_out ) )
519                 break;
520
521             msg_Dbg( p_input, "waiting decoder fifos to empty" );
522
523             msleep( INPUT_IDLE_SLEEP );
524         }
525
526         /* We have finished */
527         input_ChangeState( p_input, END_S );
528     }
529
530     /* Wait until we are asked to die */
531     if( !p_input->b_die )
532     {
533         WaitDie( p_input );
534     }
535
536     /* Clean up */
537     End( p_input );
538     vlc_restorecancel( canc );
539     return NULL;
540 }
541
542 /*****************************************************************************
543  * RunAndDestroy: main thread loop
544  * This is the "just forget me" thread that spawns the input processing chain,
545  * reads the stream, cleans up and releases memory
546  *****************************************************************************/
547 static void* RunAndDestroy( vlc_object_t *p_this )
548 {
549     input_thread_t *p_input = (input_thread_t *)p_this;
550     const int canc = vlc_savecancel();
551
552     /* Signal that the thread is launched */
553     vlc_thread_ready( p_input );
554
555     if( Init( p_input ) )
556         goto exit;
557
558     MainLoop( p_input );
559
560     if( !p_input->b_eof && !p_input->b_error && p_input->p->input.b_eof )
561     {
562         /* We have finished demuxing data but not playing it */
563         while( !p_input->b_die )
564         {
565             if( input_EsOutDecodersEmpty( p_input->p->p_es_out ) )
566                 break;
567
568             msg_Dbg( p_input, "waiting decoder fifos to empty" );
569
570             msleep( INPUT_IDLE_SLEEP );
571         }
572
573         /* We have finished */
574         input_ChangeState( p_input, END_S );
575     }
576
577     /* Clean up */
578     End( p_input );
579
580 exit:
581     /* Release memory */
582     vlc_object_release( p_input );
583     vlc_restorecancel( canc );
584     return NULL;
585 }
586
587 /*****************************************************************************
588  * Main loop: Fill buffers from access, and demux
589  *****************************************************************************/
590 static void MainLoop( input_thread_t *p_input )
591 {
592     int64_t i_start_mdate = mdate();
593     int64_t i_intf_update = 0;
594     int i_updates = 0;
595
596     /* Stop the timer */
597     stats_TimerStop( p_input, STATS_TIMER_INPUT_LAUNCHING );
598
599     while( !p_input->b_die && !p_input->b_error && !p_input->p->input.b_eof )
600     {
601         bool b_force_update = false;
602         int i_ret;
603         int i_type;
604         vlc_value_t val;
605
606         /* Do the read */
607         if( p_input->i_state != PAUSE_S )
608         {
609             if( ( p_input->p->i_stop > 0 && p_input->i_time >= p_input->p->i_stop ) ||
610                 ( p_input->p->i_run > 0 && i_start_mdate+p_input->p->i_run < mdate() ) )
611                 i_ret = 0; /* EOF */
612             else
613                 i_ret = p_input->p->input.p_demux->pf_demux(p_input->p->input.p_demux);
614
615             if( i_ret > 0 )
616             {
617                 /* TODO */
618                 if( p_input->p->input.b_title_demux &&
619                     p_input->p->input.p_demux->info.i_update )
620                 {
621                     i_ret = UpdateFromDemux( p_input );
622                     b_force_update = true;
623                 }
624                 else if( !p_input->p->input.b_title_demux &&
625                           p_input->p->input.p_access &&
626                           p_input->p->input.p_access->info.i_update )
627                 {
628                     i_ret = UpdateFromAccess( p_input );
629                     b_force_update = true;
630                 }
631             }
632
633             if( i_ret == 0 )    /* EOF */
634             {
635                 vlc_value_t repeat;
636
637                 var_Get( p_input, "input-repeat", &repeat );
638                 if( repeat.i_int == 0 )
639                 {
640                     /* End of file - we do not set b_die because only the
641                      * playlist is allowed to do so. */
642                     msg_Dbg( p_input, "EOF reached" );
643                     p_input->p->input.b_eof = true;
644                 }
645                 else
646                 {
647                     msg_Dbg( p_input, "repeating the same input (%d)",
648                              repeat.i_int );
649                     if( repeat.i_int > 0 )
650                     {
651                         repeat.i_int--;
652                         var_Set( p_input, "input-repeat", repeat );
653                     }
654
655                     /* Seek to start title/seekpoint */
656                     val.i_int = p_input->p->input.i_title_start -
657                         p_input->p->input.i_title_offset;
658                     if( val.i_int < 0 || val.i_int >= p_input->p->input.i_title )
659                         val.i_int = 0;
660                     input_ControlPush( p_input,
661                                        INPUT_CONTROL_SET_TITLE, &val );
662
663                     val.i_int = p_input->p->input.i_seekpoint_start -
664                         p_input->p->input.i_seekpoint_offset;
665                     if( val.i_int > 0 /* TODO: check upper boundary */ )
666                         input_ControlPush( p_input,
667                                            INPUT_CONTROL_SET_SEEKPOINT, &val );
668
669                     /* Seek to start position */
670                     if( p_input->p->i_start > 0 )
671                     {
672                         val.i_time = p_input->p->i_start;
673                         input_ControlPush( p_input, INPUT_CONTROL_SET_TIME,
674                                            &val );
675                     }
676                     else
677                     {
678                         val.f_float = 0.0;
679                         input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION,
680                                            &val );
681                     }
682
683                     /* */
684                     i_start_mdate = mdate();
685                 }
686             }
687             else if( i_ret < 0 )
688             {
689                 input_ChangeState( p_input, ERROR_S );
690             }
691
692             if( i_ret > 0 && p_input->p->i_slave > 0 )
693             {
694                 SlaveDemux( p_input );
695             }
696         }
697         else
698         {
699             /* Small wait */
700             msleep( 10*1000 );
701         }
702
703         /* Handle control */
704         vlc_mutex_lock( &p_input->p->lock_control );
705         ControlReduce( p_input );
706         while( !ControlPopNoLock( p_input, &i_type, &val ) )
707         {
708             msg_Dbg( p_input, "control type=%d", i_type );
709             if( Control( p_input, i_type, val ) )
710                 b_force_update = true;
711         }
712         vlc_mutex_unlock( &p_input->p->lock_control );
713
714         if( b_force_update || i_intf_update < mdate() )
715         {
716             vlc_value_t val;
717             double f_pos;
718             int64_t i_time, i_length;
719             /* update input status variables */
720             if( !demux_Control( p_input->p->input.p_demux,
721                                  DEMUX_GET_POSITION, &f_pos ) )
722             {
723                 val.f_float = (float)f_pos;
724                 var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
725             }
726             if( !demux_Control( p_input->p->input.p_demux,
727                                  DEMUX_GET_TIME, &i_time ) )
728             {
729                 p_input->i_time = i_time;
730                 val.i_time = i_time;
731                 var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
732             }
733             if( !demux_Control( p_input->p->input.p_demux,
734                                  DEMUX_GET_LENGTH, &i_length ) )
735             {
736                 vlc_value_t old_val;
737                 var_Get( p_input, "length", &old_val );
738                 val.i_time = i_length;
739                 var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
740
741                 if( old_val.i_time != val.i_time )
742                 {
743                     UpdateItemLength( p_input, i_length );
744                 }
745             }
746
747             var_SetBool( p_input, "intf-change", true );
748             i_intf_update = mdate() + INT64_C(150000);
749         }
750         /* 150ms * 8 = ~ 1 second */
751         if( ++i_updates % 8 == 0 )
752         {
753             stats_ComputeInputStats( p_input, p_input->p->input.p_item->p_stats );
754             /* Are we the thread responsible for computing global stats ? */
755             if( libvlc_priv( p_input->p_libvlc )->p_stats_computer == p_input )
756             {
757                 stats_ComputeGlobalStats( p_input->p_libvlc,
758                                           p_input->p_libvlc->p_stats );
759             }
760         }
761     }
762 }
763
764 static void InitStatistics( input_thread_t * p_input )
765 {
766     if( p_input->b_preparsing ) return;
767
768     /* Prepare statistics */
769 #define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \
770  stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
771     if( libvlc_stats( p_input ) )
772     {
773         INIT_COUNTER( read_bytes, INTEGER, COUNTER );
774         INIT_COUNTER( read_packets, INTEGER, COUNTER );
775         INIT_COUNTER( demux_read, INTEGER, COUNTER );
776         INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
777         INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
778         INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
779         INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
780         INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
781         INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
782         INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
783         INIT_COUNTER( decoded_video, INTEGER, COUNTER );
784         INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
785         p_input->p->counters.p_sout_send_bitrate = NULL;
786         p_input->p->counters.p_sout_sent_packets = NULL;
787         p_input->p->counters.p_sout_sent_bytes = NULL;
788         if( p_input->p->counters.p_demux_bitrate )
789             p_input->p->counters.p_demux_bitrate->update_interval = 1000000;
790         if( p_input->p->counters.p_input_bitrate )
791             p_input->p->counters.p_input_bitrate->update_interval = 1000000;
792     }
793 }
794
795 #ifdef ENABLE_SOUT
796 static int InitSout( input_thread_t * p_input )
797 {
798     char *psz;
799
800     if( p_input->b_preparsing ) return VLC_SUCCESS;
801
802     /* Find a usable sout and attach it to p_input */
803     psz = var_GetNonEmptyString( p_input, "sout" );
804     if( psz && strncasecmp( p_input->p->input.p_item->psz_uri, "vlc:", 4 ) )
805     {
806         /* Check the validity of the provided sout */
807         if( p_input->p->p_sout )
808         {
809             if( strcmp( p_input->p->p_sout->psz_sout, psz ) )
810             {
811                 msg_Dbg( p_input, "destroying unusable sout" );
812
813                 sout_DeleteInstance( p_input->p->p_sout );
814                 p_input->p->p_sout = NULL;
815             }
816         }
817
818         if( p_input->p->p_sout )
819         {
820             /* Reuse it */
821             msg_Dbg( p_input, "sout keep: reusing sout" );
822             msg_Dbg( p_input, "sout keep: you probably want to use "
823                               "gather stream_out" );
824             vlc_object_attach( p_input->p->p_sout, p_input );
825         }
826         else
827         {
828             /* Create a new one */
829             p_input->p->p_sout = sout_NewInstance( p_input, psz );
830             if( !p_input->p->p_sout )
831             {
832                 input_ChangeState( p_input, ERROR_S );
833                 msg_Err( p_input, "cannot start stream output instance, " \
834                                   "aborting" );
835                 free( psz );
836                 return VLC_EGENERIC;
837             }
838         }
839         if( libvlc_stats( p_input ) )
840         {
841             INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
842             INIT_COUNTER( sout_sent_bytes, INTEGER, COUNTER );
843             INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
844             if( p_input->p->counters.p_sout_send_bitrate )
845                  p_input->p->counters.p_sout_send_bitrate->update_interval =
846                          1000000;
847         }
848     }
849     else if( p_input->p->p_sout )
850     {
851         msg_Dbg( p_input, "destroying useless sout" );
852
853         sout_DeleteInstance( p_input->p->p_sout );
854         p_input->p->p_sout = NULL;
855     }
856     free( psz );
857
858     return VLC_SUCCESS;
859 }
860 #endif
861
862 static void InitTitle( input_thread_t * p_input )
863 {
864     vlc_value_t val;
865
866     if( p_input->b_preparsing ) return;
867
868     /* Create global title (from master) */
869     p_input->p->i_title = p_input->p->input.i_title;
870     p_input->p->title   = p_input->p->input.title;
871     p_input->p->i_title_offset = p_input->p->input.i_title_offset;
872     p_input->p->i_seekpoint_offset = p_input->p->input.i_seekpoint_offset;
873     if( p_input->p->i_title > 0 )
874     {
875         /* Setup variables */
876         input_ControlVarNavigation( p_input );
877         input_ControlVarTitle( p_input, 0 );
878     }
879
880     /* Global flag */
881     p_input->b_can_pace_control = p_input->p->input.b_can_pace_control;
882     p_input->p->b_can_pause        = p_input->p->input.b_can_pause;
883     p_input->p->b_can_rate_control = p_input->p->input.b_can_rate_control;
884
885     /* Fix pts delay */
886     if( p_input->i_pts_delay < 0 )
887         p_input->i_pts_delay = 0;
888
889     /* If the desynchronisation requested by the user is < 0, we need to
890      * cache more data. */
891     var_Get( p_input, "audio-desync", &val );
892     if( val.i_int < 0 ) p_input->i_pts_delay -= (val.i_int * 1000);
893
894     /* Update cr_average depending on the caching */
895     p_input->p->input.i_cr_average *= (10 * p_input->i_pts_delay / 200000);
896     p_input->p->input.i_cr_average /= 10;
897     if( p_input->