@ -1073,90 +1073,90 @@ void ast_rtp_instance_set_bridged(struct ast_rtp_instance *instance, struct ast_
instance - > bridged = bridged ;
}
void ast_rtp_instance_early_bridge_make_compatible ( struct ast_channel * c 0, struct ast_channel * c1 )
void ast_rtp_instance_early_bridge_make_compatible ( struct ast_channel * c _dst, struct ast_channel * c_src )
{
struct ast_rtp_instance * instance 0 = NULL , * instance1 = NULL ,
* vinstance 0 = NULL , * vinstance1 = NULL ,
* tinstance 0 = NULL , * tinstance1 = NULL ;
struct ast_rtp_glue * glue 0, * glue1 ;
enum ast_rtp_glue_result audio_glue 0_res = AST_RTP_GLUE_RESULT_FORBID , video_glue0 _res = AST_RTP_GLUE_RESULT_FORBID ;
enum ast_rtp_glue_result audio_glue 1_res = AST_RTP_GLUE_RESULT_FORBID , video_glue1 _res = AST_RTP_GLUE_RESULT_FORBID ;
struct ast_format_cap * cap 0 = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_NOLOCK ) ;
struct ast_format_cap * cap 1 = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_NOLOCK ) ;
struct ast_rtp_instance * instance _dst = NULL , * instance_src = NULL ,
* vinstance _dst = NULL , * vinstance_src = NULL ,
* tinstance _dst = NULL , * tinstance_src = NULL ;
struct ast_rtp_glue * glue _dst, * glue_src ;
enum ast_rtp_glue_result audio_glue _dst_res = AST_RTP_GLUE_RESULT_FORBID , video_glue_dst _res = AST_RTP_GLUE_RESULT_FORBID ;
enum ast_rtp_glue_result audio_glue _src_res = AST_RTP_GLUE_RESULT_FORBID , video_glue_src _res = AST_RTP_GLUE_RESULT_FORBID ;
struct ast_format_cap * cap _dst = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_NOLOCK ) ;
struct ast_format_cap * cap _src = ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_NOLOCK ) ;
/* Lock both channels so we can look for the glue that binds them together */
ast_channel_lock_both ( c 0, c1 ) ;
ast_channel_lock_both ( c _dst, c_src ) ;
if ( ! cap 1 | | ! cap0 ) {
if ( ! cap _src | | ! cap_dst ) {
goto done ;
}
/* Grab glue that binds each channel to something using the RTP engine */
if ( ! ( glue 0 = ast_rtp_instance_get_glue ( ast_channel_tech ( c0 ) - > type ) ) | | ! ( glue 1 = ast_rtp_instance_get_glue ( ast_channel_tech ( c1 ) - > type ) ) ) {
ast_debug ( 1 , " Can't find native functions for channel '%s' \n " , glue 0 ? ast_channel_name ( c1 ) : ast_channel_name ( c0 ) ) ;
if ( ! ( glue _dst = ast_rtp_instance_get_glue ( ast_channel_tech ( c_dst ) - > type ) ) | | ! ( glue _src = ast_rtp_instance_get_glue ( ast_channel_tech ( c_src ) - > type ) ) ) {
ast_debug ( 1 , " Can't find native functions for channel '%s' \n " , glue _dst ? ast_channel_name ( c_src ) : ast_channel_name ( c_dst ) ) ;
goto done ;
}
audio_glue 0_res = glue0 - > get_rtp_info ( c0 , & instance0 ) ;
video_glue 0_res = glue0 - > get_vrtp_info ? glue0 - > get_vrtp_info ( c0 , & vinstance0 ) : AST_RTP_GLUE_RESULT_FORBID ;
audio_glue _dst_res = glue_dst - > get_rtp_info ( c_dst , & instance_dst ) ;
video_glue _dst_res = glue_dst - > get_vrtp_info ? glue_dst - > get_vrtp_info ( c_dst , & vinstance_dst ) : AST_RTP_GLUE_RESULT_FORBID ;
audio_glue 1_res = glue1 - > get_rtp_info ( c1 , & instance1 ) ;
video_glue 1_res = glue1 - > get_vrtp_info ? glue1 - > get_vrtp_info ( c1 , & vinstance1 ) : AST_RTP_GLUE_RESULT_FORBID ;
audio_glue _src_res = glue_src - > get_rtp_info ( c_src , & instance_src ) ;
video_glue _src_res = glue_src - > get_vrtp_info ? glue_src - > get_vrtp_info ( c_src , & vinstance_src ) : AST_RTP_GLUE_RESULT_FORBID ;
/* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
if ( video_glue 0 _res ! = AST_RTP_GLUE_RESULT_FORBID & & ( audio_glue 0_res ! = AST_RTP_GLUE_RESULT_REMOTE | | video_glue0 _res ! = AST_RTP_GLUE_RESULT_REMOTE ) ) {
audio_glue 0 _res = AST_RTP_GLUE_RESULT_FORBID ;
if ( video_glue _dst _res ! = AST_RTP_GLUE_RESULT_FORBID & & ( audio_glue _dst_res ! = AST_RTP_GLUE_RESULT_REMOTE | | video_glue_dst _res ! = AST_RTP_GLUE_RESULT_REMOTE ) ) {
audio_glue _dst _res = AST_RTP_GLUE_RESULT_FORBID ;
}
if ( video_glue 1 _res ! = AST_RTP_GLUE_RESULT_FORBID & & ( audio_glue 1_res ! = AST_RTP_GLUE_RESULT_REMOTE | | video_glue1 _res ! = AST_RTP_GLUE_RESULT_REMOTE ) ) {
audio_glue 1 _res = AST_RTP_GLUE_RESULT_FORBID ;
if ( video_glue _src _res ! = AST_RTP_GLUE_RESULT_FORBID & & ( audio_glue _src_res ! = AST_RTP_GLUE_RESULT_REMOTE | | video_glue_src _res ! = AST_RTP_GLUE_RESULT_REMOTE ) ) {
audio_glue _src _res = AST_RTP_GLUE_RESULT_FORBID ;
}
if ( audio_glue 0 _res = = AST_RTP_GLUE_RESULT_REMOTE & & ( video_glue 0_res = = AST_RTP_GLUE_RESULT_FORBID | | video_glue0 _res = = AST_RTP_GLUE_RESULT_REMOTE ) & & glue 0 - > get_codec ) {
glue 0- > get_codec ( c0 , cap0 ) ;
if ( audio_glue _dst _res = = AST_RTP_GLUE_RESULT_REMOTE & & ( video_glue _dst_res = = AST_RTP_GLUE_RESULT_FORBID | | video_glue_dst _res = = AST_RTP_GLUE_RESULT_REMOTE ) & & glue _dst - > get_codec ) {
glue _dst- > get_codec ( c_dst , cap_dst ) ;
}
if ( audio_glue 1 _res = = AST_RTP_GLUE_RESULT_REMOTE & & ( video_glue 1_res = = AST_RTP_GLUE_RESULT_FORBID | | video_glue1 _res = = AST_RTP_GLUE_RESULT_REMOTE ) & & glue 1 - > get_codec ) {
glue 1- > get_codec ( c1 , cap1 ) ;
if ( audio_glue _src _res = = AST_RTP_GLUE_RESULT_REMOTE & & ( video_glue _src_res = = AST_RTP_GLUE_RESULT_FORBID | | video_glue_src _res = = AST_RTP_GLUE_RESULT_REMOTE ) & & glue _src - > get_codec ) {
glue _src- > get_codec ( c_src , cap_src ) ;
}
/* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
if ( audio_glue 0_res ! = AST_RTP_GLUE_RESULT_REMOTE | | audio_glue1 _res ! = AST_RTP_GLUE_RESULT_REMOTE ) {
if ( audio_glue _dst_res ! = AST_RTP_GLUE_RESULT_REMOTE | | audio_glue_src _res ! = AST_RTP_GLUE_RESULT_REMOTE ) {
goto done ;
}
/* Make sure we have matching codecs */
if ( ! ast_format_cap_has_joint ( cap 0, cap1 ) ) {
if ( ! ast_format_cap_has_joint ( cap _dst, cap_src ) ) {
goto done ;
}
ast_rtp_codecs_payloads_copy ( & instance 0- > codecs , & instance1 - > codecs , instance1 ) ;
ast_rtp_codecs_payloads_copy ( & instance _src- > codecs , & instance_dst - > codecs , instance_dst ) ;
if ( vinstance 0 & & vinstance1 ) {
ast_rtp_codecs_payloads_copy ( & vinstance 0- > codecs , & vinstance1 - > codecs , vinstance1 ) ;
if ( vinstance _dst & & vinstance_src ) {
ast_rtp_codecs_payloads_copy ( & vinstance _src- > codecs , & vinstance_dst - > codecs , vinstance_dst ) ;
}
if ( tinstance 0 & & tinstance1 ) {
ast_rtp_codecs_payloads_copy ( & tinstance 0- > codecs , & tinstance1 - > codecs , tinstance1 ) ;
if ( tinstance _dst & & tinstance_src ) {
ast_rtp_codecs_payloads_copy ( & tinstance _src- > codecs , & tinstance_dst - > codecs , tinstance_dst ) ;
}
if ( glue 0- > update_peer ( c0 , instance1 , vinstance1 , tinstance1 , cap1 , 0 ) ) {
if ( glue _dst- > update_peer ( c_dst , instance_src , vinstance_src , tinstance_src , cap_src , 0 ) ) {
ast_log ( LOG_WARNING , " Channel '%s' failed to setup early bridge to '%s' \n " ,
ast_channel_name ( c 0) , ast_channel_name ( c1 ) ) ;
ast_channel_name ( c _dst) , ast_channel_name ( c_src ) ) ;
} else {
ast_debug ( 1 , " Seeded SDP of '%s' with that of '%s' \n " ,
ast_channel_name ( c 0) , ast_channel_name ( c1 ) ) ;
ast_channel_name ( c _dst) , ast_channel_name ( c_src ) ) ;
}
done :
ast_channel_unlock ( c 0 ) ;
ast_channel_unlock ( c 1 ) ;
ast_format_cap_destroy ( cap 0 ) ;
ast_format_cap_destroy ( cap 1 ) ;
unref_instance_cond ( & instance 0 ) ;
unref_instance_cond ( & instance 1 ) ;
unref_instance_cond ( & vinstance 0 ) ;
unref_instance_cond ( & vinstance 1 ) ;
unref_instance_cond ( & tinstance 0 ) ;
unref_instance_cond ( & tinstance 1 ) ;
ast_channel_unlock ( c _dst ) ;
ast_channel_unlock ( c _src ) ;
ast_format_cap_destroy ( cap _dst ) ;
ast_format_cap_destroy ( cap _src ) ;
unref_instance_cond ( & instance _dst ) ;
unref_instance_cond ( & instance _src ) ;
unref_instance_cond ( & vinstance _dst ) ;
unref_instance_cond ( & vinstance _src ) ;
unref_instance_cond ( & tinstance _dst ) ;
unref_instance_cond ( & tinstance _src ) ;
}
int ast_rtp_instance_early_bridge ( struct ast_channel * c0 , struct ast_channel * c1 )