Changeset e87abf624a0302f8d6f7bdd0a9f550cec1f5fb12

Show
Ignore:
Timestamp:
28/02/07 23:45:02 (2 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1172702702 +0000
git-parent:

[0bf39ed37db37db3d1c925e3af7a742ff251a522]

git-author:
Laurent Aimar <fenrir@videolan.org> 1172702702 +0000
Message:

Reworked/improved the way sout-keep works. (VLM sout-keep does not
work again yet )

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/input/input.c

    rd7bc817 re87abf6  
    5353 
    5454static input_thread_t * Create  ( vlc_object_t *, input_item_t *, 
    55                                   const char *, vlc_bool_t ); 
     55                                  const char *, vlc_bool_t, sout_instance_t * ); 
    5656static  int             Init    ( input_thread_t *p_input ); 
    5757static void             Error   ( input_thread_t *p_input ); 
    5858static void             End     ( input_thread_t *p_input ); 
    5959static void             MainLoop( input_thread_t *p_input ); 
     60static void             Destroy( input_thread_t *p_input, sout_instance_t **pp_sout ); 
    6061 
    6162static inline int ControlPopNoLock( input_thread_t *, int *, vlc_value_t * ); 
     
    8081 
    8182static void InputMetaUser( input_thread_t *p_input ); 
     83 
     84static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, vlc_bool_t * ); 
     85static void SoutKeep( sout_instance_t * ); 
    8286 
    8387/***************************************************************************** 
     
    106110 *****************************************************************************/ 
    107111static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, 
    108                                const char *psz_header, vlc_bool_t b_quick
     112                               const char *psz_header, vlc_bool_t b_quick, sout_instance_t *p_sout
    109113{ 
    110114    input_thread_t *p_input = NULL;                 /* thread descriptor */ 
     
    152156    p_input->p->p_es_out = NULL; 
    153157    p_input->p->p_sout  = NULL; 
     158    p_input->p->b_sout_keep  = VLC_FALSE; 
    154159    p_input->p->b_out_pace_control = VLC_FALSE; 
    155160    p_input->i_pts_delay = 0; 
     
    189194    vlc_mutex_lock( &p_item->lock ); 
    190195    for( i = 0; i < p_item->i_options; i++ ) 
    191     { 
    192196        var_OptionParse( p_input, p_item->ppsz_options[i] ); 
    193     } 
    194197    vlc_mutex_unlock( &p_item->lock ); 
    195198 
     
    258261        p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT; 
    259262 
     263    /* */ 
     264    if( p_sout ) 
     265        p_input->p->p_sout = p_sout; 
     266 
    260267    /* Attach only once we are ready */ 
    261268    vlc_object_attach( p_input, p_parent ); 
     
    264271} 
    265272 
    266 static void Destroy( input_thread_t *p_input
     273static void Destroy( input_thread_t *p_input, sout_instance_t **pp_sout
    267274{ 
    268275    vlc_object_detach( p_input ); 
     276 
     277    if( pp_sout ) 
     278        *pp_sout = NULL; 
     279    if( p_input->p->p_sout ) 
     280    { 
     281        if( pp_sout ) 
     282            *pp_sout = p_input->p->p_sout; 
     283        else if( p_input->p->b_sout_keep ) 
     284            SoutKeep( p_input->p->p_sout ); 
     285        else 
     286            sout_DeleteInstance( p_input->p->p_sout ); 
     287    } 
    269288 
    270289    vlc_mutex_destroy( &p_input->p->lock_control ); 
     
    273292    vlc_object_destroy( p_input ); 
    274293} 
     294 
    275295/** 
    276296 * Initialize an input thread and run it. You will need to monitor the 
     
    284304                                      input_item_t *p_item ) 
    285305{ 
    286     return __input_CreateThread2( p_parent, p_item, NULL ); 
    287 
    288  
    289 /* Gruik ! */ 
    290 input_thread_t *__input_CreateThread2( vlc_object_t *p_parent, 
    291                                        input_item_t *p_item, 
    292                                        const char *psz_header ) 
    293 
    294     input_thread_t *p_input = NULL;      /* thread descriptor */ 
    295  
    296     p_input = Create( p_parent, p_item, psz_header, VLC_FALSE ); 
     306    vlc_bool_t b_sout_keep; 
     307    sout_instance_t *p_sout = SoutFind( p_parent, p_item, &b_sout_keep ); 
     308    input_thread_t *p_input =  __input_CreateThreadExtended( p_parent, p_item, NULL, p_sout ); 
     309 
     310    if( !p_input && p_sout ) 
     311        SoutKeep( p_sout ); 
     312 
     313    p_input->p->b_sout_keep = b_sout_keep; 
     314    return p_input; 
     315
     316 
     317/* */ 
     318input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent, 
     319                                              input_item_t *p_item, 
     320                                              const char *psz_log, sout_instance_t *p_sout ) 
     321
     322    input_thread_t *p_input; 
     323 
     324    p_input = Create( p_parent, p_item, psz_log, VLC_FALSE, p_sout ); 
    297325    if( !p_input ) 
    298326        return NULL; 
     
    300328    /* Create thread and wait for its readiness. */ 
    301329    if( vlc_thread_create( p_input, "input", Run, 
    302                             VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) 
     330                           VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) 
    303331    { 
    304332        input_ChangeState( p_input, ERROR_S ); 
    305333        msg_Err( p_input, "cannot create input thread" ); 
    306         Destroy( p_input ); 
     334        Destroy( p_input, &p_sout ); 
    307335        return NULL; 
    308336    } 
     
    323351                   vlc_bool_t b_block ) 
    324352{ 
    325     input_thread_t *p_input = NULL;         /* thread descriptor */ 
    326  
    327     p_input = Create( p_parent, p_item, NULL, VLC_FALSE ); 
    328     if( !p_input ) 
     353    vlc_bool_t b_sout_keep; 
     354    sout_instance_t *p_sout = SoutFind( p_parent, p_item, &b_sout_keep ); 
     355    input_thread_t *p_input; 
     356 
     357    p_input = Create( p_parent, p_item, NULL, VLC_FALSE, p_sout ); 
     358    if( !p_input && p_sout ) 
     359    { 
     360        SoutKeep( p_sout ); 
    329361        return VLC_EGENERIC; 
     362    } 
     363    p_input->p->b_sout_keep = b_sout_keep; 
    330364 
    331365    if( b_block ) 
     
    341375            input_ChangeState( p_input, ERROR_S ); 
    342376            msg_Err( p_input, "cannot create input thread" ); 
    343             Destroy( p_input ); 
     377            Destroy( p_input, NULL ); 
    344378            return VLC_EGENERIC; 
    345379        } 
     
    358392int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item ) 
    359393{ 
    360     input_thread_t *p_input = NULL;           /* thread descriptor */ 
     394    input_thread_t *p_input; 
    361395 
    362396    /* Allocate descriptor */ 
    363     p_input = Create( p_parent, p_item, NULL, VLC_TRUE ); 
     397    p_input = Create( p_parent, p_item, NULL, VLC_TRUE, NULL ); 
    364398    if( !p_input ) 
    365399        return VLC_EGENERIC; 
     
    368402    End( p_input ); 
    369403 
    370     Destroy( p_input ); 
     404    Destroy( p_input, NULL ); 
    371405 
    372406    return VLC_SUCCESS; 
     
    424458void input_DestroyThread( input_thread_t *p_input ) 
    425459{ 
     460    input_DestroyThreadExtended( p_input, NULL ); 
     461} 
     462 
     463void input_DestroyThreadExtended( input_thread_t *p_input, sout_instance_t **pp_sout ) 
     464{ 
    426465    /* Join the thread */ 
    427466    vlc_thread_join( p_input ); 
    428467 
    429468    /* */ 
    430     Destroy( p_input ); 
     469    Destroy( p_input, pp_sout ); 
    431470} 
    432471 
     
    524563exit: 
    525564    /* Release memory */ 
    526     Destroy( p_input ); 
     565    Destroy( p_input, NULL ); 
    527566    return 0; 
    528567} 
     
    535574    int64_t i_intf_update = 0; 
    536575    int i_updates = 0; 
     576 
    537577    while( !p_input->b_die && !p_input->b_error && !p_input->p->input.b_eof ) 
    538578    { 
     
    745785        } 
    746786 
    747         /* handle sout */ 
     787        /* Find a usable sout and attach it to p_input */ 
    748788        psz = var_GetString( p_input, "sout" ); 
    749789        if( *psz && strncasecmp( p_input->p->input.p_item->psz_uri, "vlc:", 4 ) ) 
    750790        { 
    751             p_input->p->p_sout = sout_NewInstance( p_input, psz ); 
    752             if( p_input->p->p_sout == NULL ) 
    753             { 
    754                 input_ChangeState( p_input, ERROR_S ); 
    755                 msg_Err( p_input, "cannot start stream output instance, " \ 
    756                                   "aborting" ); 
    757                 free( psz ); 
    758                 return VLC_EGENERIC; 
    759             } 
     791            /* Check the validity of the provided sout */ 
     792            if( p_input->p->p_sout ) 
     793            { 
     794                if( strcmp( p_input->p->p_sout->psz_sout, psz ) ) 
     795                { 
     796                    msg_Dbg( p_input, "destroying unusable sout" ); 
     797 
     798                    sout_DeleteInstance( p_input->p->p_sout ); 
     799                    p_input->p->p_sout = NULL; 
     800                } 
     801            } 
     802 
     803            if( p_input->p->p_sout ) 
     804            { 
     805                /* Reuse it */ 
     806                msg_Dbg( p_input, "sout keep: reusing sout" ); 
     807                msg_Dbg( p_input, "sout keep: you probably want to use " 
     808                                  "gather stream_out" ); 
     809                vlc_object_attach( p_input->p->p_sout, p_input ); 
     810            } 
     811            else 
     812            { 
     813                /* Create a new one */ 
     814                p_input->p->p_sout = sout_NewInstance( p_input, psz ); 
     815 
     816                if( !p_input->p->p_sout ) 
     817                { 
     818                    input_ChangeState( p_input, ERROR_S ); 
     819                    msg_Err( p_input, "cannot start stream output instance, " \ 
     820                                      "aborting" ); 
     821                    free( psz ); 
     822                    return VLC_EGENERIC; 
     823                } 
     824            } 
     825 
    760826            if( p_input->p_libvlc->b_stats ) 
    761827            { 
     
    767833                             1000000; 
    768834            } 
     835        } 
     836        else if( p_input->p->p_sout ) 
     837        { 
     838            msg_Dbg( p_input, "destroying useless sout" ); 
     839 
     840            sout_DeleteInstance( p_input->p->p_sout ); 
     841            p_input->p->p_sout = NULL; 
    769842        } 
    770843        free( psz ); 
     
    10941167 
    10951168    if( p_input->p->p_sout ) 
    1096         sout_DeleteInstance( p_input->p->p_sout ); 
     1169        vlc_object_detach( p_input->p->p_sout ); 
    10971170 
    10981171    /* Mark them deleted */ 
     
    11791252        if( p_input->p->p_sout ) 
    11801253        { 
    1181             vlc_value_t keep; 
    1182  
    11831254            CL_CO( sout_sent_packets ); 
    11841255            CL_CO( sout_sent_bytes ); 
    11851256            CL_CO( sout_send_bitrate ); 
    11861257 
    1187             if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool ) 
    1188             { 
    1189                 playlist_t  *p_playlist = pl_Yield( p_input ); 
    1190  
    1191                 /* attach sout to the playlist */ 
    1192                 vlc_object_detach( p_input->p->p_sout ); 
    1193                 vlc_object_attach( p_input->p->p_sout, p_playlist ); 
    1194                 pl_Release( p_input ); 
    1195                 msg_Dbg( p_input, "kept sout" ); 
    1196             } 
    1197             else 
    1198             { 
    1199                 sout_DeleteInstance( p_input->p->p_sout ); 
    1200                 msg_Dbg( p_input, "destroyed sout" ); 
    1201             } 
     1258            vlc_object_detach( p_input->p->p_sout ); 
    12021259        } 
    12031260#undef CL_CO 
     
    12081265    /* Tell we're dead */ 
    12091266    p_input->b_dead = VLC_TRUE; 
     1267} 
     1268 
     1269static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, vlc_bool_t *pb_sout_keep ) 
     1270{ 
     1271    vlc_bool_t b_keep_sout = var_CreateGetBool( p_parent, "sout-keep" ); 
     1272    sout_instance_t *p_sout = NULL; 
     1273    int i; 
     1274 
     1275    /* Search sout-keep options 
     1276     * XXX it has to be done here, but it is duplicated work :( */ 
     1277    vlc_mutex_lock( &p_item->lock ); 
     1278    for( i = 0; i < p_item->i_options; i++ ) 
     1279    { 
     1280        const char *psz_option = p_item->ppsz_options[i]; 
     1281        if( !psz_option ) 
     1282            continue; 
     1283        if( *psz_option == ':' ) 
     1284            psz_option++; 
     1285 
     1286        if( !strcmp( psz_option, "sout-keep" ) ) 
     1287            b_keep_sout = VLC_TRUE; 
     1288        else if( !strcmp( psz_option, "no-sout-keep" ) || !strcmp( psz_option, "nosout-keep" ) ) 
     1289            b_keep_sout = VLC_FALSE; 
     1290    } 
     1291    vlc_mutex_unlock( &p_item->lock ); 
     1292 
     1293    /* Find a potential sout to reuse 
     1294     * XXX it might be unusable but this will be checked later */ 
     1295    if( b_keep_sout ) 
     1296    { 
     1297        /* Remove the sout from the playlist garbage collector */ 
     1298        playlist_t *p_playlist = pl_Yield( p_parent ); 
     1299 
     1300        vlc_mutex_lock( &p_playlist->gc_lock ); 
     1301        p_sout = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD ); 
     1302        if( p_sout ) 
     1303        { 
     1304            if( p_sout->p_parent != VLC_OBJECT(p_playlist) ) 
     1305            { 
     1306                vlc_object_release( p_sout ); 
     1307                p_sout = NULL; 
     1308            } 
     1309            else 
     1310            { 
     1311                vlc_object_detach( p_sout );    /* Remove it from the GC */ 
     1312 
     1313                vlc_object_release( p_sout ); 
     1314            } 
     1315        } 
     1316        vlc_mutex_unlock( &p_playlist->gc_lock ); 
     1317 
     1318        pl_Release( p_parent ); 
     1319    } 
     1320 
     1321    if( pb_sout_keep ) 
     1322        *pb_sout_keep = b_keep_sout; 
     1323 
     1324    return p_sout; 
     1325} 
     1326static void SoutKeep( sout_instance_t *p_sout ) 
     1327{ 
     1328    /* attach sout to the playlist */ 
     1329    playlist_t  *p_playlist = pl_Yield( p_sout ); 
     1330 
     1331    msg_Dbg( p_sout, "sout has been kept" ); 
     1332    vlc_object_attach( p_sout, p_playlist ); 
     1333 
     1334    pl_Release( p_sout ); 
    12101335} 
    12111336 
  • src/input/input_internal.h

    r7c8c88f re87abf6  
    9494    es_out_t    *p_es_out; 
    9595    sout_instance_t *p_sout;            /* XXX Move it to es_out ? */ 
     96    vlc_bool_t      b_sout_keep; 
    9697    vlc_bool_t      b_out_pace_control; /*     idem ? */ 
    9798 
     
    226227 
    227228/* input.c */ 
    228 #define input_CreateThread2(a,b,c) __input_CreateThread2(VLC_OBJECT(a),b,c) 
    229 input_thread_t *__input_CreateThread2 ( vlc_object_t *, input_item_t *, const char * ); 
     229#define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d) 
     230input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, sout_instance_t * ); 
     231 
     232void input_DestroyThreadExtended( input_thread_t *p_input, sout_instance_t ** ); 
    230233 
    231234/* var.c */ 
  • src/input/vlm.c

    rd7bc817 re87abf6  
    11411141            asprintf( &psz_header, _("Media: %s"), media->psz_name ); 
    11421142 
    1143             if( (p_input = input_CreateThread2( vlm, &media->item, psz_header 
    1144                                               ) ) ) 
     1143            if( (p_input = input_CreateThreadExtended( vlm, &media->item, psz_header, NULL ) ) ) 
    11451144            { 
    11461145                while( !p_input->b_eof && !p_input->b_error ) 
     
    11481147 
    11491148                input_StopThread( p_input ); 
    1150                 input_DestroyThread( p_input ); 
     1149                input_DestroyThreadExtended( p_input, NULL ); 
    11511150            } 
    11521151            free( psz_output ); 
     
    12431242        { 
    12441243            input_StopThread( p_instance->p_input ); 
    1245             input_DestroyThread( p_instance->p_input ); 
     1244            input_DestroyThreadExtended( p_instance->p_input, NULL ); 
    12461245        } 
    12471246 
    12481247        asprintf( &psz_header, _("Media: %s"), media->psz_name ); 
    1249         p_instance->p_input = input_CreateThread2( vlm, &p_instance->item, 
    1250                                                    psz_header ); 
     1248        p_instance->p_input = input_CreateThreadExtended( vlm, &p_instance->item, psz_header, NULL ); 
    12511249        if( !p_instance->p_input ) 
    12521250        { 
     
    13621360        { 
    13631361            input_StopThread( p_instance->p_input ); 
    1364             input_DestroyThread( p_instance->p_input ); 
     1362            input_DestroyThreadExtended( p_instance->p_input, NULL ); 
    13651363        } 
    13661364 
     
    25032501 
    25042502                    input_StopThread( p_instance->p_input ); 
    2505                     input_DestroyThread( p_instance->p_input ); 
     2503                    input_DestroyThreadExtended( p_instance->p_input, NULL ); 
    25062504                    p_instance->p_input = NULL; 
    25072505 
  • src/playlist/engine.c

    r600e2cd re87abf6  
    211211            break; 
    212212        } 
     213        msg_Dbg( p_playlist, "garbage collector destroying 1 sout" ); 
     214        vlc_object_detach( p_obj ); 
    213215        vlc_object_release( p_obj ); 
    214216        sout_DeleteInstance( (sout_instance_t*)p_obj ); 
     
    410412                                      VLC_OBJECT_SOUT, FIND_CHILD ) ) ) 
    411413    { 
     414        vlc_object_detach( p_obj ); 
    412415        vlc_object_release( p_obj ); 
    413416        sout_DeleteInstance( (sout_instance_t*)p_obj ); 
  • src/stream_output/stream_output.c

    rd7bc817 re87abf6  
    7474{ 
    7575    sout_instance_t *p_sout; 
    76     vlc_value_t keep; 
    77  
    78     if( var_Get( p_parent, "sout-keep", &keep ) >= 0 && keep.b_bool ) 
    79     { 
    80         /* Remove the sout from the playlist garbage collector */ 
    81         playlist_t *p_playlist = pl_Yield( p_parent ); 
    82  
    83         vlc_mutex_lock( &p_playlist->gc_lock ); 
    84         p_sout = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD ); 
    85         if( p_sout && p_sout->p_parent != (vlc_object_t *)p_playlist ) 
    86         { 
    87             vlc_object_release( p_sout ); 
    88             p_sout = NULL; 
    89         } 
    90         if( p_sout ) 
    91             vlc_object_detach( p_sout );    /* Remove it from the GC */ 
    92         vlc_mutex_unlock( &p_playlist->gc_lock ); 
    93  
    94         pl_Release( p_parent ); 
    95  
    96         /* */ 
    97  
    98         if( p_sout ) 
    99         { 
    100             if( !strcmp( p_sout->psz_sout, psz_dest ) ) 
    101             { 
    102                 msg_Dbg( p_parent, "sout keep: reusing sout" ); 
    103                 msg_Dbg( p_parent, "sout keep: you probably want to use " 
    104                           "gather stream_out" ); 
    105                 vlc_object_attach( p_sout, p_parent ); 
    106                 vlc_object_release( p_sout ); 
    107                 return p_sout; 
    108             } 
    109  
    110             msg_Dbg( p_parent, "sout keep: destroying unusable sout" ); 
    111             vlc_object_release( p_sout ); 
    112             sout_DeleteInstance( p_sout ); 
    113         } 
    114     } 
    11576 
    11677    /* *** Allocate descriptor *** */ 
     
    165126void sout_DeleteInstance( sout_instance_t * p_sout ) 
    166127{ 
    167     /* Unlink object */ 
    168     vlc_object_detach( p_sout ); 
    169  
    170128    /* remove the stream out chain */ 
    171129    sout_StreamDelete( p_sout->p_stream );