~ubuntu-branches/ubuntu/natty/vlc/natty

« back to all changes in this revision

Viewing changes to src/input/vlm.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-06-25 01:09:16 UTC
  • mfrom: (1.1.30 upstream)
  • Revision ID: james.westby@ubuntu.com-20100625010916-asxhep2mutg6g6pd
Tags: 1.1.0-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - build and install the libx264 plugin
  - add Xb-Npp header to vlc package
  - Add apport hook to include more vlc dependencies in bug reports
* Drop xulrunner patches.
* Drop 502_xulrunner_191.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * vlm.c: VLM interface plugin
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2000-2005 the VideoLAN team
5
 
 * $Id: d1ef0964fdc58859da19d6c546ac0c21406972ed $
 
5
 * $Id: facc49c001dc0bd751a379e73300b1f84faf5c3a $
6
6
 *
7
7
 * Authors: Simon Latapie <garf@videolan.org>
8
8
 *          Laurent Aimar <fenrir@videolan.org>
56
56
#include "vlm_internal.h"
57
57
#include "vlm_event.h"
58
58
#include <vlc_vod.h>
59
 
#include <vlc_charset.h>
60
59
#include <vlc_sout.h>
61
60
#include "../stream_output/stream_output.h"
62
61
#include "../libvlc.h"
69
68
static void* Manage( void * );
70
69
static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list );
71
70
 
 
71
static int InputEventPreparse( vlc_object_t *p_this, char const *psz_cmd,
 
72
                               vlc_value_t oldval, vlc_value_t newval, void *p_data )
 
73
{
 
74
    VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
 
75
    vlc_sem_t *p_sem_preparse = p_data;
 
76
 
 
77
    if( newval.i_int == INPUT_EVENT_DEAD ||
 
78
        newval.i_int == INPUT_EVENT_ITEM_META )
 
79
        vlc_sem_post( p_sem_preparse );
 
80
 
 
81
    return VLC_SUCCESS;
 
82
}
 
83
 
 
84
static int InputEvent( vlc_object_t *p_this, char const *psz_cmd,
 
85
                       vlc_value_t oldval, vlc_value_t newval,
 
86
                       void *p_data )
 
87
{
 
88
    VLC_UNUSED(psz_cmd);
 
89
    VLC_UNUSED(oldval);
 
90
    input_thread_t *p_input = (input_thread_t *)p_this;
 
91
    vlm_t *p_vlm = libvlc_priv( p_input->p_libvlc )->p_vlm;
 
92
    assert( p_vlm );
 
93
    vlm_media_sys_t *p_media = p_data;
 
94
    const char *psz_instance_name = NULL;
 
95
 
 
96
    if( newval.i_int == INPUT_EVENT_STATE )
 
97
    {
 
98
        for( int i = 0; i < p_media->i_instance; i++ )
 
99
        {
 
100
            if( p_media->instance[i]->p_input == p_input )
 
101
            {
 
102
                psz_instance_name = p_media->instance[i]->psz_name;
 
103
                break;
 
104
            }
 
105
        }
 
106
        vlm_SendEventMediaInstanceState( p_vlm, p_media->cfg.id, p_media->cfg.psz_name, psz_instance_name, var_GetInteger( p_input, "state" ) );
 
107
 
 
108
        vlc_mutex_lock( &p_vlm->lock_manage );
 
109
        p_vlm->input_state_changed = true;
 
110
        vlc_cond_signal( &p_vlm->wait_manage );
 
111
        vlc_mutex_unlock( &p_vlm->lock_manage );
 
112
    }
 
113
    return VLC_SUCCESS;
 
114
}
 
115
 
 
116
static vlc_mutex_t vlm_mutex = VLC_STATIC_MUTEX;
 
117
 
 
118
#undef vlm_New
72
119
/*****************************************************************************
73
120
 * vlm_New:
74
121
 *****************************************************************************/
75
 
vlm_t *__vlm_New ( vlc_object_t *p_this )
 
122
vlm_t *vlm_New ( vlc_object_t *p_this )
76
123
{
77
 
    vlc_value_t lockval;
78
124
    vlm_t *p_vlm = NULL, **pp_vlm = &(libvlc_priv (p_this->p_libvlc)->p_vlm);
79
125
    char *psz_vlmconf;
80
126
    static const char vlm_object_name[] = "vlm daemon";
81
127
 
82
128
    /* Avoid multiple creation */
83
 
    if( var_Create( p_this->p_libvlc, "vlm_mutex", VLC_VAR_MUTEX ) ||
84
 
        var_Get( p_this->p_libvlc, "vlm_mutex", &lockval ) )
85
 
        return NULL;
86
 
 
87
 
    vlc_mutex_lock( lockval.p_address );
 
129
    vlc_mutex_lock( &vlm_mutex );
88
130
 
89
131
    p_vlm = *pp_vlm;
90
132
    if( p_vlm )
91
133
    {   /* VLM already exists */
92
134
        vlc_object_hold( p_vlm );
93
 
        vlc_mutex_unlock( lockval.p_address );
 
135
        vlc_mutex_unlock( &vlm_mutex );
94
136
        return p_vlm;
95
137
    }
96
138
 
100
142
                               vlm_object_name );
101
143
    if( !p_vlm )
102
144
    {
103
 
        vlc_mutex_unlock( lockval.p_address );
 
145
        vlc_mutex_unlock( &vlm_mutex );
104
146
        return NULL;
105
147
    }
106
148
 
107
149
    vlc_mutex_init( &p_vlm->lock );
 
150
    vlc_mutex_init( &p_vlm->lock_manage );
 
151
    vlc_cond_init_daytime( &p_vlm->wait_manage );
 
152
    p_vlm->input_state_changed = false;
108
153
    p_vlm->i_id = 1;
109
154
    TAB_INIT( p_vlm->i_media, p_vlm->media );
110
155
    TAB_INIT( p_vlm->i_schedule, p_vlm->schedule );
111
 
    p_vlm->i_vod = 0;
112
156
    p_vlm->p_vod = NULL;
113
157
    var_Create( p_vlm, "intf-event", VLC_VAR_ADDRESS );
114
158
    vlc_object_attach( p_vlm, p_this->p_libvlc );
115
159
 
116
160
    if( vlc_clone( &p_vlm->thread, Manage, p_vlm, VLC_THREAD_PRIORITY_LOW ) )
117
161
    {
 
162
        vlc_cond_destroy( &p_vlm->wait_manage );
118
163
        vlc_mutex_destroy( &p_vlm->lock );
 
164
        vlc_mutex_destroy( &p_vlm->lock_manage );
119
165
        vlc_object_release( p_vlm );
 
166
        vlc_mutex_unlock( &vlm_mutex );
120
167
        return NULL;
121
168
    }
122
169
 
 
170
    *pp_vlm = p_vlm; /* for future reference */
 
171
 
123
172
    /* Load our configuration file */
124
173
    psz_vlmconf = var_CreateGetString( p_vlm, "vlm-conf" );
125
174
    if( psz_vlmconf && *psz_vlmconf )
141
190
    free( psz_vlmconf );
142
191
 
143
192
    vlc_object_set_destructor( p_vlm, (vlc_destructor_t)vlm_Destructor );
144
 
    *pp_vlm = p_vlm; /* for future reference */
145
 
    vlc_mutex_unlock( lockval.p_address );
 
193
    vlc_mutex_unlock( &vlm_mutex );
146
194
 
147
195
    return p_vlm;
148
196
}
152
200
 *****************************************************************************/
153
201
void vlm_Delete( vlm_t *p_vlm )
154
202
{
155
 
    vlc_value_t lockval;
156
 
 
157
203
    /* vlm_Delete() is serialized against itself, and against vlm_New().
158
204
     * This way, vlm_Destructor () (called from vlc_objet_release() above)
159
205
     * is serialized against setting libvlc_priv->p_vlm from vlm_New(). */
160
 
    var_Get( p_vlm->p_libvlc, "vlm_mutex", &lockval );
161
 
    vlc_mutex_lock( lockval.p_address );
 
206
    vlc_mutex_lock( &vlm_mutex );
162
207
    vlc_object_release( p_vlm );
163
 
    vlc_mutex_unlock( lockval.p_address );
 
208
    vlc_mutex_unlock( &vlm_mutex );
164
209
}
165
210
 
166
211
/*****************************************************************************
168
213
 *****************************************************************************/
169
214
static void vlm_Destructor( vlm_t *p_vlm )
170
215
{
171
 
    libvlc_priv (p_vlm->p_libvlc)->p_vlm = NULL;
172
 
 
 
216
    vlc_mutex_lock( &p_vlm->lock );
173
217
    vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS );
174
218
    TAB_CLEAN( p_vlm->i_media, p_vlm->media );
175
219
 
176
220
    vlm_ControlInternal( p_vlm, VLM_CLEAR_SCHEDULES );
