📄 stream_output.c
字号:
p_mux->p_sout = p_sout; psz_next = sout_CfgCreate( &p_mux->psz_mux, &p_mux->p_cfg, psz_mux ); if( psz_next ) 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 = VLC_FALSE; p_mux->b_waiting_stream = VLC_TRUE; p_mux->i_add_stream_start = -1; vlc_object_attach( p_mux, p_sout ); p_mux->p_module = module_Need( p_mux, "sout mux", p_mux->psz_mux, VLC_TRUE ); if( p_mux->p_module == NULL ) { FREE( p_mux->psz_mux ); vlc_object_detach( p_mux ); vlc_object_destroy( p_mux ); return NULL; } /* *** probe mux capacity *** */ if( p_mux->pf_control ) { int b_answer = VLC_FALSE; if( sout_MuxControl( p_mux, MUX_CAN_ADD_STREAM_WHILE_MUXING, &b_answer ) ) { b_answer = VLC_FALSE; } if( b_answer ) { msg_Dbg( p_sout, "muxer support adding stream at any time" ); p_mux->b_add_stream_any_time = VLC_TRUE; p_mux->b_waiting_stream = VLC_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 = VLC_TRUE; } else if( sout_MuxControl( p_mux, MUX_GET_ADD_STREAM_WAIT, &b_answer ) ) { b_answer = VLC_FALSE; } if( b_answer ) { msg_Dbg( p_sout, "muxer prefers waiting for all ES before " "starting muxing" ); p_mux->b_waiting_stream = VLC_TRUE; } } } return p_mux;}/***************************************************************************** * sout_MuxDelete: *****************************************************************************/void sout_MuxDelete( sout_mux_t *p_mux ){ vlc_object_detach( p_mux ); if( p_mux->p_module ) { module_Unneed( p_mux, p_mux->p_module ); } free( p_mux->psz_mux ); sout_CfgDestroy( p_mux->p_cfg ); vlc_object_destroy( p_mux );}/***************************************************************************** * sout_MuxAddStream: *****************************************************************************/sout_input_t *sout_MuxAddStream( sout_mux_t *p_mux, es_format_t *p_fmt ){ sout_input_t *p_input; if( !p_mux->b_add_stream_any_time && !p_mux->b_waiting_stream ) { msg_Err( p_mux, "cannot add a new stream (unsuported while muxing " "for this format)" ); return NULL; } msg_Dbg( p_mux, "adding a new input" ); /* create a new sout input */ p_input = malloc( sizeof( sout_input_t ) ); p_input->p_sout = p_mux->p_sout; p_input->p_fmt = p_fmt; p_input->p_fifo = block_FifoNew( p_mux->p_sout ); p_input->p_sys = NULL; TAB_APPEND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input ); if( p_mux->pf_addstream( p_mux, p_input ) < 0 ) { msg_Err( p_mux, "cannot add this stream" ); TAB_REMOVE( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input ); block_FifoRelease( p_input->p_fifo ); free( p_input ); return NULL; } return p_input;}/***************************************************************************** * sout_MuxDeleteStream: *****************************************************************************/void sout_MuxDeleteStream( sout_mux_t *p_mux, sout_input_t *p_input ){ int i_index; if( p_mux->b_waiting_stream && p_input->p_fifo->i_depth > 0 ) { /* We stop waiting, and call the muxer for taking care of the data * before we remove this es */ p_mux->b_waiting_stream = VLC_FALSE; p_mux->pf_mux( p_mux ); } TAB_FIND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input, i_index ); if( i_index >= 0 ) { if( p_mux->pf_delstream( p_mux, p_input ) < 0 ) { msg_Err( p_mux, "cannot del this stream from mux" ); } /* remove the entry */ TAB_REMOVE( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input ); if( p_mux->i_nb_inputs == 0 ) { msg_Warn( p_mux, "no more input stream for this mux" ); } block_FifoRelease( p_input->p_fifo ); free( p_input ); }}/***************************************************************************** * sout_MuxSendBuffer: *****************************************************************************/void sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input, block_t *p_buffer ){ block_FifoPut( p_input->p_fifo, p_buffer ); if( p_mux->p_sout->i_out_pace_nocontrol ) { mtime_t current_date = mdate(); if ( current_date > p_buffer->i_dts ) msg_Warn( p_mux, "late buffer for mux input ("I64Fd")", current_date - p_buffer->i_dts ); } if( p_mux->b_waiting_stream ) { if( p_mux->i_add_stream_start < 0 ) { p_mux->i_add_stream_start = p_buffer->i_dts; } if( p_mux->i_add_stream_start >= 0 && p_mux->i_add_stream_start + I64C(1500000) < p_buffer->i_dts ) { /* Wait until we have more than 1.5 seconds worth of data * before start muxing */ p_mux->b_waiting_stream = VLC_FALSE; } else { return; } } p_mux->pf_mux( p_mux );}/***************************************************************************** * *****************************************************************************/static int mrl_Parse( mrl_t *p_mrl, char *psz_mrl ){ char * psz_dup = strdup( psz_mrl ); char * psz_parser = psz_dup; char * psz_access = ""; char * psz_way = ""; char * psz_name = ""; /* *** first parse psz_dest */ while( *psz_parser && *psz_parser != ':' ) { if( *psz_parser == '{' ) { while( *psz_parser && *psz_parser != '}' ) { psz_parser++; } if( *psz_parser ) { psz_parser++; } } else { psz_parser++; } }#if defined( WIN32 ) || defined( UNDER_CE ) if( psz_parser - psz_dup == 1 ) { /* msg_Warn( p_sout, "drive letter %c: found in source string", *psz_dup ) ; */ psz_parser = ""; }#endif if( !*psz_parser ) { psz_access = psz_way = ""; psz_name = psz_dup; } else { *psz_parser++ = '\0'; /* let's skip '//' */ if( psz_parser[0] == '/' && psz_parser[1] == '/' ) { psz_parser += 2 ; } psz_name = psz_parser ; /* Come back to parse the access and mux plug-ins */ psz_parser = psz_dup; if( !*psz_parser ) { /* No access */ psz_access = ""; } else if( *psz_parser == '/' ) { /* No access */ psz_access = ""; psz_parser++; } else { psz_access = psz_parser; while( *psz_parser && *psz_parser != '/' ) { if( *psz_parser == '{' ) { while( *psz_parser && *psz_parser != '}' ) { psz_parser++; } if( *psz_parser ) { psz_parser++; } } else { psz_parser++; } } if( *psz_parser == '/' ) { *psz_parser++ = '\0'; } } if( !*psz_parser ) { /* No mux */ psz_way = ""; } else { psz_way = psz_parser; } } p_mrl->psz_access = strdup( psz_access ); p_mrl->psz_way = strdup( psz_way ); p_mrl->psz_name = strdup( psz_name ); free( psz_dup ); return( VLC_SUCCESS );}/* mrl_Clean: clean p_mrl after a call to mrl_Parse */static void mrl_Clean( mrl_t *p_mrl ){ FREE( p_mrl->psz_access ); FREE( p_mrl->psz_way ); FREE( p_mrl->psz_name );}/**************************************************************************** **************************************************************************** ** ** ** **************************************************************************** ****************************************************************************//* create a complete chain *//* chain format: module{option=*:option=*}[:module{option=*:...}] *//* * parse module{options=str, option="str "}: * return a pointer on the rest * XXX: psz_chain is modified */#define SKIPSPACE( p ) { while( *p && ( *p == ' ' || *p == '\t' ) ) p++; }#define SKIPTRAILINGSPACE( p, e ) \ { while( e > p && ( *(e-1) == ' ' || *(e-1) == '\t' ) ) e--; }/* go accross " " and { } */static char *_get_chain_end( char *str ){ char c, *p = str; SKIPSPACE( p ); for( ;; ) { if( !*p || *p == ',' || *p == '}' ) return p; if( *p != '{' && *p != '"' && *p != '\'' ) { p++; continue; } if( *p == '{' ) c = '}'; else c = *p; p++; for( ;; ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -