diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c index 50d3a69c798b644dca6e148cadc78a19e4b84dae..c404e54baea2ad1661c09c2248a0d12705e858ab 100644 --- a/channels/chan_brcm.c +++ b/channels/chan_brcm.c @@ -701,9 +701,19 @@ static void endpt_connection(int line, int id, char *action) { static void chan_brcm_modify_codec(struct brcm_subchannel *sub) { if (sub->owner && sub->updated_codec != 1 ) { ast_debug(4, "sub->owner Channel %s, ast_channel_codec_get(): %s\n",ast_channel_name(sub->owner), ast_channel_codec_get(sub->owner)); - ast_channel_unlock(sub->owner); - struct ast_channel *bridged_chan = ast_channel_bridge_peer(sub->owner); ast_channel_lock(sub->owner); + struct ast_bridge *bridge = ast_channel_internal_bridge(sub->owner); + struct ast_bridge_channel *bridge_channel; + struct ast_channel *bridged_chan=NULL; + if(bridge){ + AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) { + if ( strcmp(ast_channel_name(bridge_channel->chan), ast_channel_name(sub->owner)) ){ + bridged_chan = ast_channel_get_by_name(ast_channel_name(bridge_channel->chan)); + break; + } + } + } + if (bridged_chan) { ast_debug(5, "Got bridged_chan\n"); @@ -729,8 +739,7 @@ static void chan_brcm_modify_codec(struct brcm_subchannel *sub) { ast_channel_codec_get(bridged_chan) : ast_format_get_name(ast_channel_writeformat(bridged_chan))); } ao2_ref(bridged_chan, -1); - } else if ((!brcm_in_conference(sub->parent) && sub->call_direction == INCOMING_CALL) || ast_strlen_zero(ast_channel_codec_get(sub->owner))) { - //return for incoming_call that waiting for bridge peer, but exclude the scenario of conference which could not obtain the bridged_chan here. + } else if (ast_strlen_zero(ast_channel_codec_get(sub->owner))) { //return if has no codec set ast_channel_unlock(sub->owner); return; @@ -820,8 +829,8 @@ static int brcm_indicate(struct ast_channel *ast, int condition, const void *dat //do not re-sync if the held party left when still on the other conversation sub->updated_codec = 1; } - chan_brcm_modify_codec(sub); pvt_unlock(sub->parent); + chan_brcm_modify_codec(sub); break; case AST_CONTROL_RINGING: pvt_lock(sub->parent, "indicate"); @@ -832,7 +841,9 @@ static int brcm_indicate(struct ast_channel *ast, int condition, const void *dat endpt_signal(sub->parent->line_id, "ringback", "on", NULL); } else { sub->updated_codec = 0; // do a sync if incoming media. + pvt_unlock(sub->parent); chan_brcm_modify_codec(sub); + pvt_lock(sub->parent, "indicate"); } if (sub->owner && (get_callid_state(sub->call_id) != CALLID_ESTABLISHED)) { sub->call_id = ast_channel_callid(sub->owner); @@ -1036,16 +1047,16 @@ static int brcm_getRtpStats(struct ast_channel *ast) return -1; } - pvt_lock(sub->parent, "brcm_getRtpStats"); if (sub->parent) { + pvt_lock(sub->parent, "brcm_getRtpStats"); if (endpt_get_rtp_stats(sub->parent->line_id)) { ast_log(LOG_WARNING, "Unable to get RTP statistics\n"); } + pvt_unlock(sub->parent); ast_channel_lock(ast); ast_channel_rtpStats_set(ast, &sub->rtp_stats); ast_channel_unlock(ast); } - pvt_unlock(sub->parent); return 0; } @@ -1736,10 +1747,10 @@ static int brcm_write(struct ast_channel *ast, struct ast_frame *frame) ast_channel_codec_set(sub->owner, ast_format_get_name(frame->subclass.format)); ast_log(LOG_NOTICE, "set local codec to :%s \n", ast_channel_codec_get(sub->owner)); } - chan_brcm_modify_codec(sub); //in case of no bridge peer when doing the modify_codec during incoming call, or early media on outgoing //ast_mutex_unlock(&sub->parent->lock); pvt_unlock(sub->parent); + chan_brcm_modify_codec(sub); //in case of early media on outgoing pe_bus_send(audio_tx_bus, (uint8_t *)ap, packet_size); free(ap);