177
221
    TAB_CLEAN( p_vlm->schedule, p_vlm->schedule );
 
222
    vlc_mutex_unlock( &p_vlm->lock );
178
223
 
 
224
    libvlc_priv(p_vlm->p_libvlc)->p_vlm = NULL;
179
225
    vlc_object_kill( p_vlm );
 
226
 
 
227
    if( p_vlm->p_vod )
 
228
    {
 
229
        module_unneed( p_vlm->p_vod, p_vlm->p_vod->p_module );
 
230
        vlc_object_detach( p_vlm->p_vod );
 
231
        vlc_object_release( p_vlm->p_vod );
 
232
    }
 
233
 
 
234
    vlc_mutex_lock( &p_vlm->lock_manage );
 
235
    p_vlm->input_state_changed = true;
 
236
    vlc_cond_signal( &p_vlm->wait_manage );
 
237
    vlc_mutex_unlock( &p_vlm->lock_manage );
 
238
 
180
239
    /*vlc_cancel( p_vlm->thread ); */
181
240
    vlc_join( p_vlm->thread, NULL );
 
241
 
 
242
    vlc_cond_destroy( &p_vlm->wait_manage );
182
243
    vlc_mutex_destroy( &p_vlm->lock );
 
244
    vlc_mutex_destroy( &p_vlm->lock_manage );
183
245
}
184
246
 
185
247
/*****************************************************************************
313
375
    int i, j;
314
376
    mtime_t i_lastcheck;
315
377
    mtime_t i_time;
 
378
    mtime_t i_nextschedule = 0;
316
379
 
317
380
    int canc = vlc_savecancel ();
318
381
    i_lastcheck = vlm_Date();
321
384
    {
322
385
        char **ppsz_scheduled_commands = NULL;
323
386
        int    i_scheduled_commands = 0;
 
387
        bool scheduled_command = false;
324
388
 
 
389
        vlc_mutex_lock( &vlm->lock_manage );
 
390
        while( !vlm->input_state_changed && !scheduled_command )
 
391
        {
 
392
            if( i_nextschedule )
 
393
                scheduled_command = vlc_cond_timedwait( &vlm->wait_manage, &vlm->lock_manage, i_nextschedule ) != 0;
 
394
            else
 
395
                vlc_cond_wait( &vlm->wait_manage, &vlm->lock_manage );
 
396
        }
 
397
        vlm->input_state_changed = false;
 
398
        vlc_mutex_unlock( &vlm->lock_manage );
 
399
        /* destroy the inputs that wants to die, and launch the next input */
325
400
        vlc_mutex_lock( &vlm->lock );
326
 
 
327
 
        /* destroy the inputs that wants to die, and launch the next input */
328
401
        for( i = 0; i < vlm->i_media; i++ )
329
402
        {
330
403
            vlm_media_sys_t *p_media = vlm->media[i];
359
432
 
360
433
        /* scheduling */
361
434
        i_time = vlm_Date();
 
435
        i_nextschedule = 0;
362
436
 
363
437
        for( i = 0; i < vlm->i_schedule; i++ )
364
438
        {
386
460
                        vlm->schedule[i]->i_period;
387
461
                }
388
462
 
389
 
                if( i_real_date <= i_time && i_real_date > i_lastcheck )
 
463
                if( i_real_date <= i_time )
390
464
                {
391
 
                    for( j = 0; j < vlm->schedule[i]->i_command; j++ )
 
465
                    if( i_real_date > i_lastcheck )
392
466
                    {
393
 
                        TAB_APPEND( i_scheduled_commands,
394
 
                                    ppsz_scheduled_commands,
395
 
                                    strdup(vlm->schedule[i]->command[j] ) );
 
467
                        for( j = 0; j < vlm->schedule[i]->i_command; j++ )
 
468
                        {
 
469
                            TAB_APPEND( i_scheduled_commands,
 
470
                                        ppsz_scheduled_commands,
 
471
                                        strdup(vlm->schedule[i]->command[j] ) );
 
472
                        }
396
473
                    }
397
474
                }
 
475
                else
 
476
                {
 
477
                    i_nextschedule = i_real_date;
 
478
                }
398
479
            }
399
480
        }
 
481
 
400
482
        while( i_scheduled_commands )
401
483
        {
402
484
            vlm_message_t *message = NULL;
412
494
        }
413
495
 
414
496
        i_lastcheck = i_time;
415
 
 
416
497
        vlc_mutex_unlock( &vlm->lock );
