📄 bridge.c
字号:
}static int DelOut( sout_stream_t *p_stream, sout_stream_id_t *id ){ VLC_UNUSED(id); out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys; bridged_es_t *p_es; if ( !p_sys->b_inited ) { return VLC_SUCCESS; } vlc_mutex_lock( p_sys->p_lock ); p_es = p_sys->p_es; p_es->b_empty = true; block_ChainRelease( p_es->p_block ); p_es->p_block = false; p_es->b_changed = true; vlc_mutex_unlock( p_sys->p_lock ); p_sys->b_inited = false; return VLC_SUCCESS;}static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *p_buffer ){ out_sout_stream_sys_t *p_sys = (out_sout_stream_sys_t *)p_stream->p_sys; bridged_es_t *p_es; if ( (out_sout_stream_sys_t *)id != p_sys ) { block_ChainRelease( p_buffer ); return VLC_SUCCESS; } vlc_mutex_lock( p_sys->p_lock ); p_es = p_sys->p_es; *p_es->pp_last = p_buffer; while ( p_buffer != NULL ) { p_es->pp_last = &p_buffer->p_next; p_buffer = p_buffer->p_next; } vlc_mutex_unlock( p_sys->p_lock ); return VLC_SUCCESS;}/* * Bridge in */typedef struct in_sout_stream_sys_t{ sout_stream_t *p_out; vlc_mutex_t *p_lock; int i_id_offset; mtime_t i_delay;} in_sout_stream_sys_t;/***************************************************************************** * OpenIn: *****************************************************************************/static int OpenIn( vlc_object_t *p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; in_sout_stream_sys_t *p_sys; vlc_value_t val; p_sys = malloc( sizeof( in_sout_stream_sys_t ) ); p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next ); if( !p_sys->p_out ) { msg_Err( p_stream, "cannot create chain" ); free( p_sys ); return VLC_EGENERIC; } config_ChainParse( p_stream, SOUT_CFG_PREFIX_IN, ppsz_sout_options_in, p_stream->p_cfg ); var_Create( p_this->p_libvlc, "bridge-lock", VLC_VAR_MUTEX ); var_Get( p_this->p_libvlc, "bridge-lock", &val ); p_sys->p_lock = val.p_address; var_Get( p_stream, SOUT_CFG_PREFIX_IN "id-offset", &val ); p_sys->i_id_offset = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX_IN "delay", &val ); p_sys->i_delay = (mtime_t)val.i_int * 1000; p_stream->pf_add = AddIn; p_stream->pf_del = DelIn; p_stream->pf_send = SendIn; p_stream->p_sys = (sout_stream_sys_t *)p_sys; /* update p_sout->i_out_pace_nocontrol */ p_stream->p_sout->i_out_pace_nocontrol++; return VLC_SUCCESS;}/***************************************************************************** * CloseIn: *****************************************************************************/static void CloseIn( vlc_object_t * p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys; sout_StreamDelete( p_sys->p_out ); p_stream->p_sout->i_out_pace_nocontrol--; free( p_sys );}static sout_stream_id_t * AddIn( sout_stream_t *p_stream, es_format_t *p_fmt ){ in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys; return p_sys->p_out->pf_add( p_sys->p_out, p_fmt );}static int DelIn( sout_stream_t *p_stream, sout_stream_id_t *id ){ in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys; return p_sys->p_out->pf_del( p_sys->p_out, id );}static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *p_buffer ){ in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys; bridge_t *p_bridge; bool b_no_es = true; int i; /* First forward the packet for our own ES */ p_sys->p_out->pf_send( p_sys->p_out, id, p_buffer ); /* Then check all bridged streams */ vlc_mutex_lock( p_sys->p_lock ); p_bridge = GetBridge( p_stream ); if ( p_bridge == NULL ) { vlc_mutex_unlock( p_sys->p_lock ); return VLC_SUCCESS; } for ( i = 0; i < p_bridge->i_es_num; i++ ) { if ( !p_bridge->pp_es[i]->b_empty ) b_no_es = false; while ( p_bridge->pp_es[i]->p_block != NULL && (p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay < mdate() || p_bridge->pp_es[i]->p_block->i_dts + p_sys->i_delay < p_bridge->pp_es[i]->i_last) ) { block_t *p_block = p_bridge->pp_es[i]->p_block; msg_Dbg( p_stream, "dropping a packet (%"PRId64 ")", mdate() - p_block->i_dts - p_sys->i_delay ); p_bridge->pp_es[i]->p_block = p_bridge->pp_es[i]->p_block->p_next; block_Release( p_block ); } if ( p_bridge->pp_es[i]->p_block == NULL ) { p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block; } if ( p_bridge->pp_es[i]->b_changed ) { if ( p_bridge->pp_es[i]->b_empty && p_bridge->pp_es[i]->id != NULL ) { p_sys->p_out->pf_del( p_sys->p_out, p_bridge->pp_es[i]->id ); } else { /* We need at least two packets to enter the mux. */ if ( p_bridge->pp_es[i]->p_block == NULL || p_bridge->pp_es[i]->p_block->p_next == NULL ) { continue; } p_bridge->pp_es[i]->fmt.i_id += p_sys->i_id_offset; p_bridge->pp_es[i]->id = p_sys->p_out->pf_add( p_sys->p_out, &p_bridge->pp_es[i]->fmt ); if ( p_bridge->pp_es[i]->id == NULL ) { msg_Warn( p_stream, "couldn't create chain for id %d", p_bridge->pp_es[i]->fmt.i_id ); } msg_Dbg( p_stream, "bridging in input codec=%4.4s id=%d pos=%d", (char*)&p_bridge->pp_es[i]->fmt.i_codec, p_bridge->pp_es[i]->fmt.i_id, i ); } } p_bridge->pp_es[i]->b_changed = false; if ( p_bridge->pp_es[i]->b_empty ) continue; if ( p_bridge->pp_es[i]->p_block == NULL ) { if ( p_bridge->pp_es[i]->id != NULL && p_bridge->pp_es[i]->i_last < mdate() ) { p_sys->p_out->pf_del( p_sys->p_out, p_bridge->pp_es[i]->id ); p_bridge->pp_es[i]->fmt.i_id -= p_sys->i_id_offset; p_bridge->pp_es[i]->b_changed = true; p_bridge->pp_es[i]->id = NULL; } continue; } if ( p_bridge->pp_es[i]->id != NULL ) { block_t *p_block = p_bridge->pp_es[i]->p_block; while ( p_block != NULL ) { p_bridge->pp_es[i]->i_last = p_block->i_dts; p_block->i_pts += p_sys->i_delay; p_block->i_dts += p_sys->i_delay; p_block = p_block->p_next; } p_sys->p_out->pf_send( p_sys->p_out, p_bridge->pp_es[i]->id, p_bridge->pp_es[i]->p_block ); } else { block_ChainRelease( p_bridge->pp_es[i]->p_block ); } p_bridge->pp_es[i]->p_block = NULL; p_bridge->pp_es[i]->pp_last = &p_bridge->pp_es[i]->p_block; } if( b_no_es ) { vlc_object_t *p_libvlc = VLC_OBJECT( p_stream->p_libvlc ); for ( i = 0; i < p_bridge->i_es_num; i++ ) free( p_bridge->pp_es[i] ); free( p_bridge->pp_es ); free( p_bridge ); var_Destroy( p_libvlc, "bridge-struct" ); } vlc_mutex_unlock( p_sys->p_lock ); return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -