Changeset e87abf624a0302f8d6f7bdd0a9f550cec1f5fb12
- Timestamp:
- 28/02/07 23:45:02 (2 years ago)
- git-parent:
- Files:
-
- src/input/input.c (modified) (22 diffs)
- src/input/input_internal.h (modified) (2 diffs)
- src/input/vlm.c (modified) (5 diffs)
- src/playlist/engine.c (modified) (2 diffs)
- src/stream_output/stream_output.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/input/input.c
rd7bc817 re87abf6 53 53 54 54 static 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 * ); 56 56 static int Init ( input_thread_t *p_input ); 57 57 static void Error ( input_thread_t *p_input ); 58 58 static void End ( input_thread_t *p_input ); 59 59 static void MainLoop( input_thread_t *p_input ); 60 static void Destroy( input_thread_t *p_input, sout_instance_t **pp_sout ); 60 61 61 62 static inline int ControlPopNoLock( input_thread_t *, int *, vlc_value_t * ); … … 80 81 81 82 static void InputMetaUser( input_thread_t *p_input ); 83 84 static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, vlc_bool_t * ); 85 static void SoutKeep( sout_instance_t * ); 82 86 83 87 /***************************************************************************** … … 106 110 *****************************************************************************/ 107 111 static 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 ) 109 113 { 110 114 input_thread_t *p_input = NULL; /* thread descriptor */ … … 152 156 p_input->p->p_es_out = NULL; 153 157 p_input->p->p_sout = NULL; 158 p_input->p->b_sout_keep = VLC_FALSE; 154 159 p_input->p->b_out_pace_control = VLC_FALSE; 155 160 p_input->i_pts_delay = 0; … … 189 194 vlc_mutex_lock( &p_item->lock ); 190 195 for( i = 0; i < p_item->i_options; i++ ) 191 {192 196 var_OptionParse( p_input, p_item->ppsz_options[i] ); 193 }194 197 vlc_mutex_unlock( &p_item->lock ); 195 198 … … 258 261 p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT; 259 262 263 /* */ 264 if( p_sout ) 265 p_input->p->p_sout = p_sout; 266 260 267 /* Attach only once we are ready */ 261 268 vlc_object_attach( p_input, p_parent ); … … 264 271 } 265 272 266 static void Destroy( input_thread_t *p_input )273 static void Destroy( input_thread_t *p_input, sout_instance_t **pp_sout ) 267 274 { 268 275 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 } 269 288 270 289 vlc_mutex_destroy( &p_input->p->lock_control ); … … 273 292 vlc_object_destroy( p_input ); 274 293 } 294 275 295 /** 276 296 * Initialize an input thread and run it. You will need to monitor the … … 284 304 input_item_t *p_item ) 285 305 { 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 /* */ 318 input_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 ); 297 325 if( !p_input ) 298 326 return NULL; … … 300 328 /* Create thread and wait for its readiness. */ 301 329 if( vlc_thread_create( p_input, "input", Run, 302 VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )330 VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) 303 331 { 304 332 input_ChangeState( p_input, ERROR_S ); 305 333 msg_Err( p_input, "cannot create input thread" ); 306 Destroy( p_input );334 Destroy( p_input, &p_sout ); 307 335 return NULL; 308 336 } … … 323 351 vlc_bool_t b_block ) 324 352 { 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 ); 329 361 return VLC_EGENERIC; 362 } 363 p_input->p->b_sout_keep = b_sout_keep; 330 364 331 365 if( b_block ) … … 341 375 input_ChangeState( p_input, ERROR_S ); 342 376 msg_Err( p_input, "cannot create input thread" ); 343 Destroy( p_input );377 Destroy( p_input, NULL ); 344 378 return VLC_EGENERIC; 345 379 } … … 358 392 int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item ) 359 393 { 360 input_thread_t *p_input = NULL; /* thread descriptor */394 input_thread_t *p_input; 361 395 362 396 /* 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 ); 364 398 if( !p_input ) 365 399 return VLC_EGENERIC; … … 368 402 End( p_input ); 369 403 370 Destroy( p_input );404 Destroy( p_input, NULL ); 371 405 372 406 return VLC_SUCCESS; … … 424 458 void input_DestroyThread( input_thread_t *p_input ) 425 459 { 460 input_DestroyThreadExtended( p_input, NULL ); 461 } 462 463 void input_DestroyThreadExtended( input_thread_t *p_input, sout_instance_t **pp_sout ) 464 { 426 465 /* Join the thread */ 427 466 vlc_thread_join( p_input ); 428 467 429 468 /* */ 430 Destroy( p_input );469 Destroy( p_input, pp_sout ); 431 470 } 432 471 … … 524 563 exit: 525 564 /* Release memory */ 526 Destroy( p_input );565 Destroy( p_input, NULL ); 527 566 return 0; 528 567 } … … 535 574 int64_t i_intf_update = 0; 536 575 int i_updates = 0; 576 537 577 while( !p_input->b_die && !p_input->b_error && !p_input->p->input.b_eof ) 538 578 { … … 745 785 } 746 786 747 /* handle sout */787 /* Find a usable sout and attach it to p_input */ 748 788 psz = var_GetString( p_input, "sout" ); 749 789 if( *psz && strncasecmp( p_input->p->input.p_item->psz_uri, "vlc:", 4 ) ) 750 790 { 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 760 826 if( p_input->p_libvlc->b_stats ) 761 827 { … … 767 833 1000000; 768 834 } 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; 769 842 } 770 843 free( psz ); … … 1094 1167 1095 1168 if( p_input->p->p_sout ) 1096 sout_DeleteInstance( p_input->p->p_sout );1169 vlc_object_detach( p_input->p->p_sout ); 1097 1170 1098 1171 /* Mark them deleted */ … … 1179 1252 if( p_input->p->p_sout ) 1180 1253 { 1181 vlc_value_t keep;1182 1183 1254 CL_CO( sout_sent_packets ); 1184 1255 CL_CO( sout_sent_bytes ); 1185 1256 CL_CO( sout_send_bitrate ); 1186 1257 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 ); 1202 1259 } 1203 1260 #undef CL_CO … … 1208 1265 /* Tell we're dead */ 1209 1266 p_input->b_dead = VLC_TRUE; 1267 } 1268 1269 static 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 } 1326 static 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 ); 1210 1335 } 1211 1336 src/input/input_internal.h
r7c8c88f re87abf6 94 94 es_out_t *p_es_out; 95 95 sout_instance_t *p_sout; /* XXX Move it to es_out ? */ 96 vlc_bool_t b_sout_keep; 96 97 vlc_bool_t b_out_pace_control; /* idem ? */ 97 98 … … 226 227 227 228 /* 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) 230 input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, sout_instance_t * ); 231 232 void input_DestroyThreadExtended( input_thread_t *p_input, sout_instance_t ** ); 230 233 231 234 /* var.c */ src/input/vlm.c
rd7bc817 re87abf6 1141 1141 asprintf( &psz_header, _("Media: %s"), media->psz_name ); 1142 1142 1143 if( (p_input = input_CreateThread2( vlm, &media->item, psz_header 1144 ) ) ) 1143 if( (p_input = input_CreateThreadExtended( vlm, &media->item, psz_header, NULL ) ) ) 1145 1144 { 1146 1145 while( !p_input->b_eof && !p_input->b_error ) … … 1148 1147 1149 1148 input_StopThread( p_input ); 1150 input_DestroyThread ( p_input);1149 input_DestroyThreadExtended( p_input, NULL ); 1151 1150 } 1152 1151 free( psz_output ); … … 1243 1242 { 1244 1243 input_StopThread( p_instance->p_input ); 1245 input_DestroyThread ( p_instance->p_input);1244 input_DestroyThreadExtended( p_instance->p_input, NULL ); 1246 1245 } 1247 1246 1248 1247 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 ); 1251 1249 if( !p_instance->p_input ) 1252 1250 { … … 1362 1360 { 1363 1361 input_StopThread( p_instance->p_input ); 1364 input_DestroyThread ( p_instance->p_input);1362 input_DestroyThreadExtended( p_instance->p_input, NULL ); 1365 1363 } 1366 1364 … … 2503 2501 2504 2502 input_StopThread( p_instance->p_input ); 2505 input_DestroyThread ( p_instance->p_input);2503 input_DestroyThreadExtended( p_instance->p_input, NULL ); 2506 2504 p_instance->p_input = NULL; 2507 2505 src/playlist/engine.c
r600e2cd re87abf6 211 211 break; 212 212 } 213 msg_Dbg( p_playlist, "garbage collector destroying 1 sout" ); 214 vlc_object_detach( p_obj ); 213 215 vlc_object_release( p_obj ); 214 216 sout_DeleteInstance( (sout_instance_t*)p_obj ); … … 410 412 VLC_OBJECT_SOUT, FIND_CHILD ) ) ) 411 413 { 414 vlc_object_detach( p_obj ); 412 415 vlc_object_release( p_obj ); 413 416 sout_DeleteInstance( (sout_instance_t*)p_obj ); src/stream_output/stream_output.c
rd7bc817 re87abf6 74 74 { 75 75 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 }115 76 116 77 /* *** Allocate descriptor *** */ … … 165 126 void sout_DeleteInstance( sout_instance_t * p_sout ) 166 127 { 167 /* Unlink object */168 vlc_object_detach( p_sout );169 170 128 /* remove the stream out chain */ 171 129 sout_StreamDelete( p_sout->p_stream );