417
498
 
418
 
        msleep( 100000 );
419
499
    }
420
500
 
421
501
    vlc_restorecancel (canc);
489
569
{
490
570
    vlm_media_t *p_cfg = &p_media->cfg;
491
571
    /* Check if we need to create/delete a vod media */
492
 
    if( p_cfg->b_vod )
 
572
    if( p_cfg->b_vod && p_vlm->p_vod )
493
573
    {
494
574
        if( !p_cfg->b_enabled && p_media->vod.p_media )
495
575
        {
531
611
            if( asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name ) == -1 )
532
612
                psz_header = NULL;
533
613
 
534
 
            if( (p_input = input_CreateAndStart( p_vlm->p_libvlc, p_media->vod.p_item, psz_header ) ) )
 
614
            p_input = input_Create( p_vlm->p_vod, p_media->vod.p_item, psz_header, NULL );
 
615
            if( p_input )
535
616
            {
536
 
                while( !p_input->b_eof && !p_input->b_error )
537
 
                    msleep( 100000 );
538
 
 
539
 
                input_Stop( p_input, false );
 
617
                vlc_sem_t sem_preparse;
 
618
                vlc_sem_init( &sem_preparse, 0 );
 
619
                var_AddCallback( p_input, "intf-event", InputEventPreparse, &sem_preparse );
 
620
 
 
621
                if( !input_Start( p_input ) )
 
622
                {
 
623
                    while( !p_input->b_dead && ( !p_cfg->vod.psz_mux || !input_item_IsPreparsed( p_media->vod.p_item ) ) )
 
624
                        vlc_sem_wait( &sem_preparse );
 
625
                }
 
626
 
 
627
                var_DelCallback( p_input, "intf-event", InputEventPreparse, &sem_preparse );
 
628
                vlc_sem_destroy( &sem_preparse );
 
629
 
 
630
                input_Stop( p_input, true );
540
631
                vlc_thread_join( p_input );
541
632
                vlc_object_release( p_input );
542
633
            }
570
661
            }
571
662
        }
572
663
    }
 
664
    else if ( p_cfg->b_vod )
 
665
        msg_Err( p_vlm, "vod server is not loaded" );
573
666
    else
574
667
    {
575
668
        /* TODO start media if needed */
611
704
        return VLC_EGENERIC;
612
705
    }
613
706
    /* Check if we need to load the VOD server */
614
 
    if( p_cfg->b_vod && !p_vlm->i_vod )
 
707
    if( p_cfg->b_vod && !p_vlm->p_vod )
615
708
    {
616
709
        p_vlm->p_vod = vlc_custom_create( VLC_OBJECT(p_vlm), sizeof( vod_t ),
617
710
                                          VLC_OBJECT_GENERIC, "vod server" );
620
713
        if( !p_vlm->p_vod->p_module )
621
714
        {
622
715
            msg_Err( p_vlm, "cannot find vod server" );
623
 
            vlc_object_detach( p_vlm->p_vod );
624
716
            vlc_object_release( p_vlm->p_vod );
625
717
            p_vlm->p_vod = NULL;
626
718
            return VLC_EGENERIC;
634
726
    if( !p_media )
635
727
        return VLC_ENOMEM;
636
728
 
637
 
    if( p_cfg->b_vod )
638
 
        p_vlm->i_vod++;
639
 
 
640
729
    vlm_media_Copy( &p_media->cfg, p_cfg );
641
730
    p_media->cfg.id = p_vlm->i_id++;
642
731
    /* FIXME do we do something here if enabled is true ? */
671
760
    {
672
761
        p_media->cfg.b_enabled = false;
673
762
        vlm_OnMediaUpdate( p_vlm, p_media );
674
 
        p_vlm->i_vod--;
675
763
    }
676
764
 
677
765
    /* */
681
769
 
682
770
    vlc_gc_decref( p_media->vod.p_item );
683
771
 
 
772
    if( p_media->vod.p_media )
 
773
        p_vlm->p_vod->pf_media_del( p_vlm->p_vod, p_media->vod.p_media );
 
774
 
684
775
    TAB_REMOVE( p_vlm->i_media, p_vlm->media, p_media );
685
 
 
686
776
    free( p_media );
687
777
 
688
 
    /* Check if we need to unload the VOD server */
689
 
    if( p_vlm->p_vod && p_vlm->i_vod <= 0 )
690
 
    {
691
 
        module_unneed( p_vlm->p_vod, p_vlm->p_vod->p_module );
692
 
        vlc_object_detach( p_vlm->p_vod );
693
 
        vlc_object_release( p_vlm->p_vod );
694
 
        p_vlm->p_vod = NULL;
695
 
    }
696
 
 
697
778
    return VLC_SUCCESS;
698
779
}
699
780
 
773
854
 
774
855
    return p_instance;
775
856
}
776
 
