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