/***************************************************************************** * sout_AccessOutNew: allocate a new access out *****************************************************************************/ sout_access_out_t *sout_AccessOutNew( vlc_object_t *p_sout, const char *psz_access, const char *psz_name ) { sout_access_out_t *p_access; char *psz_next; p_access = vlc_custom_create( p_sout, sizeof( *p_access ), "access out" ); if( !p_access ) return NULL; psz_next = config_ChainCreate( &p_access->psz_access, &p_access->p_cfg, psz_access ); free( psz_next ); p_access->psz_path = strdup( psz_name ? psz_name : "" ); p_access->p_sys = NULL; p_access->pf_seek = NULL; p_access->pf_read = NULL; p_access->pf_write = NULL; p_access->pf_control = NULL; p_access->p_module = NULL; p_access->p_module = module_need( p_access, "sout access", p_access->psz_access, true ); if( !p_access->p_module ) { free( p_access->psz_access ); free( p_access->psz_path ); vlc_object_release( p_access ); return( NULL ); } return p_access; }
static int filter_chain_AppendFromStringInternal( filter_chain_t *p_chain, const char *psz_string ) { config_chain_t *p_cfg = NULL; char *psz_name = NULL; char* psz_new_string; if( !psz_string || !*psz_string ) return 0; psz_new_string = config_ChainCreate( &psz_name, &p_cfg, psz_string ); filter_t *p_filter = filter_chain_AppendFilterInternal( p_chain, psz_name, p_cfg, NULL, NULL ); if( !p_filter ) { msg_Err( p_chain->p_this, "Failed while trying to append '%s' " "to filter chain", psz_name ); free( psz_name ); free( p_cfg ); free( psz_new_string ); return -1; } free( psz_name ); const int i_ret = filter_chain_AppendFromStringInternal( p_chain, psz_new_string ); free( psz_new_string ); if( i_ret < 0 ) { filter_chain_DeleteFilterInternal( p_chain, p_filter ); return i_ret; } return 1 + i_ret; }
static filter_t * AppendTransform( filter_chain_t *p_chain, const es_format_t *p_fmt1, const es_format_t *p_fmt2 ) { video_transform_t transform = video_format_GetTransform(p_fmt1->video.orientation, p_fmt2->video.orientation); const char *type; switch ( transform ) { case TRANSFORM_R90: type = "90"; break; case TRANSFORM_R180: type = "180"; break; case TRANSFORM_R270: type = "270"; break; case TRANSFORM_HFLIP: type = "hflip"; break; case TRANSFORM_VFLIP: type = "vflip"; break; case TRANSFORM_TRANSPOSE: type = "transpose"; break; case TRANSFORM_ANTI_TRANSPOSE: type = "antitranspose"; break; default: type = NULL; break; } if( !type ) return NULL; config_chain_t *cfg; char *name; char config[100]; snprintf( config, 100, "transform{type=%s}", type ); char *next = config_ChainCreate( &name, &cfg, config ); filter_t *p_filter = filter_chain_AppendFilter( p_chain, name, cfg, p_fmt1, p_fmt2 ); config_ChainDestroy(cfg); free(name); free(next); return p_filter; }
/*******************************************************************//** * Create a Service discovery ***********************************************************************/ services_discovery_t *vlc_sd_Create( vlc_object_t *p_super, const char *cfg ) { services_discovery_t *p_sd; p_sd = vlc_custom_create( p_super, sizeof( *p_sd ), "services discovery" ); if( !p_sd ) return NULL; free(config_ChainCreate( &p_sd->psz_name, &p_sd->p_cfg, cfg )); vlc_event_manager_t *em = &p_sd->event_manager; vlc_event_manager_init( em, p_sd ); vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryItemAdded); vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryItemRemoved); vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryItemRemoveAll); vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryStarted); vlc_event_manager_register_event_type(em, vlc_ServicesDiscoveryEnded); vlc_object_set_destructor( p_sd, services_discovery_Destructor ); return p_sd; }
/* Creates a complete "stream_out" modules chain * * chain format: module1{option=*:option=*}[:module2{option=*:...}] * * The modules are created starting from the last one and linked together * A pointer to the last module created is stored if pp_last isn't NULL, to * make sure sout_StreamChainDelete doesn't delete modules created in another * place. * * Returns a pointer to the first module. */ sout_stream_t *sout_StreamChainNew(sout_instance_t *p_sout, const char *psz_chain, sout_stream_t *p_next, sout_stream_t **pp_last) { if(!psz_chain || !*psz_chain) { if(pp_last) *pp_last = NULL; return p_next; } char *psz_parser = strdup(psz_chain); if(!psz_parser) return NULL; vlc_array_t cfg, name; vlc_array_init(&cfg); vlc_array_init(&name); /* parse chain */ while(psz_parser) { config_chain_t *p_cfg; char *psz_name; char *psz_rest_chain = config_ChainCreate( &psz_name, &p_cfg, psz_parser ); free( psz_parser ); psz_parser = psz_rest_chain; vlc_array_append(&cfg, p_cfg); vlc_array_append(&name, psz_name); } int i = vlc_array_count(&name); vlc_array_t module; vlc_array_init(&module); while(i--) { p_next = sout_StreamNew( p_sout, vlc_array_item_at_index(&name, i), vlc_array_item_at_index(&cfg, i), p_next); if(!p_next) goto error; if(i == vlc_array_count(&name) - 1 && pp_last) *pp_last = p_next; /* last module created in the chain */ vlc_array_append(&module, p_next); } vlc_array_clear(&name); vlc_array_clear(&cfg); vlc_array_clear(&module); return p_next; error: i++; /* last module couldn't be created */ /* destroy all modules created, starting with the last one */ int modules = vlc_array_count(&module); while(modules--) sout_StreamDelete(vlc_array_item_at_index(&module, modules)); vlc_array_clear(&module); /* then destroy all names and config which weren't destroyed by * sout_StreamDelete */ while(i--) { free(vlc_array_item_at_index(&name, i)); config_ChainDestroy(vlc_array_item_at_index(&cfg, i)); } vlc_array_clear(&name); vlc_array_clear(&cfg); return NULL; }
/***************************************************************************** * sout_MuxNew: create a new mux *****************************************************************************/ sout_mux_t * sout_MuxNew( sout_instance_t *p_sout, const char *psz_mux, sout_access_out_t *p_access ) { sout_mux_t *p_mux; char *psz_next; p_mux = vlc_custom_create( p_sout, sizeof( *p_mux ), "mux" ); if( p_mux == NULL ) return NULL; p_mux->p_sout = p_sout; psz_next = config_ChainCreate( &p_mux->psz_mux, &p_mux->p_cfg, psz_mux ); free( psz_next ); p_mux->p_access = p_access; p_mux->pf_control = NULL; p_mux->pf_addstream = NULL; p_mux->pf_delstream = NULL; p_mux->pf_mux = NULL; p_mux->i_nb_inputs = 0; p_mux->pp_inputs = NULL; p_mux->p_sys = NULL; p_mux->p_module = NULL; p_mux->b_add_stream_any_time = false; p_mux->b_waiting_stream = true; p_mux->i_add_stream_start = -1; p_mux->p_module = module_need( p_mux, "sout mux", p_mux->psz_mux, true ); if( p_mux->p_module == NULL ) { FREENULL( p_mux->psz_mux ); vlc_object_release( p_mux ); return NULL; } /* *** probe mux capacity *** */ if( p_mux->pf_control ) { int b_answer = false; if( sout_MuxControl( p_mux, MUX_CAN_ADD_STREAM_WHILE_MUXING, &b_answer ) ) { b_answer = false; } if( b_answer ) { msg_Dbg( p_sout, "muxer support adding stream at any time" ); p_mux->b_add_stream_any_time = true; p_mux->b_waiting_stream = false; /* If we control the output pace then it's better to wait before * starting muxing (generates better streams/files). */ if( !p_sout->i_out_pace_nocontrol ) { b_answer = true; } else if( sout_MuxControl( p_mux, MUX_GET_ADD_STREAM_WAIT, &b_answer ) ) { b_answer = false; } if( b_answer ) { msg_Dbg( p_sout, "muxer prefers to wait for all ES before " "starting to mux" ); p_mux->b_waiting_stream = true; } } } return p_mux; }
/** * Create and start an interface. * * @param p_this the calling vlc_object_t * @param psz_module a preferred interface module * @return VLC_SUCCESS or an error code */ int intf_Create( vlc_object_t *p_this, const char *psz_module ) { libvlc_int_t *p_libvlc = p_this->p_libvlc; intf_thread_t * p_intf; /* Allocate structure */ p_intf = vlc_custom_create( p_libvlc, sizeof( *p_intf ), "interface" ); if( !p_intf ) return VLC_ENOMEM; /* Variable used for interface spawning */ vlc_value_t val, text; var_Create( p_intf, "intf-add", VLC_VAR_STRING | VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND ); text.psz_string = _("Add Interface"); var_Change( p_intf, "intf-add", VLC_VAR_SETTEXT, &text, NULL ); #if !defined(WIN32) && defined(HAVE_ISATTY) if( isatty( 0 ) ) #endif { val.psz_string = (char *)"rc"; text.psz_string = (char *)_("Console"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); } val.psz_string = (char *)"telnet"; text.psz_string = (char *)_("Telnet"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"http"; text.psz_string = (char *)_("Web"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"logger"; text.psz_string = (char *)_("Debug logging"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"gestures"; text.psz_string = (char *)_("Mouse Gestures"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); var_AddCallback( p_intf, "intf-add", AddIntfCallback, NULL ); /* Attach interface to LibVLC */ #if defined( __APPLE__ ) p_intf->b_should_run_on_first_thread = false; #endif /* Choose the best module */ p_intf->p_cfg = NULL; char *psz_parser = *psz_module == '$' ? var_CreateGetString(p_intf,psz_module+1) : strdup( psz_module ); char *psz_tmp = config_ChainCreate( &p_intf->psz_intf, &p_intf->p_cfg, psz_parser ); free( psz_tmp ); free( psz_parser ); p_intf->p_module = module_need( p_intf, "interface", p_intf->psz_intf, true ); if( p_intf->p_module == NULL ) { msg_Err( p_intf, "no suitable interface module" ); goto error; } #if defined( __APPLE__ ) /* Hack to get Mac OS X Cocoa runtime running * (it needs access to the main thread) */ if( p_intf->b_should_run_on_first_thread ) { if( vlc_clone( &p_intf->thread, MonitorLibVLCDeath, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { msg_Err( p_intf, "cannot spawn libvlc death monitoring thread" ); goto error; } assert( p_intf->pf_run ); p_intf->pf_run( p_intf ); /* It is monitoring libvlc, not the p_intf */ vlc_object_kill( p_intf->p_libvlc ); vlc_join( p_intf->thread, NULL ); } else #endif /* Run the interface in a separate thread */ if( p_intf->pf_run && vlc_clone( &p_intf->thread, RunInterface, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { msg_Err( p_intf, "cannot spawn interface thread" ); goto error; } vlc_mutex_lock( &lock ); p_intf->p_next = libvlc_priv( p_libvlc )->p_intf; libvlc_priv( p_libvlc )->p_intf = p_intf; vlc_mutex_unlock( &lock ); return VLC_SUCCESS; error: if( p_intf->p_module ) module_unneed( p_intf, p_intf->p_module ); config_ChainDestroy( p_intf->p_cfg ); free( p_intf->psz_intf ); vlc_object_release( p_intf ); return VLC_EGENERIC; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; char *psz_string; if( !p_stream->p_next ) { msg_Err( p_stream, "cannot create chain" ); return VLC_EGENERIC; } p_sys = calloc( 1, sizeof( *p_sys ) ); p_sys->i_master_drift = 0; config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); /* Audio transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" ); p_sys->psz_aenc = NULL; p_sys->p_audio_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "acodec" ); p_sys->i_acodec = 0; if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); p_sys->psz_alang = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "alang" ); p_sys->i_abitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ab" ); if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000; p_sys->i_sample_rate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "samplerate" ); p_sys->i_channels = var_GetInteger( p_stream, SOUT_CFG_PREFIX "channels" ); if( p_sys->i_acodec ) { if( ( p_sys->i_acodec == VLC_CODEC_MP3 || p_sys->i_acodec == VLC_CODEC_MP2 || p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 ) { msg_Warn( p_stream, "%d channels invalid for mp2/mp3, forcing to 2", p_sys->i_channels ); p_sys->i_channels = 2; } msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", (char *)&p_sys->i_acodec, p_sys->i_sample_rate, p_sys->i_channels, p_sys->i_abitrate / 1000 ); } psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "afilter" ); if( psz_string && *psz_string ) p_sys->psz_af = strdup( psz_string ); else p_sys->psz_af = NULL; free( psz_string ); /* Video transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" ); p_sys->psz_venc = NULL; p_sys->p_video_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" ); p_sys->i_vcodec = 0; if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" ); if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000; p_sys->f_scale = var_GetFloat( p_stream, SOUT_CFG_PREFIX "scale" ); p_sys->f_fps = var_GetFloat( p_stream, SOUT_CFG_PREFIX "fps" ); p_sys->b_hurry_up = var_GetBool( p_stream, SOUT_CFG_PREFIX "hurry-up" ); p_sys->i_width = var_GetInteger( p_stream, SOUT_CFG_PREFIX "width" ); p_sys->i_height = var_GetInteger( p_stream, SOUT_CFG_PREFIX "height" ); p_sys->i_maxwidth = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxwidth" ); p_sys->i_maxheight = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxheight" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vfilter" ); if( psz_string && *psz_string ) p_sys->psz_vf2 = strdup(psz_string ); else p_sys->psz_vf2 = NULL; free( psz_string ); p_sys->b_deinterlace = var_GetBool( p_stream, SOUT_CFG_PREFIX "deinterlace" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "deinterlace-module" ); p_sys->psz_deinterlace = NULL; p_sys->p_deinterlace_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_deinterlace, &p_sys->p_deinterlace_cfg, psz_string ); free( psz_next ); } free( psz_string ); p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" ); p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ); if( p_sys->i_vcodec ) { msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s", (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height, p_sys->f_scale, p_sys->i_vbitrate / 1000 ); } /* Subpictures transcoding parameters */ p_sys->p_spu = NULL; p_sys->p_spu_blend = NULL; p_sys->psz_senc = NULL; p_sys->p_spu_cfg = NULL; p_sys->i_scodec = 0; psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "senc" ); if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "scodec" ); if( psz_string && *psz_string ) { char fcc[4] = " "; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } free( psz_string ); if( p_sys->i_scodec ) { msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec ); } p_sys->b_soverlay = var_GetBool( p_stream, SOUT_CFG_PREFIX "soverlay" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" ); if( psz_string && *psz_string ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, psz_string ); } free( psz_string ); /* OSD menu transcoding parameters */ p_sys->psz_osdenc = NULL; p_sys->p_osd_cfg = NULL; p_sys->i_osdcodec = 0; p_sys->b_osd = var_GetBool( p_stream, SOUT_CFG_PREFIX "osd" ); if( p_sys->b_osd ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_osdenc, &p_sys->p_osd_cfg, strdup( "dvbsub") ); free( psz_next ); p_sys->i_osdcodec = VLC_CODEC_YUVP; msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec ); if( !p_sys->p_spu ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } else { spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } } /* Audio settings */ p_sys->b_master_sync = var_GetBool( p_stream, SOUT_CFG_PREFIX "audio-sync" ); if( p_sys->f_fps > 0 ) p_sys->b_master_sync = true; p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; return VLC_SUCCESS; }
/** * Create and start an interface. * * @param playlist playlist and parent object for the interface * @param chain configuration chain string * @return VLC_SUCCESS or an error code */ int intf_Create( playlist_t *playlist, const char *chain ) { /* Allocate structure */ intf_thread_t *p_intf = vlc_custom_create( playlist, sizeof( *p_intf ), "interface" ); if( unlikely(p_intf == NULL) ) return VLC_ENOMEM; /* Variable used for interface spawning */ vlc_value_t val, text; var_Create( p_intf, "intf-add", VLC_VAR_STRING | VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND ); text.psz_string = _("Add Interface"); var_Change( p_intf, "intf-add", VLC_VAR_SETTEXT, &text, NULL ); #if !defined(_WIN32) && defined(HAVE_ISATTY) if( isatty( 0 ) ) #endif { val.psz_string = (char *)"rc,none"; text.psz_string = (char *)_("Console"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); } val.psz_string = (char *)"telnet,none"; text.psz_string = (char *)_("Telnet"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"http,none"; text.psz_string = (char *)_("Web"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"logger,none"; text.psz_string = (char *)_("Debug logging"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = (char *)"gestures,none"; text.psz_string = (char *)_("Mouse Gestures"); var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); var_AddCallback( p_intf, "intf-add", AddIntfCallback, playlist ); /* Choose the best module */ char *module; p_intf->p_cfg = NULL; free( config_ChainCreate( &module, &p_intf->p_cfg, chain ) ); p_intf->p_module = module_need( p_intf, "interface", module, true ); free(module); if( p_intf->p_module == NULL ) { msg_Err( p_intf, "no suitable interface module" ); goto error; } vlc_mutex_lock( &lock ); p_intf->p_next = pl_priv( playlist )->interface; pl_priv( playlist )->interface = p_intf; vlc_mutex_unlock( &lock ); return VLC_SUCCESS; error: if( p_intf->p_module ) module_unneed( p_intf, p_intf->p_module ); config_ChainDestroy( p_intf->p_cfg ); vlc_object_release( p_intf ); return VLC_EGENERIC; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; char *psz_string; if( !p_stream->p_next ) { msg_Err( p_stream, "cannot create chain" ); return VLC_EGENERIC; } p_sys = calloc( 1, sizeof( *p_sys ) ); p_sys->i_master_drift = 0; config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); /* Audio transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "aenc" ); p_sys->psz_aenc = NULL; p_sys->p_audio_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "acodec" ); p_sys->i_acodec = 0; if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_acodec = vlc_fourcc_GetCodecFromString( AUDIO_ES, fcc ); msg_Dbg( p_stream, "Checking codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_acodec); } free( psz_string ); p_sys->psz_alang = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "alang" ); p_sys->i_abitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ab" ); if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000; p_sys->i_sample_rate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "samplerate" ); p_sys->i_channels = var_GetInteger( p_stream, SOUT_CFG_PREFIX "channels" ); if( p_sys->i_acodec ) { if( ( p_sys->i_acodec == VLC_CODEC_MP3 || p_sys->i_acodec == VLC_CODEC_MP2 || p_sys->i_acodec == VLC_CODEC_MPGA ) && p_sys->i_channels > 2 ) { msg_Warn( p_stream, "%d channels invalid for mp2/mp3, forcing to 2", p_sys->i_channels ); p_sys->i_channels = 2; } msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", (char *)&p_sys->i_acodec, p_sys->i_sample_rate, p_sys->i_channels, p_sys->i_abitrate / 1000 ); } psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "afilter" ); if( psz_string && *psz_string ) p_sys->psz_af = strdup( psz_string ); else p_sys->psz_af = NULL; free( psz_string ); /* Video transcoding parameters */ psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "venc" ); p_sys->psz_venc = NULL; p_sys->p_video_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_venc, &p_sys->p_video_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vcodec" ); p_sys->i_vcodec = 0; if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_vcodec = vlc_fourcc_GetCodecFromString( VIDEO_ES, fcc ); msg_Dbg( p_stream, "Checking video codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_vcodec); } free( psz_string ); p_sys->i_vbitrate = var_GetInteger( p_stream, SOUT_CFG_PREFIX "vb" ); if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000; p_sys->f_scale = var_GetFloat( p_stream, SOUT_CFG_PREFIX "scale" ); p_sys->b_master_sync = var_InheritURational( p_stream, &p_sys->fps_num, &p_sys->fps_den, SOUT_CFG_PREFIX "fps" ) == VLC_SUCCESS; p_sys->i_width = var_GetInteger( p_stream, SOUT_CFG_PREFIX "width" ); p_sys->i_height = var_GetInteger( p_stream, SOUT_CFG_PREFIX "height" ); p_sys->i_maxwidth = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxwidth" ); p_sys->i_maxheight = var_GetInteger( p_stream, SOUT_CFG_PREFIX "maxheight" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "vfilter" ); if( psz_string && *psz_string ) p_sys->psz_vf2 = strdup(psz_string ); else p_sys->psz_vf2 = NULL; free( psz_string ); p_sys->b_deinterlace = var_GetBool( p_stream, SOUT_CFG_PREFIX "deinterlace" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "deinterlace-module" ); p_sys->psz_deinterlace = NULL; p_sys->p_deinterlace_cfg = NULL; if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_deinterlace, &p_sys->p_deinterlace_cfg, psz_string ); free( psz_next ); } free( psz_string ); p_sys->i_threads = var_GetInteger( p_stream, SOUT_CFG_PREFIX "threads" ); p_sys->b_high_priority = var_GetBool( p_stream, SOUT_CFG_PREFIX "high-priority" ); if( p_sys->i_vcodec ) { msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s", (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height, p_sys->f_scale, p_sys->i_vbitrate / 1000 ); } /* Disable hardware decoding by default (unlike normal playback) */ psz_string = var_CreateGetString( p_stream, "avcodec-hw" ); if( !strcasecmp( "any", psz_string ) ) var_SetString( p_stream, "avcodec-hw", "none" ); free( psz_string ); /* Subpictures transcoding parameters */ p_sys->p_spu = NULL; p_sys->p_spu_blend = NULL; p_sys->psz_senc = NULL; p_sys->p_spu_cfg = NULL; p_sys->i_scodec = 0; psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "senc" ); if( psz_string && *psz_string ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg, psz_string ); free( psz_next ); } free( psz_string ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "scodec" ); if( psz_string && *psz_string ) { char fcc[5] = " \0"; memcpy( fcc, psz_string, __MIN( strlen( psz_string ), 4 ) ); p_sys->i_scodec = vlc_fourcc_GetCodecFromString( SPU_ES, fcc ); msg_Dbg( p_stream, "Checking spu codec mapping for %s got %4.4s ", fcc, (char*)&p_sys->i_scodec); } free( psz_string ); if( p_sys->i_scodec ) { msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec ); } p_sys->b_soverlay = var_GetBool( p_stream, SOUT_CFG_PREFIX "soverlay" ); psz_string = var_GetString( p_stream, SOUT_CFG_PREFIX "sfilter" ); if( psz_string && *psz_string ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, psz_string ); } free( psz_string ); /* OSD menu transcoding parameters */ p_sys->psz_osdenc = NULL; p_sys->p_osd_cfg = NULL; p_sys->i_osdcodec = 0; p_sys->b_osd = var_GetBool( p_stream, SOUT_CFG_PREFIX "osd" ); if( p_sys->b_osd ) { char *psz_next; psz_next = config_ChainCreate( &p_sys->psz_osdenc, &p_sys->p_osd_cfg, "dvbsub" ); free( psz_next ); p_sys->i_osdcodec = VLC_CODEC_YUVP; msg_Dbg( p_stream, "codec osd=%4.4s", (char *)&p_sys->i_osdcodec ); if( !p_sys->p_spu ) { p_sys->p_spu = spu_Create( p_stream ); if( p_sys->p_spu ) spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } else { spu_ChangeSources( p_sys->p_spu, "osdmenu" ); } } p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; return VLC_SUCCESS; }