static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instance_sys_t *p_instance, const char *psz_name )
 
857
static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instance_sys_t *p_instance, vlm_media_sys_t *p_media )
777
858
{
778
859
    input_thread_t *p_input = p_instance->p_input;
779
860
    if( p_input )
786
867
        p_resource = input_DetachResource( p_input );
787
868
        input_resource_Delete( p_resource );
788
869
 
 
870
        var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
789
871
        vlc_object_release( p_input );
790
872
 
791
 
        vlm_SendEventMediaInstanceStopped( p_vlm, id, psz_name );
 
873
        vlm_SendEventMediaInstanceStopped( p_vlm, id, p_media->cfg.psz_name );
792
874
    }
793
875
    if( p_instance->p_input_resource )
794
876
        input_resource_Delete( p_instance->p_input_resource );
795
877
 
 
878
    TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
796
879
    vlc_gc_decref( p_instance->p_item );
797
880
    free( p_instance->psz_name );
798
881
    free( p_instance );
863
946
            return VLC_SUCCESS;
864
947
        }
865
948
 
866
 
        input_Stop( p_input, !p_input->b_eof && !p_input->b_error );
 
949
 
 
950
        input_Stop( p_input, true );
867
951
        vlc_thread_join( p_input );
868
952
 
869
953
        p_instance->p_input_resource = input_DetachResource( p_input );
870
954
 
 
955
        var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
871
956
        vlc_object_release( p_input );
872
957
 
873
958
        if( !p_instance->b_sout_keep )
883
968
 
884
969
    if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 )
885
970
    {
886
 
        p_instance->p_input = input_Create( p_vlm->p_libvlc, p_instance->p_item,
 
971
        vlc_object_t *p_parent = p_media->cfg.b_vod ?
 
972
                                     VLC_OBJECT(p_vlm->p_vod) :
 
973
                                     VLC_OBJECT(p_vlm->p_libvlc);
 
974
        p_instance->p_input = input_Create( p_parent, p_instance->p_item,
887
975
                                            psz_log, p_instance->p_input_resource );
888
 
        if( p_instance->p_input && input_Start( p_instance->p_input ) )
 
976
        if( p_instance->p_input )
889
977
        {
890
 
            vlc_object_release( p_instance->p_input );
891
 
            p_instance->p_input = NULL;
 
978
            var_AddCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
 
979
            if( input_Start( p_instance->p_input ) != VLC_SUCCESS )
 
980
            {
 
981
                var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
 
982
                vlc_object_release( p_instance->p_input );
 
983
                p_instance->p_input = NULL;
 
984
            }
892
985
        }
893
986
        p_instance->p_input_resource = NULL;
894
987
 
895
988
        if( !p_instance->p_input )
896
989
        {
897
 
            TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
898
 
            vlm_MediaInstanceDelete( p_vlm, id, p_instance, p_media->cfg.psz_name );
 
990
            vlm_MediaInstanceDelete( p_vlm, id, p_instance, p_media );
899
991
        }
900
992
        else
901
993
        {
919
1011
    if( !p_instance )
920
1012
        return VLC_EGENERIC;
921
1013
 
922
 
    TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
923
 
 
924
 
    vlm_MediaInstanceDelete( p_vlm, id, p_instance, p_media->cfg.psz_name );
 
1014
    vlm_MediaInstanceDelete( p_vlm, id, p_instance, p_media );
925
1015
 
926
1016
    return VLC_SUCCESS;
927
1017
}
1008
1098
            p_idsc->d_position = var_GetFloat( p_instance->p_input, "position" );
1009
1099
            if( var_GetInteger( p_instance->p_input, "state" ) == PAUSE_S )
1010
1100
                p_idsc->b_paused = true;
1011
 
            p_idsc->i_rate = var_GetInteger( p_instance->p_input, "rate" );
 
1101
            p_idsc->i_rate = INPUT_RATE_DEFAULT
 
1102
                             / var_GetFloat( p_instance->p_input, "rate" );
1012
1103
        }
1013
1104
 
1014
1105
        TAB_APPEND( i_idsc, pp_idsc, p_idsc );