📄 stream_output.c
字号:
if( !*p ) return p; if( *p == c ) return ++p; else if( *p == '{' && c == '}' ) p = _get_chain_end( p ); else p++; } }}char *sout_CfgCreate( char **ppsz_name, sout_cfg_t **pp_cfg, char *psz_chain ){ sout_cfg_t *p_cfg = NULL; char *p = psz_chain; *ppsz_name = NULL; *pp_cfg = NULL; if( !p ) return NULL; SKIPSPACE( p ); while( *p && *p != '{' && *p != ':' && *p != ' ' && *p != '\t' ) p++; if( p == psz_chain ) return NULL; *ppsz_name = strndup( psz_chain, p - psz_chain ); SKIPSPACE( p ); if( *p == '{' ) { char *psz_name; p++; for( ;; ) { sout_cfg_t cfg; SKIPSPACE( p ); psz_name = p; while( *p && *p != '=' && *p != ',' && *p != '{' && *p != '}' && *p != ' ' && *p != '\t' ) p++; /* fprintf( stderr, "name=%s - rest=%s\n", psz_name, p ); */ if( p == psz_name ) { fprintf( stderr, "invalid options (empty)" ); break; } cfg.psz_name = strndup( psz_name, p - psz_name ); SKIPSPACE( p ); if( *p == '=' || *p == '{' ) { char *end; vlc_bool_t b_keep_brackets = (*p == '{'); if( *p == '=' ) p++; end = _get_chain_end( p ); if( end <= p ) { cfg.psz_value = NULL; } else { /* Skip heading and trailing spaces. * This ain't necessary but will avoid simple * user mistakes. */ SKIPSPACE( p ); } if( end <= p ) { cfg.psz_value = NULL; } else { if( *p == '\'' || *p == '"' || ( !b_keep_brackets && *p == '{' ) ) { p++; if( *(end-1) != '\'' && *(end-1) == '"' ) SKIPTRAILINGSPACE( p, end ); if( end - 1 <= p ) cfg.psz_value = NULL; else cfg.psz_value = strndup( p, end -1 - p ); } else { SKIPTRAILINGSPACE( p, end ); if( end <= p ) cfg.psz_value = NULL; else cfg.psz_value = strndup( p, end - p ); } } p = end; SKIPSPACE( p ); } else { cfg.psz_value = NULL; } cfg.p_next = NULL; if( p_cfg ) { p_cfg->p_next = malloc( sizeof( sout_cfg_t ) ); memcpy( p_cfg->p_next, &cfg, sizeof( sout_cfg_t ) ); p_cfg = p_cfg->p_next; } else { p_cfg = malloc( sizeof( sout_cfg_t ) ); memcpy( p_cfg, &cfg, sizeof( sout_cfg_t ) ); *pp_cfg = p_cfg; } if( *p == ',' ) p++; if( *p == '}' ) { p++; break; } } } if( *p == ':' ) return( strdup( p + 1 ) ); return NULL;}static void sout_CfgDestroy( sout_cfg_t *p_cfg ){ while( p_cfg != NULL ) { sout_cfg_t *p_next; p_next = p_cfg->p_next; FREE( p_cfg->psz_name ); FREE( p_cfg->psz_value ); free( p_cfg ); p_cfg = p_next; }}void __sout_CfgParse( vlc_object_t *p_this, char *psz_prefix, const char **ppsz_options, sout_cfg_t *cfg ){ char *psz_name; int i_type; int i; /* First, var_Create all variables */ for( i = 0; ppsz_options[i] != NULL; i++ ) { asprintf( &psz_name, "%s%s", psz_prefix, *ppsz_options[i] == '*' ? &ppsz_options[i][1] : ppsz_options[i] ); i_type = config_GetType( p_this, psz_name ); var_Create( p_this, psz_name, i_type | VLC_VAR_DOINHERIT ); free( psz_name ); } /* Now parse options and set value */ if( psz_prefix == NULL ) psz_prefix = ""; while( cfg ) { vlc_value_t val; vlc_bool_t b_yes = VLC_TRUE; vlc_bool_t b_once = VLC_FALSE; if( cfg->psz_name == NULL || *cfg->psz_name == '\0' ) { cfg = cfg->p_next; continue; } for( i = 0; ppsz_options[i] != NULL; i++ ) { if( !strcmp( ppsz_options[i], cfg->psz_name ) ) { break; } if( ( !strncmp( cfg->psz_name, "no-", 3 ) && !strcmp( ppsz_options[i], cfg->psz_name + 3 ) ) || ( !strncmp( cfg->psz_name, "no", 2 ) && !strcmp( ppsz_options[i], cfg->psz_name + 2 ) ) ) { b_yes = VLC_FALSE; break; } if( *ppsz_options[i] == '*' && !strcmp( &ppsz_options[i][1], cfg->psz_name ) ) { b_once = VLC_TRUE; break; } } if( ppsz_options[i] == NULL ) { msg_Warn( p_this, "option %s is unknown", cfg->psz_name ); cfg = cfg->p_next; continue; } /* create name */ asprintf( &psz_name, "%s%s", psz_prefix, b_once ? &ppsz_options[i][1] : ppsz_options[i] ); /* get the type of the variable */ i_type = config_GetType( p_this, psz_name ); if( !i_type ) { msg_Warn( p_this, "unknown option %s (value=%s)", cfg->psz_name, cfg->psz_value ); goto next; } if( i_type != VLC_VAR_BOOL && cfg->psz_value == NULL ) { msg_Warn( p_this, "missing value for option %s", cfg->psz_name ); goto next; } if( i_type != VLC_VAR_STRING && b_once ) { msg_Warn( p_this, "*option_name need to be a string option" ); goto next; } switch( i_type ) { case VLC_VAR_BOOL: val.b_bool = b_yes; break; case VLC_VAR_INTEGER: val.i_int = strtol( cfg->psz_value ? cfg->psz_value : "0", NULL, 0 ); break; case VLC_VAR_FLOAT: val.f_float = atof( cfg->psz_value ? cfg->psz_value : "0" ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: val.psz_string = cfg->psz_value; break; default: msg_Warn( p_this, "unhandled config var type" ); memset( &val, 0, sizeof( vlc_value_t ) ); break; } if( b_once ) { vlc_value_t val2; var_Get( p_this, psz_name, &val2 ); if( *val2.psz_string ) { free( val2.psz_string ); msg_Dbg( p_this, "ignoring option %s (not first occurrence)", psz_name ); goto next; } free( val2.psz_string ); } var_Set( p_this, psz_name, val ); msg_Dbg( p_this, "set sout option: %s to %s", psz_name, cfg->psz_value ); next: free( psz_name ); cfg = cfg->p_next; }}/* * XXX name and p_cfg are used (-> do NOT free them) */sout_stream_t *sout_StreamNew( sout_instance_t *p_sout, char *psz_chain ){ sout_stream_t *p_stream; if( !psz_chain ) { msg_Err( p_sout, "invalid chain" ); return NULL; } p_stream = vlc_object_create( p_sout, sizeof( sout_stream_t ) ); if( !p_stream ) { msg_Err( p_sout, "out of memory" ); return NULL; } p_stream->p_sout = p_sout; p_stream->p_sys = NULL; p_stream->psz_next = sout_CfgCreate( &p_stream->psz_name, &p_stream->p_cfg, psz_chain); msg_Dbg( p_sout, "stream=`%s'", p_stream->psz_name ); vlc_object_attach( p_stream, p_sout ); p_stream->p_module = module_Need( p_stream, "sout stream", p_stream->psz_name, VLC_TRUE ); if( !p_stream->p_module ) { sout_StreamDelete( p_stream ); return NULL; } return p_stream;}void sout_StreamDelete( sout_stream_t *p_stream ){ msg_Dbg( p_stream, "destroying chain... (name=%s)", p_stream->psz_name ); vlc_object_detach( p_stream ); if( p_stream->p_module ) module_Unneed( p_stream, p_stream->p_module ); FREE( p_stream->psz_name ); FREE( p_stream->psz_next ); sout_CfgDestroy( p_stream->p_cfg ); msg_Dbg( p_stream, "destroying chain done" ); vlc_object_destroy( p_stream );}static char *_sout_stream_url_to_chain( vlc_object_t *p_this, char *psz_url ){ mrl_t mrl; char *psz_chain, *p; mrl_Parse( &mrl, psz_url ); p = psz_chain = malloc( 500 + strlen( mrl.psz_way ) + strlen( mrl.psz_access ) + strlen( mrl.psz_name ) ); if( config_GetInt( p_this, "sout-display" ) ) { p += sprintf( p, "duplicate{dst=display,dst=std{mux=\"%s\"," "access=\"%s\",url=\"%s\"}}", mrl.psz_way, mrl.psz_access, mrl.psz_name ); } else { p += sprintf( p, "std{mux=\"%s\",access=\"%s\",url=\"%s\"}", mrl.psz_way, mrl.psz_access, mrl.psz_name ); } mrl_Clean( &mrl ); return( psz_chain );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -